protected function generateCallCode($typeName, \ReflectionFunction $ref, $num, array $prepend = [], array $resolvers = NULL)
	{
		$code = '$this->call_' . $num . '(';
		
		foreach($ref->getParameters() as $i => $param)
		{
			if($i != 0)
			{
				$code .= ', ';
			}
			
			if(array_key_exists($i, $prepend))
			{
				$code .= $prepend[$i];
				
				continue;
			}
			
			if($resolvers !== NULL && array_key_exists($param->name, $resolvers))
			{
				$resolver = $resolvers[$param->name];
				
				if($resolver instanceof \Closure)
				{
					$num = count($this->methods);
						
					$ref = new \ReflectionFunction($resolver);
					$sig = $this->generateReplacementMethodSignature($ref, $num);
					$body = $this->extractClosureCode($ref);
					
					$this->methods[] = "\t\t" . $sig . " {\n" . $body . "\n\t\t}";
					
					$code .= $this->generateCallCode($typeName, $ref, $num);
					
					continue;
				}
				elseif($resolver instanceof CompiledCodeFragment)
				{
					$code .= $resolver;
					
					continue;
				}
				
				$code .= var_export($resolver, true);
				
				continue;
			}
			
			if(NULL !== ($ptype = $this->getParamType($param)))
			{
				if($ptype === InjectionPointInterface::class)
				{
					$code .= '$point';
					
					continue;
				}
				
				$code .= '$this->get(' . var_export($ptype, true) . ', isset($point) ? $point : NULL)';
				
				continue;
			}
			
			if($param->isOptional())
			{
				$code .= $param->isDefaultValueAvailable() ? var_export($param->getDefaultValue(), true) : 'NULL';
				
				continue;
			}
			
			throw new TypeNotFoundException(sprintf('Cannot populate closure param "%s" without type hint or resolver', $param->name));
		}
		
		return $code . ')';
	}