function mixin(Base) {
  if (!Base.MIXINS) {
    Base.MIXINS = [];
  }

  for (var _len = arguments.length, mixins = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    mixins[_key - 1] = arguments[_key];
  }

  (0, _array.arrayEach)(mixins, function (mixinItem) {
    Base.MIXINS.push(mixinItem.MIXIN_NAME);
    objectEach(mixinItem, function (value, key) {
      if (Base.prototype[key] !== void 0) {
        throw new Error("Mixin conflict. Property '".concat(key, "' already exist and cannot be overwritten."));
      }

      if (typeof value === 'function') {
        Base.prototype[key] = value;
      } else {
        var getter = function _getter(property, initialValue) {
          var propertyName = "_".concat(property);

          var initValue = function initValue(newValue) {
            var result = newValue;

            if (Array.isArray(result) || isObject(result)) {
              result = deepClone(result);
            }

            return result;
          };

          return function () {
            if (this[propertyName] === void 0) {
              this[propertyName] = initValue(initialValue);
            }

            return this[propertyName];
          };
        };

        var setter = function _setter(property) {
          var propertyName = "_".concat(property);
          return function (newValue) {
            this[propertyName] = newValue;
          };
        };

        Object.defineProperty(Base.prototype, key, {
          get: getter(key, value),
          set: setter(key),
          configurable: true
        });
      }
    });
  });
  return Base;
}
Extend the Base object (usually prototype) of the functionality the `mixins` objects.

@param {Object} Base Base object which will be extended.
@param {Object} mixins The object of the functionality will be "copied".
@returns {Object}