Start documentation + add eclipse support

Copied eclipse support from uploadvalidator plugin.

Started the plugin documentation.

Change-Id: I74c0560974060c8b42ea22a35cf1f75d8b88a2cb
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..0285a1b
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..8667cfd
--- /dev/null
+++ b/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Tue Sep 02 16:59:24 PDT 2008
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..40e022d
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,126 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=ignore
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..d4218a5
--- /dev/null
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+#Wed Jul 29 11:31:38 PDT 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Google Format
+formatter_settings_version=11
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=com.google;com;junit;net;org;java;javax;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
new file mode 100644
index 0000000..e700891
--- /dev/null
+++ b/src/main/resources/Documentation/about.md
@@ -0,0 +1,50 @@
+This plugin allows to configure required copyright reviews.
+
+The plugin looks for text patterns that might be license terms or copyright
+ownership declarations in newly uploaded revisions. It broadly groups findings
+into first-party, third-party, forbidden or unknown.
+
+The plugin requires special review when third-party code appears outside of
+areas designated for third-party code, or when forbidden or unknown licenses
+appear anywhere.
+
+Note: The plugin does not make definitive assertions about the licenses or
+owners it finds. It leaves that up to a copyright-knowledgeable human reviewer.
+
+It will have false-positives--especially in the unknown category. It may also
+have false negatives.
+
+## First-party
+
+Licensed or owned by the owner of the gerrit repository.
+
+e.g. The Android Open Source Project (AOSP) uses the Apache 2.0 License and
+accepts any contributions released under that license as first-party.
+
+## Third-party
+
+Licensed or owned by someone other than the user or the owner of the gerrit
+repository, but released under license terms compatible with the first-party
+license and accepted by the owners of the repository.
+
+e.g. AOSP accepts a handful of legacy open-source licenses like MIT or BSD.
+
+## Forbidden
+
+Licensed under terms incompatible with the first-party license or considered
+onerous by the owner of the host.
+
+e.g. AOSP cannot accept restrictions prohibiting "commercial use" because
+vendors generally sell Android devices for profit.
+
+## Unknown
+
+In addition to common copyright and license patterns, the scanner searches for
+a set of words and patterns that often appear in or near copyright/license
+declarations, but do not often appear elsewhere in source code.
+
+These apparent license terms do not match any of the known licenses. Because 
+such licenses might contain any number of incompatible or onerous terms, they
+are treated the same as forbidden. i.e. always require review.
+
+Unrecognized authors or owners are considered third-party rather than unknown.
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
new file mode 100644
index 0000000..81eec27
--- /dev/null
+++ b/src/main/resources/Documentation/build.md
@@ -0,0 +1,93 @@
+Build
+=====
+
+This plugin is built with Bazel, and two build modes are supported:
+
+* Standalone
+* In Gerrit tree
+
+Standalone build mode is recommended, as this mode doesn't require local Gerrit
+tree to exist. Moreover, there are additional manual steps required when building
+in Gerrit tree mode (see corresponding section).
+
+## Build standalone
+
+To build the plugin, issue the following command:
+
+```
+  bazel build @PLUGIN@
+```
+
+The output is created in
+
+```
+  bazel-genfiles/@PLUGIN@.jar
+```
+
+To package the plugin sources run:
+
+```
+  bazel build lib@PLUGIN@__plugin-src.jar
+```
+
+The output is created in:
+
+```
+  bazel-bin/lib@PLUGIN@__plugin-src.jar
+```
+
+To execute the tests run:
+
+```
+  bazel test //...
+```
+
+This project can be imported into the Eclipse IDE:
+
+```
+  ./tools/eclipse/project.sh
+```
+
+## Build in Gerrit tree
+
+Clone (or link) this plugin to the `plugins` directory of Gerrit's source
+tree.
+
+```
+  git clone https://gerrit.googlesource.com/gerrit
+  git clone https://gerrit.googlesource.com/plugins/@PLUGIN@
+  cd gerrit/plugins
+  ln -s ../../@PLUGIN@ .
+```
+
+From Gerrit source tree issue the command:
+
+```
+  bazel build plugins/@PLUGIN@
+```
+
+The output is created in
+
+```
+  bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
+```
+
+To execute the tests run:
+
+```
+  bazel test plugins/@PLUGIN@:all
+```
+
+or filtering using the comma separated tags:
+
+````
+  bazel test --test_tag_filters=@PLUGIN@ //...
+````
+
+This project can be imported into the Eclipse IDE.
+Add the plugin name to the `CUSTOM_PLUGINS` set in
+Gerrit core in `tools/bzl/plugins.bzl`, and execute:
+
+```
+  ./tools/eclipse/project.py
+```
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..32b4ef9
--- /dev/null
+++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,296 @@
+@PLUGIN@ Configuration
+======================
+
+## Server Configuration
+
+The server's `gerrit.config` plugin configuration has two parameters mostly to
+protect the server against overly expensive scanner patterns.
+
+```
+  [plugin "@PLUGIN@"]
+    enable = true
+    timeTestMax = 8
+```
+
+plugin.@PLUGIN@.enable
+:    Whether to run the scanner on the server
+
+    When false, the server will not run the copyright scanner even in projects
+    where the plugin has been enabled.
+
+plugin.@PLUGIN@.timeTestMax
+:    The maximum latency for a simulated heavy load in seconds
+
+    When greater than 0, any time a new configuration changes the scanner
+    pattern, the plugin will look for a specially constructed token in the
+    commit message. The token is created by running a command-line tool that
+    tests the scanner pattern against a simulated load that tries to trigger
+    excessive backtracking.
+
+    The token encodes the duration in a manner specific to the scanner pattern.
+
+    If the token does not match the current pattern, the plugin will reject the
+    configuration change.
+
+    If the time it took to perform the scan exceeds the configured parameter,
+    the plugin will reject the configuration change.
+
+    The token is not secure. Anyone with access to the source code can fake the
+    token with some effort so take care not to grant `All-Projects` access to
+    potentially malicious actors.
+
+    In general, folks with administrative access will find it easier to just run
+    the command-line tool, to take heed of any warnings or errors it prints, and
+    to copy+paste the token.
+
+## Project Configuration
+
+Each project's `project.config` has a configuration parameter to enable or to
+disable the scanner. If the `All-Projects` `project.config` enables the scanner
+by default, the project-level config can disable it and vice versa.
+
+```
+  [plugin "@PLUGIN@"]
+    enable = true
+```
+
+plugin.@PLUGIN@.enable
+:    Whether to run the scanner for files in the project
+
+    When false, the server will not run the copyright scanner for revisions in
+    the project even if enabled by default in the `All-Projects`
+    `project.config`.
+
+    When true, the server will run the copyright scanner for revisions in the
+    project even if disabled by default in the `All-Projects` `project.config`.
+
+## Plugin Configuration
+
+The configuration of the @PLUGIN@ plugin is primarily done for the entire server
+in the `project.config` file of the `All-Projects` default configuration.
+
+```
+  [plugin "@PLUGIN@"]
+    fromAccountId = 31415926
+    reviewLabel = Copyright-Review
+    reviewer = copyright-expert
+    reviewer = legal@example.com
+    cc = needs-to-know@example.com
+    cc = also-needs-to-know
+    matchProjects = .*
+    excludeProjects = ^private$
+    excludeProjects = ^not-ours$
+    thirdPartyAllowedProjects = ^external/
+    thirdPartyAllowedProjects = ^third-party/
+    alwaysReview = PATENT$
+    exclude = EXAMPLES
+    excludePattern = driver license
+    excludePattern = 007 license to
+    firstParty = ANDROID
+    firstParty = APACHE2
+    firstPartyPattern = owner special pattern for us
+    firstPartyPattern = license special pattern for our license
+    thirdParty = BSD
+    thirdParty = MIT
+    thirdParty = CC_BY_C
+   thirdPartyPattern = owner special pattern for them
+   thirdPartyPattern = license special pattern for their license
+    forbidden = NOT_A_CONTRIBUTION
+    forbidden = NON_COMMERCIAL
+    forbidden = CC_BY_NC
+    forbiddenPattern = owner we don't want them
+    forbiddenPattern = license .*(?:Previously|formerly) licen[cs]ed under.*
+    forbiddenPattern = license we don't like their terms
+```
+
+plugin.@PLUGIN@.alwaysReview
+:    List of Path Patterns to Always Review
+
+    The plugin first joins the project name to the file path within the project
+    to create a full path. If any of this list of [regular
+    expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+    is found within the full path, the plugin will require review of the entire
+    file without scanning the content.
+
+    e.g. The example above would match all PATENT files, which could contain
+    important legal terms requiring review without being licenses or copyrights
+    per se.
+
+plugin.@PLUGIN@.cc
+:    List of Accounts or Email Addresses to CC on the Review
+
+    When the plugin determines that review is required, it will add these
+    accounts or addresses as CC reviewers.
+
+plugin.@PLUGIN@.exclude
+:    List of [Known Patterns](known-patterns.md) to Ignore when Found
+
+    When found in a revision, the scanner will skip these patterns as if never
+    found. They do not get reported as findings in review comments.
+
+    This is a noise-reduction parameter.
+
+    e.g. The example above would skip made-up examples of copyrights that can
+    appear in tests or documentation but are not actual copyright declarations.
+
+plugin.@PLUGIN@.excludePattern
+:    List of [Modified Regular Expressions](modified-regex.md) to Ignore
+
+    When found in a revision, the scanner will skip these patterns as if never
+    found. They do not get reported as findings in review comments.
+
+    This is a noise-reduction parameter.
+
+    Unlike first-party, third-party or forbidden, it doesn't matter whether the
+    match is for an owner or for a license. Do not use the `owner` or `license`
+    keyword for this parameter.
+
+plugin.@PLUGIN@.excludeProjects
+:    List of Project Patterns to Skip
+
+    When any of these [regular
+    expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+    are found in the project name, the plugin will skip the revision regardless
+    whether the `project.config` enables scanning.
+
+    Defaults to skipping no projects.
+
+plugin.@PLUGIN@.firstParty
+:    List of [Known Patterns](known-patterns.md) to Treat as First-Party
+
+    When found in a revision, the scanner will treat these patterns as
+    first-party. The plugin will not require review, and it will report the
+    finding in a resolved comment.
+
+plugin.@PLUGIN@.firstPartyPattern
+:    List of Owner or License Patterns to Treat as First-Party
+
+    When found in a revision, the scanner will treat these patterns as
+    first-party. Each of these patterns must start with the `owner` or `license`
+    keyword followed by the [Modified Regular Expression](modified-regex.md) to
+    find.
+
+    When combined with other findings in the same file, the `owner` or `license`
+    affects whether the plugin will require review:
+
+    A first-party license will take precedence over a third-party author
+    because multiple contributors to an open-source project is the norm. It
+    does not take precedence over other licenses.
+
+    A first-party owner will combine with a first-party license, but will not
+    take precedence over other licenses or owners.
+
+    Regardless whether the file needs review, the plugin will report first-party
+    findings in resolved comments.
+
+plugin.@PLUGIN@.forbidden
+:    List of [Known Patterns](known-patterns.md) to Treat as Forbidden
+
+    When found in a revision, the scanner will treat these patterns as
+    forbidden. The plugin will always require review, and it will report the
+    finding in an unresolved comment.
+
+    e.g. The example given above requires review for non-commercial licenses and
+    the phrase "not a contribution" as documented in the Apache 2.0 license for
+    identifying modified Apache 2.0 code to explicitly exclude the modifications
+    from the license.
+
+plugin.@PLUGIN@.forbiddenPattern
+:    List of Owner or License Patterns to Treat as Forbidden
+
+    When found in a revision, the scanner will treat these patterns as
+    forbidden. Each of these patterns must start with the `owner` or `license`
+    keyword followed by the [Modified Regular Expression](modified-regex.md) to
+    find.
+
+    The plugin uses the `owner` or `license` to describe the finding.
+
+    Any file containing a forbidden match will always require review, and the
+    plugin will report the finding as an unresolved comment.
+
+    e.g. One of the examples given above requires review for phrases sometimes
+    used like "not a contribution" to disclaim the prior license.
+
+plugin.@PLUGIN@.fromAccountId
+:    Numeric Account Id Impersonated by the Plugin
+
+    Review comments will appear to come from the given account. Recommend
+    creating a non-interactive user with a descriptive name like
+    "Copyright Scanner".
+
+plugin.@PLUGIN@.matchProjects
+:    List of Project Patterns to Scan
+
+    When any of these [regular
+    expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+    are found in the project name, the plugin will look to the `project.config`
+    and `All-Projects` default to determine whether the scanner is enabled.
+
+    If enabled, the plugin will scan the files in the revision.
+
+    Defaults to scanning all enabled projects.
+
+plugin.@PLUGIN@.reviewLabel
+:    Single Review Label for Copyrights
+
+    When the plugin determines a revision requires review, it will vote -1 on
+    the configured label and add reviewers. When it determines the revision
+    requires no special review, it will vote +2 on the configured label and make
+    no changes to the reviewers.
+
+plugin.@PLUGIN@.reviewer
+:    List of Accounts or Email Address to Add as Reviewers
+
+    When the plugin determines the revision requires review, it will add these
+    accounts as reviewers. At least one reviewer must be able to vote +2 on
+    the review label and have adequate knowledge of copyright licenses to
+    review their texts.
+
+plugin.@PLUGIN@.thirdParty
+:    List of [Known Patterns](known-patterns.md) to Treat as Third-Party
+
+    When found in a revision, the scanner will treat these patterns as
+    third-party. The plugin will require review unless the revision is in a
+    project configured to allow third-party code. When the third-party finding
+    requires review, the plugin will report the finding in an unresolved
+    comment. When the configuration allows the third-party finding--in a
+    project configured to allow third-party licenses or a third-party author of
+    first-party-licensed code--the plugin will report the finding in a resolved
+    comment.
+
+    e.g. The example above shows the legacy MIT and BSD open-source licenses as
+    well as the pseudo-license CC_BY_C, which matches all of the Creative
+    Commons Attribution license variants allowing commercial use.
+
+plugin.@PLUGIN@.thirdPartyAllowedProjects
+:    List of Project Patterns Where Third-Party Licenses Allowed
+
+    When any of these [regular
+    expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+    are found in the project name, the plugin will accept third-party licenses
+    and owners without requiring review.
+
+plugin.@PLUGIN@.thirdPartyPattern
+:    List of Owner or License Patterns to Treat as Third-Party
+
+    When found in a revision, the scanner will treat these patterns as
+    third-party. Each of these patterns must start with the `owner` or `license`
+    keyword followed by the [Modified Regular Expression](modified-regex.md) to
+    find.
+
+    When combined with other findings in the same file, the `owner` or `license`
+    affects whether the plugin will require review:
+
+    A third-party license will take precedence over any first-party findings.
+
+    A third-party owner be reported as third-party but accepted as part of a
+    first-party license. In open-source projects, multiple contributors are the
+    norm.
+
+    When a review is required for the third-party finding--not in a project
+    configured to accept third-party code and not a third-party author of
+    first-party licensed code--the plugin will report the finding in an
+    unresolved comment.
+
+    When found in a location that allows third-party or as part of a first-party
+    license, the plugin will report the finding in a resolved comment.
diff --git a/src/main/resources/Documentation/known-patterns.md b/src/main/resources/Documentation/known-patterns.md
new file mode 100644
index 0000000..fae7a2d
--- /dev/null
+++ b/src/main/resources/Documentation/known-patterns.md
@@ -0,0 +1,17 @@
+Known Patterns
+==============
+
+To simplify @PLUGIN@ plugin configurations, the `firstParty`, `thirdParty`,
+`forbidden`, and `exclude` configuration parameters reference sets of named
+known [modified regular expressions](modified-regex.md).
+
+Initially seeded with the patterns needed for the Android Open Source Project
+(AOSP), the definitions are released open-source as part of the plugin, and
+can be extended with contributions likewise released under Apache 2.0
+
+To see the list of known names, earch for `lookup` in
+[CopyrightPatterns.java](https://gerrit.googlesource.com/plugins/copyright/+/refs/heads/master/src/main/java/com/googlesource/gerrit/plugins/copyright/lib/CopyrightPatterns.java)
+
+The names do not have to match an exact license or entity per se. For example,
+the Creative Commons folks do not define a CC_BY_C license. The named pattern
+matches any of several Creative Commons licenses that allow commercial use.
diff --git a/src/main/resources/Documentation/modified-regex.md b/src/main/resources/Documentation/modified-regex.md
new file mode 100644
index 0000000..9e1bd9e
--- /dev/null
+++ b/src/main/resources/Documentation/modified-regex.md
@@ -0,0 +1,78 @@
+Modified Regular Expressions
+============================
+
+The copyright scanner has to meet several competing requirements: 1) it must
+be fast to keep server load and latency reasonable, 2) it must find copyrights
+and licenses appearing in and interrupted by any number of comment formats,
+and 3) it must be configurable by mere mortals.
+
+Configured patterns are basically [regular
+expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+with modifications to assist the 3 requirements above.
+
+## Unlimited Wildcards
+
+If you run the ScanTool.java command-line tool against the files in your
+repository, it will already find a lot of the copyright and license declarations
+that interest. Often it will pick up a couple extra junk words before or after
+the text you want. In these cases, the natural inclination to use wildcards:
+e.g. something like `.*My License.*` in a first-party pattern. However, when
+scanning a large file, those wildcards can pick up a lot more junk words and
+slow the scan to a crawl.
+
+To allow the easy and obvious choice, the plugin allows you to use the .* and .+
+patterns, and it modifies your pattern before scanning. When they appear at the
+start or the end of the pattern, the plugin removes them before scanning the
+file and puts them back when classifying the matches.
+
+The scanner will still find all of the matches containing the pattern that it
+found before plus it might find a few exact matches without increasing the work
+to scan the file. The matches are limited in size. When it puts the wildcards
+back to analyze the matches, the wildcards in your first-party pattern cause
+it to match despite the junk words so it correctly identifies the first-party
+license without costing much cpu time.
+
+When they appear in the middle of your pattern, the plugin replaces them with a
+pattern that matches a limited number of words separated by a limited number of
+whitespace characters. The limits are large enough generally to match anything
+of interest, but small enough to keep the scan down to a reasonable time.
+
+If the limits cause the plugin to miss too many desired hits, it's always
+possible to write a more complex pattern with different limits.
+
+## Comment Characters and Whitespace
+
+Whitespace does not affect the meaning of a license. The same text may be
+formatted all manner of different ways using spaces, tabs, newlines, etc. to
+align margins, center text, word-wrap at different columns etc. without changing
+the meaning. Many times the same text will be incorporated into comments of
+different languages. Even in the same language, sometimes the author will use
+multi-line comments /*...*/ and sometimes the author will use single-line
+comments //. Some languages use a completely different comment character #.
+
+You could insert a complex expression anywhere you expect whitespace.
+e.g. `[\\s/*#]+` But the configuration will already be unreadable, and if a file
+has a lot of whitespace, that pattern could match large blocks while slowing
+the scan.
+
+To keep configurations readable, the plugin substitutes any embedded spaces with
+a regular expression to match a limited number of whitespace or comment
+characters where the limit is long enough to match almost all of the potential
+hits without slowing the scan too much.
+
+Mostly you don't need to worry about the details. Just use a space between words
+even if they might appear on different lines etc.
+
+However, if you use a space inside a character class [ a-z0-9], the plugin will
+reject the pattern. You need to break that out into a more complicated pattern:
+`(?: |[a-z0-9])`
+
+## Capture Groups
+
+The plugin uses capture groups to keep track of licenses versus owners. To group
+parts of your patterns, use a non-capturing group `(?:pattern)` instead of
+`(pattern)`. The plugin will reject your configuration if you try to use a
+pattern that looks like it contains a capture group.
+
+This might also force you to use a different order in character classes:
+e.g.  `[)a-d(]` instead of `[(a-d)]`
diff --git a/tools/bzl/classpath.bzl b/tools/bzl/classpath.bzl
new file mode 100644
index 0000000..d5764f7
--- /dev/null
+++ b/tools/bzl/classpath.bzl
@@ -0,0 +1,4 @@
+load(
+    "@com_googlesource_gerrit_bazlets//tools:classpath.bzl",
+    "classpath_collector",
+)
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
new file mode 100644
index 0000000..0a5fbff
--- /dev/null
+++ b/tools/eclipse/BUILD
@@ -0,0 +1,9 @@
+load("//tools/bzl:classpath.bzl", "classpath_collector")
+
+classpath_collector(
+    name = "main_classpath_collect",
+    testonly = 1,
+    deps = [
+        "//:copyright_classpath_deps",
+    ],
+)
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh
new file mode 100755
index 0000000..2428a9f
--- /dev/null
+++ b/tools/eclipse/project.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+`bazel query @com_googlesource_gerrit_bazlets//tools/eclipse:project --output location | sed s/BUILD:.*//`project.py -n copyright -r .