function Monkey(tree, pathInTree, definition) {
    var _this2 = this;

    // Properties
    this.tree = tree;
    this.path = pathInTree;
    this.definition = definition; // Adapting the definition's paths & projection to this monkey's case

    var projection = definition.projection,
        relative = _helpers.solveRelativePath.bind(null, pathInTree.slice(0, -1));

    if (definition.type === 'object') {
      this.projection = Object.keys(projection).reduce(function (acc, k) {
        acc[k] = relative(projection[k]);
        return acc;
      }, {});
      this.depPaths = Object.keys(this.projection).map(function (k) {
        return _this2.projection[k];
      });
    } else {
      this.projection = projection.map(relative);
      this.depPaths = this.projection;
    } // Internal state


    this.state = {
      killed: false
    };
    /**
     * Listener on the tree's `write` event.
     *
     * When the tree writes, this listener will check whether the updated paths
     * are of any use to the monkey and, if so, will update the tree's node
     * where the monkey sits.
     */

    this.writeListener = function (_ref) {
      var path = _ref.data.path;
      if (_this2.state.killed) return; // Is the monkey affected by the current write event?

      var concerned = (0, _helpers.solveUpdate)([path], _this2.relatedPaths());
      if (concerned) _this2.update();
    };
    /**
     * Listener on the tree's `monkey` event.
     *
     * When another monkey updates, this listener will check whether the
     * updated paths are of any use to the monkey and, if so, will update the
     * tree's node where the monkey sits.
     */


    this.recursiveListener = function (_ref2) {
      var _ref2$data = _ref2.data,
          monkey = _ref2$data.monkey,
          path = _ref2$data.path;
      if (_this2.state.killed) return; // Breaking if this is the same monkey

      if (_this2 === monkey) return; // Is the monkey affected by the current monkey event?

      var concerned = (0, _helpers.solveUpdate)([path], _this2.relatedPaths(false));
      if (concerned) _this2.update();
    }; // Binding listeners


    this.tree.on('write', this.writeListener);
    this.tree.on('_monkey', this.recursiveListener); // Updating relevant node

    this.update();
  }
Monkey core class

@constructor
@param {Baobab}           tree       - The bound tree.
@param {MonkeyDefinition} definition - A definition instance.