@param Definition $definition
@param string     $method

@throws RuntimeException

@return \ReflectionFunctionAbstract
970146
protected function getReflectionMethod(Definition $definition, $method)
    {
        if ('__construct' === $method) {
            return $this->getConstructor($definition, true);
        }

        if (!$class = $definition->getClass()) {
            throw new RuntimeException(sprintf('Invalid service "%s": the class is not set.', $this->currentId));
        }

        if (!$r = $this->container->getReflectionClass($class)) {
            throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class));
        }

        if (!$r->hasMethod($method)) {
            throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
        }

        $r = $r->getMethod($method);
        if (!$r->isPublic()) {
            throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
        }

        return $r;
    }
1262659
private function buildDefinition(\ReflectionMethod $method, DocBlock $docBlock, $token = null)
    {
        $definition = new InputDefinition();

        foreach ($docBlock->getTags() as $tag) {
            if ($tag instanceof DocBlock\Tags\Param) {
                $tagsDescription[$tag->getVariableName()] = $tag->getDescription()->render();
            }
        }

        foreach ($method->getParameters() as $parameter) {

            if ($parameter->isDefaultValueAvailable()) {
                //option
                $definition->addOption(new InputOption($parameter->getName(), null, InputOption::VALUE_REQUIRED, $tagsDescription[$parameter->getName()], $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null));
            } else {
                //argument
                $definition->addArgument(new InputArgument($parameter->getName(), InputArgument::REQUIRED, $tagsDescription[$parameter->getName()], null));
            }
        }

        $definition->addOption(new InputOption('token', null, InputOption::VALUE_REQUIRED, 'Auth token to use', $token));
        $definition->addOption(new InputOption('debug', null, InputOption::VALUE_NONE, 'Display raw response'));

        return $definition;
    }
706517
protected function getMethodBody(ReflectionMethod $method)
    {
        // Get file content for the method

        $file = new SplFileObject($method->getFileName());

        $methodBodyLines = iterator_to_array(
            new LimitIterator(
                $file,
                $method->getStartLine(),
                $method->getEndLine() - $method->getStartLine()
            )
        );

        return implode("\n", $methodBodyLines);
    }
402521
public function each($method)
    {
        foreach ($this as $rec) {
            if (is_string($method)) {
                $rec->$method();
            } elseif (is_callable($method)) {
                call_user_func($method, $rec);
            }
        }

        return $this;
    }
1142531
private function createCode($namespace, \ReflectionMethod $method)
    {
        $app = $this->application;

        return function (InputInterface $input, OutputInterface $output) use ($namespace, $method, $app) {
            $methodName = $method->getName();

            $client = new Client(Environment::getClient());
            $api    = $client->api(strtolower($namespace));
            $api->setEventDispatcher($app->getDispatcher());

            if (true === $input->hasParameterOption('--no-plugins')) {
                // tells to Api, do not use any plugins
                $api->activatePlugins(false);
            }
            if (true === $input->hasParameterOption('--progress')) {
                $formats = array(
                    'very_verbose' => ' %current%/%max% %percent:3s%% %elapsed:6s% %message%',
                    'very_verbose_nomax' => ' %current% %elapsed:6s% %message%',

                    'debug' => ' %current%/%max% %percent:3s%% %elapsed:6s% %memory:6s% %message%',
                    'debug_nomax' => ' %current% %elapsed:6s% %memory:6s% %message%',
                );
                foreach ($formats as $name => $format) {
                    ProgressBar::setFormatDefinition($name, $format);
                }
                $progress = new ProgressBar($output);
                $progress->setMessage('');

                $api->getEventDispatcher()->addListener(
                    Events::PROGRESS,
                    function (GenericEvent $event) use ($progress) {
                        if ($progress instanceof ProgressBar) {
                            $progress->setMessage(
                                sprintf(
                                    'File %s in progress...',
                                    $event['file']->getRelativePathname()
                                )
                            );
                            $progress->advance();
                        }
                    }
                );
            }

            $args = array();

            foreach ($method->getParameters() as $parameter) {
                if ($parameter->isOptional()) {
                    // option
                    $args[$parameter->getName()] = $input->getOption($parameter->getName());
                } else {
                    // argument
                    $args[$parameter->getName()] = $input->getArgument($parameter->getName());
                }
            }

            if (isset($progress) && $progress instanceof ProgressBar) {
                $progress->start();
            }

            // calls the Api method
            try {
                $response = call_user_func_array(
                    array($api, $methodName),
                    $args
                );
            } catch (\Exception $e) {
                $response = $e;
            }

            if (isset($progress) && $progress instanceof ProgressBar) {
                $progress->finish();
                $progress->clear();
            }
            $output->writeln('');

            // prints response returned
            $classParts      = explode('\\', get_class($api));
            $class           = array_pop($classParts);
            $outputFormatter = str_replace("\\Api\\$class", "\\Output\\$class", get_class($api));

            // handle all Api exceptions when occured
            if ($response instanceof \Exception) {
                if (substr_count($response->getMessage(), "\n") > 0) {
                    // message on multiple lines
                    $fmt = new FormatterHelper;
                    $output->writeln(
                        $fmt->formatBlock(
                            explode("\n", $response->getMessage()),
                            'error'
                        )
                    );
                } else {
                    // message on single line
                    $output->writeln('<error>' . $response->getMessage() . '</error>');
                }
                return;
            }

            if (!method_exists($outputFormatter, $methodName)
                || !is_callable(array($outputFormatter, $methodName))
                || $output->isDebug()
            ) {
                $output->writeln('<debug>Raw response</debug>');
                $output->writeln(print_r($response, true), OutputInterface::OUTPUT_RAW);
                return;
            }

            $result = new $outputFormatter();

            if ($input->hasParameterOption('--format')) {
                 return $output->write($response, OutputInterface::OUTPUT_RAW);
            }
            $result->$methodName($output, $response);
        };
    }
365719
public function setDefinition($definition)
	{
		if ($definition instanceof InputDefinition)
		{
			$this->definition = $definition;
		}
		else
		{
			$this->definition->setDefinition($definition);
		}

		$this->applicationDefinitionMerged = false;
	}
921525
private function getResourceMetadata(Definition $definition, $method)
    {
        foreach ($definition->getMethodCalls() as $methodCall) {
            if ($methodCall[0] === $method) {
                return $methodCall[1][0];
            }
        }
    }
750987
protected function methodToConfiguration(ReflectionMethod $method): ?array
    {
        // Silently ignore setter with anything than exactly 1 parameter
        $params = $method->getParameters();
        if (count($params) !== 1) {
            return null;
        }
        $param = reset($params);

        // Get a field from annotation, or an empty one
        /** @var Input $field */
        $field = $this->getAnnotationReader()->getMethodAnnotation($method, Input::class) ?? new Input();

        if (!$field->getTypeInstance()) {
            $this->convertTypeDeclarationsToInstances($method, $field);
            $this->completeField($field, $method, $param);
        }

        return $field->toArray();
    }
1132501
public function withMethod($method)
    {
        if ($this->getMethod() === $method) {
            return $this;
        }

        $newInstance = clone $this;
        $newInstance->setMethod($method);
        return $newInstance;
    }
254210
public function getMethodPrefix($method)
    {
        $method = strtolower($method);

        return isset($this->methodPrefix[$method]) ? $this->methodPrefix[$method] : null;
    }
161765
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
    {
        return $this->findReader($method->getDeclaringClass())
            ->getMethodAnnotation($method, $annotationName);
    }
1200628
protected function _getMethodParameters(
        MethodInjection $method = null,
        ReflectionMethod $methodReflection = null,
        array $parameters = []
    ) {
        $args = [];
        if ($methodReflection) {
            foreach ($methodReflection->getParameters() as $index => $parameter) {
                if (array_key_exists($parameter->getName(), $parameters)) {
                    $value = $parameters[$parameter->getName()];
                } elseif ($method && $method->hasParameter($index)) {
                    $value = $method->getParameter($index);
                } else {
                    // If the parameter is optional and wasn't specified,
                    // we take its default value
                    if ($parameter->isOptional()) {
                        $args[] = $this->_getParameterDefaultValue(
                            $parameter,
                            $methodReflection
                        );
                        continue;
                    }

                    throw new DefinitionException(sprintf(
                        "The parameter '%s' of %s::%s has no value defined " .
                        "or guessable",
                        $parameter->getName(),
                        $methodReflection->getDeclaringClass()->getName(),
                        $methodReflection->getName()
                    ));
                }

                if ($value instanceof ObjectDefinition\EntryReference) {
                    $args[] = $this->_container->get($value->getName());
                } else {
                    $args[] = $value;
                }
            }
        }
        return $args;
    }
582453
protected function createFromDefinition(array $definition)
    {
        if (!isset($definition['class'])) {
            throw new ContainerException(
                'Service could not be created from definition:'
                    . ' option "class" is not exists in definition array.'
            );
        }

        $className = $definition['class'];

        if (!class_exists($className)) {
            throw new ContainerException(sprintf(
                'Service could not be created from definition:'
                    . ' Class "%s" is not exists.',
                $className
            ));
        }

        $reflection = new \ReflectionClass($className);

        if (!$reflection->isInstantiable()) {
            throw new ContainerException(sprintf(
                'Service could not be created from definition:'
                    . ' Unable to create instance of class "%s".',
                $className
            ));
        }

        if (null !== ($constructor = $reflection->getConstructor())) {
            if (!isset($definition['args'])) {
                throw new ContainerException(
                    'Service could not be created from definition:'
                        . ' option "args" is not exists in definition array.'
                );
            }
            $params = $this->resolveArgs($constructor->getParameters(), $definition['args']);
            $service = $reflection->newInstanceArgs($params);
        } else {
            // we don't have a constructor
            $service = $reflection->newInstance();
        }

        if (!isset($definition['calls'])) {
            return $service;
        }

        $calls = isset($definition['calls']) ? $definition['calls'] : [];
        foreach ($calls as $method => $args) {
            if (!is_callable([$service, $method])) {
                throw new ContainerException(sprintf(
                    'Service could not be created from definition:'
                        . ' can not call method "%s" from class: "%s"',
                    $method,
                    $className
                ));
            }
            $method = new \ReflectionMethod($service, $method);
            $params = $method->getParameters();
            $arguments = is_array($args)
                    ? $this->resolveArgs($params, $args)
                    : [];
            $method->invokeArgs($service, $arguments);
        }

        return $service;
    }
1330506
private function getReflectionClass($id, Definition $definition)
    {
        if (isset($this->reflectionClasses[$id])) {
            return $this->reflectionClasses[$id];
        }

        // Cannot use reflection if the class isn't set
        if (!$class = $definition->getClass()) {
            return false;
        }

        $class = $this->container->getParameterBag()->resolveValue($class);

        try {
            $reflector = new \ReflectionClass($class);
        } catch (\ReflectionException $e) {
            $reflector = false;
        }

        return $this->reflectionClasses[$id] = $reflector;
    }
298536
private function convertTypeDeclarationsToInstances(ReflectionMethod $method, Field $field): void
    {
        $field->type = $this->getTypeFromPhpDeclaration($method, $field->type);
        $args = [];

        /** @var Argument $arg */
        foreach ($field->args as $arg) {
            $arg->setTypeInstance($this->getTypeFromPhpDeclaration($method, $arg->getType()));
            $args[$arg->getName()] = $arg;
        }
        $field->args = $args;
    }
317608
protected function _injectMethodsAndProperties(
        DefinitionInterface $definition, $instance)
    {
        $classReflection = new ReflectionClass($instance);

        /** @var ObjectDefinition $definition */

        // Property injections
        foreach ($definition->getProperties() as $property)
        {
            $this->_propertyInjection($instance, $property, $classReflection);
        }

        // Method injections
        foreach ($definition->getMethods() as $method) {
            $this->_methodInjection($instance, $method, $classReflection);
        }
    }
741540
private function reflectionParams(string $method)
    {
        $class = new ReflectionClass($this);

        if (! is_string($method)) {
            return;
        }

        if (! $class->hasMethod($method)) {
            return;
        }

        $parameters = $class->getMethod($method)->getParameters();

        $arguments = [];

        foreach ($parameters as $key => $parameter) {
            $arguments[] = $this->bind($key, $parameter);
        }

        $this->arguments = $arguments;
    }