Index: /trunk/build.xml
===================================================================
--- /trunk/build.xml	(revision 12581)
+++ /trunk/build.xml	(revision 12582)
@@ -24,4 +24,5 @@
         <property name="mapcss.dir" location="${src.dir}/org/openstreetmap/josm/gui/mappaint/mapcss"/>
         <property name="proj-build.dir" location="${base.dir}/build2"/>
+        <property name="checkstyle-build.dir" location="${base.dir}/build2"/>
         <property name="epsg.output" location="${base.dir}/data/projection/custom-epsg"/>
         <property name="groovy.jar" location="${base.dir}/tools/groovy-all.jar"/>
@@ -302,5 +303,5 @@
         </javac>
         <!-- JOSM -->
-        <javac compiler="${javac.compiler}" sourcepath="" srcdir="${src.dir}" 
+        <javac compiler="${javac.compiler}" sourcepath="" srcdir="${src.dir}"
             excludes="com/**,oauth/**,org/apache/commons/**,org/glassfish/**,org/openstreetmap/gui/jmapviewer/**"
             destdir="build" target="1.8" source="1.8" debug="on" includeantruntime="false" createMissingPackageInfoClass="false" encoding="UTF-8">
@@ -366,4 +367,5 @@
         <delete dir="${build.dir}"/>
         <delete dir="${proj-build.dir}"/>
+        <delete dir="${checkstyle-build.dir}"/>
         <delete dir="${dist.dir}"/>
         <delete dir="${mapcss.dir}/parsergen"/>
@@ -760,7 +762,15 @@
     </target>
 
-    <target name="checkstyle" depends="init-properties">
+    <target name="checkstyle-compile" depends="init-properties">
+        <mkdir dir="${checkstyle-build.dir}"/>
+        <javac sourcepath="" srcdir="${base.dir}/tools/checkstyle/checks" failonerror="true"
+            destdir="${checkstyle-build.dir}" target="1.8" source="1.8" debug="on"
+            includeantruntime="false" createMissingPackageInfoClass="false"
+            encoding="UTF-8" classpath="tools/checkstyle/checkstyle-all.jar">
+        </javac>
+    </target>
+    <target name="checkstyle" depends="checkstyle-compile">
         <taskdef resource="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties"
-             classpath="tools/checkstyle/checkstyle-all.jar"/>
+             classpath="tools/checkstyle/checkstyle-all.jar:dist/josm-custom.jar:${checkstyle-build.dir}"/>
         <checkstyle config="tools/checkstyle/josm_checks.xml">
             <fileset dir="${base.dir}/src/org/openstreetmap/josm" includes="**/*.java"
Index: /trunk/tools/checkstyle/checks/org/openstreetmap/josm/TopLevelJavadocCheck.java
===================================================================
--- /trunk/tools/checkstyle/checks/org/openstreetmap/josm/TopLevelJavadocCheck.java	(revision 12582)
+++ /trunk/tools/checkstyle/checks/org/openstreetmap/josm/TopLevelJavadocCheck.java	(revision 12582)
@@ -0,0 +1,87 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm;
+
+import com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser;
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
+import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
+
+/**
+ * Checks that there is Javadoc for every top level class, interface or enum.
+ */
+public class TopLevelJavadocCheck extends AbstractCheck
+{
+    private boolean foundTopLevelClass;
+
+    @Override
+    public int[] getDefaultTokens()
+    {
+        return new int[]{TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF, TokenTypes.ENUM_DEF};
+    }
+
+    @Override
+    public boolean isCommentNodesRequired() {
+        return true;
+    }
+
+    @Override
+    public void beginTree(DetailAST rootAST) {
+        foundTopLevelClass = false;
+    }
+
+    @Override
+    public void finishTree(DetailAST rootAST) {
+        if (!foundTopLevelClass) {
+            this.log(rootAST.getLineNo(), "assertion failure: unable to find toplevel class or interface");
+        }
+    }
+
+    private boolean hasJavadoc(DetailAST ast) {
+        DetailAST blockCommentBegin = ast.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
+        if (blockCommentBegin == null) {
+            DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
+            if (modifiers == null)
+                return false;
+            blockCommentBegin = modifiers.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
+            if (blockCommentBegin == null) {
+                DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION);
+                if (annotation == null)
+                    return false;
+                blockCommentBegin = annotation.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
+                if (blockCommentBegin == null)
+                    return false;
+            }
+        }
+        if (!JavadocUtils.isJavadocComment(blockCommentBegin))
+            return false;
+        DetailNode javadocTree = new JavadocDetailNodeParser().parseJavadocAsDetailNode(blockCommentBegin).getTree();
+        return hasProperText(javadocTree);
+    }
+
+    private boolean hasProperText(DetailNode javadoc) {
+        for (DetailNode child : javadoc.getChildren()) {
+            if (child.getType() == JavadocTokenTypes.TEXT) {
+                if (!child.getText().trim().isEmpty())
+                    return true;
+            } else if (child.getType() == JavadocTokenTypes.HTML_ELEMENT) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void visitToken(DetailAST ast)
+    {
+        DetailAST parent = ast.getParent();
+        if (parent == null || parent.getType() == TokenTypes.EOF) {
+            foundTopLevelClass = true;
+            if (!hasJavadoc(ast)) {
+                this.log(ast.getLineNo(), "no/incomplete Javadoc for top level class or interface");
+            }
+        }
+   }
+}
Index: /trunk/tools/checkstyle/josm_checks.xml
===================================================================
--- /trunk/tools/checkstyle/josm_checks.xml	(revision 12581)
+++ /trunk/tools/checkstyle/josm_checks.xml	(revision 12582)
@@ -103,4 +103,5 @@
     <module name="FinalClass"/>
     <module name="HideUtilityClassConstructor"/>
+    <module name="org.openstreetmap.josm.TopLevelJavadocCheck"/>
   </module>
   <module name="Header">
Index: /trunk/tools/checkstyle/josm_filters.xml
===================================================================
--- /trunk/tools/checkstyle/josm_filters.xml	(revision 12581)
+++ /trunk/tools/checkstyle/josm_filters.xml	(revision 12582)
@@ -44,3 +44,4 @@
   <suppress checks="HeaderCheck" files="DNSName(Fix)?\.java" />
   <suppress checks="FileLengthCheck" files="DomainValidator\.java" />
+  <suppress checks="org.openstreetmap.josm.TopLevelJavadocCheck" files="package-info\.java" />
 </suppressions>
