/**
 *  Copyright 2015 Jaime Pajuelo
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */


"use strict";


/**
 * @param {Function} parentClass
 * @returns {Function} The instance on which this method was called.
 */
Function.prototype.inherit = function inherit(parentClass) {
    this.prototype = Object.create(parentClass.prototype);
    this.prototype.constructor = this;

    // TODO: think a better way to get the parent class.
    this.prototype.parentClass = parentClass;

    return this;
};


/**
 * @param {String} memberName
 * @param {Function} memberMethod
 * @returns {Function} The instance on which this method was called.
 */
Function.prototype.member = function member(memberName, memberMethod) {
    this.prototype[memberName] = memberMethod;

    return this;
};


/**
 * @namespace
 */
var utils = {

    /**
     * @param {Object} sourceObject
     * @returns {Object} The new object cloned.
     */
    cloneObject: function cloneObject(sourceObject) {
        if (sourceObject == null || typeof sourceObject !== 'object') {
            sourceObject = {};
        }

        return JSON.parse(JSON.stringify(sourceObject))
    },

    /**
     * @param {String} sourceString
     * @param {Object.<String, *>} namedArgs
     * @returns {String} The new string formatted.
     */
    formatString: function formatString(sourceString, namedArgs) {
        var name;

        for (name in namedArgs) {
            if (sourceString.indexOf("%(" + name + ")s") != -1) {
                sourceString = sourceString.replace("%(" + name + ")s", namedArgs[name]);
            }
        }

        return sourceString;
    },

    /**
     * @param {Object} sourceObject
     * @param {Object} targetObject
     * @return {Object} The sourceObject merged with targetObject.
     */
    updateObject: function updateObject(sourceObject, targetObject) {
        var name;

        sourceObject = this.cloneObject(sourceObject);
        targetObject = this.cloneObject(targetObject);

        for (name in sourceObject) {
            if (name in targetObject) {
                sourceObject[name] = targetObject[name];
            }
        }

        return sourceObject;
    }

};

@@ -1371,32 +1371,70 @@
 t%7D sourceObject%0A
+     * @param %7BBoolean%7D recursiveCall%0A
      * @returns 
@@ -1515,35 +1515,170 @@
 ect(sourceObject
-) %7B
+, recursiveCall) %7B%0A        var cloned, i;%0A%0A        if (typeof recursiveCall !== 'boolean') %7B%0A            recursiveCall = false;%0A        %7D%0A
 %0A        if (sou
@@ -1737,32 +1737,55 @@
 ') %7B%0A           
+ return recursiveCall ?
  sourceObject = 
@@ -1782,17 +1782,17 @@
 eObject 
-=
+:
  %7B%7D;%0A   
@@ -1811,55 +1811,509 @@
     
-return JSON.parse(JSON.stringify(sourceObject))
+if (sourceObject instanceof RegExp) %7B%0A            return sourceObject;%0A        %7D%0A%0A        if (Array.isArray(sourceObject)) %7B%0A            cloned = %5B%5D;%0A        %7D else %7B%0A            cloned = %7B%7D;%0A        %7D%0A%0A        for (i in sourceObject) %7B%0A            if (sourceObject%5Bi%5D != null && typeof sourceObject%5Bi%5D === 'object') %7B%0A                cloned%5Bi%5D = this.cloneObject(sourceObject%5Bi%5D, true);%0A            %7D else %7B%0A                cloned%5Bi%5D = sourceObject%5Bi%5D;%0A            %7D%0A        %7D%0A%0A        return cloned;
 %0A   

Improve the form of cloning objects