Get reflection parameters
@param  \ReflectionFunctionAbstract $reflection
@param  array                       $args
@return array
328500
public function getParameters(\ReflectionFunctionAbstract $reflection, array $args = [])
    {
        $dependencies = $reflection->getParameters();
        $parameters = [];

        foreach ($dependencies as $parameter) {
            $parameters[] = $this->getParameter($parameter, $args);
        }

        return $parameters;
    }
107603
protected function getPropertiesMeta(ReflectionClass $reflection): array
    {
        $meta = [];
        $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);

        foreach ($properties as $item) {
            $doc = $item->getDocComment();
            $notations = $this->parser->parse($doc);

            if (count($notations) > 0) {
                $meta[$item->getName()] = $notations;
            }
        }

        return $meta;
    }
1221921
final private static function sortConstants(ReflectionClass $reflection): array
    {
        $constants = [];
        while ($reflection && __CLASS__ !== $reflection->getName()) {
            $scope = [];
            foreach ($reflection->getReflectionConstants() as $const) {
                if ($const->isPublic()) {
                    $scope[$const->getName()] = $const->getValue();
                }
            }
            $constants = $scope + $constants;
            $reflection = $reflection->getParentClass();
        }


        return $constants;
    }
1220107
public static function extractReflectionParams($sr, \ReflectionMethod $method)
    {
        $regex = $sr[1] ?: $sr[0];
        $default = '';
        $params = [];
        $parameters = $method->getParameters();
        $requirements = [];
        /** @var \ReflectionParameter $param */
        if (count($parameters) > 0) {
            foreach ($parameters as $param) {
                if ($param->isOptional() && !is_array($param->getDefaultValue())) {
                    $params[$param->getName()] = $param->getDefaultValue();
                    $default = str_replace('{' . $param->getName() . '}', $param->getDefaultValue(), $regex);
                } elseif(!$param->isOptional()) {
                    $requirements[] = $param->getName();
                }
            }
        } else {
            $default = $regex;
        }

        return [$regex, $default, $params, $requirements];
    }
1156200
public function argumentsForCallback(callable $callback): array
    {
        $definition = new ReflectionFunction($callback);
        $arguments = [];

        foreach ($definition->getParameters() as $parameter) {
            if ($type = $parameter->getType()) {
                $arguments[] = Phony::emptyValue($type);
            } else {
                $arguments[] = null;
            }
        }

        return $arguments;
    }
413373
private function getArguments(\ReflectionMethod $method)
    {
        $arguments = [];

        foreach ($method->getParameters() as $index => $parameter) {
            $argument = $this->getArgument($index, $parameter);

            if (null === $argument && false === $parameter->allowsNull()) {
                throw new Exception(
                    sprintf('Could not inject parameter #%d into "%s::__construct"', $index, $this->item)
                );
            }

            $arguments[] = $argument;
        }

        return $arguments;
    }
1301907
public function getParameterTypes(\ReflectionParameter $parameter) : array
    {
        $name = $parameter->getName();
        $function = $parameter->getDeclaringFunction();
        $types = $this->getFunctionParameterTypes($function);

        return isset($types[$name]) ? $types[$name] : [];
    }
1370162
private function resolveConstructorArguments(array $args, \ReflectionClass $reflection): array
    {
        $params = [];
        foreach ($reflection->getConstructor()->getParameters() as $param) {
            $params[$param->getName()] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
        }
        return array_merge($params, array_intersect_key($args, $params));
    }
229705
private function computeArguments(
        \ReflectionMethod $constructor,
        MapInterface $properties
    ): MapInterface {
        $arguments = $properties->clear();

        foreach ($constructor->getParameters() as $parameter) {
            if ($this->canInject($parameter, $properties)) {
                $arguments = $arguments->put(
                    $parameter->name,
                    $properties->get($parameter->name)
                );
            }
        }

        return $arguments;
    }
6429
final public function resolveArguments(
        ContextFunction $reflection,
        array $parameters = [],
        string $context = null
    ): array {
        $arguments = [];
        foreach ($reflection->getParameters() as $parameter) {
            try {
                //Information we need to know about argument in order to resolve it's value
                $name = $parameter->getName();
                $class = $parameter->getClass();
            } catch (\Throwable $e) {
                //Possibly invalid class definition or syntax error
                throw new ContainerException($e->getMessage(), $e->getCode(), $e);
            }

            if (isset($parameters[$name]) && is_object($parameters[$name])) {
                if ($parameters[$name] instanceof Autowire) {
                    //Supplied by user as late dependency
                    $arguments[] = $parameters[$name]->resolve($this);
                } else {
                    //Supplied by user as object
                    $arguments[] = $parameters[$name];
                }
                continue;
            }

            //No declared type or scalar type or array
            if (empty($class)) {
                //Provided from outside
                if (array_key_exists($name, $parameters)) {
                    //Make sure it's properly typed
                    $this->assertType($parameter, $reflection, $parameters[$name]);
                    $arguments[] = $parameters[$name];
                    continue;
                }

                if ($parameter->isDefaultValueAvailable()) {
                    //Default value
                    $arguments[] = $parameter->getDefaultValue();

                    continue;
                }

                //Unable to resolve scalar argument value
                throw new ArgumentException($parameter, $reflection);
            }

            try {
                //Requesting for contextual dependency
                $arguments[] = $this->get($class->getName(), $name);

                continue;
            } catch (AutowireException $e) {
                if ($parameter->isOptional()) {
                    //This is optional dependency, skip
                    $arguments[] = null;
                    continue;
                }

                throw $e;
            }
        }

        return $arguments;
    }
517680
protected function matchArguments(
        array $reflectionParameters,
        array $providedArguments
    )/*# : array */ {
        // result
        $resolvedArguments = [];
        foreach ($reflectionParameters as $i => $param) {
            $class = $param->getClass();

            if ($this->isTypeMatched($class, $providedArguments)) {
                $resolvedArguments[$i] = array_shift($providedArguments);
            } elseif ($this->isRequiredClass($param, $providedArguments)) {
                $resolvedArguments[$i] = $this->getObjectByClass($class->getName());
            }
        }
        return array_merge($resolvedArguments, $providedArguments);
    }
898291
protected function resolveArguments(
        ReflectionMethod $method,
        array $arguments
    ) {
        $params = $method->getParameters();
        $result = [];

        foreach ($params as $param) {
            /** @var ReflectionParameter $param */
            if (isset($arguments[$param->name])) {
                $result[$param->name] = $arguments[$param->name];
                continue;
            }

            $class = $param->getClass();
            if ($class) {
                $className = $class->getName();
                if ($this->isShared($className)) {
                    $result[$className] = isset($this->sharedInstances[$className])
                        ? $this->sharedInstances[$className]
                        : $this->get($className);
                } else {
                    $result[$className] = $this->create($className);
                }
            }
        }

        return $result;
    }
827158
public function invoke(Callable $callable, array $args = [])
    {
        // object/class method
        if (is_string($callable) && false !== strpos($callable, '::')) {
            $callable = explode('::', $callable);
        }
        if (is_array($callable)) {
            $reflection = new \ReflectionMethod($callable[0], $callable[1]);
        }

        // closures, functions and any other callable
        if (!isset($reflection)) {
            $reflection = new \ReflectionFunction($callable);
        }

        // inject arguments
        $arguments = $this->inject($reflection, $args);
        return $callable(...$arguments);
    }
573042
protected function resolveCallableArguments(\ReflectionFunctionAbstract $reflector, $args = [])
    {
        return array_map(
            function (\ReflectionParameter $parameter) use ($args) {
                $name  = $parameter->name;
                $class = $parameter->getClass();

                if ( array_key_exists($name, $args) ) {
                    return $args[ $name ];
                }

                if ( $class ) {
                    return $this->get($class->name);
                }

                if ( $parameter->isDefaultValueAvailable() ) {
                    return $parameter->getDefaultValue();
                }

                throw new \RuntimeException(
                    sprintf(
                        'Cannot resolve argument [%s], it should be provided within an array of arguments passed to ' .
                        '[%s::call], have a default value or be type hinted',
                        $name,
                        get_class($this)
                    )
                );
            },
            $reflector->getParameters()
        );
    }
424044
public function getReflectionParam($dependency)
    {
        $resolveClass = null;
        //Get constructor class name
        $resolveClass = $dependency->getClass()->name;

        return [$resolveClass, new \ReflectionClass($resolveClass)];
    }
971165
public function autowireArguments(ReflectionFunctionAbstract $reflection, array $arguments)
    {
        $newArguments = $arguments;
        foreach ($reflection->getParameters() as $index => $parameter) {
            if ($this->isArgumentWireable($newArguments, $index, $parameter)) {
                $newArguments[$index] = $this->container->get($parameter->getClass()->getName());
            }
        }

        return $newArguments;
    }
117472
private function getInstance($class, array $args)
    {
        // Hack to avoid Reflection for most cases
        switch (count($args)) {
            case 0:
                return new $class;
            case 1:
                return new $class($args[0]);
            case 2:
                return new $class($args[0], $args[1]);
            case 3:
                return new $class($args[0], $args[1], $args[2]);
            case 4:
                return new $class($args[0], $args[1], $args[2], $args[3]);
            case 5:
                return new $class($args[0], $args[1], $args[2], $args[3], $args[4]);
            case 6:
                return new $class($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
            default:
                $reflection = new ReflectionClass();
                return $reflection->newInstanceArgs($args);
        }
    }