text: 'use strict';
  
  var hasOwn = Object.prototype.hasOwnProperty;
  var toStr = Object.prototype.toString;
  
  var isPlainObject = function isPlainObject(obj) {
  	if (!obj || toStr.call(obj) !== '[object Object]') {
  		return false;
  	}
  
  	var hasOwnConstructor = hasOwn.call(obj, 'constructor');
  	var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
  	// Not own constructor property must be Object
  	if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
  		return false;
  	}
  
  	// Own properties are enumerated firstly, so to speed up,
  	// if last one is own, then all properties are own.
  	var key;
  	for (key in obj) {/**/}
  
  	return typeof key === 'undefined' || hasOwn.call(obj, key);
  };
  
  function merge() {
    var i, src, copy, clone, name,
        result = {},
       current = null,
        length = arguments.length;
  
    for (i=0; i < length; i++) {
      current = arguments[i];
      if (current == null) {
        continue;
      }
  
      for (name in current) {
        src = result[name];
        copy = current[name];
        if (result !== copy) {
          if (copy && isPlainObject(copy)) {
            clone = src && isPlainObject(src) ? src : {};
            result[name] = merge(clone, copy);
          } else if (typeof copy !== 'undefined') {
            result[name] = copy;
          }
        }
      }
    }
    return result;
  }
  
  module.exports = merge;
  