protected function call_closure( $closure, array $parameters = [] ) {
		if ( $closure instanceof Closure ) {
			$rc      = new ReflectionFunction( $closure );
			$args    = $rc->getParameters();
		} else if ( $closure instanceof ReflectionClass ) {
			$rc = $closure;

			if ( $constructor = $rc->getConstructor() ) {
				$args = $constructor->getParameters();
			} else {
				$args = [];
			}

			$closure = function () use ( $rc ) {
				return $rc->newInstanceArgs( func_get_args() );
			};
		}

		if ( $closure instanceof Closure === false ) {
			return $closure;
		}

		$args    = is_array( $args ) ? $args : [];
		$params  = $parameters;
		$classes = [
			$this->get_class_prefix( get_class( $this ) ),
			get_class( $this ),
			get_parent_class( $this )
		];

		foreach ( (array) $args as $index => $arg ) {
			if ( $arg->getClass() === null ) {
				continue;
			}

			if ( in_array( $arg->getClass()->name, $classes, true ) ) {
				$parameters[$index] = $this;
			} else if ( $this->bound( $arg->getClass()->name ) ) {
				$parameters[$index] = $this->make( $arg->getClass()->name );
			}
		}

		if ( ! empty( $args ) && empty( $parameters ) ) {
			$parameters[0] = $this;
		}

		if ( count( $args ) > count( $parameters ) ) {
			$parameters = array_merge( $parameters, $params );
		}

		return $this->call_closure( call_user_func_array( $closure, $parameters ), $parameters );
	}