Merge "Fix DEX type name for `long`" am: 5051c31aae am: 26b317d35b
am: 17ac1739ae

Change-Id: Ic72d3bb08d512c7bc339e5b50abf025bbb137e18
diff --git a/.gitignore b/.gitignore
index 3770f89..17d7fbe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 .classpath
 .project
 .settings
+*.iml
diff --git a/res/assets/templates-sdk/head_tag.cs b/res/assets/templates-sdk/head_tag.cs
index 50e36fa..bb698b9 100644
--- a/res/assets/templates-sdk/head_tag.cs
+++ b/res/assets/templates-sdk/head_tag.cs
@@ -13,15 +13,27 @@
 # END if/else devsite ?></title><?cs
   ####### If building devsite, add some meta data needed for when generating the top nav ######### ?><?cs
 if:devsite ?><?cs
-  # if this build set `library.root` then set a django variable to be used by the subsequent
-  # _reference-head-tags.html file for the book path (or ignored if its no longer needed)
-  ?><?cs
-  if:library.root ?>
-  {% setvar book_path %}/reference/<?cs var:library.root ?>/_book.yaml{% endsetvar %}<?cs
-  /if ?>
-  {% include "_shared/_reference-head-tags.html" %}
-  <meta name="body_class" value="api apilevel-<?cs var:class.since ?><?cs var:package.since ?>" /><?cs
-else ?>
+  if:dac ?><?cs
+    # if this build set `library.root` then set a django variable to be used by the subsequent
+    # _reference-head-tags.html file for the book path (or ignored if its no longer needed)
+    ?><?cs
+    if:library.root ?>
+      {% setvar book_path %}/reference/<?cs var:library.root ?>/_book.yaml{% endsetvar %}<?cs
+    /if ?>
+    {% include "_shared/_reference-head-tags.html" %}
+    <meta name="body_class" value="api apilevel-<?cs var:class.since ?><?cs var:package.since ?>" /><?cs
+  else ?><?cs # If NOT dac... ?>
+    <meta name="hide_page_heading" value="true" />
+    <meta name="book_path" value="<?cs
+      if:book.path ?><?cs var:book.path ?><?cs
+      else ?>/_book.yaml<?cs
+      /if ?>" />
+    <meta name="project_path" value="<?cs
+      if:project.path ?><?cs var:project.path ?><?cs
+      else ?>/_project.yaml<?cs
+      /if ?>" /><?cs
+  /if ?><?cs # End if/else dac ?><?cs
+else ?><?cs # if NOT devsite... ?>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
 <meta content="IE=edge" http-equiv="X-UA-Compatible">
diff --git a/res/assets/templates-sdk/macros_override.cs b/res/assets/templates-sdk/macros_override.cs
index dab5dcc..08ed856 100644
--- a/res/assets/templates-sdk/macros_override.cs
+++ b/res/assets/templates-sdk/macros_override.cs
@@ -64,6 +64,7 @@
       elif:tag.kind == "@returnDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs
       elif:tag.kind == "@range" ?><?cs call:dump_range(tag) ?><?cs
       elif:tag.kind == "@intDef" ?><?cs call:dump_int_def(tag) ?><?cs
+      elif:tag.kind == "@stringDef" ?><?cs call:dump_string_def(tag) ?><?cs
       elif:tag.kind == "@permission" ?><?cs call:dump_permission(tag) ?><?cs
       elif:tag.kind == "@service" ?><?cs call:dump_service(tag) ?><?cs
       /if ?><?cs
@@ -96,6 +97,18 @@
   /loop ?>.<?cs
 /def ?><?cs
 
+# Print output for @stringDef tags ?><?cs
+def:dump_string_def(tag) ?>Value is <?cs
+  loop:i = #0, subcount(tag.values), #1 ?><?cs
+    with:val = tag.values[i] ?><?cs
+      call:tag_list(val.commentTags) ?><?cs
+      if i == subcount(tag.values) - 2 ?> or <?cs
+      elif:i < subcount(tag.values) - 2 ?>, <?cs
+      /if ?><?cs
+    /with ?><?cs
+  /loop ?>.<?cs
+/def ?><?cs
+
 # Print output for @permission tags ?><?cs
 def:dump_permission(tag) ?>Requires the <?cs
   loop:i = #0, subcount(tag.values), #1 ?><?cs
diff --git a/src/com/google/doclava/AndroidAuxSource.java b/src/com/google/doclava/AndroidAuxSource.java
index 8ed9fb0..b5735e3 100644
--- a/src/com/google/doclava/AndroidAuxSource.java
+++ b/src/com/google/doclava/AndroidAuxSource.java
@@ -202,21 +202,28 @@
 
       // Document integer values
       for (AnnotationInstanceInfo inner : annotation.type().annotations()) {
-        if (inner.type().qualifiedNameMatches("android", "annotation.IntDef")) {
+        boolean intDef = inner.type().qualifiedNameMatches("android", "annotation.IntDef");
+        boolean stringDef = inner.type().qualifiedNameMatches("android", "annotation.StringDef");
+        if (intDef || stringDef) {
           ArrayList<AnnotationValueInfo> prefixes = null;
+          ArrayList<AnnotationValueInfo> suffixes = null;
           ArrayList<AnnotationValueInfo> values = null;
+          final String kind = intDef ? "@intDef" : "@stringDef";
           boolean flag = false;
 
           for (AnnotationValueInfo val : inner.elementValues()) {
             switch (val.element().name()) {
               case "prefix": prefixes = (ArrayList<AnnotationValueInfo>) val.value(); break;
+              case "suffix": suffixes = (ArrayList<AnnotationValueInfo>) val.value(); break;
               case "value": values = (ArrayList<AnnotationValueInfo>) val.value(); break;
               case "flag": flag = Boolean.parseBoolean(String.valueOf(val.value())); break;
             }
           }
 
-          // Sadly we can only generate docs when told about a prefix
-          if (prefixes == null || prefixes.isEmpty()) continue;
+          // Sadly we can only generate docs when told about a prefix/suffix
+          if (prefixes == null) prefixes = new ArrayList<>();
+          if (suffixes == null) suffixes = new ArrayList<>();
+          if (prefixes.isEmpty() && suffixes.isEmpty()) continue;
 
           final ClassInfo clazz = annotation.type().containingClass();
           final HashMap<String, FieldInfo> candidates = new HashMap<>();
@@ -227,6 +234,11 @@
                 candidates.put(String.valueOf(field.constantValue()), field);
               }
             }
+            for (AnnotationValueInfo suffix : suffixes) {
+              if (field.name().endsWith(String.valueOf(suffix.value()))) {
+                candidates.put(String.valueOf(field.constantValue()), field);
+              }
+            }
           }
 
           ArrayList<TagInfo> valueTags = new ArrayList<>();
@@ -243,7 +255,7 @@
           if (!valueTags.isEmpty()) {
             Map<String, String> args = new HashMap<>();
             if (flag) args.put("flag", "true");
-            tags.add(new AuxTagInfo("@intDef", "@intDef", SourcePositionInfo.UNKNOWN, args,
+            tags.add(new AuxTagInfo(kind, kind, SourcePositionInfo.UNKNOWN, args,
                 valueTags.toArray(TagInfo.getArray(valueTags.size()))));
           }
         }
diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java
index 2393c2c..dbe7783 100644
--- a/src/com/google/doclava/ClassInfo.java
+++ b/src/com/google/doclava/ClassInfo.java
@@ -2193,16 +2193,20 @@
          * abstractness affects how users use it. See also Stubs.methodIsOverride().
          */
         MethodInfo mi = ClassInfo.overriddenMethod(mInfo, this);
-        if (mi == null ||
-            mi.isAbstract() != mInfo.isAbstract()) {
-          Errors.error(Errors.ADDED_METHOD, mInfo.position(), "Added public method "
-              + mInfo.prettyQualifiedSignature());
-          if (diffMode) {
-            newMethods.add(mInfo);
-          }
+        if (mi == null && mInfo.isAbstract()) {
+          Errors.error(Errors.ADDED_ABSTRACT_METHOD, mInfo.position(),
+              "Added abstract public method "
+              + mInfo.prettyQualifiedSignature() + " to existing class");
           consistent = false;
+        } else if (mi == null || mi.isAbstract() != mInfo.isAbstract()) {
+            Errors.error(Errors.ADDED_METHOD, mInfo.position(), "Added public method "
+                + mInfo.prettyQualifiedSignature());
+            if (diffMode) {
+              newMethods.add(mInfo);
+            }
+            consistent = false;
+          }
         }
-      }
     }
     if (diffMode) {
       Collections.sort(newMethods, MethodInfo.comparator);
diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java
index 1f2891a..2241098 100644
--- a/src/com/google/doclava/Doclava.java
+++ b/src/com/google/doclava/Doclava.java
@@ -790,6 +790,9 @@
     if (option.equals("-showAnnotation")) {
       return 2;
     }
+    if (option.equals("-hideAnnotation")) {
+      return 2;
+    }
     if (option.equals("-showAnnotationOverridesVisibility")) {
       return 1;
     }
diff --git a/src/com/google/doclava/Errors.java b/src/com/google/doclava/Errors.java
index 9edd239..6b0eee0 100644
--- a/src/com/google/doclava/Errors.java
+++ b/src/com/google/doclava/Errors.java
@@ -281,6 +281,7 @@
   public static final Error REMOVED_DEPRECATED_CLASS = new Error(28, REMOVED_CLASS);
   public static final Error REMOVED_DEPRECATED_METHOD = new Error(29, REMOVED_METHOD);
   public static final Error REMOVED_DEPRECATED_FIELD = new Error(30, REMOVED_FIELD);
+  public static final Error ADDED_ABSTRACT_METHOD = new Error(31, ADDED_METHOD);
 
   // Errors in javadoc generation
   public static final Error UNRESOLVED_LINK = new Error(101, LINT);
diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java
index 908c0ea..ac6d2c5 100644
--- a/src/com/google/doclava/MethodInfo.java
+++ b/src/com/google/doclava/MethodInfo.java
@@ -909,8 +909,6 @@
           + " to " + mInfo.scope());
     }
 
-    // Changing the deprecated annotation is binary- and source-compatible, but
-    // we still need to log the API change.
     if (!isDeprecated() == mInfo.isDeprecated()) {
       Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(), "Method "
           + mInfo.prettyQualifiedSignature() + " has changed deprecation state " + isDeprecated()
@@ -918,14 +916,16 @@
       consistent = false;
     }
 
-    // Changing the synchronized modifier is binary- and source-compatible (see
-    // JLS 3 13.4.20), but we still need to log the API change.
+    // see JLS 3 13.4.20 "Adding or deleting a synchronized modifier of a method does not break "
+    // "compatibility with existing binaries."
+    /*
     if (mIsSynchronized != mInfo.mIsSynchronized) {
       Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(), "Method " + mInfo.qualifiedName()
           + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to "
           + mInfo.mIsSynchronized);
       consistent = false;
     }
+    */
 
     for (ClassInfo exception : thrownExceptions()) {
       if (!mInfo.throwsException(exception)) {
diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java
index 8098ff2..17cda4d 100644
--- a/src/com/google/doclava/Stubs.java
+++ b/src/com/google/doclava/Stubs.java
@@ -678,6 +678,7 @@
     int N = enumConstants.size();
     int i = 0;
     for (FieldInfo field : enumConstants) {
+      writeAnnotations(stream, field.annotations(), field.isDeprecated());
       if (!field.constantLiteralValue().equals("null")) {
         stream.println(field.name() + "(" + field.constantLiteralValue()
             + (i == N - 1 ? ");" : "),"));
@@ -929,7 +930,7 @@
       if (canCallMethod(cl, m)) {
         if (m.thrownExceptions() != null) {
           for (ClassInfo thrown : m.thrownExceptions()) {
-            if (!exceptionNames.contains(thrown.name())) {
+            if (thrownExceptions != null && !exceptionNames.contains(thrown.name())) {
               badException = true;
             }
           }
@@ -1027,6 +1028,14 @@
     stream.println(";");
   }
 
+  public static void writeXml(PrintStream xmlWriter, Collection<PackageInfo> pkgs, boolean strip) {
+    if (strip) {
+      Stubs.writeXml(xmlWriter, pkgs);
+    } else {
+      Stubs.writeXml(xmlWriter, pkgs, c -> true);
+    }
+  }
+
   public static void writeXml(PrintStream xmlWriter, Collection<PackageInfo> pkgs,
       Predicate<ClassInfo> notStrippable) {
 
diff --git a/src/com/google/doclava/apicheck/ApiCheck.java b/src/com/google/doclava/apicheck/ApiCheck.java
index 4828720..ab7ee84 100644
--- a/src/com/google/doclava/apicheck/ApiCheck.java
+++ b/src/com/google/doclava/apicheck/ApiCheck.java
@@ -71,7 +71,11 @@
     } else if (originalArgs.length == 4 && "-new_api".equals(originalArgs[0])) {
       // command syntax: -new_api oldapi.txt newapi.txt diff.xml
       // TODO: Support reading in other options for new_api, such as ignored classes/packages.
-      System.exit(newApi(originalArgs[1], originalArgs[2], originalArgs[3]));
+      System.exit(newApi(originalArgs[1], originalArgs[2], originalArgs[3], true));
+    } else if (originalArgs.length == 4 && "-new_api_no_strip".equals(originalArgs[0])) {
+      // command syntax: -new_api oldapi.txt newapi.txt diff.xml
+      // TODO: Support reading in other options for new_api, such as ignored classes/packages.
+      System.exit(newApi(originalArgs[1], originalArgs[2], originalArgs[3], false));
     } else {
       ApiCheck acheck = new ApiCheck();
       Report report = acheck.checkApi(originalArgs);
@@ -272,7 +276,7 @@
       System.err.println("can't open file: " + dst);
     }
 
-    Stubs.writeXml(apiWriter, api.getPackages().values(), c -> true);
+    Stubs.writeXml(apiWriter, api.getPackages().values(), strip);
 
     return 0;
   }
@@ -282,9 +286,10 @@
    * @param origApiPath path to old API text file
    * @param newApiPath path to new API text file
    * @param outputPath output XML path for the generated diff
+   * @param strip true if any unknown classes should be stripped from the output, false otherwise
    * @return
    */
-  static int newApi(String origApiPath, String newApiPath, String outputPath) {
+  static int newApi(String origApiPath, String newApiPath, String outputPath, boolean strip) {
     ApiInfo origApi, newApi;
     try {
       origApi = parseApi(origApiPath);
@@ -308,7 +313,7 @@
       } catch (FileNotFoundException ex) {
         System.err.println("can't open file: " + outputPath);
       }
-      Stubs.writeXml(apiWriter, pkgInfoDiff);
+      Stubs.writeXml(apiWriter, pkgInfoDiff, strip);
     } else {
       System.err.println("No API change detected, not generating diff.");
     }
diff --git a/test/doclava/ApiCheckTest.java b/test/doclava/ApiCheckTest.java
index ce0464a..98cb020 100644
--- a/test/doclava/ApiCheckTest.java
+++ b/test/doclava/ApiCheckTest.java
@@ -17,31 +17,26 @@
 package doclava;
 
 import com.google.doclava.Errors;
+import com.google.doclava.Errors.Error;
 import com.google.doclava.Errors.ErrorMessage;
 import com.google.doclava.apicheck.ApiCheck;
 import com.google.doclava.apicheck.ApiCheck.Report;
 
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
+import junit.framework.TestCase;
 
 import java.util.Iterator;
 
-public class ApiCheckTest {
-
-  @Before
+public class ApiCheckTest extends TestCase {
+  /**
+   * Clear all errors and make sure all future errors will be recorded.
+   */
   public void setUp() {
-    // Clear all errors and make sure all future errors will be recorded.
     Errors.clearErrors();
     for (Errors.Error error : Errors.sErrors) {
       Errors.setErrorLevel(error.code, Errors.ERROR);
     }
   }
 
-  @Test
   public void testEquivalentApi() {
     String[] args = { "test/api/medium.xml", "test/api/medium.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -49,7 +44,6 @@
     assertEquals(report.errors().size(), 0);
   }
 
-  @Test
   public void testMethodReturnTypeChanged() {
     String[] args = { "test/api/return-type-changed-1.xml", "test/api/return-type-changed-2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -58,7 +52,6 @@
     assertEquals(Errors.CHANGED_TYPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testMethodParameterChanged() {
     String[] args = { "test/api/parameter-changed-1.xml", "test/api/parameter-changed-2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -73,7 +66,6 @@
     assertTrue(m2.error().equals(Errors.ADDED_METHOD) || m2.error().equals(Errors.REMOVED_METHOD));
   }
 
-  @Test
   public void testConstructorParameterChanged() {
     String[] args = { "test/api/parameter-changed-1.xml", "test/api/parameter-changed-3.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -87,7 +79,6 @@
     assertTrue(m2.error().equals(Errors.ADDED_METHOD) || m2.error().equals(Errors.REMOVED_METHOD));
   }
 
-  @Test
   public void testAddedClass() {
     String[] args = { "test/api/simple.xml", "test/api/added-class.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -96,7 +87,6 @@
     assertEquals(Errors.ADDED_CLASS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedClass() {
     String[] args = { "test/api/added-class.xml", "test/api/simple.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -105,7 +95,6 @@
     assertEquals(Errors.REMOVED_CLASS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedDeprecatedClass() {
     String[] args = { "test/api/added-deprecated-class.xml", "test/api/simple.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -114,7 +103,6 @@
     assertEquals(Errors.REMOVED_DEPRECATED_CLASS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedSuper() {
     String[] args = { "test/api/simple.xml", "test/api/changed-super.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -123,7 +111,6 @@
     assertEquals(Errors.CHANGED_SUPERCLASS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedAssignableReturn() {
     String[] args = {
         "test/api/changed-assignable-return-1.xml",
@@ -135,7 +122,6 @@
     assertEquals(Errors.CHANGED_TYPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testInsertedSuper() {
     String[] args = { "test/api/inserted-super-1.xml", "test/api/inserted-super-2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -143,7 +129,6 @@
     assertEquals(0, report.errors().size());
   }
 
-  @Test
   public void testAddedInterface() {
     String[] args = { "test/api/removed-interface.xml", "test/api/medium.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -152,7 +137,6 @@
     assertEquals(Errors.ADDED_INTERFACE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedInterface() {
     String[] args = { "test/api/medium.xml", "test/api/removed-interface.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -161,7 +145,6 @@
     assertEquals(Errors.REMOVED_INTERFACE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedAbstractClass() {
     String[] args = { "test/api/medium.xml", "test/api/changed-abstract.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -170,7 +153,6 @@
     assertEquals(Errors.CHANGED_ABSTRACT, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedAbstractClass2() {
     String[] args = { "test/api/changed-abstract.xml", "test/api/medium.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -179,7 +161,6 @@
     assertEquals(Errors.CHANGED_ABSTRACT, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedAbstractMethod() {
     String[] args = { "test/api/medium.xml", "test/api/changed-abstract2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -188,7 +169,6 @@
     assertEquals(Errors.CHANGED_ABSTRACT, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedAbstractMethod2() {
     String[] args = { "test/api/changed-abstract2.xml", "test/api/medium.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -197,7 +177,6 @@
     assertEquals(Errors.CHANGED_ABSTRACT, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedPackage() {
     String[] args = { "test/api/medium.xml", "test/api/added-package.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -206,7 +185,6 @@
     assertEquals(Errors.ADDED_PACKAGE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedPackage() {
     String[] args = { "test/api/added-package.xml", "test/api/medium.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -215,7 +193,6 @@
     assertEquals(Errors.REMOVED_PACKAGE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedValue() {
     String[] args = { "test/api/constants.xml", "test/api/changed-value.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -224,7 +201,6 @@
     assertEquals(Errors.CHANGED_VALUE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedValue2() {
     String[] args = { "test/api/constants.xml", "test/api/changed-value2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -233,7 +209,6 @@
     assertEquals(Errors.CHANGED_VALUE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedType() {
     String[] args = { "test/api/constants.xml", "test/api/changed-type.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -242,7 +217,6 @@
     assertEquals(Errors.CHANGED_TYPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedFinalField() {
     String[] args = { "test/api/constants.xml", "test/api/changed-final.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -251,7 +225,6 @@
     assertEquals(Errors.ADDED_FINAL, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedFinalMethod() {
     String[] args = { "test/api/constants.xml", "test/api/changed-final2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -260,7 +233,6 @@
     assertEquals(Errors.ADDED_FINAL, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedFinalClass() {
     String[] args = { "test/api/constants.xml", "test/api/changed-final3.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -270,7 +242,6 @@
     assertEquals(Errors.ADDED_FINAL, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedFinalClass() {
     String[] args = { "test/api/changed-final3.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -280,7 +251,6 @@
     assertEquals(Errors.REMOVED_FINAL, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedField() {
     String[] args = { "test/api/constants.xml", "test/api/added-field.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -289,7 +259,6 @@
     assertEquals(Errors.ADDED_FIELD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedField() {
     String[] args = { "test/api/added-field.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -298,7 +267,6 @@
     assertEquals(Errors.REMOVED_FIELD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedDeprecatedField() {
     String[] args = { "test/api/added-deprecated-field.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -307,7 +275,6 @@
     assertEquals(Errors.REMOVED_DEPRECATED_FIELD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testAddedMethod() {
     String[] args = { "test/api/constants.xml", "test/api/added-method.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -316,7 +283,6 @@
     assertEquals(Errors.ADDED_METHOD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedMethod() {
     String[] args = { "test/api/added-method.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -325,7 +291,6 @@
     assertEquals(Errors.REMOVED_METHOD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testRemovedDeprecatedMethod() {
     String[] args = { "test/api/added-deprecated-method.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -334,7 +299,6 @@
     assertEquals(Errors.REMOVED_DEPRECATED_METHOD, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedStaticMethod() {
     String[] args = { "test/api/constants.xml", "test/api/changed-static.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -343,7 +307,6 @@
     assertEquals(Errors.CHANGED_STATIC, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedStaticClass() {
     String[] args = { "test/api/constants.xml", "test/api/changed-static2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -352,7 +315,6 @@
     assertEquals(Errors.CHANGED_STATIC, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedStaticField() {
     String[] args = { "test/api/constants.xml", "test/api/changed-static3.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -361,7 +323,6 @@
     assertEquals(Errors.CHANGED_STATIC, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedTransient() {
     String[] args = { "test/api/constants.xml", "test/api/changed-transient.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -370,15 +331,13 @@
     assertEquals(Errors.CHANGED_TRANSIENT, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedSynchronized() {
     String[] args = { "test/api/constants.xml", "test/api/changed-synchronized.xml" };
     ApiCheck apiCheck = new ApiCheck();
     Report report = apiCheck.checkApi(args);
-    assertEquals(1, report.errors().size());
+    assertEquals(0, report.errors().size());
   }
 
-  @Test
   public void testChangedVolatile() {
     String[] args = { "test/api/constants.xml", "test/api/changed-volatile.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -387,7 +346,6 @@
     assertEquals(Errors.CHANGED_VOLATILE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedNative() {
     String[] args = { "test/api/constants.xml", "test/api/changed-native.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -396,7 +354,6 @@
     assertEquals(Errors.CHANGED_NATIVE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedScopeMethod() {
     String[] args = { "test/api/constants.xml", "test/api/changed-scope.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -405,7 +362,6 @@
     assertEquals(Errors.CHANGED_SCOPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedScopeClass() {
     String[] args = { "test/api/changed-scope.xml", "test/api/constants.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -414,7 +370,6 @@
     assertEquals(Errors.CHANGED_SCOPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedScopeClass2() {
     String[] args = { "test/api/constants.xml", "test/api/changed-scope2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -423,7 +378,6 @@
     assertEquals(Errors.CHANGED_SCOPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedScopeField() {
     String[] args = { "test/api/constants.xml", "test/api/changed-scope3.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -432,7 +386,6 @@
     assertEquals(Errors.CHANGED_SCOPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedConstructorScope() {
     String[] args = { "test/api/constants.xml", "test/api/changed-scope4.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -441,7 +394,6 @@
     assertEquals(Errors.CHANGED_SCOPE, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedMethodThrows() {
     String[] args = { "test/api/throws.xml", "test/api/removed-exception.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -450,7 +402,6 @@
     assertEquals(Errors.CHANGED_THROWS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedMethodThrows2() {
     String[] args = { "test/api/removed-exception.xml", "test/api/throws.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -459,7 +410,6 @@
     assertEquals(Errors.CHANGED_THROWS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedConstructorThrows() {
     String[] args = { "test/api/throws.xml", "test/api/added-exception.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -468,7 +418,6 @@
     assertEquals(Errors.CHANGED_THROWS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedConstructorThrows2() {
     String[] args = { "test/api/added-exception.xml", "test/api/throws.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -477,7 +426,6 @@
     assertEquals(Errors.CHANGED_THROWS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedMethodDeprecated() {
     String[] args = { "test/api/constants.xml", "test/api/changed-deprecated.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -486,7 +434,6 @@
     assertEquals(Errors.CHANGED_DEPRECATED, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedConstructorDeprecated() {
     String[] args = { "test/api/constants.xml", "test/api/changed-deprecated2.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -495,7 +442,6 @@
     assertEquals(Errors.CHANGED_DEPRECATED, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedFieldDeprecated() {
     String[] args = { "test/api/constants.xml", "test/api/changed-deprecated3.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -504,7 +450,6 @@
     assertEquals(Errors.CHANGED_DEPRECATED, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedClassToInterface() {
     String[] args = { "test/api/changed-class-info2.xml", "test/api/changed-class-info.xml" };
     ApiCheck apiCheck = new ApiCheck();
@@ -513,7 +458,6 @@
     assertEquals(Errors.CHANGED_CLASS, report.errors().iterator().next().error());
   }
 
-  @Test
   public void testChangedInterfaceToClass() {
     String[] args = { "test/api/changed-class-info.xml", "test/api/changed-class-info2.xml" };
     ApiCheck apiCheck = new ApiCheck();