TRouting TUrlRoute::findRouting(Tf::HttpMethod method, const QStringList &components) const
{
    if (routes.isEmpty()) {
        TRouting();
    }

    bool denied = false;
    for (QListIterator<TRoute> i(routes); i.hasNext(); ) {
        const TRoute &rt = i.next();

        // Too long or short?
        if (rt.hasVariableParams) {
            if (components.length() < rt.componentList.length() - 1) {
                continue;
            }
        } else {
            if (components.length() != rt.componentList.length()) {
                continue;
            }
        }

        for (QListIterator<int> it(rt.keywordIndexes); it.hasNext(); ) {
            int idx = it.next();
            if (components.value(idx) != rt.componentList[idx]) {
                goto continue_next;
            }
        }

        denied = true;

        if (rt.method == TRoute::Match || rt.method == method) {
            // Generates parameters for action
            QStringList params = components;

            if (params.count() == 1 && params[0].isEmpty()) {  // means path="/"
                params.clear();
            } else {
                // Erases non-parameters
                QListIterator<int> it(rt.keywordIndexes);
                it.toBack();
                while (it.hasPrevious()) {
                    int idx = it.previous();
                    params.removeAt(idx);
                }
            }

            return TRouting(rt.controller, rt.action, params);
        }
continue_next:
        continue;
    }

    return (denied) ? TRouting("", "") : TRouting() /* Not found routing info */ ;
}
TRouting TUrlRoute::findRouting(Tf::HttpMethod method, const QStringList &components) const
{
    if (_routes.isEmpty()) {
        return TRouting();
    }

    for (const auto &rt : _routes) {
        // Too long or short?
        if (rt.hasVariableParams) {
            if (components.length() < rt.componentList.length() - 1) {
                continue;
            }
        } else {
            if (components.length() != rt.componentList.length()) {
                continue;
            }
        }

        for (int idx : (const QList<int>&)rt.keywordIndexes) {
            if (components.value(idx) != rt.componentList[idx]) {
                goto continue_next;
            }
        }

        if (rt.method == TRoute::Match || rt.method == method) {
            // Generates parameters for action
            QStringList params = components;

            if (params.count() == 1 && params[0].isEmpty()) {  // means path="/"
                params.clear();
            } else {
                // Erases non-parameters
                QListIterator<int> it(rt.keywordIndexes);
                it.toBack();
                while (it.hasPrevious()) {
                    int idx = it.previous();
                    params.removeAt(idx);
                }
            }

            TRouting routing(rt.controller, rt.action, params);
            routing.exists = true;
            return routing;
        }
continue_next:
        continue;
    }

    return TRouting() /* Not found routing info */ ;
}
TRouting TUrlRoute::findRouting(Tf::HttpMethod method, const QString &path) const
{
    QStringList params;
    QStringList components = path.split('/');
    components.takeFirst();
    components.takeLast();

    for (QListIterator<TRoute> i(routes); i.hasNext(); ) {
        const TRoute &rt = i.next();

        //Check if we have a good http verb
        switch(rt.method)
        {
            case TRoute::Match:
                //We match anything here
                break;
            case TRoute::Get:
                if (method != Tf::Get) continue;
                break;
            case TRoute::Post:
                if (method != Tf::Post) continue;
                break;
            case TRoute::Patch:
                if (method != Tf::Patch) continue;
                break;
            case TRoute::Put:
                if (method != Tf::Put) continue;
                break;
            case TRoute::Delete:
                if (method != Tf::Delete) continue;
                break;
            default:
                tSystemWarn("Unkown route method in findRouting: %d", rt.method);
                continue;
                break;
        }

        //To short?
        if (components.length() < rt.components.length()) continue;

        //Parse any parameters
        for(int j=0; j < rt.components.length(); j++)
        {
            if (rt.components[j] == components[j]) continue;

            if (rt.components[j] == ":param") {
                params << components[j];
                continue;
            }

            goto trynext;
        }

        //Add any variable params
        if (rt.has_variable_params)
            params << components.mid(rt.components.length());

        return TRouting(rt.controller, rt.action, params);

trynext:
        continue;
    }

    return TRouting();  // Not found routing info
}