code: function(newValues, oldValues, paths) {
        var name, method, called = {};
        for (var i in oldValues) {
          // note: paths is of form [object, path, object, path]
          name = paths[2 * i + 1];
          method = this.observe[name];
          if (method) {
            var ov = oldValues[i], nv = newValues[i];
            // observes the value if it is an array
            this.observeArrayValue(name, nv, ov);
            if (!called[method]) {
              // only invoke change method if one of ov or nv is not (undefined | null)
              if ((ov !== undefined && ov !== null) || (nv !== undefined && nv !== null)) {
                called[method] = true;
                // TODO(sorvell): call method with the set of values it's expecting;
                // e.g. 'foo bar': 'invalidate' expects the new and old values for
                // foo and bar. Currently we give only one of these and then
                // deliver all the arguments.
                this.invokeMethod(method, [ov, nv, arguments]);
              }
            }
          }
        }
      }
docs: handler for property changes; routes changes to observing methods note: array valued properties are observed for array splices