/**
  * @param array $listeners
  * @return array
  */
 private function mergeListenerGroups(array $listeners)
 {
     $listeners = new Collection($listeners);
     return $listeners->keys()->reduce(function (Collection $carry, $listenerGroup) use($listeners) {
         $events = new Collection($listeners->get($listenerGroup));
         return $events->keys()->reduce(function (Collection $carry, $event) use($events) {
             $listeners = $events->get($event);
             if (!is_array($listeners)) {
                 throw InvalidArgumentException::typeMisMatch('array', $listeners);
             }
             return $carry->set($event, array_merge($carry->get($event, []), $listeners));
         }, $carry);
     }, new Collection())->getArrayCopy();
 }
 /**
  * @param string $eventName
  * @param array $listeners
  * @param ContainerInterface $container
  * @param EventDispatcher $dispatcher
  * @throws \PhpSchool\PhpWorkshop\Exception\InvalidArgumentException
  */
 private function attachListeners($eventName, array $listeners, ContainerInterface $container, EventDispatcher $dispatcher)
 {
     array_walk($listeners, function ($listener) use($eventName, $dispatcher, $container) {
         if (is_callable($listener)) {
             return $dispatcher->listen($eventName, $listener);
         }
         if (!is_string($listener)) {
             throw new InvalidArgumentException(sprintf('Listener must be a callable or a container entry for a callable service.'));
         }
         if (!$container->has($listener)) {
             throw new InvalidArgumentException(sprintf('Container has no entry named: "%s"', $listener));
         }
         $listener = $container->get($listener);
         if (!is_callable($listener)) {
             throw InvalidArgumentException::typeMisMatch('callable', $listener);
         }
         return $dispatcher->listen($eventName, $listener);
     });
 }
 public function testExceptionFromTypeMisMatchConstructor()
 {
     $e = InvalidArgumentException::typeMisMatch('string', new \stdClass());
     $this->assertEquals('Expected: "string" Received: "stdClass"', $e->getMessage());
 }