      $(function() {
        
        function toString(obj) {
          var o = [];
          if (obj == undefined) {
            o.push('undefined');
          } else if (obj === null) {
            o.push('null');
          } else if (obj === true) {
            o.push("true");
          } else if (obj === false) {
            o.push("false");
          } else if (obj.constructor == Object) {
            o.push("{");
            $.each(obj, function (key, value) {
              o.push("'");
              o.push(key);
              o.push("': ");
              o.push(toString(value));
              o.push(", ");
            });
            var last = o.pop();
            if (last == '{')
              o.push("{");
            o.push("}");
          } else if (obj.constructor == Array) {
            o.push("[");
            $.each(obj, function (key, value) {
              o.push(toString(value));
              o.push(", ");
            });
            o.pop();
            o.push("]");
          } else if (obj.constructor == String) {
            o.push('"');
            o.push(obj.replace('"', '\"'));
            o.push('"');
          } else {
            o.push(obj);
          }
          return o.join("");
        }
        
        $.fn.addOutput = function() {
          if (typeof console == 'object' && typeof console.log == 'function')
            console.log.apply(console, arguments);
          return this.append("<p>" + Array.prototype.slice.call(arguments, 0).join("") + "</p>");
        };

        function runTest() {
            var test = $(".output").empty();
            $.each($.query.get(), function(key, value) {
              test.addOutput('get "', key, '" => ', toString(value));
            });
            test.addOutput('tostring => ', toString(decodeURIComponent($.query.toString())));
        }

        $(window).bind("hashchange", function() {
            $.query = $.query.load(location.href);
            runTest();
        });
        runTest();
        
      });