/**
  * Resolve AbstractFactory
  *
  * @param ResolvedClass $resolved
  */
 public function resolve(ResolvedClass $resolved)
 {
     $class = $resolved->getClass();
     $pattern = new AbstractFactory($class->getFullname());
     $resolver = new TypeResolver();
     // we don't look private and non static methods
     $collection = (new Collection($class->getMethods()))->where(sprintf('method => method.getVisibility() == "public" and method.getState() == %s', ReflectedMethod::STATE_STATIC));
     if (empty($collection)) {
         return;
     }
     /** @var ReflectedMethod $method */
     foreach ($collection as $method) {
         // method instanciates at least one object
         $instanciated = array_unique($method->getInstanciedClasses());
         if (empty($instanciated)) {
             continue;
         }
         foreach ($method->getReturns() as $return) {
             // returns an object
             if ($resolver->isNative($return->getType())) {
                 continue;
             }
             // doesn't return itself (avoid singleton)
             if (in_array($return->getType(), array('\\self', '\\static', $class->getFullname()))) {
                 continue;
             }
             $pattern->setCreated($return->getType());
             $resolved->pushPattern($pattern);
             return;
         }
     }
 }
 /**
  * @return array
  */
 public function getDependencies()
 {
     // on read : compare with aliases. We cannot make it in pushDependency() => aliases aren't yet known
     $dependencies = array();
     foreach ($this->dependencies as $name) {
         array_push($dependencies, $this->nameResolver->resolve($name, null));
     }
     // returned values
     $resolver = new TypeResolver();
     foreach ($this->returns as $return) {
         $name = $return->getType();
         if (!$resolver->isNative($name)) {
             array_push($dependencies, $this->nameResolver->resolve($name, null));
         }
     }
     // anonymous classes in method (inner class)
     foreach ($this->anonymousClasses as $c) {
         array_push($dependencies, $c->getParent());
         $dependencies = array_merge($dependencies, $c->getDependencies());
     }
     return array_unique($dependencies);
 }
 /**
  * Extracts content of method
  *
  * @param ReflectedMethod $method
  * @param integer $n
  * @param TokenCollection $tokens
  * @param ReflectedClass $currentClass
  * @return $this
  */
 private function extractDependencies(ReflectedMethod $method, $n, TokenCollection $tokens, ReflectedClass $currentClass = null)
 {
     //
     // Object creation
     $extractor = new CallExtractor($this->searcher, $currentClass);
     $start = $n;
     $len = sizeof($tokens, COUNT_NORMAL);
     for ($i = $start; $i < $len; $i++) {
         $token = $tokens[$i];
         switch ($token->getType()) {
             case T_PAAMAYIM_NEKUDOTAYIM:
             case T_NEW:
                 $call = $extractor->extract($i, $tokens, $currentClass);
                 if ($call !== 'class') {
                     // anonymous class
                     $method->pushDependency($call);
                     $method->pushInstanciedClass($call);
                 }
                 break;
         }
     }
     //
     // Parameters in Method API
     $resolver = new TypeResolver();
     foreach ($method->getArguments() as $argument) {
         $name = $argument->getType();
         if (strlen($name) > 0 && !$resolver->isNative($name)) {
             $method->pushDependency($name);
         }
     }
     return $this;
 }