function mergeObjects(a, b) {
    var merged, prop;

    if (typeof b === 'undefined') {
      return a;
    }

    // Check that we're dealing with two objects or two arrays.
    if (isVanillaObject(a) && isVanillaObject(b)) {
      merged = {};
    } else if (isArray(a) && isArray(b)) {
      merged = [];
    } else {
      // Otherwise there's no merging to do -- just replace a w/ b.
      return b;
    }

    for (prop in a) {
      merged[prop] = mergeObjects(a[prop], b[prop]);
    }
    for (prop in b) {
      if (!merged[prop]) {
        merged[prop] = b[prop];
      }
    }
    return merged;
  }
@private
@examples
mergeObjects({ foo: 1 }, { bar: 2 }); // => { foo: 1, bar: 2 }
mergeObjects({ foo: { bar: 1 } }, { foo: { baz: 2 } }); // => { foo: { bar: 1, baz: 2 } }
mergeObjects({ foo: { bar: 1 } }, { foo: undefined }); // => { foo: { bar: 1 } }
mergeObjects({ foo: { bar: 1 } }, { foo: null }); // => { foo: null }
mergeObjects({ array: [0, 1, 2] }, { array: [3, 4, 5] }).array; // instanceof Array
mergeObjects({ date: new Date() }, { date: new Date() }).date; // instanceof Date
mergeObjects([{ foo: 1 }], [{ bar: 2 }]); // => [{ foo: 1, bar: 2 }]