docs: function encode(object, memo, path ) {
          memo = memo || new Map();
          path = path || "";
          if (object === undefined) {
              return {"%": "undefined"};
          } else if (Object(object) !== object) {
              if (typeof object == "number") {
                  if (object === Number.POSITIVE_INFINITY) {
                      return {"%": "+Infinity"};
                  } else if (object === Number.NEGATIVE_INFINITY) {
                      return {"%": "-Infinity"};
                  } else if (isNaN(object)) {
                      return {"%": "NaN"};
                  }
              }
              return object;
          } else {
              var id;
              if (memo.has(object)) {
                  return {"$": memo.get(object)};
              } else {
                  memo.set(object, path);
              }
  
              if (Q.isPromise(object) || typeof object === "function") {
                  if (remotes.has(object)) {
                      id = remotes.get(object);
                      // "@l" because it is local to the recieving end
                      return {"@l": id, "type": typeof object);
                  } else {
                    id = makeId();
                    makeLocal(id);
                    dispatchLocal(id, "resolve", object);
                    // "@r" because it is remote to the recieving end
                    return {"@r": id, "type": typeof object};
                  }
              } else if (Array.isArray(object)) {
                  return object.map(function (value, index) {
                      return encode(value, memo, path + "/" + index);
                  });
              } else if (
                  (
                      object.constructor === Object &&
                      Object.getPrototypeOf(object) === Object.prototype
                  ) ||
                  object instanceof Error
              ) {
                  var result = {};
                  if (object instanceof Error) {
                      result.message = object.message;
                      result.stack = object.stack;
                  }
                  for (var key in object) {
                      if (has.call(object, key)) {
                          var newKey = key.replace(/[@!%\$\/\\]/, function ($0) {
                              return "\\" + $0;
                          });
                          result[newKey] = encode(object[key], memo, path + "/" + newKey);
                      }
                  }
                  return result;
              } else {
                  id = makeId();
                  makeLocal(id);
                  dispatchLocal(id, "resolve", object);
                  // "@r" because it is remote to the recieving end
                  return {"@r": id, "type": typeof object};
              }
          }
      }