/**
  * @param AggregateMessageGroup $agg
  * @return mixed
  */
 protected static function expandAggregates(AggregateMessageGroup $agg)
 {
     $flattened = array();
     /** @var MessageGroup|AggregateMessageGroup $group */
     foreach ($agg->getGroups() as $group) {
         if ($group instanceof AggregateMessageGroup) {
             $flattened += self::expandAggregates($group);
         } else {
             $flattened[$group->getId()] = $group;
         }
     }
     return $flattened;
 }
 /**
  * Like getGroupStructure but start from one root which must be an
  * AggregateMessageGroup.
  *
  * @param AggregateMessageGroup $parent
  * @throws MWException
  * @return array
  * @since Public since 2012-11-29
  */
 public static function subGroups(AggregateMessageGroup $parent)
 {
     static $recursionGuard = array();
     $pid = $parent->getId();
     if (isset($recursionGuard[$pid])) {
         $tid = $pid;
         $path = array($tid);
         do {
             $tid = $recursionGuard[$tid];
             $path[] = $tid;
             // Until we have gone full cycle
         } while ($tid !== $pid);
         $path = implode(' > ', $path);
         throw new MWException("Found cyclic aggregate message groups: {$path}");
     }
     // We don't care about the ids.
     $tree = array_values($parent->getGroups());
     usort($tree, array(__CLASS__, 'groupLabelSort'));
     // Expand aggregate groups (if any left) after sorting to form a tree
     foreach ($tree as $index => $group) {
         if ($group instanceof AggregateMessageGroup) {
             $sid = $group->getId();
             $recursionGuard[$pid] = $sid;
             $tree[$index] = self::subGroups($group);
             unset($recursionGuard[$pid]);
         }
     }
     // Parent group must be first item in the array
     array_unshift($tree, $parent);
     return $tree;
 }