Merge anything recursively.
Objects get merged, special objects (classes etc.) are re-assigned "as is".
Basic types overwrite objects or other basic types.

@param {(IConfig | any)} origin
@param {...any[]} newComers
@returns the result
function index (origin) {
    var newComers = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        newComers[_i - 1] = arguments[_i];
    }
    var extensions = null;
    var base = origin;
    if (isPlainObject(origin) && origin.extensions && Object.keys(origin).length === 1) {
        base = {};
        extensions = origin.extensions;
    }
    return newComers.reduce(function (result, newComer) {
        return mergeRecursively(result, newComer, extensions);
    }, base);
}