def _route(self, args, request=None):
        '''
        Routes a request to the appropriate controller and returns its result.
        Performs a bit of validation - refuses to route delete and put actions
        via a GET request).
        '''
        if request is None:
            from pecan import request
        method = request.params.get('_method', request.method).lower()
        if request.method == 'GET' and method in ('delete', 'put'):
            abort(405)
        result = self._find_sub_controllers(args, request)
        if result:
            return result
        handler = getattr(
            self,
            '_handle_%s' % method,
            self._handle_unknown_method
        )
        try:
            if len(getargspec(handler).args) == 3:
                result = handler(method, args)
            else:
                result = handler(method, args, request)
            argspec = self._get_args_for_controller(result[0])
            num_args = len(argspec)
            if num_args < len(args):
                _lookup_result = self._handle_lookup(args, request)
                if _lookup_result:
                    return _lookup_result
        except (exc.HTTPClientError, exc.HTTPNotFound,
                exc.HTTPMethodNotAllowed) as e:
            _lookup_result = self._handle_lookup(args, request)
            if _lookup_result:
                return _lookup_result
            if isinstance(e, exc.HTTPMethodNotAllowed):
                def method_iter():
                    for func in ('get', 'get_one', 'get_all', 'new', 'edit',
                                 'get_delete'):
                        if self._find_controller(func):
                            yield 'GET'
                            break
                    for method in ('HEAD', 'POST', 'PUT', 'DELETE', 'TRACE',
                                   'PATCH'):
                        func = method.lower()
                        if self._find_controller(func):
                            yield method
                e.allow = sorted(method_iter())
            raise
        return result