function Router() {
    this._routes = [];
    this._map = new RouteMap();
}

function Route() {
}

function RouteMap() {
    this._paths = {};
    this._assignedRoute = null;
}

function simplifyPath(path) {
    return path.split('/').filter(function (part) {
        return part !== '';
    });
}

function preparePath(pathArray) {
    var result = [];
    Array.prototype.forEach.call(pathArray, function (path) {
        if (typeof path === 'string') {
            simplifyPath(path).forEach(function (path) {
                result.push(path);
            });
        } else {
            result.push(path);
        }
    });
    return result;
}

function defineRoute(route, map, paths) {
    paths.forEach(function (path) {
        map = map.createPath(path);
    });
    map.assignRoute(route);
}

Router.Route = Route;

RouteMap.prototype.createPath = function (path) {
    if (this._paths.hasOwnProperty(path)) {
        return this._paths[path];
    }
    var map = new RouteMap();
    this._paths[path] = map;
    return map;
};

RouteMap.prototype.findPath = function (path) {
    if (this._paths.hasOwnProperty(path)) {
        return this._paths[path];
    }
    return null;
};

RouteMap.prototype.assignRoute = function (route) {
    this._assignedRoute = route;
};

RouteMap.prototype.getAssignedRoute = function () {
    return this._assignedRoute;
};

/**
 * @param {object} [params={}]
 */
Route.prototype.link = function (params) {
};

Router.getRoutes = function () {
    return this._routes;
};

/**
 * @param {...string} paths
 * @returns Route
 */
Router.prototype.route = function (paths) {
    var route = new Route();
    this._routes.push(route);
    defineRoute(
        route,
        this._map,
        preparePath(arguments)
    );
    return route;
};

/**
 * @param {string} path
 * @param {object} [options]
 * @param {boolean} [options.ignoreEmpty=false]
 * @param {boolean} [options.tolerateTrailingSlash=false]
 * @returns Route
 */
Router.prototype.detect = function (path, options) {
    var map = this._map,
        len,
        i;
    path = simplifyPath(path);
    for (i = 0, len = path.length; i < len; ++i) {
        map = map.findPath(path[i]);
        if (map === null) {
            return null;
        }
    }
    return map.getAssignedRoute();
};

module.exports = Router;

@@ -206,22 +206,36 @@
 ) %7B%0A    
-return
+var simplifiedPath =
  path.sp
@@ -304,16 +304,152 @@
     %7D);%0A
+    if (path.length === 0 %7C%7C path.substr(path.length - 1) === '/') %7B%0A        simplifiedPath.push('/');%0A    %7D%0A    return simplifiedPath;%0A
 %7D%0A%0Afunct
@@ -2206,23 +2206,251 @@
     
-len,%0A        i;
+nextMap,%0A        len,%0A        i;%0A%0A    function tolerateTrailingSlash() %7B%0A        return options && options.tolerateTrailingSlash;%0A    %7D%0A%0A    function pathEndsWithSlash() %7B%0A        return path.length %3E 0 && path%5Bpath.length - 1%5D === '/';%0A    %7D%0A
 %0A   
@@ -2528,33 +2528,37 @@
  ++i) %7B%0A        
-m
+nextM
 ap = map.findPat
@@ -2581,17 +2581,21 @@
     if (
-m
+nextM
 ap === n
@@ -2597,24 +2597,158 @@
 === null) %7B%0A
+            if (i === len - 1 && pathEndsWithSlash() && tolerateTrailingSlash()) %7B%0A                continue;%0A            %7D else %7B%0A    
             
@@ -2772,49 +2772,306 @@
     
+  
-%7D%0A
+  %7D%0A   
     
+ 
 %7D%0A    
-return map.getAssignedRoute()
+    map = nextMap;%0A    %7D%0A    var route = map.getAssignedRoute();%0A    if (route === null && tolerateTrailingSlash() && !pathEndsWithSlash()) %7B%0A        map = map.findPath('/');%0A        if (map !== null) %7B%0A            return map.getAssignedRoute();%0A        %7D%0A    %7D%0A    return route
 ;%0A%7D;

tolerateTrailingSlash option