    //@include lib_Class.js

    /**
     * Utility sort callback functions to sort arrays.
     *
     * @requires sol.commom.DateUtils
     */
    sol.define("sol.common.ObjectSortUtils", {
      singleton: true,

      default: function (a, b) {
        if (a === b) {
          return 0;
        } else {
          return a < b ? -1 : 1;
        }
      },

      date: function (a, b) {
        return sol.common.DateUtils.isoToMoment(a)
          .diff(sol.common.DateUtils.isoToMoment(b));
      },

      number: function (a, b) {
        a = parseFloat(a);
        b = parseFloat(b);
        return sol.common.ObjectSortUtils.default(a, b);
      }

    });

    /**
     * @author MHe (ELO Digital Office GmbH)
     *
     * @requires sol.common.ObjectUtils
     * @requires sol.common.ObjectSortUtils
     */
    sol.define("sol.common.mixins.ObjectSort", {
      mixin: true,

      /**
         * Sort an array by specify sortCriteria.
         *
         * Imagine you have the following array:
         *
         *     [ { data: { propA: "A", propB: "B"} }, {data: { propA: "A", propB: "B"} }]
         *
         * If you want to sort by propA you can use the following sortCriteria structure.
         *  { prop: "data.propA" }
         *
         * Now the array will be sort by the object prop `propA` with ObjectSortUtils.default sort function.
         *
         * The sortCriteria will be used ObjectUtils.getProp function to determine the object property,
         * so the object could be sort by deeper structures as well as flat structures
         *
         * If you want simple sort an array by a prop you can easily pass the object keypath
         * instead of a sortCritiera object
         *
         *    sortCriterias: ["data.propA"]
         *
         * A sortCriteria has furthermore options. To use another sorting strategy you can pass
         * another function from ObjectSortUtils. Currently supported functions are default, date, number
         *
         *  sortCriterias: [{ prop: "data.propDate", type: "date" }]
         *
         * @param {Array<Object>} arr The array to sort
         * @param {Array<Object>} sortCriterias determine the props to sort
         * @param {*} options object
         * @param {Boolean} [options.clone=true] If you want to sort the original object set this option to false. Default is true
         *
         *
         * @returns sorted array
         */
      sortArray: function (arr, sortCriterias, options) {
        var arrayToSort = arr, me = this,
            ObjectUtils = sol.common.ObjectUtils,
            ObjectSortUtils = sol.common.ObjectSortUtils,
            propSortAlgorithm = function (a, b) {
              var result, aValue, bValue, sortFunction, index = 0,
                  currentCriteria = sortCriterias[index];

              do {
                aValue = ObjectUtils.getProp(a, currentCriteria.prop);
                bValue = ObjectUtils.getProp(b, currentCriteria.prop);

                // Call dynamically the passed sort function. If the type doesn't exist
                // default sort function will be used
                me.logger.info(["current type {0}, {1}", currentCriteria.type, ObjectSortUtils[currentCriteria.type]]);
                sortFunction = ObjectSortUtils[currentCriteria.type] || ObjectSortUtils.default;
                result = sortFunction.call(me, aValue, bValue);

                currentCriteria = sortCriterias[++index];
                // perform sort criteria as soon as sort criteria are available
                // so we can sort after multiple criteria
              } while (result === 0 && currentCriteria);

              return result;
            };

        options = options || {};
        options.clone = options.clone || true;

        if (!arr) {
          throw Error("`arr` is not defined");
        }

        if (options.clone) {
          // make a copy of the arr to sort - avoid potentially side effects
          arrayToSort = ObjectUtils.clone(arr);
        }

        me.logger.debug(["sort criteria {0}", JSON.stringify(sortCriterias)]);

        me.hasSortCriteria(sortCriterias)
            && arrayToSort.sort(propSortAlgorithm);

        return arrayToSort;
      },

      hasSortCriteria: function (sortCriterias) {
        return sortCriterias && sortCriterias.length > 0;
      },

      generateSort: function (sorts) {
        var sortStatements = [], statement,
            ObjectUtils = sol.common.ObjectUtils;

        if (sorts && !sol.common.ObjectUtils.isArray(sorts)) {
          throw "`options.sort` must be an array! current type: " + typeof sorts;
        }

        ObjectUtils.forEach(sorts, function (el) {
          if (ObjectUtils.isObject(el)) {
            if (!el.prop) {
              throw Error("`options.sort` entry need attribute `prop`. Example: { 'prop': 'name' }");
            }

            statement = el;
          } else if (ObjectUtils.isString(el)) {
            statement = { prop: el };
          } else {
            throw Error("`options.sort` entry could not parse " + JSON.stringify(el));
          }

          sortStatements.push(statement);
        });

        return sortStatements;
      }
    });