code: function groupBy(keySelector, elementSelector, resultSelector, keyComparator) {
                              __assertFunction(keySelector);
                              __assertFunction(elementSelector);
                              __assert(__isUndefined(resultSelector) || __isFunction(resultSelector), 'resultSelector must be undefined or function!');
                              __assertFunction(keyComparator);
                              var groups = new Map();
                              var result = void 0;
                              var _iteratorNormalCompletion15 = true;
                              var _didIteratorError15 = false;
                              var _iteratorError15 = undefined;
  
                              try {
                                  for (var _iterator15 = self[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
                                      var val = _step15.value;
  
                                      // Instead of checking groups.has we use our custom function since we want to treat some keys as equal even if they aren't for the Map
                                      var key = __Collection.__getEqualKey(groups, keySelector(val), keyComparator);
                                      var elem = elementSelector(val);
                                      if (groups.has(key)) {
                                          groups.get(key).push(elem);
                                      } else {
                                          groups.set(key, [elem]);
                                      }
                                  }
                              } catch (err) {
                                  _didIteratorError15 = true;
                                  _iteratorError15 = err;
                              } finally {
                                  try {
                                      if (!_iteratorNormalCompletion15 && _iterator15.return) {
                                          _iterator15.return();
                                      }
                                  } finally {
                                      if (_didIteratorError15) {
                                          throw _iteratorError15;
                                      }
                                  }
                              }
  
                              if (resultSelector) {
                                  // If we want to select the final result with the resultSelector, we use the built-in Select function and retrieve a new Collection
                                  result = __Collection.from(groups).select(function (g) {
                                      return resultSelector.apply(undefined, _toConsumableArray(g));
                                  });
                              } else {
                                  // our result is just the groups -> return the Map
                                  result = groups;
                              }
                              return result;
                          }
docs: /*
  This is the "basic" function to use. The others just transform their parameters to be used with this one.