code: function copy(source, destination){
    if (isWindow(source) || isScope(source)) throw Error("Can't copy Window or Scope");
    if (!destination) {
      destination = source;
      if (source) {
        if (isArray(source)) {
          destination = copy(source, []);
        } else if (isDate(source)) {
          destination = new Date(source.getTime());
        } else if (isObject(source)) {
          destination = copy(source, {});
        }
      }
    } else {
      if (source === destination) throw Error("Can't copy equivalent objects or arrays");
      if (isArray(source)) {
        while(destination.length) {
          destination.pop();
        }
        for ( var i = 0; i < source.length; i++) {
          destination.push(copy(source[i]));
        }
      } else {
        forEach(destination, function(value, key){
          delete destination[key];
        });
        for ( var key in source) {
          destination[key] = copy(source[key]);
        }
      }
    }
    return destination;
  }
docs: @ngdoc function
  @name angular.copy
  @function
  
  @description
  Creates a deep copy of `source`, which should be an object or an array.
  
  * If no destination is supplied, a copy of the object or array is created.
  * If a destination is provided, all of its elements (for array) or properties (for objects)
  are deleted and then all elements/properties from the source are copied to it.
  * If  `source` is not an object or array, `source` is returned.
  
  Note: this function is used to augment the Object type in Angular expressions. See
  {@link ng.$filter} for more information about Angular arrays.
  
  @param {*} source The source that will be used to make a copy.
  Can be any type, including primitives, `null`, and `undefined`.
  @param {(Object|Array)=} destination Destination into which the source is copied. If
  provided, must be of the same type as `source`.
  @returns {*} The copy or updated `destination`, if `destination` was specified.