combineParameters = function combineParameters() {
  for (var _len = arguments.length, parameterSets = new Array(_len), _key = 0; _key < _len; _key++) {
    parameterSets[_key] = arguments[_key];
  }

  var mergeKeys = {};
  var combined = parameterSets.filter(Boolean).reduce(function (acc, p) {
    Object.entries(p).forEach(function (_ref) {
      var _ref2 = _slicedToArray(_ref, 2),
          key = _ref2[0],
          value = _ref2[1];

      var existing = acc[key];

      if (Array.isArray(value) || typeof existing === 'undefined') {
        acc[key] = value;
      } else if (lodash_isPlainObject__WEBPACK_IMPORTED_MODULE_16___default()(value) && lodash_isPlainObject__WEBPACK_IMPORTED_MODULE_16___default()(existing)) {
        // do nothing, we'll handle this later
        mergeKeys[key] = true;
      } else if (typeof value !== 'undefined') {
        acc[key] = value;
      }
    });
    return acc;
  }, {});
  Object.keys(mergeKeys).forEach(function (key) {
    var mergeValues = parameterSets.filter(Boolean).map(function (p) {
      return p[key];
    }).filter(function (value) {
      return typeof value !== 'undefined';
    });

    if (mergeValues.every(function (value) {
      return lodash_isPlainObject__WEBPACK_IMPORTED_MODULE_16___default()(value);
    })) {
      combined[key] = combineParameters.apply(void 0, _toConsumableArray(mergeValues));
    } else {
      combined[key] = mergeValues[mergeValues.length - 1];
    }
  });
  return combined;
}
Safely combine parameters recursively. Only copy objects when needed.
Algorithm = always overwrite the existing value UNLESS both values
are plain objects. In this case flag the key as "special" and handle
it with a heuristic.