__parseModelsFromRows__(rows, grouped) {

    if (grouped) {
      return ItemArray.from(rows);
    }

    if (!rows.length) {
      return new ModelArray(this.Model);
    }

    let keys = Object.keys(rows[0]);
    let cache = {};
    let mainCache = {};
    cache[this.Model.name] = mainCache;

    let columns = keys
      .filter(k => k[0] !== '$');

    let columnsObject = columns
      .reduce((columns, k) => {

        columns[k] = null;
        return columns;

      }, {});

    let shortAliasResolver = Object.keys(this._shortAliasMap).reduce((shortAliasResolver, alias) => {
      shortAliasResolver[this._shortAliasMap[alias]] = alias;
      return shortAliasResolver;
    }, {});

    let joinsObject = keys
      .filter(k => k[0] === '$')
      .reduce((joinsObject, k) => {

        let shortAliasMid = k.indexOf('$', 1);
        let shortAlias = k.substring(1, shortAliasMid);
        let resolved = k.split('$').map(c => c.split('__').map(v => shortAliasResolver[v] || v).join('__')).join('$');
        let resolvedMid = resolved.indexOf('$', 1);
        let resolvedName = resolved.substring(1, resolvedMid);
        let field = resolved.substring(resolvedMid + 1);
        let relationship = this.Model.relationship(resolvedName);

        joinsObject[resolvedName] = joinsObject[resolvedName] || {};

        let rModel = relationship.getModel()
        joinsObject[resolvedName].Model = rModel;
        cache[rModel.name] = {};

        joinsObject[resolvedName].shortAlias = shortAlias;
        joinsObject[resolvedName].resolvedName = resolvedName;
        joinsObject[resolvedName].key = k;
        joinsObject[resolvedName].multiple = relationship.immediateMultiple();

        joinsObject[resolvedName].columns = joinsObject[resolvedName].columns || [];
        joinsObject[resolvedName].columns.push(field);

        joinsObject[resolvedName].columnsObject = joinsObject[resolvedName].columnsObject || {};
        joinsObject[resolvedName].columnsObject[field] = null;

        joinsObject[resolvedName].cachedModel = null;

        return joinsObject;

      }, {});

    let joins = Object
      .keys(joinsObject)
      .sort((a, b) => a.length > b.length ? 1 : -1)
      .map(k => joinsObject[k]);

    let models = new ModelArray(this.Model);

    rows.forEach(row => {

      let model = mainCache[row.id];

      if (!model) {

        model = mainCache[row.id] = new this.Model(columns.reduce((obj, k) => {
          obj[k] = row[k];
          return obj;
        }, columnsObject), true);
        models.push(model);

      }

      joins.forEach(join => {

        let id = row[`\$${join.shortAlias}\$id`];

        let resolvedName = join.resolvedName;
        let resolvedNames = resolvedName.split('__');
        let joinName = resolvedNames.pop();
        let parentName = resolvedNames.join('__');

        let parentModel = parentName ? joinsObject[parentName].cachedModel : model;

        if (join.multiple) {
          parentModel && (parentModel.joined(joinName) || parentModel.setJoined(joinName, new ModelArray(join.Model)));
        }

        if (!id) {
          return;
        }

        let joinCache = cache[join.Model.name];
        let joinModel = join.cachedModel = joinCache[id];

        if (!joinModel) {
          joinModel = join.cachedModel = joinCache[id] = new join.Model(join.columns.reduce((obj, k) => {
            obj[k] = row[`\$${join.shortAlias}\$${k}`];
            return obj;
          }, join.columnsObject), true)
        }


        if (join.multiple) {
          let modelArray = parentModel.joined(joinName);
          !modelArray.has(joinModel) && modelArray.push(joinModel);
        } else {
          parentModel.joined(joinName) || parentModel.setJoined(joinName, joinModel);
        }

      });

    });

    return models;

  }
Given rows with repeated data (due to joining in multiple children), return only parent models (but include references to their children)
@param {Array} rows Rows from sql result
@param {Boolean} grouped Are these models grouped, if so, different procedure
@return {Nodal.ModelArray}
@private