docs: function makeProxy(definition, names, send, rootDefinition) {
      if (! names) throw new Error("No name proxying definition " + JSON.stringify(definition));
      if (! Array.isArray(names)) names = [ names ];
  
      /* All definitions are objects! */
      if (typeof(definition) !== 'object') {
        throw new Error("Wrong proxy definition at " + names.join('.') + " for \n"
                      + JSON.stringify(rootDefinition, null, 1));
      }
  
      /* Initial object */
      var object = {};
  
      /* Function definitions, can be also at top level */
      if (definition['!$invocable$!'] === true) {
        var clone = names.slice(0);
  
        /* Can be called as "new F()" or "f()" */
        var Invocable = function() {
  
          /* Prepare our message */
          var message = { proxy: { proxy: clone, arguments: arguments }};
  
          /* Is this "new F()" or a normal call? */
          if (this instanceof Invocable) {
            message.newInstance = true;
            ProxyPromise.call(this, message, send);
            this.asProxy(true);
          } else {
            return new ProxyPromise(message, send);
          }
        }
  
        /* Functions can have members, so keep processing */
        object = Invocable;
  
      }
  
      /* Clone all the members of the definition */
      for (var i in definition) {
        (function(i) {
          var child = definition[i];
          var clone = names.slice(0);
          clone.push(i);
  
          /* Basic properties for the object to define */
          var props = { enumerable: true, configurable: false };
  
          /* Function definitions */
          if (child['!$invocable$!'] === true) {
            props.value = makeProxy(child, clone, send, rootDefinition);
          }
  
          /* Setters/getters definitions */
          else if (child.hasOwnProperty('!$value$!')) {
            var initialValue = child['!$value$!'];
            props['get'] = function() {
              var message = { proxy: { proxy: clone } };
              var promise = new ProxyPromise(message, send, initialValue);
              promise.asProxy = function() { return promise } // already a proxy
              promise.then(function(success) { initialValue = success });
              return promise; // return the original ProxyPromise instance
            };
            props['set'] = function(value) {
              initialValue = value;
              send({ proxy: { value: value, proxy: clone } })
                .then(function(success) { initialValue = success });
            };
          }
  
          /* Nested definitions get recursively processed */
          else if (typeof(child) === 'object') {
            props.value = makeProxy(child, clone, send, rootDefinition);
          }
  
          else if (i !== '!$invocable$!') {
            throw new Error("Wrong proxy definition at " + names.join('.') + "." + i + " for \n"
                          + JSON.stringify(rootDefinition, null, 1));
          }
  
          /* Define the properties for this */
          Object.defineProperty(object, i, props);
        })(i);
      }
  
      /* All done, return our object clone */
      return object;
    }