code: function diff(orig, dest, options) {
          var result, key, obj, objEx, origObj, origObjEx, i, t;
          orig = listToObject(orig, options.key);
          dest = listToObject(dest, options.key);
          result = { added: [], removed: [], modified: [], unchanged: [] };
          for (key in dest.valids) {
              if (dest.valids.hasOwnProperty(key)) {
                  obj = dest.valids[key];
                  origObj = orig.valids[key];
                  if (origObj === undefined) {
                      result.added.push(obj);
                  } else {
                      // keep and exclude
                      keep(origObj, obj, options);
                      objEx = exclude(obj, options.exclude);
                      origObjEx = exclude(origObj, options.exclude);
                      // compare
                      if (deepEqual(objEx, origObjEx)) {
                          result.unchanged.push(obj);
                      } else {
                          result.modified.push(obj);
                      }
                      delete orig.valids[key];
                  }
              }
          }
          for (key in orig.valids) {
              if (orig.valids.hasOwnProperty(key)) {
                  result.removed.push(orig.valids[key]);
              }
          }
          // discarded object (without a key)
          if (orig.discarded.length) {
              result.discardedOrig = orig.discarded;
          }
          if (dest.discarded.length) {
              result.discardedDest = dest.discarded;
          }
          // for (i = 0; i < orig.discarded.length; i =+ 1) {
          //     t = orig.discarded[i];
          // }
  
          return result;
      }
docs: Compare two arrays of objects and return the added/removed/modified objects
  
  options:
  - key: name of the key (mandatory)
  - exclude: optional list of excluded key (not compared)
  - keep: optional list of keys copied (before comparing) from orig to dest