Method passed to routes file to build up routes definition.
Adds a single route definition.
function(pattern, controller, options) {
    var realAction, action, handler, route, routeObj, routerContext = this;

    route = parseRouteDefinitions([controller, options]);
    realAction = this.getAction(route);

    if (isServer) {
      action = realAction;
    } else {
      action = function(params, callback) {
        var self = this;
        var myLoadNumber = ++loadNumber;
        function next() {
          // To prevent race conditions we ensure that no future requests have been processed in the mean time.
          if (myLoadNumber === loadNumber) {
            callback.apply(self, arguments);
          }
        }
        // in AMD environment realAction is the string containing path to the controller
        // which will be loaded async (might be preloaded)
        // Only used in AMD environment
        if (typeof realAction === 'string') {
          routerContext._requireAMD([realAction], function(controller) {
            // check we have everything we need
            if (typeof controller[route.action] != 'function') {
              throw new Error("Missing action \"" + route.action + "\" for controller \"" + route.controller + "\"");
            }
            controller[route.action].call(self, params, next);
          });
        }
        else {
          realAction.call(self, params, next);
        }
      }
    }

    if (!(pattern instanceof RegExp) && pattern.slice(0, 1) !== '/') {
      pattern = "/" + pattern;
    }

    handler = this.getHandler(action, pattern, route);
    routeObj = [pattern, route, handler];

    this._routes.push(routeObj);
    this.trigger('route:add', routeObj);

    return routeObj;
  }