def url(value,
        allow_empty = False,
        allow_special_ips = False,
        **kwargs):
    """Validate that ``value`` is a valid URL.

    .. note::

      URL validation is...complicated. The methodology that we have
      adopted here is *generally* compliant with
      `RFC 1738 <https://tools.ietf.org/html/rfc1738>`_,
      `RFC 6761 <https://tools.ietf.org/html/rfc6761>`_,
      `RFC 2181 <https://tools.ietf.org/html/rfc2181>`_  and uses a combination of
      string parsing and regular expressions,

      This approach ensures more complete coverage for unusual edge cases, while
      still letting us use regular expressions that perform quickly.

    :param value: The value to validate.
    :type value: :class:`str <python:str>` / :obj:`None <python:None>`

    :param allow_empty: If ``True``, returns :obj:`None <python:None>` if
      ``value`` is empty. If ``False``, raises a
      :class:`EmptyValueError <validator_collection.errors.EmptyValueError>`
      if ``value`` is empty. Defaults to ``False``.
    :type allow_empty: :class:`bool <python:bool>`

    :param allow_special_ips: If ``True``, will succeed when validating special IP
      addresses, such as loopback IPs like ``127.0.0.1`` or ``0.0.0.0``. If ``False``,
      will raise a :class:`InvalidURLError` if ``value`` is a special IP address. Defaults
      to ``False``.
    :type allow_special_ips: :class:`bool <python:bool>`

    :returns: ``value`` / :obj:`None <python:None>`
    :rtype: :class:`str <python:str>` / :obj:`None <python:None>`

    :raises EmptyValueError: if ``value`` is empty and ``allow_empty`` is ``False``
    :raises CannotCoerceError: if ``value`` is not a :class:`str <python:str>` or
      :obj:`None <python:None>`
    :raises InvalidURLError: if ``value`` is not a valid URL or
      empty with ``allow_empty`` set to ``True``

    """
    is_recursive = kwargs.pop('is_recursive', False)

    if not value and not allow_empty:
        raise errors.EmptyValueError('value (%s) was empty' % value)
    elif not value:
        return None

    if not isinstance(value, basestring):
        raise errors.CannotCoerceError('value must be a valid string, '
                                       'was %s' % type(value))

    value = value.lower()

    is_valid = False
    stripped_value = None
    for protocol in URL_PROTOCOLS:
        if protocol in value:
            stripped_value = value.replace(protocol, '')

    for special_use_domain in SPECIAL_USE_DOMAIN_NAMES:
        if special_use_domain in value:
            if stripped_value:
                try:
                    domain(stripped_value,
                           allow_empty = False,
                           is_recursive = is_recursive)
                    is_valid = True

                except (ValueError, TypeError):
                    pass

    if not is_valid and allow_special_ips:
        try:
            ip_address(stripped_value, allow_empty = False)
            is_valid = True
        except (ValueError, TypeError):
            pass

    if not is_valid:
        is_valid = URL_REGEX.match(value)

    if not is_valid and allow_special_ips:
        is_valid = URL_SPECIAL_IP_REGEX.match(value)

    if not is_valid:
        raise errors.InvalidURLError('value (%s) is not a valid URL' % value)

    return value
Validate that ``value`` is a valid URL.

    .. note::

      URL validation is...complicated. The methodology that we have
      adopted here is *generally* compliant with
      `RFC 1738 <https://tools.ietf.org/html/rfc1738>`_,
      `RFC 6761 <https://tools.ietf.org/html/rfc6761>`_,
      `RFC 2181 <https://tools.ietf.org/html/rfc2181>`_  and uses a combination of
      string parsing and regular expressions,

      This approach ensures more complete coverage for unusual edge cases, while
      still letting us use regular expressions that perform quickly.

    :param value: The value to validate.
    :type value: :class:`str <python:str>` / :obj:`None <python:None>`

    :param allow_empty: If ``True``, returns :obj:`None <python:None>` if
      ``value`` is empty. If ``False``, raises a
      :class:`EmptyValueError <validator_collection.errors.EmptyValueError>`
      if ``value`` is empty. Defaults to ``False``.
    :type allow_empty: :class:`bool <python:bool>`

    :param allow_special_ips: If ``True``, will succeed when validating special IP
      addresses, such as loopback IPs like ``127.0.0.1`` or ``0.0.0.0``. If ``False``,
      will raise a :class:`InvalidURLError` if ``value`` is a special IP address. Defaults
      to ``False``.
    :type allow_special_ips: :class:`bool <python:bool>`

    :returns: ``value`` / :obj:`None <python:None>`
    :rtype: :class:`str <python:str>` / :obj:`None <python:None>`

    :raises EmptyValueError: if ``value`` is empty and ``allow_empty`` is ``False``
    :raises CannotCoerceError: if ``value`` is not a :class:`str <python:str>` or
      :obj:`None <python:None>`
    :raises InvalidURLError: if ``value`` is not a valid URL or
      empty with ``allow_empty`` set to ``True``