code: function groupRowsByParents(rows, from, to) {
      if (from && to) {
          var nodeById = {};
          var l = rows.length;
          var node = null;
          nodeById[0] = new TreeNode(); // that's the root node
          var uniqIDs = rows.reduce(function (arr, item) {
              var toValue = to(item);
              if (arr.indexOf(toValue) === -1) {
                  arr.push(toValue);
              }
              return arr;
          }, []);
          for (var i = 0; i < l; i++) { // make TreeNode objects for each item
              nodeById[to(rows[i])] = new TreeNode(rows[i]);
          }
          for (var i = 0; i < l; i++) { // link all TreeNode objects
              node = nodeById[to(rows[i])];
              var parent_1 = 0;
              var fromValue = from(node.row);
              if (!!fromValue && (uniqIDs.indexOf(fromValue) > -1)) {
                  parent_1 = fromValue;
              }
              node.parent = nodeById[parent_1];
              node.row['level'] = node.parent.row['level'] + 1;
              node.parent.children.push(node);
          }
          var resolvedRows_1 = [];
          nodeById[0].flatten(function () {
              resolvedRows_1 = resolvedRows_1.concat([this.row]);
          }, true);
          return resolvedRows_1;
      }
      else {
          return rows;
      }
  }
docs: This functions rearrange items by their parents
  Also sets the level value to each of the items
  
  Note: Expecting each item has a property called parentId
  Note: This algorithm will fail if a list has two or more items with same ID
  NOTE: This algorithm will fail if there is a deadlock of relationship
  
  For example,
  
  Input
  
  id -> parent
  1  -> 0
  2  -> 0
  3  -> 1
  4  -> 1
  5  -> 2
  7  -> 8
  6  -> 3
  
  
  Output
  id -> level
  1      -> 0
  --3    -> 1
  ----6  -> 2
  --4    -> 1
  2      -> 0
  --5    -> 1
  7     -> 8
  
  
  @param rows