Create and setup menu item creation factory

@param  array $defaultRouteParams
@param  array|[] $routeParams
@param  array $extra
@return MenuFactoryInterface
517861
protected function createFactory(array $defaultRouteParams, array $routeParams = array(), array $extra = array())
    {
        //@todo How to pass route params ?
        //1. remove factory from service and create new instance here ?
        //2. clone factory and replace route params (faster?)
        //3. add parameters to options array
        //4. remove per item routeParams, use only per menu defaultRouteParams
        $factory = clone $this->factory;

        $this->addVoter();

        $factory
            ->setDefaultRouteParameters($defaultRouteParams)
            ->setRouteParameters($routeParams)
            ->setDefaultExtraParameters($extra)
        ;

        return $factory;
    }
410194
public function mount($baseroute, $callable, $extra = [])
	{
		$Route = clone $this->Route;
		$this->Route->addExtra($extra);
		// Track current baseroute
		$curBaseroute = $this->baseUri;

		$this->baseUri .= $baseroute;

		// Call the callable
		$callable($this);
		$this->Route = $Route;

		// Restore original baseroute
		$this->baseUri = $curBaseroute;
	}
474525
public function buildAdminMenu(MenuItem $menu, array $extras = [])
    {
        if ($this->hasAdmin()) {
            if (!isset($extras['beforeCode'])) {
                $extras['beforeCode'] = $this->adminMenuBeforeCode;
            }

            $menu->addChild($this->getShortName(), [
                'uri' => $this->container->get('router')->generate('cms_admin_index').$this->getShortName().'/',
            ])->setExtras($extras);
        }

        return $menu;
    }
225823
public function amOnRoute($routeName, array $params = [])
    {
        if (!$this->di->has('url')) {
            $this->fail('Unable to resolve "url" service.');
        }

        /** @var Url $url */
        $url = $this->di->getShared('url');

        $urlParams = ['for' => $routeName];

        if ($params) {
            $urlParams += $params;
        }

        $this->amOnPage($url->get($urlParams, null, true));
    }
528130
public static function createRouteRedirect(
        $route,
        array $parameters = [],
        $statusCode = Response::HTTP_FOUND,
        array $headers = []
    ) {
        $view = static::create(null, $statusCode, $headers);
        $view->setRoute($route);
        $view->setRouteParameters($parameters);

        return $view;
    }
902037
public function createUrl( $route, $params = [ ], $absolute = FALSE )
    {
        return $this[ 'request' ]->createUrl( $route, $params, $absolute );
    }
382707
public function addRoute($method, $route, $action, $extra = [])
	{
		$name = (isset($extra["name"])) ? $extra["name"] : $route;

		if (isset($this->rawRoutes[$name])) {
			$Route = $this->rawRoutes[$name];
		} else {
			$Route              = clone $this->Route;
			$Route->route       = $this->baseUri.$route;
			$Route->name 		= $name;
		}

		$Route->addExtra($extra);
		$methods = [];
		if ("ANY" === $method) {
			$methods["GET"]  = $action;
			$methods["POST"] =& $methods["GET"];
			$methods["PUT"]  =& $methods["GET"];

			$Route->methods = $methods;
			$Route->action = $action;

			$this->rawRoutes[$name] = $Route;
		} else {

			$arrayedMethod = (array) $method;
			$count = count($arrayedMethod);

			for ($i = 0; $i < $count; $i++) {
				if (!isset($this->allowedMethods[$arrayedMethod[$i]])) {
					throw new InvalidMethodException("Method: " . $arrayedMethod[$i] . " is not valid");
				}
				$method = $arrayedMethod[$i];
				$Route->action = $action;
				$Route->method = $method;
				$Route->name = $name;
				$this->rawRoutes[$name] = $Route;
			}
		}


		return $Route;
	}
699683
public function setRouteParameters($routeParameters)
    {
        if (!is_string($routeParameters)) {
            $this->routeParameters = json_encode($routeParameters);
        } else {
            $this->routeParameters = $routeParameters;
        }

        return $this;
    }
1347985
public static function instance(/** @noinspection PhpUnusedParameterInspection */
        array $routeParams,
        ContainerInterface $container,
        ServerRequestInterface $request
    ): ResponseInterface {
        $params = [
            'post_create_url' => static::createUrl($container, UserSchema::TYPE, self::METHOD_CREATE),
            'roles'           => static::createApi($container, RolesApi::class)->index()->getData(),
            'model'           => [UserSchema::REL_ROLE => RolesSeed::ROLE_USER],
        ];

        $body = self::view($container, Views::USER_MODIFY_PAGE, $params);

        return new HtmlResponse($body);
    }
665062
private function addRoute(RouteCollection $routeCollection, string $resourceClass, string $operationName, array $operation, ResourceMetadata $resourceMetadata, string $operationType): void
    {
        $resourceShortName = $resourceMetadata->getShortName();

        if (isset($operation['route_name'])) {
            return;
        }

        if (!isset($operation['method'])) {
            throw new RuntimeException(sprintf('Either a "route_name" or a "method" operation attribute must exist for the operation "%s" of the resource "%s".', $operationName, $resourceClass));
        }

        if (null === $controller = $operation['controller'] ?? null) {
            $controller = sprintf('%s%s_%s', self::DEFAULT_ACTION_PATTERN, strtolower($operation['method']), $operationType);

            if (!$this->container->has($controller)) {
                throw new RuntimeException(sprintf('There is no builtin action for the %s %s operation. You need to define the controller yourself.', $operationType, $operation['method']));
            }
        }

        $path = trim(trim($resourceMetadata->getAttribute('route_prefix', '')), '/');
        $path .= $this->operationPathResolver->resolveOperationPath($resourceShortName, $operation, $operationType, $operationName);

        $route = new Route(
            $path,
            [
                '_controller' => $controller,
                '_format' => null,
                '_api_resource_class' => $resourceClass,
                sprintf('_api_%s_operation_name', $operationType) => $operationName,
            ] + ($operation['defaults'] ?? []),
            $operation['requirements'] ?? [],
            $operation['options'] ?? [],
            $operation['host'] ?? '',
            $operation['schemes'] ?? [],
            [$operation['method']],
            $operation['condition'] ?? ''
        );

        $routeCollection->add(RouteNameGenerator::generate($operationName, $resourceShortName, $operationType), $route);
    }
758928
public function amOnRoute($routeName, $params = [])
    {
        $route = $this->getRouteByName($routeName);

        $absolute = !is_null($route->domain());
        $url = $this->app['url']->route($routeName, $params, $absolute);
        $this->amOnPage($url);
    }
336881
public function getResetPath($route, $extraParams = array())
    {
        $params = array(
            $this->getActionParameterName() => $this->getResetActionParameterName(),
            $this->getDatagridParameterName() => $this->getName(),
        );
        return $this->container->get('router')->generate($route, array_merge($params, $extraParams));
    }
473816
protected function addLinkRoute(ItemInterface $menu, $label, $route, $routeParameters = array())
    {
        $item = $menu->addChild($label, array('route' => $route, 'routeParameters' => $routeParameters, 'routeAbsolute' => UrlGeneratorInterface::ABSOLUTE_PATH));
        $item->setExtra('translation_domain', $this->translation_domain);

        if ($this->isCurrentUri($item->getUri())) {
            $this->setActive($item);
        }

        return $item;
    }
1323918
public static function fromRoute(Route $route, array $params = []): self
    {
        $result = new self();
        $result->success = true;
        $result->route = $route;
        $result->matchedParams = $params;

        return $result;
    }
1192068
public void prepareParameters(Map<String, Object> extra) {
        if (paramConfig == null) return;
        for (ParamConfig param : paramConfig)
        {
            param.prepareParameter(extra);
        }
    }
1371366
public function createLink($name, array $defaultRouteParams = array(), array $extra = array())
    {
        $options = $this->getLinkOptions($name);
        $factory = $this->createFactory($defaultRouteParams, $extra);

        return $factory->createItem($name, $options);
    }
90904
public function createService(string $key, ServiceLocatorInterface $serviceLocator, array $extra = null): object
    {
        $config = $serviceLocator->getConfig();
        $config = $config[RouterInterface::class] ?? [];

        $router = new Router();
        foreach ($config['routes'] ?? [] as $name => $config) {
            $router->addRoute(
                $this->createRoute($serviceLocator, $config),
                $name
            );
        }

        return $router;
    }