var Stack = require('./_Stack'),

assignMergeValue = require('./_assignMergeValue'),
baseFor = require('./_baseFor'),
baseMergeDeep = require('./_baseMergeDeep'),
isObject = require('./isObject'),
keysIn = require('./keysIn'),
safeGet = require('./_safeGet');

/**

* The base implementation of `_.merge` without support for multiple sources.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {number} srcIndex The index of `source`.
* @param {Function} [customizer] The function to customize merged values.
* @param {Object} [stack] Tracks traversed source values and their merged
*  counterparts.
*/

function baseMerge(object, source, srcIndex, customizer, stack) {

if (object === source) {
  return;
}
baseFor(source, function(srcValue, key) {
  stack || (stack = new Stack);
  if (isObject(srcValue)) {
    baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
  }
  else {
    var newValue = customizer
      ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
      : undefined;

    if (newValue === undefined) {
      newValue = srcValue;
    }
    assignMergeValue(object, key, newValue);
  }
}, keysIn);

}

module.exports = baseMerge;