'Connects a URL rule.  Works exactly like the :meth:`route`
decorator.  If a view_func is provided it will be registered with the
endpoint.
Basically this example::
@app.route(\'/\')
def index():
pass
Is equivalent to the following::
def index():
pass
app.add_url_rule(\'/\', \'index\', index)
If the view_func is not provided you will need to connect the endpoint
to a view function like so::
app.view_functions[\'index\'] = index
Internally :meth:`route` invokes :meth:`add_url_rule` so if you want
to customize the behavior via subclassing you only need to change
this method.
For more information refer to :ref:`url-route-registrations`.
.. versionchanged:: 0.2
`view_func` parameter added.
.. versionchanged:: 0.6
``OPTIONS`` is added automatically as method.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule.  Flask
itself assumes the name of the view function as
endpoint
:param view_func: the function to call when serving a request to the
provided endpoint
:param provide_automatic_options: controls whether the ``OPTIONS``
method should be added automatically. This can also be controlled
by setting the ``view_func.provide_automatic_options = False``
before adding the rule.
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object.  A change
to Werkzeug is handling of method options.  methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.).  By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.'

@setupmethod
def add_url_rule(self, rule, endpoint=None, view_func=None, provide_automatic_options=None, **options):

    if (endpoint is None):
        endpoint = _endpoint_from_view_func(view_func)
    options['endpoint'] = endpoint
    methods = options.pop('methods', None)
    if (methods is None):
        methods = (getattr(view_func, 'methods', None) or ('GET',))
    if isinstance(methods, string_types):
        raise TypeError('Allowed    methods    have    to    be    iterables    of    strings,    for    example:    @app.route(...,    methods=["POST"])')
    methods = set((item.upper() for item in methods))
    required_methods = set(getattr(view_func, 'required_methods', ()))
    if (provide_automatic_options is None):
        provide_automatic_options = getattr(view_func, 'provide_automatic_options', None)
    if (provide_automatic_options is None):
        if ('OPTIONS' not in methods):
            provide_automatic_options = True
            required_methods.add('OPTIONS')
        else:
            provide_automatic_options = False
    methods |= required_methods
    rule = self.url_rule_class(rule, methods=methods, **options)
    rule.provide_automatic_options = provide_automatic_options
    self.url_map.add(rule)
    if (view_func is not None):
        old_func = self.view_functions.get(endpoint)
        if ((old_func is not None) and (old_func != view_func)):
            raise AssertionError(('View    function    mapping    is    overwriting    an    existing    endpoint    function:    %s' % endpoint))
        self.view_functions[endpoint] = view_func
