Add support for @removed tag.

@removed tags can be applied to packages, classes, methods, fields
that were once public API, but later removed. Things annotated by
@removed cannot be used by outside developers. But applications compiled
against the old API where the @removed API were still public should
continue to work and we must not delete the @removed APIs from the
source. This fix makes sure of that.

BUG: b/11293324

Change-Id: Iab3a8bdcaa0cb0742501c33e29b8121bc169bf1b
diff --git a/src/com/google/doclava/Converter.java b/src/com/google/doclava/Converter.java
index bdf6af5..e620bf3 100644
--- a/src/com/google/doclava/Converter.java
+++ b/src/com/google/doclava/Converter.java
@@ -41,6 +41,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 
 public class Converter {
   private static RootDoc root;
@@ -131,6 +132,18 @@
 
     cl.setHiddenMethods(
             new ArrayList<MethodInfo>(Arrays.asList(Converter.getHiddenMethods(c.methods(false)))));
+    cl.setRemovedMethods(
+            new ArrayList<MethodInfo>(Arrays.asList(Converter.getRemovedMethods(c.methods(false)))));
+
+    cl.setRemovedSelfMethods(
+        new ArrayList<MethodInfo>(Converter.convertAllMethods(c.methods(false))));
+    cl.setRemovedConstructors(
+        new ArrayList<MethodInfo>(Converter.convertAllMethods(c.constructors(false))));
+    cl.setRemovedSelfFields(
+        new ArrayList<FieldInfo>(Converter.convertAllFields(c.fields(false))));
+    cl.setRemovedEnumConstants(
+        new ArrayList<FieldInfo>(Converter.convertAllFields(c.enumConstants())));
+
     cl.setNonWrittenConstructors(
             new ArrayList<MethodInfo>(Arrays.asList(Converter.convertNonWrittenConstructors(
                     c.constructors(false)))));
@@ -288,81 +301,91 @@
 
   private static MethodInfo[] getHiddenMethods(MethodDoc[] methods) {
     if (methods == null) return null;
-    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
-    int N = methods.length;
-    for (int i = 0; i < N; i++) {
-      MethodInfo m = Converter.obtainMethod(methods[i]);
-      // System.out.println(m.toString() + ": ");
-      // for (TypeInfo ti : m.getTypeParameters()){
-      // if (ti.asClassInfo() != null){
-      // System.out.println(" " +ti.asClassInfo().toString());
-      // } else {
-      // System.out.println(" null");
-      // }
-      // }
-      if (m.isHidden()) {
-        out.add(m);
+    ArrayList<MethodInfo> hiddenMethods = new ArrayList<MethodInfo>();
+    for (MethodDoc method : methods) {
+      MethodInfo methodInfo = Converter.obtainMethod(method);
+      if (methodInfo.isHidden()) {
+        hiddenMethods.add(methodInfo);
       }
     }
-    return out.toArray(new MethodInfo[out.size()]);
+
+    return hiddenMethods.toArray(new MethodInfo[hiddenMethods.size()]);
+  }
+
+  // Gets the removed methods regardless of access levels
+  private static MethodInfo[] getRemovedMethods(MethodDoc[] methods) {
+    if (methods == null) return null;
+    ArrayList<MethodInfo> removedMethods = new ArrayList<MethodInfo>();
+    for (MethodDoc method : methods) {
+      MethodInfo methodInfo = Converter.obtainMethod(method);
+      if (methodInfo.isRemoved()) {
+        removedMethods.add(methodInfo);
+      }
+    }
+
+    return removedMethods.toArray(new MethodInfo[removedMethods.size()]);
   }
 
   /**
-   * Convert MethodDoc[] into MethodInfo[]. Also filters according to the -private, -public option,
-   * because the filtering doesn't seem to be working in the ClassDoc.constructors(boolean) call.
+   * Converts FieldDoc[] into List<FieldInfo>. No filtering is done.
    */
-  private static MethodInfo[] convertMethods(MethodDoc[] methods) {
-    if (methods == null) return null;
-    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
-    int N = methods.length;
-    for (int i = 0; i < N; i++) {
-      MethodInfo m = Converter.obtainMethod(methods[i]);
-      // System.out.println(m.toString() + ": ");
-      // for (TypeInfo ti : m.getTypeParameters()){
-      // if (ti.asClassInfo() != null){
-      // System.out.println(" " +ti.asClassInfo().toString());
-      // } else {
-      // System.out.println(" null");
-      // }
-      // }
-      if (m.checkLevel()) {
-        out.add(m);
-      }
+  private static List<FieldInfo> convertAllFields(FieldDoc[] fields) {
+    if (fields == null) return null;
+    List<FieldInfo> allFields = new ArrayList<FieldInfo>();
+
+    for (FieldDoc field : fields) {
+      FieldInfo fieldInfo = Converter.obtainField(field);
+      allFields.add(fieldInfo);
     }
-    return out.toArray(new MethodInfo[out.size()]);
+
+    return allFields;
   }
 
-  private static MethodInfo[] convertMethods(ConstructorDoc[] methods) {
+  /**
+   * Converts ExecutableMemberDoc[] into List<MethodInfo>. No filtering is done.
+   */
+  private static List<MethodInfo> convertAllMethods(ExecutableMemberDoc[] methods) {
     if (methods == null) return null;
-    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
-    int N = methods.length;
-    for (int i = 0; i < N; i++) {
-      MethodInfo m = Converter.obtainMethod(methods[i]);
-      if (m.checkLevel()) {
-        out.add(m);
+    List<MethodInfo> allMethods = new ArrayList<MethodInfo>();
+    for (ExecutableMemberDoc method : methods) {
+      MethodInfo methodInfo = Converter.obtainMethod(method);
+      allMethods.add(methodInfo);
+    }
+    return allMethods;
+  }
+
+  /**
+   * Convert MethodDoc[] or ConstructorDoc[] into MethodInfo[].
+   * Also filters according to the -private, -public option,
+   * because the filtering doesn't seem to be working in the ClassDoc.constructors(boolean) call.
+   */
+  private static MethodInfo[] convertMethods(ExecutableMemberDoc[] methods) {
+    if (methods == null) return null;
+    List<MethodInfo> filteredMethods = new ArrayList<MethodInfo>();
+    for (ExecutableMemberDoc method : methods) {
+      MethodInfo methodInfo = Converter.obtainMethod(method);
+      if (methodInfo.checkLevel()) {
+        filteredMethods.add(methodInfo);
       }
     }
-    return out.toArray(new MethodInfo[out.size()]);
+
+    return filteredMethods.toArray(new MethodInfo[filteredMethods.size()]);
   }
 
   private static MethodInfo[] convertNonWrittenConstructors(ConstructorDoc[] methods) {
     if (methods == null) return null;
-    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
-    int N = methods.length;
-    for (int i = 0; i < N; i++) {
-      MethodInfo m = Converter.obtainMethod(methods[i]);
-      if (!m.checkLevel()) {
-        out.add(m);
+    ArrayList<MethodInfo> ctors = new ArrayList<MethodInfo>();
+    for (ConstructorDoc method : methods) {
+      MethodInfo methodInfo = Converter.obtainMethod(method);
+      if (!methodInfo.checkLevel()) {
+        ctors.add(methodInfo);
       }
     }
-    return out.toArray(new MethodInfo[out.size()]);
+
+    return ctors.toArray(new MethodInfo[ctors.size()]);
   }
 
-  private static MethodInfo obtainMethod(MethodDoc o) {
-    return (MethodInfo) mMethods.obtain(o);
-  }
-
-  private static MethodInfo obtainMethod(ConstructorDoc o) {
+  private static <E extends ExecutableMemberDoc> MethodInfo obtainMethod(E o) {
     return (MethodInfo) mMethods.obtain(o);
   }
 
@@ -559,11 +582,11 @@
       return keyString;
     }
   };
-  
+
   public static TypeInfo obtainTypeFromString(String type) {
     return (TypeInfo) mTypesFromString.obtain(type);
   }
-  
+
   private static final Cache mTypesFromString = new Cache() {
     @Override
     protected Object make(Object o) {
@@ -573,7 +596,7 @@
 
     @Override
     protected void made(Object o, Object r) {
-      
+
     }
 
     @Override