public function buildGroups($entities, $level = 0) {
		if(!count($this->groupDefinitions)) {
			throw new \RuntimeException('There are no groups defined.');
		}

		// Building groups
		/** @var Group[] $groups */
		$groups = [];
		if(!isset($this->groupDefinitions[$level])) {
			return [];
		}
		$groupDefinition = $this->groupDefinitions[$level];
		$entitiesByGroupUid = [];
		foreach($entities as $entity) {
			$groupUid = $level . '-' . call_user_func($groupDefinition->getUidRetriever(), $entity);
			if(!isset($groups[$groupUid])) {
				$groups[$groupUid] = new Group(
					$groupUid,
					call_user_func($groupDefinition->getGroupDataFactory(), $entity),
					$level,
					$entity
				);
				$entitiesByGroupUid[$groupUid] = [];
			}
			$entitiesByGroupUid[$groupUid][] = $entity;
		}
		foreach($entitiesByGroupUid as $groupUid => $iEntities) {
			$subGroups = $this->buildGroups($iEntities, $level + 1);
			foreach($subGroups as $subGroup) {
				$groups[$groupUid]->addChild($subGroup);
			}
		}

		/** @var IColumnData[][] $columnDatasByGroupUid */
		$columnDatasByGroupUid = [];
		foreach($entitiesByGroupUid as $groupUid => $iEntities) {
			if (!isset($columnDatasByGroupUid[$groupUid])) {
				$columnDatasByGroupUid[$groupUid] = [];
			}
		}

		$groupDefinition = $this->getGroup($level);
		foreach($this->getColumnDefinitions() as $columnId => $columnDefinition) {
			$columnFoundInGroup = false;
			foreach ($groupDefinition->getColumnDefinitionsWithDataFactories() as $columnDefinitionsWithDataFactory) {
				list($groupColumnDefinition, $columnDataFactory) = $columnDefinitionsWithDataFactory;
				if ($columnDefinition->equals($groupColumnDefinition)) {
					foreach($entitiesByGroupUid as $groupUid => $iEntities) {
						$columnDatasByGroupUid[$groupUid][] = $columnDataFactory($iEntities);
					}
					$columnFoundInGroup = true;
					break;
				}
			}
			if(!$columnFoundInGroup) {
				foreach($entitiesByGroupUid as $groupUid => $iEntities) {
					$columnDatasByGroupUid[$groupUid][] = null;
				}
			}
		}

		foreach($columnDatasByGroupUid as $groupUid => $columnDatas) {
			$groups[$groupUid]->setColumnDatas($columnDatas);
		}

		$finalGroups = array_values($groups);
		if(($sortingComparator = $groupDefinition->getSortingComparator()) !== null) {
			usort($finalGroups, $sortingComparator);
		}
		return $finalGroups;
	}