docs: function objectExtendDeep(extended) {
    var currentObject;
    var currentType;
    var extendedType;
    var currentItem;
    var currentTypeInner;
  
    for (var i = 1, c = arguments.length; i < c; i++) {
      currentObject = arguments[i];
      if (!currentObject)
        continue;
      currentType = type(currentObject);
      extendedType = type(extended);
      // type mismatch
      if (currentType !== extendedType) {
        if (currentType === 'array') {
          extended = [];
        } else if (currentType === 'object' && extendedType !== 'function') {
          extended = {};
        }
        // else copy, primitive, date, regexp, function ...
      }
      // extend arrays
      if (currentType === 'array') {
        extended = extended.concat(currentObject);
      } else {
        // or objects ;)
        for (var key in currentObject) {
          if (ownProperty.call(currentObject, key)) {
            currentTypeInner = type(currentObject[key]);
            currentItem = currentObject[key];
            if (/^(object|array)$/.test(currentTypeInner)) {
              extended[key] = objectExtendDeep(extended[key], currentItem);
            } else if (currentTypeInner === 'date') {
              extended[key] = new Date(currentItem.getTime());
            } else if (currentTypeInner === 'regexp') {
              extended[key] = cloneRegExp(currentItem);
            } else {
              extended[key] = currentItem;
            }
          }
        }
      }
    }
    return extended;
  }