#!/usr/bin/env python3
# -*- coding: utf-8 -*- vim60:fdm=marker
#
# Copyright: 2016, Maximiliano Curia <maxy@debian.org>
#
# License: ISC
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#  .
#  THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
#  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
#  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
#  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
#  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
#  PERFORMANCE OF THIS SOFTWARE.

''' Generic functions used by the parsers. '''

import re

from collections import namedtuple

# Local modules
from .datatypes import CopyrightHolder, ReSub

# Internal types
ReText = namedtuple('ReText', ('re', 'text'))
ReLicense = namedtuple('ReLicense', ('re', 'license', 'get_detail'))


COMMENTS_SUBS = (
    # White without newlines
    ReSub(re.compile(r'[ \t\r\f\v]{2,}'), r' '),
    # Fortran
    ReSub(re.compile(r'^ ?[cC]\s', re.MULTILINE), r' '),
    # C / C++
    ReSub(re.compile(r'\*/|/[/*]'), r' '),
    # Lisp
    ReSub(re.compile(r'(^\s?;;|;;$)', re.MULTILINE), r' '),
    # (HT|X)ML
    ReSub(re.compile(r'(^\s?<!--|-->\s?$)', re.MULTILINE), r' '),
    # m4
    ReSub(re.compile(r'^dnl\s', re.MULTILINE), r' '),
    # Generic
    ReSub(re.compile(r'^[\s\W]+\s', re.MULTILINE), r' '),
    # Non text
    ReSub(re.compile(r'[^ \w\'.,@;()/+-]+'), r' '),
    # White with newlines
    ReSub(re.compile(r'\s{2,}'), r' '),
)


def clean_comments(text):
    for sub in COMMENTS_SUBS:
        text = sub.re.sub(sub.repl, text)

    return text


COPYRIGHT_PRE_IGNORE_REGEX = r'''
    (?:^[#]\s*define\s+.*\([^)]*c[^)]*\)     # #define foo(c) -- not copyright
      |^(?:msgstr|msgid)\s                   # po files data
      |We\sprotect\syour\srights\swith\s
       (?:two\ssteps:
         |a\stwo-step\smethod:)\s\(1\)\s(?:we\s)?copyright
      |and\sput\sthe\sfollowing\scopyright
      |connection\swith\sthe\scopyright
      |applicable\scopyright\slaw\sincludes
      |Original\scopyright\sfollows                     # mostly gpl stuff
      |compilation\sand\sits\sresulting\scopyright
      |under\sapplicable\scopyright\slaw                # clean up
      |copyright\son\sthe\sProgram,\sand
      |copyright\son\sthe\ssoftware,\sand
      |can\sgive\sappropriate\scopyright\spermission
      |requiring\scopyright\spermission
      |copyright\streaty\sadopted\son
      |copyright\sby\stheir\scontributors
      |the\ same\ copyright\ terms
      |for\ copyright\ years
      |Added\ copyright\ notes
      |adjust\ copyright
      |use\ copyright\ ranges
      |disclaims\ copyright                             # public domain
      |the\ applicable\ copyright                       # creative commons
      |under\ copyright\ law\ or
      |free\ from\ copyright\ or
      |WIPO\ Copyright\ Treaty
      |requirements\ and\ penalties\ of\ the\ U\.S\.\ Copyright   # Academic
      |Grant\ of\ Copyright\ License\.                            # Academic
      |prohibited\ by\ U\.S\.\ copyright\ law                     # Academic
      |copyright\ doctrines\ of\ fair\ use                        # MPL-2.0
      |group_by\ copyright            # found in decopy
      |copyright\ file                # found in decopy
      |copyright\ attribution         # found in decopy
      |copyright\ format              # found in decopy
      |copyright\ helper              # found in decopy
      |copyright\ detection           # found in decopy
      |Copyright\sflag                # found in krita code
      |{\scopyright\s=\sc;\s}         # found in plan code
      |Quick\scopyright\s:\sgimp_quick_copyright # krita gmic
      # found in muffin/nemo/cinnamon-c-c
      |\bcopyright\s(?:info|headers?|lines?|messages?|reasons?|symbols?)\b
      |\bUpdate\scopyright\b          # found in muffin
      |LTEXT.*Copyright.*IDC_STATIC   # found in breakpad
      |copyright\ shortname           # found in a changelog
      |copyright\ es\ ilegal          # found in a translation
      |copyright\ existente           # found in a translation
      |copyright\ existent            # found in a translation
      |copyright\ on\ that\ code      # found in kdepimlibs
      |copyright\ on\ this\ code      # found in boringssl
      |for\ copyright\ in             # found in telepathy-logger-qt
      |Fix\ copyright                 # changelog entry
      |concern\ over\ copyright       # found in marble
      |copyright\ &copy;\ @copyright@ # found in marble
      |Copyright\ with\ his\ permission     # found in boringssl
      |optional\ string\ copyright\ =       # found in dom_distiller_js
      |copyright\ &\ original\ defaults     # found in ffmpeg
      |--copyright                          # found in ffmpeg
      |skip\ copyright                      # found in ffmpeg
      |U_COPYRIGHT_STRING              # found in icu
      |LATIN\ CAPITAL\ LETTER\ C       # found in icu
      |copyright\ at\ the\ end         # found in icu, thanks, I guess
      |copyright\ generation           # found in icu
      |print\ our\ copyright           # found in icu
      |copyright\ into\ the            # found in icu
      |Copyright\ (?:Exists|chunk|length|offset|signature|it\.)   # found in ffmpeg
      |AUTHOR\(S\)\ and\ COPYRIGHT\ sections  # found in spacezero
      |\bif\b.*\(\s?c\s?\)             # damn you (c)
      |\bwhile\b.*\(\s?c\s?\)          # damn you (c)
      |Similar\sto\s\(\s?c\s?\)        # damn you (c)
      |\(\s?c\s?\)\sit\smakes\suse     # damn you (c)
      |replaced\s\(C\)                 # damn you (c)
      |\(c\)\ have                     # damn you (c)
      |\(c\)\ the\ sum                 # damn you (c)
      |\(unsigned\ int\)               # damn you (c)
      |\(\*?a\),\ ?\(b\),\ ?\(c\)      # damn you (c)
      |\(\w\).*[^\s,;]\s*\(\w\)        # damn you (c)
      |\(c\).*\(c2\)                   # damn you (c)
      |ISUPPER\ ?\(c\)                 # damn you (c)
      |\(c\)\ You\ must\ retain        # damn you (c)
      |\(c\)\ ?[\*/&|<>\+-]?=          # damn you (c)
      |\(c\)\ ?\)                      # damn you (c)
      |sizeof\([^)]+\)                 # damn you (c)
      |\(c\)(?:->|\.)[^ ]              # damn you (c)
      |=\s*\(c\)\s*\*.*;               # damn you (c) var = (c) * ... ;
      |\(c\)\s*[*/+-]\s*\(             # damn you (c) (c) * (...
      |\(c\)\ and\ its\ data           # damn you (c)
      |character\ \(c\)                # damn you (c)
      |\(c\)\ differs\ for             # damn you (c)
      |combining\ mark\ \(c\)          # damn you (c)
      |\(c\)\ *processed                 # damn you (c)
      |\(c\)\ data\ (?:[^ ]+\ ){,5}has\ been\ received  # damn you (c)
      |shown\sby\s\(c\)\ssupports
      |AND\s\(c\)
      |following\scopyright\sand\slicense   # more text
      |\bcopyright\ssign\b
      |"Country\ Code\ \(C\)"         # found in qca
      |\bcopyright\ and\b             # found in cinnamon
      |\bCopyright:?\s(?:\(\s*C\s*\)\s)?YEAR\b          # template used in po
      # found in cinnamon-settings-daemon
      |free\sof\sknown\scopyright\srestrictions
      |[-\s–—]%[ds][-\s–—]
      |<\*\*authorname\*\*>                          # template (marble)
      |%{AUTHOR}                                     # template (kcoreaddons)
      |krazy:exclude(?:all)?=[^\s]*copyright         # tagged to be ignored
      # Test case in ark
      |UNRAR\s+[0-9.]+\ (\(iconv\)|beta\ [0-9])\ freeware\s+Copyright\ \(c\)\ [0-9-]+\ Alexander\ Roshal
    )'''
COPYRIGHT_PRE_IGNORE_RE = re.compile(COPYRIGHT_PRE_IGNORE_REGEX,
                                     re.IGNORECASE | re.VERBOSE)

COPYRIGHT_INDICATOR_REGEX = r'''(?:^|\s)
    (
       (?:
          copyright(?:\s*\(c\))?  # The full word
         |copr\.             # Legally-valid abbreviation
         |©                  # Unicode character COPYRIGHT SIGN
         |\xa9               # Unicode copyright sign encoded in iso8859
         |&copy;             # HTML copyright sign
       )(?:[:\s]+)
      |(?:\(\s?c\s?\))(?:[:\s]*)   # Legally-null representation of sign
    )(?=\S)'''
COPYRIGHT_INDICATOR_RE = re.compile(COPYRIGHT_INDICATOR_REGEX,
                                    re.IGNORECASE | re.VERBOSE)

COPYRIGHT_POST_IGNORE_REGEX = r'''
    \b(?:
        information             # Discussing copyright information
       |(notice|statement|claim|string)s? # Discussing the notice
       |\<?name\ of\ author\>?  # GPL template
       |YEAR\s+YOUR\s+NAME      # template
       # |and|or used in: and/or its subsidiary(-ies).
       # |in used in .in tld
       |\ in\                   # Part of a sentence
       |is|to|if                # Part of a sentence
       |(holder|owner)s?        # Part of a sentence
       |ownership               # Part of a sentence
       |IDC_STATIC              # template
    )\b
    |(?:^|\s)(?:
        &&|\|\|                 # (c) conditional
       |\(\s?[abd-f]\s?\)       # ugly one letter expressions
    )(?:\s|$)
    |^\s*(?:
        law[.:]?                # GPL text
       |{                       # if (c) {
       |L?GPL$                  # Copyright: License
       |@\w+\{\w+\}             # template
       )\s*$'''
COPYRIGHT_POST_IGNORE_RE = re.compile(COPYRIGHT_POST_IGNORE_REGEX,
                                      re.IGNORECASE | re.VERBOSE)

CRUFT_SUBS = (
    ReSub(re.compile(r'''(?:(?:some|all)? rights reserved'''
                     r'''|(?:some|all) rights)[\s,.;\*#'"]*''',
                     re.IGNORECASE), r''),
    ReSub(re.compile(r'It can be distributed', re.IGNORECASE), r''),
    ReSub(re.compile(r'and contributors', re.IGNORECASE), r''),
    ReSub(re.compile(r'et al', re.IGNORECASE), r''),
    ReSub(re.compile(r'\band$', re.IGNORECASE), r''),
    ReSub(re.compile(r'\\$'), r''),
    ReSub(re.compile(r'''[\s,.;\*#'"]*$'''), r''),
    ReSub(re.compile(r'\(\sc\s\)', re.IGNORECASE), r''),
    ReSub(re.compile(r'<br/?>'), r''),
    ReSub(re.compile(r'\s{2,}'), r' '),
    ReSub(re.compile(r'^\s+'), r''),
    ReSub(re.compile(r'\\@'), r'@'),
    ReSub(re.compile(r'&ndash;'), r'-'),
)


def _parse_copyright_continuation(text, continuation):

    if not continuation:
        return '', None
    prefix = continuation.string[:continuation.start(1)]
    # Special case for C style multiline comments
    alt_prefix = prefix.replace('/*', ' *')
    if not text.startswith(prefix) and not text.startswith(alt_prefix):
        return '', None
    cont_match = re.match(r'\s+', text[len(prefix):])
    if not cont_match:
        return '', None
    rest = cont_match.string[cont_match.end():]
    match = continuation
    return rest, match


def parse_copyright(text, continuation=None):

    if COPYRIGHT_PRE_IGNORE_RE.search(text):
        return None, None

    match = COPYRIGHT_INDICATOR_RE.search(text)
    if match:
        rest = match.string[match.end():]
    else:
        # Process continuations
        rest, match = _parse_copyright_continuation(text, continuation)
        if not match:
            return None, None
    if COPYRIGHT_POST_IGNORE_RE.search(rest):
        return None, None

    copyrights = []
    parts = COPYRIGHT_INDICATOR_RE.split(rest)
    for i, part in enumerate(parts):
        if i % 2:
            # the re split includes the separators, skip them
            continue
        for sub in CRUFT_SUBS:
            part = sub.re.sub(sub.repl, part)
        if part and len(part) > 2:
            copyrights.append(part)

    return copyrights, match


def parse_holders(content):

    holders = []
    continuation = None

    for line in content.split('\n'):
        copyrights, continuation = parse_copyright(line, continuation)
        if not copyrights:
            continue
        for copyright_ in copyrights:
            holder = CopyrightHolder.from_copyright(copyright_)
            if holder:
                holders.append(holder)

    return holders


ARTISTIC_RES = (
    ReSub(
        re.compile(
            r'The "?Clarified "?Artistic License"? '
            r'Preamble ',
            re.IGNORECASE),
        'ClArtistic'),
    ReSub(
        re.compile(
            r'You may charge a reasonable copying fee for any '
            r'distribution of this Package. You may charge '
            r'any fee you choose for support of this Package. '
            r'You may not charge a fee for this Package itself. '
            r'However, you may distribute this Package in aggregate '
            r'with other \(possibly commercial\) programs as '
            r'part of a larger \(possibly commercial\) software '
            r'distribution provided that you do not advertise '
            r'this Package as a product of your own. You may embed '
            r'this Package[\' ]?s interpreter within an executable '
            r'of yours \(by linking\);? this shall be construed as '
            r'a mere form of aggregation, provided that the complete '
            r'Standard Version of the interpreter is so embedded.'
            r'.+'
            r'Aggregation of this Package with a commercial '
            r'distribution is always permitted provided that '
            r'the use of this Package is embedded; that is, '
            r'when no overt attempt is made to make this Package[\' ]?s '
            r'interfaces visible to the end user of the commercial '
            r'distribution. Such use shall not be construed as a '
            r'distribution of this Package.', re.IGNORECASE),
        'Artistic-1-Perl'),
    ReSub(
        re.compile(
            r'Aggregation of this Package with a commercial '
            r'distribution is always permitted provided that '
            r'the use of this Package is embedded; that is, '
            r'when no overt attempt is made to make this Package[\' ]?s '
            r'interfaces visible to the end user of the commercial '
            r'distribution. Such use shall not be construed as a '
            r'distribution of this Package.', re.IGNORECASE),
        'Artistic-1-cl8'),
    ReSub(
        re.compile(
            r'The "?Artistic License"? '
            r'Preamble '
            r'The intent of this document is to state the conditions under '
            r'which a Package may be copied, such that the Copyright Holder '
            r'maintains some semblance of artistic control over the '
            r'development of the package, while giving the users of the '
            r'package the right to use and distribute the Package in a '
            r'more[- ]or[- ]less customary fashion, plus the right to make '
            r'reasonable modifications.', re.IGNORECASE),
        'Artistic-1'),
)


def parse_artistic(text, match, group):
    for sub in ARTISTIC_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return group


BSD_RES = (
    ReSub(
        re.compile(
            r'4. If you include any Windows specific code \(or a derivative '
            r'thereof\) fromg? the apps directory \(application code\) you '
            r'must include an acknowledgement:? '
            r'"?This product includes software written by Tim Hudson '
            r'\(tjh@cryptsoft.com\)"?', re.IGNORECASE),
        'SSLeay'),
    ReSub(
        re.compile(r'All advertising materials mentioning features or use of '
                   r'this software must display the following '
                   r'acknowledge?ment.*This product includes software '
                   r'developed by', re.IGNORECASE),
        'BSD-4-clause'),
    ReSub(
        re.compile(
            r'You acknowledge that this software is not designed'
            r'(?:, licensed)? '
            r'or intended for use in the design, construction, operation or '
            r'maintenance of any nuclear facility.', re.IGNORECASE),
        'BSD-3-clause-no-nuclear'),
    ReSub(
        re.compile(
            r'Redistributions of source code must retain the above '
            r'copyright notice, this list of conditions and the following '
            r'disclaimer.? '
            r'(?:\* )?'
            r'(?:The name(?:\(?s\)?)? .*? may not|Neither the '
            r'(?:names? .*?|authors?) ?n?or the names of(?: '
            r'(?:its|their|other|any))? contributors may) be used to '
            r'endorse or promote products derived from this software',
            re.IGNORECASE),
        'BSD-source-code'),
    ReSub(
        re.compile(
            r'Redistributions of any form whatsoever must retain the '
            r'following acknowledgment:? \'?This product includes software '
            r'developed by ',
            re.IGNORECASE),
        'BSD-3-clause-attribution'),
    ReSub(
        re.compile(
            r'The origin of this software must not be misrepresented;? '
            r'you must not claim that you wrote the original software. '
            r'If you use this software in a product, an acknowledgment '
            r'in the product documentation would be appreciated but is '
            r'not required.'
            r'.+'
            r'Altered source versions must be plainly marked as such, '
            r'and must not be misrepresented as being the original '
            r'software.'
            r'.+'
            r'The name of the author may not be used to endorse or '
            r'promote products derived from this software without '
            r'specific prior written permission.',
            re.IGNORECASE),
        'BSD-like-bzip2'),
    ReSub(
        re.compile(r'(?:The name(?:\(?s\)?)? .*? may not|Neither the '
                   r'(?:names? .*?|authors?) n?or the names of(?: '
                   r'(?:its|their|other|any))? contributors may) be used to '
                   r'endorse or promote products derived from this software',
                   re.IGNORECASE),
        'BSD-3-clause'),
    ReSub(
        re.compile(
            r'The views and conclusions contained in the software and '
            r'documentation are those of the authors and should not '
            r'be interpreted as representing official policies, '
            r'either expressed or implied, of the FreeBSD Project.',
            re.IGNORECASE),
        'BSD-2-clause-FreeBSD'),
    ReSub(
        re.compile(
            r'This code is derived from software contributed to The '
            r'NetBSD Foundation by',
            re.IGNORECASE),
        'BSD-2-clause-NetBSD'),
    ReSub(
        re.compile(
            r'Nothing in this license shall be deemed to grant '
            r'any rights to trademarks, copyrights, patents, trade '
            r'secrets or any other intellectual property of A.M.P.A.S. '
            r'or any contributors, except as expressly stated herein, '
            r'and neither the name of A.M.P.A.S. nor of any other '
            r'contributors to this software, may be used to endorse '
            r'or promote products derived from this software without '
            r'specific prior written permission of A.M.P.A.S. or '
            r'contributor, as appropriate.', re.IGNORECASE),
        'BSD-2-clause-AMPAS'),
    ReSub(
        re.compile(
            r'This code is derived from software contributed to The '
            r'NetBSD Foundation by',
            re.IGNORECASE),
        'BSD-2-clause-NetBSD'),
    ReSub(
        re.compile(r'Redistributions of source code must retain the above '
                   r'copyright notice', re.IGNORECASE),
        'BSD-2-clause'),
    ReSub(
        re.compile(
            r'BSD PROTECTION LICENSE '
            r'TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND '
            r'MODIFICATION', re.IGNORECASE),
        'BSD-protection'),
    ReSub(
        re.compile(
            r'Permission to use, copy, modify, and/?or distribute this '
            r'software for any purpose with or without fee is hereby '
            r'granted. '
            r'THE SOFTWARE IS PROVIDED "?AS IS"? AND THE AUTHOR DISCLAIMS '
            r'ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL '
            r'IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO '
            r'EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, '
            r'INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER '
            r'RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN '
            r'ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, '
            r'ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE '
            r'OF THIS SOFTWARE.', re.IGNORECASE),
        '0BSD'),
    ReSub(
        re.compile(
            r'Redistributions of the Code in binary form must be '
            r'accompanied by this GPG-signed text in any documentation '
            r'and, each time the resulting executable program or a '
            r'program dependent thereon is launched, a prominent '
            r'display \(?e\.g\., splash screen or banner text\)? '
            r'of the Author[\' ]?s attribution information, which '
            r'includes:? '
            r'\(?a\)? Name \(?[" ]AUTHOR[" ]\)?, '
            r'\(?b\)? Professional identification \(?[" ]PROFESSIONAL '
            r'IDENTIFICATION[" ]\)?, and '
            r'\(?c\)? URL \(?[" ]URL[" ]\)?.', re.IGNORECASE),
        'AAL'),
    ReSub(
        re.compile(
            r'The Condor Team may publish revised and/or new versions '
            r'of this Condor Public License '
            r'\((?:``|[" ])?this License(?:''|[" ])?\) '
            r'from time to time\. Each '
            r'version will be given a distinguishing version number\. '
            r'Once Software has been published under a particular '
            r'version of this License, you may always continue to use '
            r'it under the terms of that version\. You may also '
            r'choose to use such Software under the terms of '
            r'any subsequent version of this License published '
            r'by the Condor Team\. No one other than the Condor '
            r'Team has the right to modify the terms of this License\.',
            re.IGNORECASE),
        'Condor-1.1+'),
    ReSub(
        re.compile(
            r'This product includes software developed by the EU DataGrid',
            re.IGNORECASE),
        'EUDatagrid'),
)


def parse_bsd(text, match, group):
    for sub in BSD_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return group


CC_BY_RES = (
    ReSub(
        re.compile(r'Creative Commons (?:Legal Code )?Attribution[- ](?:[^ ]+[- ])?'
                   r'NonCommercial', re.IGNORECASE),
        r'-NC'),
    ReSub(
        re.compile(r'Creative Commons (?:Legal Code )?Attribution[- ](?:[^ ]+[- ])?'
                   r'ShareAlike', re.IGNORECASE),
        r'-SA'),
    ReSub(
        re.compile(r'Creative Commons (?:Legal Code )?Attribution[- ](?:[^ ]+[- ])?'
                   r'(?:NoDerivatives|NoDerivs)', re.IGNORECASE),
        r'-ND'),
    ReSub(
        re.compile(r'Creative Commons (?:Legal Code )?Attribution[- ](?:[^ ]+[- ]){,2}'
                   r'([\d.]+?)(?:\.0)?[^\d.]', re.IGNORECASE),
        r'-\1'),
)


def parse_cc_by(text, match, group):
    license_ = group
    for sub in CC_BY_RES:
        match = sub.re.search(text)
        if not match:
            continue
        license_ += match.expand(sub.repl)
    return license_


CECILL_RES = (
    ReSub(
        re.compile(
            r'Une liste de questions fréquemment posées se '
            r'trouve sur le site web officiel de la famille '
            r'des licences CeCILL '
            r'\(http[: ][/ ]?[/ ]?www.cecill.info/index.fr.html\) '
            r'pour toute clarification qui serait nécessaire\.',
            re.IGNORECASE),
        'CeCILL-2.1'),
    ReSub(
        re.compile(
            r'Frequently asked questions can be found on the '
            r'official website of the CeCILL licenses family '
            r'\(http[: ][/ ]?[/ ]?www.cecill.info/index.en.html\)'
            r'for any necessary clarification\. ',
            re.IGNORECASE),
        'CeCILL-2.1'),
    ReSub(
        re.compile(
            r'un modèle de diffusion en logiciel libre',
            re.IGNORECASE),
        'CeCILL-2'),
    ReSub(
        re.compile(
            r'The exercising of these rights is conditional '
            r'upon certain obligations for users so as to preserve '
            r'this status for all subsequent redistributions\.',
            re.IGNORECASE),
        'CeCILL-2'),
    ReSub(
        re.compile(
            r'As a counterpart to the access to the source '
            r'code and rights to copy, modify and redistribute '
            r'granted by the license, users are provided only '
            r'with a limited warranty and the software\'s author, '
            r'the holder of the economic rights, and the successive '
            r'licensors only have limited liability\.',
            re.IGNORECASE),
        'CeCILL-1.1'),
    ReSub(
        re.compile(
            r'un modèle de diffusion (?:« ?)?open source ?»?',
            re.IGNORECASE),
        'CeCILL-1'),
    ReSub(
        re.compile(
            r'Nevertheless, access to the source code, and '
            r'the resulting rights to copy, modify and redistribute '
            r'only provide users with a limited warranty and the '
            r'software\'s author, the holder of the economic '
            r'rights, and the successive licensors only have '
            r'limited liability\. ',
            re.IGNORECASE),
        'CeCILL-1'),
)


def parse_cecill(text, match, group):
    license_ = group
    for sub in CECILL_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return license_


CNRI_RES = (
    ReSub(
        re.compile(
            r'Licensee may not use CNRI trademarks or trade '
            r'name, including [^ ]+ or CNRI, in a trademark '
            r'sense to endorse or promote products or services '
            r'of Licensee, or any third party\. Licensee may '
            r'use the mark [^ ]+ in connection with Licensee\'s '
            r'derivative versions that are based on or incorporate '
            r'the Software, but only in the form ',
            re.IGNORECASE),
        'CNRI-Jython'),
    ReSub(
        re.compile(
            r'URL:? ?http[: ]?[/ ]?[/ ]?hdl\.handle\.net/'
            r'1895.22/1006',
            re.IGNORECASE),
        'CNRI-Jython'),
    ReSub(
        re.compile(
            r'Notwithstanding the foregoing, with regard to '
            r'derivative works based on '
            r'.+'
            r'that incorporate non[- ]separable material that '
            r'was previously distributed under the '
            r'GNU General Public License',
            re.IGNORECASE),
        'CNRI-Python-GPL-Compatible'),
    ReSub(
        re.compile(
            r'URL:? ?http[: ]?[/ ]?[/ ]?hdl\.handle\.net/'
            r'1895.22/1013',
            re.IGNORECASE),
        'CNRI-Python-GPL-Compatible'),
    ReSub(
        re.compile(
            r'URL:? ?http[: ]?[/ ]?[/ ]?hdl\.handle\.net/'
            r'1895.22/1011',
            re.IGNORECASE),
        'CNRI-Python'),
)


def parse_cnri(text, match, group):
    license_ = group
    for sub in CNRI_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return license_


EFL_RES = (
    ReSub(
        re.compile(
            r'If the binary program depends on a modified version '
            r'of this package, you are encouraged to publicly '
            r'release the modified version of this package',
            re.IGNORECASE),
        'EFL-2'),
    ReSub(
        re.compile(
            r'if the binary program depends on a modified version '
            r'of this package, you must publicly release the '
            r'modified version of this package',
            re.IGNORECASE),
        'EFL-1'),
)


def parse_efl(text, match, group):
    license_ = group
    for sub in EFL_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return license_


GNU_VERSION_RES = (
    ReSub(
        re.compile(
            r'version ([\d.]+) (?:of the License,? )?or '
            r'(?:\(? ?at your option ?\)? )?'
            r'version ([\d.]+),? or,? (?:(?:any )?later versions? '
            r'(?:accepted|approved) by the '
            r'membership of KDE ?e\.?V\.?|at the discretion of KDE ?e\.?V\.? '
            r'(?:[^ ]+ ){,20}any later version)', re.IGNORECASE),
        r'\1+\2+KDEeV'),
    ReSub(
        re.compile(
            r'General Public License version ([\d.]+) (?:and|or),? '
            r'(?:\(? ?at your option ?\)? )?version '
            r'([\d.]+) as published by the Free Software Foundation',
            re.IGNORECASE),
        r'\1+\2'),
    ReSub(
        re.compile(
            r'General Public License as published by the Free Software '
            r'Foundation[,;]? (?:either )?version ([\d.]+) '
            r'(?:of the License,? )?'
            r'(?:and|or),? (?:\(? ?at your option ?\)? )?(?:version )?'
            r'([\d.]+?)[.,;]? ',
            re.IGNORECASE),
        r'\1+\2'),
    ReSub(
        re.compile(
            r'version ([\d.]+) of the License,? or,? '
            r'(?:\(? ?at your option ?\)? )?'
            r'(?:any later version accepted by the '
            r'membership of KDE e.V.|at the discretion of KDE ?e\.?V\.? '
            r'(?:[^ ]+ ){,20}any later version)', re.IGNORECASE),
        r'\1+KDEeV'),
    ReSub(
        re.compile(r'either version ([^ ]+?)(?: of the License)?[;,] '
                   r'or[ ,(]+at your option[ ,)]+any later version',
                   re.IGNORECASE), r'\1+'),
    ReSub(
        re.compile(
            r'(?:modify it|used) under the terms of the GNU (?:Affero )?'
            r'(?:Lesser(?:/Library)? |Library(?:/Lesser)? )?General Public '
            r'License (?:as published by the Free Software Foundation[;,]? )?'
            r'\(?(?:either )?version ?([^ ]+?)[;,)]* (?:as published by the Free '
            r'Software Foundation[;,]? )?(?:of the Licen[sc]e,? )?or '
            r'(?:later|(?:\(? ?at your option ?\)?,? )?any later version)',
            re.IGNORECASE),
        r'\1+'),
    ReSub(
        re.compile(r'licensed under (?:[^ ]+ ){,10}[AL]?GPL,? ?(?:version|v)'
                   r' ?([\d.]+) (?:(?:or )?(?:higher|later)|or[, (]+at your '
                   r'option[, )]+any later version)',
                   re.IGNORECASE),
        r'\1+'),
    ReSub(
        re.compile(
            r'General Public License,? Version ([\d.]+) or later',
            re.IGNORECASE),
        r'\1+'),
    ReSub(
        re.compile(
            r'under the terms of (?:the )?version ([^ ]+) or later of the '
            r'(?:GNU|[AL]?GPL)', re.IGNORECASE),
        r'\1+'),
    ReSub(
        re.compile(r'GNU (?:Affero )?(?:Lesser(?:/Library)? |Library )?'
                   r'General Public License (?:as )?published by the Free '
                   r'Software Foundation[;,] either version ([^ ]+?)[.,]? '
                   r'(?:of the License )?or '
                   r'(?:\(at your option\) )?any later version',
                   re.IGNORECASE),
        r'\1+'),
    ReSub(
        re.compile(r'licensed under (?:[^ ]+ ){,10}[AL]?GPL ?(?:version|v)'
                   r' ?([\d.]+?)[.,]? ',
                   re.IGNORECASE),
        r'\1'),
    ReSub(
        re.compile(r'(?:used|modify it) under the terms (?:and conditions )?'
                   r'of the GNU '
                   r'(?:Affero )?'
                   r'(?:Lesser(?:/Library)? |Library )?General Public '
                   r'License,? (?:as published by the Free Software '
                   r'Foundation;? )?(?:either )?'
                   r'Version ([\d.]+?)(?:[.,;]|as)? ', re.IGNORECASE), r'\1'),
    ReSub(
        re.compile(r'GNU (?:Affero )?(?:Lesser(?:/Library)? |Library )?'
                   r'General Public License, version ([^ ]+?)[ .,;]',
                   re.IGNORECASE), r'\1'),
    ReSub(
        re.compile(r'version ([\d.]+?)[.,]? (?:\(?only\)?.? )?'
                   r'(?:of the GNU (?:Affero )?'
                   r'(?:Lesser(?:/Library)? |Library )?'
                   r'General Public License )?(?:as )?published by the '
                   r'Free Software Foundation', re.IGNORECASE), r'\1'),
    ReSub(
        re.compile(r'GNU (?:Affero )?(?:Lesser(?:/Library)? |Library )?'
                   r'General Public License (?:as )?published by the Free '
                   r'Software Foundation[;,] version ([^ ]+?)[.,]? ',
                   re.IGNORECASE),
        r'\1'),
    ReSub(
        re.compile(
            r'(?:General Public License|GPL) (?:Vers.?ion )?([\d.]+?)[.,]? ',
            re.IGNORECASE),
        r'\1'),
)

GNU_EXCEPTION_RES = (
    ReSub(
        re.compile(
            r'As a special exception, if you create a document which uses '
            r'this font, and embed this font or unaltered portions of this '
            r'font into the document, this font does not by itself cause '
            r'the resulting document to be covered by the GNU General '
            r'Public License. This exception does not however invalidate '
            r'any other reasons why the document might be covered by the '
            r'GNU General Public License. If you modify this font, you may '
            r'extend this exception to your version of the font, but you '
            r'are not obligated to do so. If you do not wish to do so, '
            r'delete this exception statement from your version.',
            re.IGNORECASE),
        r'Font'),
    ReSub(
        re.compile(
            r'As a special exception, the copyright holders give permission '
            r'to link the code of portions of this program with the OpenSSL '
            r'library', re.IGNORECASE),
        r'OpenSSL'),
    ReSub(
        re.compile(
            r'(?:'
            r'As a special exception(?:, the respective Autoconf Macro[\' ]?s '
            r'copyright owner gives unlimited permission to copy, distribute '
            r'and modify the configure scripts that are the output of '
            r'Autoconf when processing the Macro\.'
            r'| to the GNU General Public License, if you distribute this '
            r'file as part of a program that contains a configuration '
            r'script generated by Autoconf, you may include it under the '
            r'same distribution terms that you use for the rest of that '
            r'program\.'
            r'|, the Free Software Foundation gives unlimited permission to '
            r'copy, distribute and modify the configure scripts that are '
            r'the output of Autoconf\.)'
            r'|'
            r'This Exception is an additional permission under section 7 of '
            r'the GNU General Public License, version 3 '
            r'\([" ]?GPLv3[" ]?\)\. It '
            r'applies to a given file that bears a notice placed by the '
            r'copyright holder of the file stating that the file is '
            r'governed by GPLv3 along with this Exception\. '
            r'The purpose of this Exception is to allow distribution of '
            r'Autoconf[\' ]?s typical output under terms of the '
            r'recipient[\' ]?s '
            r'choice \(including proprietary\)\.'
            r')', re.IGNORECASE),
        r'AutoConf'),
    ReSub(
        re.compile(
            r'As a special exception, you may create a larger work that '
            r'contains part or all of the Bison parser skeleton and '
            r'distribute that work under terms of your choice', re.IGNORECASE),
        r'Bison'),
    ReSub(
        re.compile(
            r'As a special exception, the copyright holders of this library '
            r'give you permission to link this library with independent '
            r'modules to produce an executable, regardless of the license '
            r'terms of these independent modules, and to copy and distribute '
            r'the resulting executable under terms of your choice, provided '
            r'that you also meet, for each linked independent module, the '
            r'terms and conditions of the license of that module\.',
            re.IGNORECASE),
        r'ClassPath'),
    ReSub(
        re.compile(
            r'(?:'
            r'In addition to the permissions in the GNU General Public '
            r'License, the Free Software Foundation gives you unlimited '
            r'permission to link the compiled version of this file into '
            r'combinations with other programs, and to distribute those '
            r'combinations without any restriction coming from the use of '
            r'this file\.'
            r'|'
            r'This GCC Runtime Library Exception '
            r'\([" ]?Exception[" ]?\) is an additional permission under '
            r'section 7 of the GNU General Public License, version 3 '
            r'\([" ]?GPLv3[" ]?\)\. It applies to a given file \(the '
            r'"?Runtime Library[" ]?\) that bears a notice placed by the '
            r'copyright holder of the file stating that the file is '
            r'governed by GPLv3 along with this Exception\.'
            r')',
            re.IGNORECASE),
        r'GCC'),
    ReSub(
        re.compile(
            r'As a special exception to the (?:[^ ]+ ){,5}if you '
            r'distribute this file as part of a program or library that '
            r'is built using GNU Libtool, you may include this file under '
            r'the same distribution terms that you use for the rest of that '
            r'program', re.IGNORECASE),
        r'LibTool'),
    ReSub(
        re.compile(
            r'In addition, as a special exception, (?:[^\s]+ ){,8}'
            r'gives You the additional right to link the code of '
            r'this Program with code not covered under the GNU '
            r'General Public License \(?[" ]?Non[- ]?GPL Code[" ]?\)? and '
            r'to distribute linked combinations including the '
            r'two, subject to the limitations in this paragraph. '
            r'Non-GPL Code permitted under this exception must only '
            r'link to the code of this Program through those well '
            r'defined interfaces identified in the file named EXCEPTION '
            r'found in the source code files \(?the "?Approved '
            r'Interfaces[" ]?[\) ]?\. The files of Non[- ]?GPL Code may '
            r'instantiate templates or use macros or inline functions '
            r'from the Approved Interfaces without causing the resulting '
            r'work to be covered by the GNU General Public License. Only '
            r'(?:[^\s]+ ){,8}may make changes or additions to the list of '
            r'Approved Interfaces. You must obey the GNU General Public '
            r'License in all respects for all of the Program code and '
            r'other code used in conjunction with the Program except the '
            r'Non-GPL Code covered by this exception. If you modify this '
            r'file, you may extend this exception to your version of the '
            r'file, but you are not obligated to do so. If you do not '
            r'wish to provide this exception without modification, you '
            r'must delete this exception statement from your version and '
            r'license this file solely under the GPL without exception.',
            re.IGNORECASE),
        r'389'),
    ReSub(
        re.compile(
            r'This copyright does NOT cover user programs that '
            r'run in CLISP and third-party packages not part '
            r'of CLISP, if a',
            re.IGNORECASE),
        r'CLISP'),
    ReSub(
        re.compile(
            r'A FOSS application developer \([“" ]?you[”" ]? or '
            r'[“" ]?your[”" ]?\) may distribute a Derivative '
            r'Work provided that you and the Derivative Work '
            r'meet all of the following conditions',
            re.IGNORECASE),
        r'DigiRule-FOSS'),
    ReSub(
        re.compile(
            r'As a special exception, if other files instantiate '
            r'templates or use macros or inline functions from '
            r'this file, or you compile this file and link '
            r'it with other works to produce a work based on '
            r'this file, this file does not by itself cause '
            r'the resulting work to be covered by the GNU General '
            r'Public License\. However the source code for '
            r'this file must still be made available in accordance '
            r'with section \(3\) of the GNU General Public License\.',
            re.IGNORECASE),
        r'eCos-2'),
    ReSub(
        re.compile(
            r'The FLTK library and included programs are provided '
            r'under the terms of the GNU Library General Public '
            r'License \(LGPL\) with the following exceptions',
            re.IGNORECASE),
        r'FLTK'),
    ReSub(
        re.compile(
            r'As a special exception, the copyright holder of '
            r'FreeRTOS gives you permission to link FreeRTOS '
            r'with independent modules that communicate with '
            r'FreeRTOS solely through the FreeRTOS API interface, '
            r'regardless of the license terms of these independent '
            r'modules, and to copy and distribute the resulting '
            r'combined work under terms of your choice, provided '
            r'that '
            r'Every copy of the combined work is accompanied by '
            r'a written statement that details to the recipient '
            r'the version of FreeRTOS used and an offer by yourself '
            r'to provide the FreeRTOS source code \(including any '
            r'modifications you may have made\) should the '
            r'recipient request it.',
            re.IGNORECASE),
        r'FreeRTOS'),
    ReSub(
        re.compile(
            r'As a special exception, if you link this library '
            r'with other files to produce an executable, this '
            r'library does not by itself cause the resulting '
            r'executable to be covered by the GNU General Public '
            r'License.',
            re.IGNORECASE),
        r'GNU-JavaMail'),
    ReSub(
        re.compile(
            r'In addition, as a special exception, .+'
            r'gives permission to link the code of this program '
            r'with the proprietary Java implementation provided '
            r'by Sun \(or other vendors as well\), and distribute '
            r'linked combinations including the two.',
            re.IGNORECASE),
        r'i2p-Java'),
    ReSub(
        re.compile(
            r'Special exception for LZMA compression module',
            re.IGNORECASE),
        r'LZMA'),
    ReSub(
        re.compile(
            r'if other files instantiate templates '
            r'or use macros or inline functions from this file, '
            r'or you compile this file and link it with other '
            r'files to produce an executable, this file does '
            r'not by itself cause the resulting executable '
            r'to be covered by the GNU General Public License.',
            re.IGNORECASE),
        r'MIF'),
    ReSub(
        re.compile(
            r'Open CASCADE Exception \(version ([\d.]+)\) '
            r'to GNU ',
            re.IGNORECASE),
        r'OCCT-\1'),
    ReSub(
        re.compile(
            r'Special exception for linking OpenVPN with OpenSSL',
            re.IGNORECASE),
        r'openvpn-openssl'),
    ReSub(
        re.compile(
            r'Qt LGPL Exception version ([\d.]+) '
            r'As an additional permission to the GNU ',
            re.IGNORECASE),
        r'Qt\1'),
    ReSub(
        re.compile(
            r'U-Boot License Exception:? '
            r'Even though ',
            re.IGNORECASE),
        r'u-boot'),
    ReSub(
        re.compile(
            r'EXCEPTION NOTICE '
            r'.{,4}As a special exception, the copyright holders '
            r'of this library give permission for additional '
            r'uses of the text contained in this release of '
            r'the library as licenced under the wxWindows '
            r'Library Licen[cs]e, applying either version 3.1 '
            r'of the Licen[cs]e, or \(at your option\) any later '
            r'version of the Licen[cs]e as published by the '
            r'copyright holders of version 3.1 of the Licen[cs]e '
            r'document\.',
            re.IGNORECASE),
        r'WxWindows-3.1+'),
)


def parse_gpl(text, match, group):
    version = ''
    for sub in GNU_VERSION_RES:
        match = sub.re.search(text)
        if not match:
            continue
        version = match.expand(sub.repl)
        break
    exceptions = []
    for sub in GNU_EXCEPTION_RES:
        match = sub.re.search(text)
        if not match:
            continue
        exceptions.append(match.expand(sub.repl).rstrip('.0'))

    exception = ' with {} exception'.format(
        '_'.join(sorted(exceptions))) if exceptions else ''

    return '{}{}{}'.format(group,
                           '-{}'.format(version.rstrip('0.')) if version else '',
                           exception)


GFDL_RES = (
    ReSub(
        re.compile(
            r'GNU Free Documentation License[,.; ]*(?:(?:Version|v)? [^ ]* )?'
            r'(?:or any later version published by the Free Software '
            r'Foundation; )?'
            r'with no Invariant Sections, no Front-Cover Texts, and no '
            r'Back-Cover Texts', re.IGNORECASE),
        r'-NIV'),
    ReSub(
        re.compile(
            r'GNU Free Documentation License[,.; ]*(?:Version|v)?  ?'
            r'(\d+(?:\.[\d]+)*)[-,.; ]+?', re.IGNORECASE),
        r'-\1'),
)


def parse_gfdl(text, match, group):
    license_ = group
    for sub in GFDL_RES:
        match = sub.re.search(text)
        if not match:
            continue
        license_ += match.expand(sub.repl)
    return license_


LPPL_RES = (
    ReSub(
        re.compile(
            r'LaTeX Project Public License'
            r'(?: Distributed from CTAN archives in directory '
            r'macros/latex/base/lppl\.txt)?[,;]? (?:either )?(?:version|v) '
            r'?([\d.]+)[; ]', re.IGNORECASE),
        r'-\1'),
    ReSub(
        re.compile(
            r'LaTeX Project Public License,? (?:[^ ]+ ){,16}or '
            r'(?:\(?at your option\)? )?any later version', re.IGNORECASE),
        r'+'),
)


def parse_lppl(text, match, group):
    license_ = group
    for sub in LPPL_RES:
        match = sub.re.search(text)
        if not match:
            continue
        license_ += match.expand(sub.repl)
    return license_


MIT_RES = (
    ReSub(
        re.compile(
            r'The above copyright notice and this permission notice shall '
            r'be included in all copies of the Software, its documentation '
            r'and marketing (?:&? )?publicity materials, and acknowledgment '
            r'shall be given in the documentation, materials and software '
            r'packages that this Software was used.',
            re.IGNORECASE),
        'MIT-advertising'),
    ReSub(
        re.compile(
            r'Permission to use, copy, modify, and distribute this software '
            r'and its documentation for any purpose and without fee is '
            r'hereby granted, provided that the above copyright notice '
            r'appear in all copies and that both that the copyright notice '
            r'and this permission notice and warranty disclaimer appear in '
            r'supporting documentation, and that the name of the author not '
            r'be used in advertising or publicity pertaining to distribution '
            r'of the software without specific, written prior permission.',
            re.IGNORECASE),
        'Expat-like-Highscore'),
    ReSub(
        re.compile(
            r'Except as contained in this notice, the name of a copyright '
            r'holder shall not be used in advertising or otherwise to '
            r'promote the sale, use or other dealings in this Software '
            r'without prior written authorization of the copyright holder.',
            re.IGNORECASE),
        'MIT-like-icu'),
    ReSub(
        re.compile(
            r'Except as contained in this notice, the name of a copyright '
            r'holder shall not be used in advertising or otherwise to '
            r'promote the sale, use or other dealings in this Software '
            r'without prior written authorization of the copyright holder.',
            re.IGNORECASE),
        'MIT-like-icu'),
    ReSub(
        re.compile(
            r'The above copyright notice and this permission notice shall '
            r'be included in all copies of the Software and its '
            r'Copyright notices. In addition publicly documented '
            r'acknowledgment must be given that this software has '
            r'been used if no source code of this software is '
            r'made available publicly. This includes acknowledgments '
            r'in either Copyright notices, Manuals, Publicity and '
            r'Marketing documents or any documentation provided '
            r'with any product containing this software. This '
            r'License does not apply to any software that links '
            r'to the libraries provided by this software \(?statically '
            r'or dynamically[\) ]?, but only to the software provided.',
            re.IGNORECASE),
        'MIT-enna'),
    ReSub(
        re.compile(
            r'The above copyright notice and this permission '
            r'notice shall be included in all copies of the '
            r'Software and its documentation and acknowledgment '
            r'shall be given in the documentation and software '
            r'packages that this Software was used.', re.IGNORECASE),
        'MIT-feh'),
    ReSub(
        re.compile(
            r'Distributions of all or part of the Software intended to be '
            r'used by the recipients as they would use the unmodified '
            r'Software, containing modifications that substantially alter, '
            r'remove, or disable functionality of the Software, '
            r'outside of the documented configuration mechanisms '
            r'provided by the Software, shall be modified such '
            r'that the Original Author[\' ]?s bug reporting '
            r'email addresses and urls are either replaced '
            r'with the contact information of the parties responsible '
            r'for the changes, or removed entirely.',
            re.IGNORECASE),
        'MITNFA'),
)


def parse_mit(text, match, group):
    for sub in MIT_RES:
        match = sub.re.search(text)
        if not match:
            continue
        return match.expand(sub.repl)

    return group


ZPL_RES = (
    ReSub(
        re.compile(
            r'(?:the )?Zope Public License(?: \(?ZPL\)?)?'
            r',? (?:Version|v)?[ ]?([\d.]+?)(?:[.0]*)[^\d.]',
            re.IGNORECASE),
        r'-\1'),
)


def parse_zpl(text, match, group):
    license_ = group
    for sub in ZPL_RES:
        match = sub.re.search(text)
        if not match:
            continue
        license_ += match.expand(sub.repl)
    return license_


LICENSES_RES = (
    # public-domain
    ReLicense(
        re.compile(
            r'(:?This [^ ]+ is in|is (?:hereby |released )?'
            r'(?:in(?:to)|to|for)) '
            r'the public domain',
            re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(r'This work is free of known copyright restrictions',
                   re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(r'http[ :]/?/?creativecommons.org/publicdomain/mark/',
                   re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(r'Public Domain, originally written by', re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(r'This [^ ]+ is put into the public domain, I claim '
                   r'no copyright on that code', re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(r' was written by(?: [^ ]+){,4}, and is placed in the '
                   r'public domain\. The author hereby disclaims copyright to '
                   r'this source code\.', re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(
            r'These files[] ]+are hereby placed in the public domain without '
            r'restrictions', re.IGNORECASE),
        'public-domain', None),
    ReLicense(
        re.compile(
            r'I hereby disclaim the copyright on this code and place it in '
            r'the public domain.', re.IGNORECASE),
        'public-domain', None),
    # Apache
    ReLicense(
        re.compile(r'under the Apache License, Version ([\d.]+)',
                   re.IGNORECASE),
        'Apache', lambda t, m, l: 'Apache-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(r'Licensed under the Apache License v([\d.]+) '
                   r'http[ :]/?/?www\.apache\.org/licenses/LICENSE-(?:[\d.]+)',
                   re.IGNORECASE),
        'Apache', lambda t, m, l: 'Apache-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'Apache License Version ([\d.]+), \w+ \d+ '
            r'http[ :]/?/?www\.apache\.org/licenses/? '
            r'TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION',
            re.IGNORECASE),
        'Apache', lambda t, m, l: 'Apache-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'Redistribution and use in source and binary forms, '
            r'with or without modification, are permitted provided '
            r'that the following conditions are met:? '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions of source code must retain the '
            r'above copyright notice, this list of conditions '
            r'and the following disclaimer. '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions in binary form must reproduce the '
            r'above copyright notice, this list of conditions '
            r'and the following disclaimer in the documentation '
            r'and[/ ]?or other materials provided with the '
            r'distribution. '
            r'(?:[^\s]+ ){,2}'
            r'All advertising materials mentioning features '
            r'or use of this software must display the following '
            r'acknowledgment:? "?This product includes software '
            r'developed by (?:[^\s]+ ){,32}'
            r'(?:[^\s]+ ){,2}'
            r'(?:[^\s]+ ){,32}must not be used to endorse or '
            r'promote products derived from this software without '
            r'prior written permission. For written permission, '
            r'please contact (?:[^\s]+ ){,8}'
            r'(?:[^\s]+ ){,2}'
            r'Products derived from this software may not be '
            r'called (?:[^\s]+ ){,8}nor may (?:[^\s]+ ){,8}'
            r'appear in their name, without prior written permission '
            r'of (?:[^\s]+ ){,8}'
            r'(?:[^\s]+ ){,2}'
            r'Redistributions of any form whatsoever must retain '
            r'the following acknowledgment:? '
            r'"?This product includes software developed by ',
            re.IGNORECASE),
        'Apache', lambda *a: 'Apache-1'
    ),
    ReLicense(
        re.compile(
            r'Redistribution and use in source and binary forms, '
            r'with or without modification, are permitted provided '
            r'that the following conditions are met:? '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions of source code must retain the '
            r'above copyright notice, this list of conditions '
            r'and the following disclaimer. '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions in binary form must reproduce the '
            r'above copyright notice, this list of conditions '
            r'and the following disclaimer in the documentation '
            r'and[/ ]?or other materials provided with the '
            r'distribution. '
            r'(?:[^\s]+ ){,2}'
            r'The end[- ]?user documentation included with the '
            r'redistribution, if any, must include the following '
            r'acknowledgment:? '
            r'"?This product includes software developed by .+."? '
            r'Alternately, this acknowledgment may appear in '
            r'the software itself, if and wherever such '
            r'third[- ]?party acknowledgments normally appear. '
            r'(?:[^\s]+ ){,2}'
            r'The .+ must not be used to endorse or promote '
            r'products derived from this software without prior '
            r'written permission. For written permission, please '
            r'contact .+ '
            r'(?:[^\s]+ ){,2}'
            r'Products derived from this software may not be '
            r'called .+ nor may .+ appear in their name, without '
            r'prior written permission of',
            re.IGNORECASE),
        'Apache', lambda *a: 'Apache-1.1'
    ),
    # Artistic
    ReLicense(
        re.compile(
            r'(?:'
            r'Released under the terms of the Artistic License '
            r'|'
            r'This (?:[^ ]+ ){,2}is distributed under the Artistic License '
            r')'
            r'(?:v|version )?([\d.]+)',
            re.IGNORECASE),
        'Artistic',
        lambda t, m, l: 'Artistic-{}'.format(
            m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'The "?(?:Clarified )?"?Artistic License"? '
            r'Preamble '
            r'The intent of this document is to state the conditions under '
            r'which a Package may be copied, such that the Copyright Holder '
            r'maintains some semblance of artistic control over the '
            r'development of the package, while giving the users of the '
            r'package the right to use and distribute the Package in a '
            r'more[- ]or[- ]less customary fashion, plus the right to make '
            r'reasonable modifications.', re.IGNORECASE),
        'Artistic', parse_artistic),
    ReLicense(
        re.compile(
            r'The "?Artistic License"? 2\.0'
            r'.+'
            r'Everyone is permitted to copy and distribute '
            r'verbatim copies of this license document, but '
            r'changing it is not allowed.', re.IGNORECASE),
        'Artistic', lambda *a: 'Artistic-2'),
    ReLicense(
        re.compile(r'you (?:can|may) (?:re)?distribute (?:it and/or modify '
                   r'it )?under the terms of.* the Artistic License',
                   re.IGNORECASE),
        'Artistic', None),
    ReLicense(
        re.compile(r'is free software under the Artistic License',
                   re.IGNORECASE),
        'Artistic', None),
    # BSD-2-clause BSD-3-clause BSD-4-clause
    ReLicense(
        re.compile(
            r'licensed under the (?:[^ ]+ ){,3}'
            r'\(?http[ :]/?/?(?:www\.)?opensource\.org/licenses/BSD-([23])-Clause\)?',
            re.IGNORECASE),
        'BSD',
        lambda t, m, l:
            'BSD-{}-clause'.format(m.group(1))
    ),
    ReLicense(
        re.compile(
            r'THIS (?:FREE )?SOFTWARE IS PROVIDED .*"?AS IS(?:\'\'|")? '
            r'AND ANY '
            r'EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT '
            r'LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY',
            re.IGNORECASE),
        'BSD', parse_bsd),
    ReLicense(
        re.compile(
            r'''THIS SOFTWARE IS PROVIDED (?:``|")?AS IS(?:''|")? AND '''
            r'WITHOUT ANY EXPRESS OR '
            r'IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE '
            r'IMPLIED WARRANTIES OF MERCHANTABILITY', re.IGNORECASE),
        'BSD', parse_bsd),
    ReLicense(
        re.compile(r'licensed under (?:[^ ]+ ){,10}the BSD license',
                   re.IGNORECASE),
        'BSD', parse_bsd),
    ReLicense(
        re.compile(r'Redistribution and use in source and binary forms, with '
                   r'or without modification, are permitted provided that '
                   r'the following conditions are met.{,32}'
                   r'Redistributions of source code must retain the above '
                   r'copyright notice, this list of conditions and the '
                   r'following disclaimer.{,32}'
                   r'Redistributions in binary form must reproduce the above '
                   r'copyright notice, this list of conditions and the '
                   r'following disclaimer in the documentation and/or other '
                   r'materials provided with the distribution.{,32}'
                   r'The name "?Carnegie Mellon University"? must not be used '
                   r'to endorse or promote products derived from this '
                   r'software without prior written permission. For '
                   r'permission or any other legal details, please contact '
                   r'Office of Technology Transfer Carnegie Mellon '
                   r'University.{,256}'
                   r'Redistributions of any form whatsoever must retain the '
                   r'following acknowledgment:? "?This product includes '
                   r'software developed by Computing Services at Carnegie '
                   r'Mellon University \(http[: ]/?/?www.cmu.edu/?computing/?\)."?',
                   re.IGNORECASE),
        'BSD', lambda *a: 'BSD_like_CMU-4-clause'),
    ReLicense(
        re.compile(
            r'Redistribution and use is allowed according to the terms of '
            r'the 2-clause BSD license.', re.IGNORECASE),
        'BSD', lambda *a: 'BSD-2-clause'),
    ReLicense(
        re.compile(
            r'Redistribution and use is allowed according to the terms of the '
            r'(?:new )?BSD license.? ([^ ]+ ){,10}COPYING-CMAKE-SCRIPTS',
            re.IGNORECASE),
        'BSD', lambda *a: 'BSD-3-clause'),
    ReLicense(
        re.compile(
            r'Redistribution and use is allowed according to the terms of the '
            r'BSD license.?', re.IGNORECASE),
        'BSD', None),
    ReLicense(
        re.compile(
            r'Distributed under the OSI-approved BSD License \(the '
            r'"?License[" ]?\)', re.IGNORECASE),
        'BSD', None),
    # TODO: learn about references to named files
    ReLicense(
        re.compile(
            r'Use of this source code is governed by a BSD-style license '
            r'that can be found in the [^ ]+ file\.', re.IGNORECASE),
        'BSD', None),
    # ISC
    ReLicense(
        re.compile(
            r'Permission to use, copy, modify, and(?:\/or)? distribute '
            r'this (?:[^ ]+ ){,4}for any purpose with or without fee is '
            r'hereby granted, provided.*copyright notice.*permission '
            r'notice.*all copies'
            r'.+'
            r'Except as contained in this notice, the '
            r'name of a copyright holder shall not be '
            r'used in advertising or otherwise to promote '
            r'the sale, use or other dealings in this '
            r'Software without prior written authorization '
            r'of the copyright holder',
            re.IGNORECASE),
        'ISC', lambda *a: 'curl'),
    ReLicense(
        re.compile(r'Permission to use, copy, modify, and(?:\/or)? distribute '
                   r'this (?:[^ ]+ ){,4}for any purpose with or without fee is '
                   r'hereby granted, provided.*copyright notice.*permission '
                   r'notice.*all copies', re.IGNORECASE),
        'ISC', None),
    # CC-BY, CC-BY-SA, CC-BY-ND, CC-BY-NC, CC-BY-NC-SA, CC-BY-NC-ND
    ReLicense(
        re.compile(r'http[ :]?/?/?creativecommons.org/licenses/by',
                   re.IGNORECASE),
        'CC-BY', parse_cc_by),
    ReLicense(
        re.compile(r'This .*is licensed under .*Creative Commons Attribution'
                   r'.*License', re.IGNORECASE),
        'CC-BY', parse_cc_by),
    ReLicense(
        re.compile(
            r'THE WORK \(?AS DEFINED BELOW\)? IS PROVIDED UNDER THE TERMS '
            r'OF THIS CREATIVE COMMONS PUBLIC LICENSE \(?[" ]?CCPL[" ]? OR '
            r'[" ]?LICENSE[" ]?\)?\. THE WORK IS PROTECTED BY COPYRIGHT '
            r'AND/OR OTHER '
            r'APPLICABLE LAW\. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED '
            r'UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED\.',
            re.IGNORECASE),
        'CC-BY', parse_cc_by),
    ReLicense(
        re.compile(
            r'License:? Creative Commons Attribution', re.IGNORECASE),
        'CC-BY', parse_cc_by),
    # CC0
    ReLicense(
        re.compile(r'http[ :]/?/?creativecommons.org/publicdomain/zero',
                   re.IGNORECASE),
        'CC0', None),
    ReLicense(
        re.compile(r'To the extent possible under law, .*the person who '
                   r'associated CC0 .*with this work has waived all copyright '
                   r'and related or neighboring rights to this work',
                   re.IGNORECASE),
        'CC0', None),
    ReLicense(
        re.compile(r'license:? CC0-1\.0 ', re.IGNORECASE),
        'CC0', None
    ),
    ReLicense(
        re.compile(r'Creative Commons CC0 1\.0 ', re.IGNORECASE),
        'CC0', None
    ),
    # CDDL
    ReLicense(
        re.compile(r'terms of the Common Development and Distribution License'
                   r'(, Version ([^( ]+))? \(the[" ]*License[" ]?\)', re.IGNORECASE),
        'CDDL',
        lambda t, m, l:
            'CDDL{}'.format('-{}'.format(m.group(2)) if m.groups()[1] else '')
    ),
    ReLicense(
        re.compile(r'COMMON DEVELOPMENT AND DISTRIBUTION LICENSE '
                   r'\(CDDL\) '
                   r'Version ([\d.]+)',
                   re.IGNORECASE),
        'CDDL',
        lambda t, m, l:
            'CDDL-{}'.format(m.group(1).rstrip('0.'))
    ),
    # CPL
    ReLicense(
        re.compile(r'(?:under the terms of|(?:licensed|released) under the) '
                   r'.*(the|this) Common Public License', re.IGNORECASE),
        'CPL', lambda *a: 'CPL-1'),
    # EFL
    ReLicense(
        re.compile(
            r'Permission is hereby granted to use, copy, modify and(?:/or) '
            r'distribute this [^ ]+ provided that:?'
            r'[-,.+* ]*copyright notices are retained unchanged'
            r'[-,.+* ]*any distribution of this [^ ]+ whether modified or '
            r'not, includes this (?:file|license text)[-,.+* \d]*'
            r'Permission is hereby also granted to distribute binary programs '
            r'which depend on this [^ ]+(?:provided that:)?'
            r'[-,.+* ]*if the binary program depends on a modified version of '
            r'this [^ ]+ you (must|are encouraged to) publicly release the '
            r'modified version of this', re.IGNORECASE),
        'EFL',
        lambda t, m, l:
            'EFL-{}'.format('1' if m.group(1).lower() == 'must' else '2')
    ),
    # Expat
    ReLicense(
        re.compile(r'(?:MIT license:?|licensed under the (?:terms of either '
                   r'the)?MIT.*|Some rights reserved:?|License:? (?:name:? )?'
                   r'MIT(?: url:?)) '
                   r'\(?http[ :]?/?/?www\.opensource\.org/licenses/mit-license\.php\)?',
                   re.IGNORECASE),
        'MIT/X11', lambda *a: 'Expat'),
    ReLicense(
        re.compile(r'Permission is hereby granted, free of charge, to any '
                   r'person obtaining a copy of this software and(?:/or)? '
                   r'associated documentation files \(the[" ]*'
                   r'(?:Software|Materials)[" ]?\), to deal in the '
                   r'(?:Software|Materials) without restriction, including '
                   r'without limitation the rights to use, copy, modify, '
                   r'merge, publish, distribute, sublicense, and(?:/or)? '
                   r'sell copies of the (?:Software|Materials?), and to '
                   r'permit persons to whom the (?:Software|Materials?) '
                   r'(?:is|are) furnished to do so, subject to the following '
                   r'conditions:? '
                   r'The above copyright notice and this permission notice '
                   r'shall be included in all copies or substantial portions '
                   r'of the (?:Software|Materials?)\. '
                   r'THE ', re.IGNORECASE),
        'MIT/X11', lambda *a: 'Expat'),
    # GPL
    ReLicense(
        re.compile(
            r'GNU General Public License Usage '
            r'(?:[^ ]+ ){,2}This [^ ]+ may be used under the terms of '
            r'the GNU General '
            r'Public License version 2\.0 or 3\.0 '
            r'.{,512} Qt GPL Exception version 1\.3', re.IGNORECASE),
        'GPL', lambda *a: 'GPL-2+3 with QT-1.3 exception'),
    ReLicense(
        re.compile(
            r'GNU General Public License Usage '
            r'(?:[^ ]+ ){,2}This [^ ]+ may be used under the terms of '
            r'the GNU General '
            r'Public License version ([\d.]+) (or later)?'
            r'.{,512} (Qt GPL Exception version 1\.3)?', re.IGNORECASE),
        'GPL',
        lambda t, m, l:
            'GPL-{}{}{}'.format(m.group(1).rstrip('0.'),
                                '+' if m.groups()[1] else '',
                                ' with QT-1.3 exception' if m.groups()[2] else '')
    ),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? (?:[^ ]+ ){,10}modify (?:it|them)|is '
            r'(?:distributed|'
            r'licensed)) under the terms of (?:the )?(?:version [^ ]+ '
            r'(?:or later )?'
            r'(?:\(?only\)? )?of )?the (?:GNU )?'
            r'(?:General Public License|GPL)', re.IGNORECASE),
        'GPL', parse_gpl),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? modify (?:it|them)|is (?:distributed|'
            r'licensed)) under the terms of (?:the )?(?:GNU )?'
            r'(?:General Public License|GPL)', re.IGNORECASE),
        'GPL', parse_gpl),
    ReLicense(re.compile(r'is distributed (?:[^ ]+ ){,16}terms (?:[^ ]+ ){,64}GPL'),
              'GPL', parse_gpl),
    ReLicense(re.compile(r'licensed under the (?:[^ ]+ ){,64}GPL '), 'GPL', parse_gpl),
    ReLicense(
        re.compile(r'may be distributed and/or modified under the '
                   r'terms of the GNU General Public License'),
        'GPL', parse_gpl),
    ReLicense(
        re.compile(r'You can Freely distribute this program under the GNU '
                   r'General Public License', re.IGNORECASE),
        'GPL', parse_gpl),
    ReLicense(
        re.compile(
            r'GNU GENERAL PUBLIC LICENSE '
            r'Version (\d+), (?:\d+ )?\w+ \d+ '
            r'Copyright \(C\) (?:[\d, ]+) Free Software Foundation, Inc. '
            r'(?:<?http[: ]?/?/?fsf.org/>? |'
            r'51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA )?'
            r'Everyone is permitted to copy and distribute verbatim copies '
            r'of this license document, but changing it is not allowed.',
            re.IGNORECASE),
        'GPL',
        lambda t, m, l:
            'GPL-{}'.format(m.group(1).rstrip('0.'))),
    ReLicense(
        re.compile(
            r'may be used under the terms of the GNU General Public License '
            r'version (\d)\.0'),
        'GPL',
        lambda t, m, l:
            'GPL-{}'.format(m.group(1))
    ),
    ReLicense(
        re.compile(
            r'license:? (?:[^ ]+ ){,2}[("]?'
            r'http[: ]/?/?creativecommons\.org/licenses/GPL/2\.0/?[")]?',
            re.IGNORECASE),
        'GPL', lambda *a: 'GPL-2+'),
    ReLicense(
        re.compile(r'License:? GPLWithACException', re.IGNORECASE),
        'GPL', lambda *a: 'GPL with AutoConf exception'),
    ReLicense(
        re.compile(r'License:? GPL[- v]*([\d.]*)(\+?)', re.IGNORECASE),
        'GPL',
        lambda t, m, l:
            'GPL{}'.format('-{}{}'.format(m.group(1).rstrip('0.'), m.group(2))
                           if m.groups()[0] else '')
    ),
    ReLicense(
        re.compile(r'This [^ ]+ is (?:freely distributable|licensed) under '
                   r'the (?:GNU (?:General )?Public License|GPL)',
                   re.IGNORECASE),
        'GPL', None),
    ReLicense(re.compile(r' GPL2 or later '), 'GPL', lambda *a: 'GPL-2+'),
    ReLicense(re.compile(r' is Free Software, released under the GNU Public '
                         r'License\. '), 'GPL', lambda *a: 'GPL-2+'),
    # LGPL
    ReLicense(
        re.compile(
            r'GNU (?:Lesser|Library) General Public License Usage '
            r'(?:[^ ]+ ){,2}This [^ ]+ may be used under the terms of '
            r'the GNU (?:Lesser|Library) General '
            r'Public License version ([\d.]+) (or later)?'
            r'.{,512} (Qt LGPL Exception version ([\d.]+))?', re.IGNORECASE),
        'LGPL',
        lambda t, m, l:
            'LGPL-{}{}{}'.format(
                m.group(1).rstrip('0.'),
                '+' if m.groups()[1] else '',
                ' with QT-{} exception'.format(m.group(4)) if m.groups()[2] else '')
    ),
    ReLicense(
        re.compile(
            r'GNU Lesser General Public License Usage '
            r'(?:[^ ]+ ){,2}This [^ ]+ may be used under the terms of '
            r'the GNU Lesser General '
            r'Public License version 2\.1 '
            r'.{,512} Qt LGPL Exception version 1\.1', re.IGNORECASE),
        'LGPL', lambda *a: 'LGPL-2.1 with QT-1.1 exception'),
    ReLicense(
        re.compile(
            r'Qwt License Version 1.0,? .+'
            r'The Qwt library and included programs are provided under '
            r'the terms of the GNU LESSER GENERAL PUBLIC LICENSE ',
            re.IGNORECASE),
        'LGPL', lambda *a: 'LGPL-2.1 with Qwt-1 exception'),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? modify (?:it|them)|is (?:distributed|'
            r'licensed)) under the terms (?:and conditions )?of (?:the )?'
            r'(?:version [^ ]+ '
            r'(?:\(?only\)? )?of )?the (?:GNU )?'
            r'(?:(?:Library(?:/Lesser)? |Lesser(?:/Library)? )'
            r'(?:GNU )?General Public License|LGPL)', re.IGNORECASE),
        'LGPL', parse_gpl),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? modify (?:it|them)|is (?:distributed|'
            r'licensed)) under the terms of (?:the )?(?:GNU )?'
            r'(?:(?:Library |Lesser(?:/Library)? )(?:GNU )?General Public '
            r'(?:version(?: [^ ]+){,5} )?License|LGPL)',
            re.IGNORECASE),
        'LGPL', parse_gpl),
    ReLicense(
        re.compile(r'licensed under (?:[^ ]+ ){,10}LGPL '),
        'LGPL', parse_gpl),
    ReLicense(
        re.compile(
            r'may be (?:distributed and/or modified|used) under the terms of '
            r'the GNU Lesser(?:/Library)? '
            r'General Public License', re.IGNORECASE),
        'LGPL', parse_gpl),
    ReLicense(
        re.compile(r'This [^ ]+ is '
                   r'(?:distributed|freely distributable|licensed) under '
                   r'the (?:(?:terms|conditions) of the |license )?(?:GNU )?'
                   r'(?:(?:Lesser|Library) (?:General )?'
                   r'Public License|LGPL)',
                   re.IGNORECASE),
        'LGPL', parse_gpl),
    ReLicense(
        re.compile(
            r'this (?:[^ ]+ ){,2}may be used under the terms of '
            r'(?:[^ ]+ ){,20}the GNU (?:Lesser|Library) General '
            r'Public License '
            r'Version ([\d.]+) ((?:or later)?)', re.IGNORECASE),
        'LGPL',
        lambda t, m, l:
            'LGPL-{}{}'.format(
                m.group(1).rstrip('0.'),
                '+' if m.groups()[1] else '')
    ),
    ReLicense(
        re.compile(r'License:? LGPL[- v]*([\d.]*)(\+?)', re.IGNORECASE),
        'LGPL',
        lambda t, m, l:
            'LGPL{}'.format('-{}{}'.format(m.group(1).rstrip('0.'), m.group(2))
                            if m.groups()[0] else '')
    ),
    ReLicense(
        re.compile(r'Distributed under the LGPL\.'),
        'LGPL', None),
    ReLicense(
        re.compile(r'This (?:[^ ]+ ){,2}is free software licensed under the '
                   r'GNU LGPL(?:\.|->) You can find a copy of this license in '
                   r'LICENSE\.txt in the top directory of the source '
                   r'code(\.|->)', re.IGNORECASE),
        'LGPL', None),  # found in marble, actually lgpl-2.1+
    ReLicense(
        re.compile(
            r'This version of the GNU Lesser General Public License '
            r'incorporates the terms and conditions of version 3 of the '
            r'GNU General Public License, supplemented by the additional '
            r'permissions listed below.',
            re.IGNORECASE),
        'LGPL', lambda t, m, l: 'LGPL-3+'),
    # GFDL, GFDL-NIV
    ReLicense(
        re.compile(r'Permission is (?:hereby )?granted to copy, distribute '
                   r'and(?:/or)? modify this [^ ]+ under the terms of the GNU '
                   r'Free Documentation License', re.IGNORECASE),
        'GFDL', parse_gfdl),
    ReLicense(
        re.compile(
            r'[< ]legalnotice[> ][& ]?FDLNotice;[< ]/legalnotice[> ]',
            re.IGNORECASE),
        'GFDL', lambda t, m, l: 'GFDL-1.2+'),
    # LPPL
    ReLicense(
        re.compile(r'This [^ ]+ (?:(?:can|may)(?: be)?|is) (?:re)?distributed '
                   r'and(?:/or)? modified under the (?:terms|conditions) of '
                   r'the LaTeX Project Public License', re.IGNORECASE),
        'LPPL', parse_lppl),
    # MPL
    # cpal is based on the mpl 1.1
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the Common '
            r'Public Attribution License Version ([\d.]+) \(the '
            r'(?:“|")?License(?:”|[" ])?\);? you may not use '
            r'this file except in compliance with the License\.',
            re.IGNORECASE),
        'MPL', lambda t, m, l: 'CPAL-{}'.format(
            m.group(1).rstrip('.0'))
    ),
    # erlpl is based on the mpl 1.0
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the Erlang '
            r'Public License,? Version ([\d.]+),? \(the '
            r'(?:“|")?License(?:”|[" ])?\);? you may not use '
            r'this file except in compliance with the License\.',
            re.IGNORECASE),
        'MPL', lambda t, m, l: 'ErlPL-{}'.format(
            m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'Mozilla Public License,? (?:Version|v\.?) ?(\d+(?:\.\d+)?)',
            re.IGNORECASE),
        'MPL', lambda t, m, l: 'MPL-{}'.format(
            m.group(1).rstrip('.0'))
    ),
    # Perl
    ReLicense(
        re.compile(r'you can redistribute it and/or modify it under the '
                   r'same terms as Perl', re.IGNORECASE),
        'GPL', lambda *a: 'GPL-1+'),
    ReLicense(
        re.compile(r'you can redistribute it and/or modify it under the '
                   r'same terms as Perl', re.IGNORECASE),
        'Artistic', lambda *a: 'Artistic-1-Perl'),
    # Python
    ReLicense(
        re.compile(r'PYTHON SOFTWARE FOUNDATION LICENSE (VERSION ([^ ]+))?',
                   re.IGNORECASE),
        'Python',
        lambda t, m, l:
            'Python{}'.format('-{}'.format(m.group(2))
                              if m.groups()[1] else
                              '')
    ),
    # QPL
    ReLicense(
        re.compile(r'This file is part of the .*Qt GUI Toolkit. This file may '
                   r'be distributed under the terms of the Q Public License '
                   r'as defined'),
        'QPL', None),
    ReLicense(
        re.compile(r'may (?:be distributed|redistribute it) under the terms '
                   r'of the Q Public License'),
        'QPL', None),
    # W3C
    ReLicense(
        re.compile(r'This [^ ]+ (?:(?:may|can)(?: be)?|is) (?:re)distributed '
                   r'under the (?:W3C®|W3C) Software License', re.IGNORECASE),
        'W3C', None),
    # Zlib
    # Eurosym license extends zlib
    ReLicense(
        re.compile(r'The origin of this software must not be misrepresented'
                   r'.*Altered source versions must be plainly marked as such'
                   r'.*You must not use any of the names of the authors '
                   r'or copyright holders of the original software for '
                   r'advertising or publicity pertaining to distribution '
                   r'without specific, written prior permission'
                   r'.*If you change this software and redistribute parts '
                   r'or all of it in any form, you must make the source '
                   r'code of the altered version of this software available'
                   r'.*This notice may not be removed or altered from any '
                   r'source distribution'
                   r'', re.IGNORECASE),
        'Zlib', lambda *a: 'Eurosym'),
    # cube license extends zlib
    ReLicense(
        re.compile(r'The origin of this software must not be misrepresented'
                   r'.*Altered source versions must be plainly marked as such'
                   r'.*This notice may not be removed or altered from any '
                   r'source distribution'
                   r'.*Source versions may not be "?relicensed"? '
                   r'under a different license without my explicitly '
                   r'written permission\.', re.IGNORECASE),
        'Zlib', lambda *a: 'Cube'),
    ReLicense(
        re.compile(r'The origin of this software must not be misrepresented'
                   r'.*Altered source versions must be plainly marked as such'
                   r'.*This notice may not be removed or altered from any '
                   r'source distribution', re.IGNORECASE),
        'Zlib', None),
    ReLicense(
        re.compile(r'see copyright notice in zlib\.h', re.IGNORECASE),
        'Zlib', None),
    ReLicense(
        re.compile(r'This code is released under the libpng license',
                   re.IGNORECASE),
        'Zlib', None),
    # Zope
    ReLicense(
        re.compile(
            r'This [^ ]+ (?:(?:(?:can|may)(?: be)?|is) (?:re)?distributed '
            r'and(?:/or)? modified under the (?:terms|conditions)|is '
            r'subject to the provisions) of the Zope Public License',
            re.IGNORECASE),
        'ZPL', parse_zpl),
    ReLicense(
        re.compile(
            r'Zope Public License \(?ZPL\)?', re.IGNORECASE),
        'ZPL', parse_zpl),

    # Other licenses not in:
    # https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    ReLicense(
        re.compile(
            r'Permission is granted to make and distribute '
            r'verbatim copies of this document provided that '
            r'the copyright notice and this permission notice '
            r'are preserved on all copies. '
            r'Permission is granted to copy and distribute '
            r'modified versions of this document under the '
            r'conditions for verbatim copying, provided that '
            r'the entire resulting derived work is distributed '
            r'under the terms of a permission notice identical '
            r'to this one.',
            re.IGNORECASE),
        'Abstyles', lambda *a: 'Abstyles'),
    ReLicense(
        re.compile(
            r'Licensed under the Academic Free License version '
            r'([\d.]+)', re.IGNORECASE),
        'Academic', lambda t, m, l: 'Academic-{}'.format(
            m.group(1).rstrip('0.'))),
    ReLicense(
        re.compile(
            r'This file may be freely copied and redistributed '
            r'as long as:? '
            r'(?:[^\s]+ ){,2}'
            r'This entire notice continues to be included in '
            r'the file[,.]? '
            r'(?:[^\s]+ ){,2}'
            r'If the file has been modified in any way, a notice '
            r'of such modification is conspicuously indicated.',
            re.IGNORECASE),
        'Adobe', lambda *a: 'Afmparse'),
    ReLicense(
        re.compile(
            r'Permission is hereby granted, free of charge, '
            r'to any person obtaining a copy of this documentation '
            r'file, to create their own derivative works from the '
            r'content of this document to use, copy, publish, '
            r'distribute, sublicense, and\/or sell the derivative '
            r'works, and to permit others to do the same, provided '
            r'that the derived work is not represented as being '
            r'a copy or version of this document. '
            r'Adobe shall not be liable to any party for any loss ',
            re.IGNORECASE),
        'Adobe', lambda *a: 'Adobe-Glyph'),
    ReLicense(
        re.compile(
            r'Adobe Systems Incorporated grants to you a perpetual, '
            r'worldwide, non-exclusive, no-charge, royalty-free, '
            r'irrevocable copyright license, to reproduce, prepare '
            r'derivative works of, publicly display, publicly '
            r'perform, and distribute this source code and such '
            r'derivative works in source or object code form without '
            r'any attribution requirements\.',
            re.IGNORECASE),
        'Adobe', lambda *a: 'Adobe-2006'),
    ReLicense(
        re.compile(
            r'This file and the (?:\d+ )?PostScript[\( ]?R\)? '
            r'AFM files it accompanies may be used, copied, and '
            r'distributed for any purpose and without charge, '
            r'with or without modification, provided that all '
            r'copyright notices are retained;? that the AFM '
            r'files are not distributed without this file;? '
            r'that all modifications to this file or any of '
            r'the AFM files are prominently noted in the modified '
            r'file[\( ]?s[\) ]?;? and that this paragraph is '
            r'not modified. Adobe Systems has no responsibility '
            r'or obligation to support the use of the AFM files.',
            re.IGNORECASE),
        'Adobe', lambda *a: 'APAFML'),
    ReLicense(
        re.compile(
            r'This software code is made available "?AS IS"? '
            r'without warranties of any kind. You may copy, '
            r'display, modify and redistribute the software '
            r'code either by itself or as incorporated into '
            r'your code; provided that you do not remove any '
            r'proprietary notices. Your use of this software '
            r'code is at your own risk and you waive any claim '
            r'against Amazon Digital Services, Inc. or its '
            r'affiliates with respect to your use of this software '
            r'code.',
            re.IGNORECASE),
        'ADSL', None),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? modify (?:it|them)|is (?:distributed|'
            r'licensed)) under the terms of (?:the )?(?:version [^ ]+ '
            r'(?:\(?only\)? )?of )?the (?:GNU )?'
            r'(?:Affero (?:GNU )?General Public License|AGPL)', re.IGNORECASE),
        'AGPL', parse_gpl),
    ReLicense(
        re.compile(
            r'(?:(?:is free software.? )?you (?:can|may) (?:re)?distribute '
            r'(?:it|them) and(?:/or)? modify (?:it|them)|is (?:distributed|'
            r'licensed)) under the terms of (?:the )?(?:GNU )?'
            r'(?:Affero (?:GNU )?General Public License|AGPL)', re.IGNORECASE),
        'AGPL', parse_gpl),
    ReLicense(
        re.compile(
            r'The licenses for most software are designed to take away your '
            r'freedom to share and change it. By contrast, the Affero '
            r'General Public License is intended to guarantee your freedom '
            r'to share and change free software[- ]?-?to make sure the '
            r'software '
            r'is free for all its users. This Public License applies to '
            r'most '
            r'of Affero[\' ]?s software and to any other program whose '
            r'authors '
            r'commit to using it. \(?Some other Affero software is covered by '
            r'the GNU Library General Public License instead.\)? You can '
            r'apply '
            r'it to your programs, too.', re.IGNORECASE),
        'AGPL', lambda *a: 'AGPL-1'),
    ReLicense(
        re.compile(
            r'Aladdin Enterprises hereby grants to anyone the '
            r'permission to apply this License to their own '
            r'work, as long as the entire License \(?including '
            r'the above notices and this paragraph\)? is copied '
            r'with no changes, additions, or deletions except '
            r'for changing the first paragraph of Section 0 '
            r'to include a suitable description of the work '
            r'to which the license is being applied and of '
            r'the person or entity that holds the copyright '
            r'in the work, and, if the License is being applied '
            r'to a work created in a country other than the '
            r'United States, replacing the first paragraph '
            r'of Section 6 with an appropriate reference to '
            r'the laws of the appropriate country.', re.IGNORECASE),
        'Aladdin', None),
    ReLicense(
        re.compile(
            r'Redistribution and use in any form of this material '
            r'and any product thereof including software in '
            r'source or binary forms, along with any related '
            r'documentation, with or without modification '
            r'\(?[" ]this material[" ]\)?, is permitted provided '
            r'that the following conditions are met:? '
            r'(?:[^\s]+ ){,80}'
            r'Neither the names nor trademarks of (?:[^\s]+ ){,8}'
            r'(?:or )?any copyright holders or contributors may '
            r'be used to endorse or promote products derived '
            r'from this material without specific prior written '
            r'permission.',
            re.IGNORECASE),
        'AMDPLPA', None),
    ReLicense(
        re.compile(
            r'In consideration of your agreement to abide by '
            r'the following terms, and subject to these terms, '
            r'Apple grants you a personal, non-exclusive license, '
            r'under Apple[\' ]?s copyrights in this original '
            r'Apple software \(?the "?Apple Software[" ]?\)?, '
            r'to use, reproduce, modify and redistribute the '
            r'Apple Software, with or without modifications, '
            r'in source and[/ ]or binary forms;? provided that '
            r'if you redistribute the Apple Software in its '
            r'entirety and without modifications, you must '
            r'retain this notice and the following text and '
            r'disclaimers in all such redistributions of the '
            r'Apple Software. Neither the name, trademarks, '
            r'service marks or logos of Apple Computer, Inc. '
            r'may be used to endorse or promote products derived '
            r'from the Apple Software without specific prior '
            r'written permission from Apple. Except as expressly '
            r'stated in this notice, no other rights or licenses, '
            r'express or implied, are granted by Apple herein, '
            r'including but not limited to any patent rights '
            r'that may be infringed by your derivative works '
            r'or by other works in which the Apple Software '
            r'may be incorporated.',
            re.IGNORECASE),
        'AML', None),
    ReLicense(
        re.compile(
            r'We reserve no legal rights to the ANTLR-?[- ]?'
            r'it is fully in the public domain. An individual '
            r'or company may do whatever they wish with source '
            r'code distributed with ANTLR or the code generated '
            r'by ANTLR, including the incorporation of ANTLR, '
            r'or its output, into commerical software.',
            re.IGNORECASE),
        'public-domain', lambda *a: 'ANTLR-PD'),
    ReLicense(
        re.compile(
            r'THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF '
            r'(?:THIS|THE) ADAPTIVE PUBLIC LICENSE '
            r'\(?[" ]?LICENSE[" ]?[\) ]?',
            re.IGNORECASE),
        'APL', lambda *a: 'APL-1'),
    ReLicense(
        re.compile(
            r'APPLE PUBLIC SOURCE LICENSE '
            r'Version ([\d.]+) - \w+ \d+, \d+ '
            r'Please read this License carefully before downloading this '
            r'software\. By downloading (?:and|or) using this software, '
            r'you are '
            r'agreeing to be bound by the terms of this License\. If you do '
            r'not or cannot agree to the terms of this License, please do '
            r'not download or use the software.', re.IGNORECASE),
        'APSL', lambda t, m, l: 'APSL-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'This file contains Original Code and/or Modifications of '
            r'Original Code as defined in and that are subject to the Apple '
            r'Public Source License Version ([\d.]+) \(the \'?License[\' ]?\). '
            r'You may not use this file except in compliance with the '
            r'License\. Please obtain a copy of the License at '
            r'.+ '
            r'and read it before using this file.', re.IGNORECASE),
        'APSL', lambda t, m, l: 'APSL-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'These patterns were developed for internal GMV '
            r'use and are made public in the hope that they '
            r'will benefit others. Also, spreading these patterns '
            r'throughout the Spanish[- ]language TeX community '
            r'is expected to provide back[- ]benefits to GMV in '
            r'that it can help keeping GMV in the mainstream '
            r'of spanish users.', re.IGNORECASE),
        'Bahyph', None),
    ReLicense(
        re.compile(
            r'Its use is unrestricted. It may be freely distributed, '
            r'unchanged, for non[- ]commercial or commercial '
            r'use. If changed, it must be renamed. Inclusion '
            r'in a commercial software package is also permitted, '
            r'but I would appreciate receiving a free copy for '
            r'my personal examination and use.', re.IGNORECASE),
        'Barr', None),
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the '
            r'BitTorrent Open Source License Version ([\d.]+) \(the '
            r'License\). You may not copy or use this file, '
            r'in either source code or executable form, except '
            r'in compliance with the License.', re.IGNORECASE),
        'BitTorrent',
        lambda t, m, l: 'BitTorrent-{}'.format(m.group(1).rstrip('.0'))),
    ReLicense(
        re.compile(
            r'You may freely use, modify, and/or distribute '
            r'each of the files in this package without limitation. '
            r'The package consists of the following files:?'
            r'.+'
            r'Of course no support is guaranteed',
            re.IGNORECASE),
        'Borceux', None),
    ReLicense(
        re.compile(
            r'License: BSD Protection license', re.IGNORECASE),
        'BSD', lambda *a: 'BSD-protection'),
    ReLicense(
        re.compile(
            r'Boost Software License[ .,-]+(Version (\d+(?:\.\d+)*)[ .,-]+?)?',
            re.IGNORECASE),
        'BSL',
        lambda t, m, l:
            'BSL{}'.format('-{}'.format(m.group(2).rstrip('.0'))
                           if m.groups()[1] else
                           '')
    ),
    ReLicense(
        re.compile(r'Permission is hereby granted, free of charge, to any '
                   r'person or organization obtaining a copy of the software '
                   r'and accompanying documentation covered by this license '
                   r'\(the[" ]*Software[" ]?\)', re.IGNORECASE),
        'BSL', None),
    ReLicense(
        re.compile(r'THE BEER-WARE LICENSE', re.IGNORECASE),
        'Beerware', None),
    ReLicense(
        re.compile(
            r'hereby grants a fee free license that includes '
            r'the rights use, modify and distribute this named '
            r'source code, including creating derived binary '
            r'products created from the source code.',
            re.IGNORECASE),
        'Caldera', None),
    ReLicense(
        re.compile(
            r'Computer Associates Trusted Open Source License '
            r'(?:Version )?1\.1',
            re.IGNORECASE),
        'CATOSL', lambda *a: 'CATOSL-1.1'),
    ReLicense(
        re.compile(
            r'(?:'
            r'Ce contrat est une licence de logiciel libre '
            r'dont l\'objectif est de conférer aux utilisateurs '
            r'la liberté de modification et de redistribution '
            r'du logiciel régi par cette licence dans le cadre '
            r'd\'un modèle de diffusion (?:en logiciel libre'
            r'|(?:« ?)?open source ?»? ?'
            r'(?: fondée sur le droit français)?)\.'
            r'|'
            r'The purpose of this Free Software Licensing Agreement '
            r'is to grant users the right to modify and redistribute '
            r'the software governed by this license within the '
            r'framework of an ["«]? ?open source ?["»]? '
            r'distribution model\. '
            r')',
            re.IGNORECASE),
        'CeCILL', parse_cecill),
    ReLicense(
        re.compile(
            r'(?:'
            r'Ce contrat est une licence de logiciel libre '
            r'dont l\'objectif est de conférer aux utilisateurs '
            r'une très large liberté de modification et de '
            r'redistribution du logiciel régi par cette licence\. '
            r'|'
            r'This Agreement is an open source software license '
            r'intended to give users significant freedom to '
            r'modify and redistribute the software licensed '
            r'hereunder\. '
            r')',
            re.IGNORECASE),
        'CeCILL', lambda *a: 'CeCILL-B'),
    ReLicense(
        re.compile(
            r'(?:'
            r'Ce contrat est une licence de logiciel libre '
            r'dont l\'objectif est de conférer aux utilisateurs '
            r'la liberté de modifier et de réutiliser le logiciel '
            r'régi par cette licence\. '
            r'|'
            r'The purpose of this Free Software license agreement '
            r'is to grant users the right to modify and re[- ]?use '
            r'the software governed by this license\. '
            r')',
            re.IGNORECASE),
        'CeCILL', lambda *a: 'CeCILL-C'),
    ReLicense(
        re.compile(r'under the terms of the CeCILL-([^ ]+) ', re.IGNORECASE),
        'CeCILL', lambda t, m, l: 'CeCILL-{}'.format(m.group(1))
    ),
    ReLicense(
        re.compile(r'under the terms of the CeCILL ', re.IGNORECASE),
        'CeCILL', None),
    ReLicense(
        re.compile(
            r'is made available subject to the terms and conditions '
            r'in CNRI\'?s License Agreement\.', re.IGNORECASE),
        'CNRI', parse_cnri),
    ReLicense(
        re.compile(
            r'IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT '
            r'OPEN LICENSE', re.IGNORECASE),
        'CPOL', lambda *a: 'CPOL-1.02'),
    ReLicense(
        re.compile(
            r'is distributed in the hope that it will be useful, '
            r'but WITHOUT ANY WARRANTY\. No author or distributor '
            r'accepts responsibility to anyone for the consequences '
            r'of using it or for whether it serves any particular '
            r'purpose or works at all, unless he says so in '
            r'writing\. '
            r'Everyone is granted permission to copy, modify '
            r'and redistribute .+, provided this copyright notice '
            r'is preserved and any modifications are indicated\.',
            re.IGNORECASE),
        'Crossword', None),
    ReLicense(
        re.compile(
            r'The module is,?(?: [^ ]+){,5} licensed under(:? [^ ]+){,2} '
            r'CRYPTOGAMS(?: [^ ]+){,16} http[: ]/?/?www.openssl.org/[~ ]?appro/cryptogams',
            re.IGNORECASE),
        'CRYPTOGAMS', None),
    ReLicense(
        re.compile(
            r'is freeware. This means you can pass copies around '
            r'freely provided you include this document in it\'s '
            r'original form in your distribution\.',
            re.IGNORECASE),
        'CrystalStacker', None),
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the '
            r'CUA Office Public License Version ([\d.]+)',
            re.IGNORECASE),
        'CUA-OPL',
        lambda t, m, l: 'CUA-OPL-{}'.format(
            m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'Dieses Programm kann durch jedermann gemäß den '
            r'Bestimmungen der Deutschen Freien Software Lizenz '
            r'genutzt werden\.',
            re.IGNORECASE),
        'D-FSL', None),
    ReLicense(
        re.compile(
            r'is open-source, freely available software, you '
            r'are free to use, modify, copy, and distribute--perpetually '
            r'and irrevocably--',
            re.IGNORECASE),
        'DOC', None),
    ReLicense(
        re.compile(
            r'This file may be freely transmitted and reproduced, '
            r'but it may not be changed unless the name is changed '
            r'also (?:\(except that you may freely change the '
            r'paper-size option for \\?documentclass\))?\. '
            'This notice must be left intact\.',
            re.IGNORECASE),
        'Dotseqn', None),
    ReLicense(
        re.compile(
            r'This program discloses material protectable under '
            r'copyright laws of the United States\. Permission '
            r'to copy and modify this software and its documentation '
            r'is hereby granted, provided that this notice is '
            r'retained thereon and on all copies or modifications\. ',
            re.IGNORECASE),
        'DSDP', None),
    ReLicense(
        re.compile(
            r'A modified version of this file may be distributed, '
            r'but it should be distributed with a \*?different\*? '
            r'name\. Changed files must be distributed \*?together '
            r'with a complete and unchanged\*? distribution of '
            r'these files\.', re.IGNORECASE),
        'dvipdfm', None),
    ReLicense(
        re.compile(
            r'1. you can do what you want with it '
            r'2. I refuse any responsibility for the consequences',
            re.IGNORECASE),
        'Permissive', lambda *a: 'diffmark'),
    ReLicense(
        re.compile(
            r'Licensed under the Educational Community License,? version '
            r'([\d.]+)',
            re.IGNORECASE),
        'ECL',
        lambda t, m, l:
            'ECL-{}'.format(m.group(1).rstrip('.0'))
    ),
    ReLicense(
        re.compile(
            r'Permission is hereby granted to use, copy, modify '
            r'and/or distribute this package, provided that:? '
            r'copyright notices are retained unchanged,? '
            r'any distribution of this package, whether modified '
            r'or not, includes this (?:license text|file)',
            re.IGNORECASE),
        'EFL', parse_efl),
    ReLicense(
        re.compile(
            r'Subject to the terms and conditions '
            r'(?:in|of this) eGenix.com Public License Agreement',
            re.IGNORECASE),
        'CNRI', lambda *a: 'eGenix'),
    ReLicense(
        re.compile(
            r'Redistribution and use in source and binary forms, '
            r'with or without modification, are permitted provided '
            r'that the following conditions are met:? '
            r'.{,4}Redistributions of source code must retain '
            r'the above copyright notice, this list of conditions '
            r'and the following disclaimer. '
            r'.{,4}Redistributions in binary form must reproduce '
            r'the above copyright notice, this list of conditions '
            r'and the following disclaimer in the documentation '
            r'and/or other materials provided with the distribution. '
            r'.{,4}The end-user documentation included with the '
            r'redistribution, if any, must include the following '
            r'acknowledgment:? '
            r'"?This product includes open source software developed by '
            r'(?:[^ ]+ ){,16}'
            r'Alternately, this acknowledgment may appear in the software '
            r'itself, if and wherever such third-party acknowledgments '
            r'normally appear. '
            r'.{,4}The names? (?:[^ ]+ ){,8}must not be used to '
            r'endorse or promote products derived from this software '
            r'without prior written permission. For written permission, '
            r'please contact (?:[^ ]+ ){,8}'
            r'.{,4}Products derived from this software may not be called '
            r'(?:[^ ]+ ){,8}nor may (?:[^ ]+ ){,8}appear in their name, '
            r'without prior written permission of (?:[^ ]+ ){,4}'
            r'''THIS SOFTWARE IS PROVIDED (?:``|''|")?AS IS(?:''|")? AND '''
            r'ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT '
            r'LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY',
            re.IGNORECASE),
        'BSD', lambda *a: 'BSD-like-Entessa'),
    ReLicense(
        re.compile(r'Eclipse Public License - v ([\d.]+) '
                   r'THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF '
                   r'THIS ECLIPSE PUBLIC LICENSE \([" ]AGREEMENT[" ]\)\. ANY USE, '
                   r'REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES '
                   r'RECIPIENT[\' ]S ACCEPTANCE OF THIS AGREEMENT\.',
                   re.IGNORECASE),
        'EPL', lambda t, m, l: 'EPL-{}'.format(m.group(1).rstrip('0.'))
    ),
    ReLicense(
        re.compile(r'The (?:[^ ]+ ){,3}are published under the EPL ([\d.]+), '
                   r'see COPYING.TESTDATA for the full license', re.IGNORECASE),
        'EPL', lambda t, m, l: 'EPL-{}'.format(m.group(1).rstrip('0.'))
    ),
    ReLicense(
        re.compile(
            r'Licensed under the EUPL V.([\d.]+)',
            re.IGNORECASE),
        'EUPL', lambda t, m, l: 'EUPL-{}'.format(m.group(1).rstrip('0.'))
    ),
    ReLicense(
        re.compile(
            r'Usage of the works is permitted provided that '
            r'this instrument is retained with the works, so '
            r'that any entity that uses the works is notified '
            r'of this instrument\. '
            r'DISCLAIMER:? THE WORKS ARE WITHOUT WARRANTY\.',
            re.IGNORECASE),
        'Fair', None),
    ReLicense(
        re.compile(
            r'This file contains software that has been made '
            r'available under The Frameworx Open License 1.0. '
            r'Use and distribution hereof are subject to the '
            r'restrictions set forth therein\.',
            re.IGNORECASE),
        'Frameworx', lambda *a: 'Frameworx-1'),
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the '
            r'FreeImage Public License Version 1.0 \(the "?License[" ]?\);? '
            r'you may not use this file except in compliance '
            r'with the License\.',
            re.IGNORECASE),
        'FreeImage', lambda *a: 'FreeImage-1'),
    ReLicense(
        re.compile(
            r'This file (?:is part of the FreeType project, and )?may only be used,? '
            r'modified,? and distributed under the terms of the FreeType project '
            r'license, LICENSE.TXT. By continuing to use, modify, or distribute '
            r'this file you indicate that you have read the license and '
            r'understand and accept it fully.', re.IGNORECASE),
        'FTL', None),
    ReLicense(
        re.compile(
            r'This license applies to all files distributed in the original '
            r'FreeType Project, including all source code, binaries and '
            r'documentation, unless otherwise stated in the file in its '
            r'original, unmodified form as distributed in the original archive. '
            r'If you are unsure whether or not a particular file is covered by '
            r'this license, you must contact us to verify this.', re.IGNORECASE),
        'FTL', None),
    ReLicense(
        re.compile(
            r'In lieu of a licence Fonts in this site are offered free for any '
            r'use; they may be installed, embedded, opened, edited, modified, '
            r'regenerated, posted, packaged and redistributed.', re.IGNORECASE),
        'fonts-ancient-scripts_license', None),
    ReLicense(
        re.compile(
            r'is gift-ware. It was created by a number of people '
            r'working in cooperation, and is given to you freely '
            r'as a gift. You may use, modify, redistribute, and '
            r'generally hack it about in any way you like, and '
            r'you do not have to give us anything in return.',
            re.IGNORECASE),
        'Giftware', None),
    ReLicense(
        re.compile(
            r'Permission to use, copy, and distribute this '
            r'software and its documentation for any purpose '
            r'with or without fee is hereby granted, provided '
            r'that the copyright notice appear in all copies '
            r'and that both that copyright notice and this '
            r'permission notice appear in supporting documentation. '
            r'Permission to modify and distribute modified versions '
            r'of this software is granted, provided that:? '
            r'.{,4}the modifications are licensed under the '
            r'same terms as this software;? '
            r'.{,4}you make available the source code of any '
            r'modifications that you distribute, either on '
            r'the same media as you distribute any executable '
            r'or other form of this software, or via a mechanism '
            r'generally accepted in the software development '
            r'community for the electronic transfer of data.',
            re.IGNORECASE),
        'GL2PS', None),
    ReLicense(
        re.compile(
            r'THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION '
            r'AND IS OFFERED ONLY PURSUANT TO THE 3DFX GLIDE '
            r'GENERAL PUBLIC LICENSE. THERE IS NO RIGHT TO '
            r'USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN '
            r'PERMISSION OF 3DFX INTERACTIVE, INC. A COPY OF '
            r'THIS LICENSE MAY BE OBTAINED FROM THE DISTRIBUTOR '
            r'OR BY CONTACTING 3DFX INTERACTIVE INC \(info@3dfx.com\). '
            r'THIS PROGRAM. IS PROVIDED "?AS IS"? WITHOUT WARRANTY '
            r'OF ANY KIND, EITHER EXPRESSED OR IMPLIED. SEE THE '
            r'3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL '
            r'TEXT OF THE NON-WARRANTY PROVISIONS.',
            re.IGNORECASE),
        'Glide', None),
    ReLicense(
        re.compile(
            r'You may copy and distribute it freely, by any '
            r'means and under any conditions, as long as the '
            r'code and documentation is not changed. You may '
            r'also incorporate this code into your own program '
            r'and distribute that, or modify this code and '
            r'use and distribute the modified version, as long '
            r'as you retain a notice in your program or documentation '
            r'which mentions my name and the URL shown above.',
            re.IGNORECASE),
        'Glulxe', None),
    ReLicense(
        re.compile(
            r'Permission to use, copy, and distribute this software '
            r'and its documentation for any purpose with or '
            r'without fee is hereby granted, provided that '
            r'the above copyright notice appear in all copies '
            r'and that both that copyright notice and this '
            r'permission notice appear in supporting documentation. '
            r'Permission to modify the software is granted, '
            r'but not the right to distribute the complete '
            r'modified source code. Modifications are to be '
            r'distributed as patches to the released version. '
            r'Permission to distribute binaries produced by '
            r'compiling modified sources is granted, provided you ',
            re.IGNORECASE),
        'gnuplot', None),
    ReLicense(
        re.compile(
            r'The contents of this file are subject to the '
            r'gSOAP Public License Version 1.3 \(the '
            r'"?License[" ]?\);? you may not use this file '
            r'except in compliance with the License.',
            re.IGNORECASE),
        'gSOAP', lambda *a: 'gSOAP-1.3'),
    ReLicense(
        re.compile(
            r'The authors intend this Report to belong to the '
            r'entire Haskell community, and so we grant permission '
            r'to copy and distribute it for any purpose, provided '
            r'that it is reproduced in its entirety, including '
            r'this Notice. Modified versions of this Report may '
            r'also be copied and distributed for any purpose, '
            r'provided that the modified version is clearly '
            r'presented as such, and that it does not claim '
            r'to be a definition of the Haskell 2010 Language.',
            re.IGNORECASE),
        'HaskellReport', None),
    ReLicense(
        re.compile(
            r'These conditions apply to any software derived from or based on the IJG '
            r'code, not just to the unmodified library. If you use our work, you ought '
            r'to acknowledge us.', re.IGNORECASE),
        'IJG', None),
    ReLicense(
        re.compile(r'Microsoft Permissive License \(Ms-PL\)', re.IGNORECASE),
        'MS-PL', None),
    ReLicense(
        re.compile(
            r'The licenses for most data are designed to take away your '
            r'freedom '
            r'to share and change it. By contrast, this License is intended '
            r'to '
            r'guarantee your freedom to share and change free data[- ]?-?to '
            r'make '
            r'sure the data are free for all their users\. '
            r'This License, the Lesser General Public License for Linguistic '
            r'Resources, applies to some specially designated linguistic '
            r'resources -?-? typically lexicons and grammars\.',
            re.IGNORECASE),
        'LGPL', lambda *a: 'LGPLLR'),
    ReLicense(
        re.compile(r'Permission to use, copy, modify and distribute this '
                   r'(?:[^ ]+ ){,3}(?:and its accompanying documentation )?'
                   r'for any purpose and without fee is hereby granted'
                   r'(?: in perpetuity)?, provided that the above copyright '
                   r'notice and this (?:paragraph|permission notice) appear '
                   r'in all copies\. The copyright holders make no '
                   r'representation about the suitability of (?:[^ ]+ ){,5}'
                   r'for any purpose\. It is provided "?as is"? without '
                   r'expressed or implied warranty\.',
                   re.IGNORECASE),
        'MIT/X11', lambda *a: 'MIT_OLIF'),
    ReLicense(
        re.compile(
            r'Subject to acceptance of the following conditions, permission '
            r'is hereby granted by Licensors without the need for written '
            r'agreement and without license or royalty fees, to use, copy, '
            r'modify and distribute this software for any purpose\. '
            r'The above copyright notice and the following four paragraphs '
            r'must be reproduced in all copies of this software and any '
            r'software including this software\.', re.IGNORECASE),
        'MIT/X11', lambda *a: 'MIT_versit'),
    ReLicense(
        re.compile(r'Permission is hereby granted, free of charge, to any '
                   r'person obtaining a copy of this software and(?:\/or)? '
                   r'associated documentation files \(the[" ]*'
                   r'(?:Software|Materials)[" ]?\), to deal in the '
                   r'(?:Software|Materials)',
                   re.IGNORECASE),
        'MIT/X11', parse_mit),
    ReLicense(
        re.compile(r'Permission to use, copy, modify, and distribute '
                   r'(?:[^ ]+ ){,3}(?:and its (:?accompanying )?documentation )?'
                   r'for any purpose and without fee is hereby granted',
                   re.IGNORECASE),
        'MIT/X11', parse_mit),
    ReLicense(
        re.compile(r'Permission is hereby granted, without written agreement '
                   r'and without license or royalty fees, to use, copy, '
                   r'modify, and distribute this software and its '
                   r'documentation for any purpose', re.IGNORECASE),
        'MIT/X11', parse_mit),
    ReLicense(
        re.compile(
            r'Permission is hereby granted, free of charge, to any member of '
            r'the KDE project \(the "?K Desktop Environment"? '
            r'http[ :]/?/?www.kde.org\) obtaining a copy of this "?Konqi '
            r'SDK"? package and associated documentation files \(the '
            r'"?Package[ "]?\), to deal in the Package without restriction, '
            r'including without limitation the rights to use, copy, modify, '
            r'merge, publish, distribute, sublicense, and/or sell copies of '
            r'the Package, and to permit persons to whom the Software is '
            r'furnished to do so, subject to the following conditions:? '
            r'The above copyright notice and this permission notice shall be '
            r'included in all copies or substantial portions of the Package.',
            re.IGNORECASE),
        'MIT/X11', lambda *a: 'Expat-like-Carddecks'),
    # as used in kf5, mmh
    ReLicense(
        re.compile(r'Distributed under terms of the MIT license\.',
                   re.IGNORECASE),
        'MIT/X11', lambda *a: 'Expat'),
    ReLicense(
        re.compile(
            r'Permission to use, copy, modify and distribute this software '
            r'and its documentation for any purpose and without fee is '
            r'hereby granted, provided that the above copyright notice '
            r'appears in all copies and that both that copyright notice '
            r'and this permission notice appear in supporting '
            r'documentation, and that the name of CMU and The Regents '
            r'of the University of California not be used in '
            r'advertising or publicity pertaining to distribution of '
            r'the software without specific written permission\.',
            re.IGNORECASE),
        'MIT/X11', lambda *a: 'MIT-CMU'),
    ReLicense(
        re.compile(
            r'Permission to use, copy, modify, distribute, and sell '
            r'this software and its documentation for any purpose is '
            r'hereby granted without fee, provided that the above '
            r'copyright notice appear in all copies and that both that '
            r'copyright notice and this permission notice appear in '
            r'supporting documentation', re.IGNORECASE),
        'MIT/X11', None),
    # as used by jquery
    ReLicense(
        re.compile(r'Released under the MIT license '
                   r'http[ :]/?/?jquery.org[ /]license', re.IGNORECASE),
        'MIT/X11', lambda *a: 'Expat'),
    ReLicense(
        re.compile(
            r'Permission to use, copy, modify, and distribute this software '
            r'for any purpose without fee is hereby granted, provided that '
            r'this entire notice is included in all copies of any software '
            r'which is or includes a copy or modification of this software '
            r'and in all copies of the supporting documentation for such '
            r'software.',
            re.IGNORECASE),
        'MIT/X11', lambda *a: 'ISC-like-dmgfp'),
    ReLicense(
        re.compile(
            r'it may be copied and furnished to others, and derivative works '
            r'that comment on or otherwise explain it or assist in its '
            r'implementation may be prepared, copied, published, and '
            r'distributed, in whole or in part, without restriction of any '
            r'kind, provided that the above copyright notice and this section '
            r'are included on all such copies and derivative works. '
            r'However, this document itself may not be modified in any way, '
            r'including by removing the copyright notice or references to '
            r'OASIS, except as needed for the purpose of developing any '
            r'document or deliverable produced by an OASIS Technical '
            r'Committee \(in which case the rules applicable to copyrights, as '
            r'set forth in the OASIS IPR Policy, must be followed\) or as '
            r'required to translate it into languages other than English. '
            r'The limited permissions granted above are perpetual and will '
            r'not be revoked by OASIS or its successors or assigns.',
            re.IGNORECASE),
        'OASIS', None),
    ReLicense(
        re.compile(
            r'Redistribution and use in source and binary forms, with or without '
            r'modification, are permitted provided that the following conditions '
            r'are met:? '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions of source code must retain the above copyright '
            r'notice, this list of conditions and the following disclaimer. '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions in binary form must reproduce the above copyright '
            r'notice, this list of conditions and the following disclaimer in '
            r'the documentation and/or other materials provided with the '
            r'distribution. '
            r'(?:[^\s]+ ){,2}'
            r'All advertising materials mentioning features or use of this '
            r'software must display the following acknowledgment:? '
            r'"?This product includes software developed by the OpenSSL Project '
            r'for use in the OpenSSL Toolkit. \(http[: ]/?/?www.openssl.org/\)"? '
            r'(?:[^\s]+ ){,2}'
            r'The names "?OpenSSL Toolkit"? and "?OpenSSL Project"? must not be used to '
            r'endorse or promote products derived from this software without '
            r'prior written permission. For written permission, please contact '
            r'(?:openssl-core|licensing)@openssl.org. '
            r'(?:[^\s]+ ){,2}'
            r'Products derived from this software may not be called "?OpenSSL"? '
            r'nor may "?OpenSSL"? appear in their names without prior written '
            r'permission of the OpenSSL Project. '
            r'(?:[^\s]+ ){,2}'
            r'Redistributions of any form whatsoever must retain the following '
            r'acknowledgment:? '
            r'"?This product includes software developed by the OpenSSL Project '
            r'for use in the OpenSSL Toolkit \(http[: ]/?/?www.openssl.org/\)"?',
            re.IGNORECASE),
        'OpenSSL', None),
    ReLicense(
        re.compile(
            r'The module is,?(?: [^ ]+){,5} licensed under OpenSSL',
            re.IGNORECASE),
        'OpenSSL', None),
    ReLicense(
        re.compile(
            r'This submission to OpenSSL is to be made available under the '
            r'OpenSSL license, and only to the OpenSSL project, in order to '
            r'allow integration into the publicly distributed code. '
            r'The use of this code, or portions of this code, or concepts '
            r'embedded in this code, or modification of this code and/or '
            r'algorithm\(s\) in it, or the use of this code for any other '
            r'purpose than stated above, requires special licensing.',
            re.IGNORECASE),
        'OpenSSL', None),
    ReLicense(
        re.compile(
            r'Rights for redistribution and usage in source and binary forms '
            r'are granted according to the OpenSSL license.', re.IGNORECASE),
        'OpenSSL', None),
    ReLicense(
        re.compile(
            r'This (?:[^ ]+ ){,2}is free (?:software|documentation); the (Free '
            r'Software Foundation|author[\( ]?s?\)?|copyright holders?) gives '
            r'unlimited permission to copy, '
            r'distribute and modify it\.', re.IGNORECASE),
        'Permissive', lambda *a: 'FSFUL'),
    ReLicense(
        re.compile(
            r'This (?:[^ ]+ ){,2}is free (?:software|documentation); the (Free '
            r'Software Foundation|author[\( ]?s?\)?|copyright holders?) gives '
            r'unlimited permission to copy '
            r'and(?:/or)? distribute it, with or without modifications, '
            r'as long as this notice is preserved\.',
            re.IGNORECASE),
        'Permissive', lambda *a: 'FSFULLR'),
    ReLicense(
        re.compile(r'Copying and distribution of this [^ ]+, with or without '
                   r'modification, are permitted in any medium without royalty '
                   r'provided the copyright notice and this notice are '
                   r'preserved.', re.IGNORECASE),
        'Permissive', lambda *a: 'FSFAP'),
    ReLicense(
        re.compile(
            r'Permission to use, copy, modify and distribute '
            r'this software and its documentation for any purpose '
            r'and without fee is hereby granted, provided that '
            r'the above copyright notice appear in all copies ?,? '
            r'(?:and )?that both (?:that )?(?:the )?copyright notice '
            r'and this permission notice appear in supporting '
            r'documentation(?: ?,? and that the name (?:of )?'
            r'(?:[^ ]+ ){,4}(?:or (?:[^ ]+ ){,8})?not be used in '
            r'advertising or publicity pertaining to distribution '
            r'of the software without specific, written prior '
            r'permission ?)?\.',
            re.IGNORECASE),
        'Permissive', lambda *a: 'HPND'),
    ReLicense(
        re.compile(r'This (?:[^ ]+ ){,2}may be copied and used freely without '
                   r'restrictions\.', re.IGNORECASE),
        'Permissive', None),
    ReLicense(
        re.compile(
            r'Copying and distribution of this file, with or without modification, '
            r'is permitted in any medium without royalty provided the copyright '
            r'notice and this notice are preserved.', re.IGNORECASE),
        'Permissive', None),
    ReLicense(
        re.compile(r'This source file is subject to version ([^ ]+) of the '
                   r'PHP license', re.IGNORECASE),
        'PHP', lambda t, m, l: 'PHP-{}'.format(m.group(1))
    ),
    ReLicense(
        re.compile(r'You may copy this prolog in any way that is directly '
                   r'related to this document. For other use of this prolog, '
                   r'see your licensing agreement for Qt.', re.IGNORECASE),
        'QT_Prolog', None),
    ReLicense(
        re.compile(r'under the SGI Free Software License B', re.IGNORECASE),
        'SGI-FSLB', None),
    # https://lists.debian.org/debian-legal/2006/01/msg00566.html
    ReLicense(
        re.compile(
            r'Unicode, Inc\. hereby grants the right to freely use the '
            r'information supplied in this file in the creation of products '
            r'supporting the Unicode Standard, and to make copies of this '
            r'file in any form for internal or external distribution as long '
            r'as this notice remains attached\.', re.IGNORECASE),
        'Unicode', None),
    ReLicense(
        re.compile(r'Do What The Fuck You Want To Public License, Version '
                   r'([^, ]+)', re.IGNORECASE),
        'WTFPL', lambda t, m, l: 'WTFPL-{}'.format(m.group(1))
    ),
    ReLicense(
        re.compile(r'Do what The Fuck You Want To Public License',
                   re.IGNORECASE),
        'WTFPL', None),
    ReLicense(
        re.compile(r'(?:License WTFPL|Under (?:the|a) WTFPL)',
                   re.IGNORECASE),
        'WTFPL', None),
)


def find_licenses(text):
    '''Scan the text for presence of any of the supported licenses.

    Returns:
        A list of the license ids found in the text.
    '''
    licenses = {}

    for i, license_re in enumerate(LICENSES_RES):
        # Keep the license name in this frame for easier debugging
        license_ = license_re.license
        if license_re.license in licenses:
            continue
        match = license_re.re.search(text)
        if not match:
            continue
        if license_re.get_detail:
            license_ = license_re.get_detail(text, match, license_)
        licenses[license_re.license] = license_

    return licenses.values()
