public function generate(Page $page, AbstractClassContent $content = null, $force = false, $exceptionOnMissingScheme = true)
    {
        if (!is_bool($force)) {
            throw new \InvalidArgumentException(sprintf(
                '%s method expect `force parameter` to be type of boolean, %s given',
                __METHOD__,
                gettype($force)
            ));
        }

        if (
            null !== $page->getUrl(false)
            && $page->getState() & Page::STATE_ONLINE
            && (!$force && $this->preserveOnline)
        ) {
            return $page->getUrl(false);
        }

        if ($page->isRoot() && array_key_exists('_root_', $this->schemes)) {
            return $this->doGenerate($this->schemes['_root_'], $page, $content);
        }

        if (isset($this->schemes['_layout_']) && is_array($this->schemes['_layout_'])) {
            if (array_key_exists($page->getLayout()->getUid(), $this->schemes['_layout_'])) {
                return $this->doGenerate($this->schemes['_layout_'][$page->getLayout()->getUid()], $page);
            }
        }

        if (null !== $content && array_key_exists('_content_', $this->schemes)) {
            $shortClassname = str_replace(AbstractContent::CLASSCONTENT_BASE_NAMESPACE, '', get_class($content));
            if (array_key_exists($shortClassname, $this->schemes['_content_'])) {
                return $this->doGenerate($this->schemes['_content_'][$shortClassname], $page, $content);
            }
        }

        if (array_key_exists('_default_', $this->schemes)) {
            return $this->doGenerate($this->schemes['_default_'], $page, $content);
        }

        $url = $page->getUrl(false);
        if (!empty($url)) {
            return $url;
        }

        if (true === $exceptionOnMissingScheme) {
            throw new RewritingException(
                sprintf('No rewriting scheme found for Page (#%s)', $page->getUid()),
                RewritingException::MISSING_SCHEME
            );
        }

        return '/'.$page->getUid();
    }