public function execute(PageRequest $pageRequest)
	{
		$this->pageRequest = $pageRequest;
		$this->pageResponse = $this->createPageResponse();

		$localization = $pageRequest->getLocalization();

		if (! $localization instanceof Localization) {
			throw new \UnexpectedValueException(sprintf(
					'Expecting Localization object only [%s] received.',
					get_class($localization)
			));
		}

		if ($pageRequest instanceof PageRequestView
				&& $localization instanceof PageLocalization
				&& $localization->hasRedirectTarget()) {

			$redirectUrl = $localization->getRedirectTarget()
					->getRedirectUrl();

			if (! empty($redirectUrl)) {
				//@TODO: check for redirect loops
				return new RedirectResponse($redirectUrl);
			}

			throw new ResourceNotFoundException();
		}

		$layout = $pageRequest->getLayout();

		if ($layout === null) {
			throw new LayoutNotFound(sprintf(
					'No layout found for page localization [%s]',
					$localization->getId()
			));
		}

		$templating = $this->container->getTemplating();

		if ($templating instanceof TwigTemplating) {
			$templating->getExtension('supraPage')
					->setPageExecutionContext(new PageExecutionContext($this->pageRequest, $this));
		}

		// searching for blocks cache
		$this->findBlockCache();

		// searching and instantiating controllers
		$this->findBlockControllers();

		// prepare controllers
		$this->prepareBlockControllers();

		// some of the block cache may be context-dependent
		// and as context may change after preparing we're searching for cache again
		$this->findContextDependentBlockCache();

		// execute controllers
		$this->executeBlockControllers();

		// stores cache
		$this->cacheBlockResponses();

		// create placeholder responses, process page layout
		$this->getLayoutProcessor()->process(
				$layout->getFilename(),
				$this->pageResponse,
				$this->createPlaceResponses()
		);

		return $this->pageResponse;
	}