cherrypick Change-Id: Ic7cc0864518fef95b106ab3d392c47eb225404bf
Add HDF meta-data for the version in which an API was deprecated

Change-Id: Iadaceb6d61d2fbc75d219295da2d8d7b52bd2eeb
diff --git a/res/assets/templates/macros.cs b/res/assets/templates/macros.cs
index 72139f4..5a6cdc6 100644
--- a/res/assets/templates/macros.cs
+++ b/res/assets/templates/macros.cs
@@ -98,15 +98,11 @@
   /each ?><?cs
 /def ?>
 
-<?cs # The message about This xxx is deprecated. ?><?cs 
-def:deprecated_text(kind) ?>
-  This <?cs var:kind ?> is deprecated.<?cs 
-/def ?>
-
 <?cs # Show the short-form description of something.  These come from shortDescr and deprecated ?><?cs 
 def:short_descr(obj) ?><?cs
   if:subcount(obj.deprecated) ?>
-      <em><?cs call:deprecated_text(obj.kind) ?>
+      <em>This <?cs var:obj.kind ?> was deprecated
+      in API level <?cs var:obj.deprecatedsince ?>.
       <?cs call:tag_list(obj.deprecated) ?></em><?cs
   else ?><?cs call:tag_list(obj.shortDescr) ?><?cs
   /if ?><?cs
@@ -116,7 +112,8 @@
 def:deprecated_warning(obj) ?><?cs 
   if:subcount(obj.deprecated) ?><p>
   <p class="caution">
-      <strong><?cs call:deprecated_text(obj.kind) ?></strong><br/> <?cs 
+      <strong>This <?cs var:obj.kind ?> was deprecated
+      in API level <?cs var:obj.deprecatedsince ?></strong>.<br/> <?cs
       call:tag_list(obj.deprecated) ?>
   </p><?cs 
   /if ?><?cs 
@@ -144,7 +141,7 @@
 <?cs # print the API Level ?><?cs
 def:since_tags(obj) ?>
 <?cs if:reference.apilevels && obj.since ?>
-  Since: <a href="<?cs var:toroot ?>guide/topics/manifest/uses-sdk-element.html#ApiLevels">API Level <?cs var:obj.since ?></a>
+  Added in <a href="<?cs var:toroot ?>guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level <?cs var:obj.since ?></a>
 <?cs /if ?>
 <?cs /def ?>
 <?cs def:federated_refs(obj) ?>
diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java
index 88d2416..f4f2853 100644
--- a/src/com/google/doclava/ClassInfo.java
+++ b/src/com/google/doclava/ClassInfo.java
@@ -852,6 +852,9 @@
     TagInfo.makeHDF(data, base + ".shortDescr", this.firstSentenceTags());
     TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
     data.setValue(base + ".since", getSince());
+    if (isDeprecated()) {
+      data.setValue(base + ".deprecatedsince", getDeprecatedSince());
+    }
     setFederatedReferences(data, base);
   }
 
@@ -895,6 +898,9 @@
       data.setValue("class.kind", kind);
     }
     data.setValue("class.since", getSince());
+    if (isDeprecated()) {
+      data.setValue("class.deprecatedsince", getDeprecatedSince());
+    }
     setFederatedReferences(data, "class");
 
     // the containing package -- note that this can be passed to type_link,
diff --git a/src/com/google/doclava/DocInfo.java b/src/com/google/doclava/DocInfo.java
index 5e05c3f..935bbda 100644
--- a/src/com/google/doclava/DocInfo.java
+++ b/src/com/google/doclava/DocInfo.java
@@ -85,6 +85,14 @@
     return mSince;
   }
   
+  public void setDeprecatedSince(String since) {
+    mDeprecatedSince = since;
+  }
+
+  public String getDeprecatedSince() {
+    return mDeprecatedSince;
+  }
+
   public final void addFederatedReference(FederatedSite source) {
     mFederatedReferences.add(source);
   }
@@ -106,5 +114,6 @@
   Comment mComment;
   SourcePositionInfo mPosition;
   private String mSince;
+  private String mDeprecatedSince;
   private Set<FederatedSite> mFederatedReferences = new LinkedHashSet<FederatedSite>();
 }
diff --git a/src/com/google/doclava/FieldInfo.java b/src/com/google/doclava/FieldInfo.java
index 0b0b6c4..0200b95 100644
--- a/src/com/google/doclava/FieldInfo.java
+++ b/src/com/google/doclava/FieldInfo.java
@@ -326,6 +326,9 @@
     TagInfo.makeHDF(data, base + ".deprecated", comment().deprecatedTags());
     TagInfo.makeHDF(data, base + ".seeAlso", comment().seeTags());
     data.setValue(base + ".since", getSince());
+    if (isDeprecated()) {
+      data.setValue(base + ".deprecatedsince", getDeprecatedSince());
+    }
     data.setValue(base + ".final", isFinal() ? "final" : "");
     data.setValue(base + ".static", isStatic() ? "static" : "");
     if (isPublic()) {
diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java
index b7cc5fc..db5e0cf 100644
--- a/src/com/google/doclava/MethodInfo.java
+++ b/src/com/google/doclava/MethodInfo.java
@@ -557,6 +557,9 @@
     TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
     TagInfo.makeHDF(data, base + ".seeAlso", seeTags());
     data.setValue(base + ".since", getSince());
+    if (isDeprecated()) {
+      data.setValue(base + ".deprecatedsince", getDeprecatedSince());
+    }
     ParamTagInfo.makeHDF(data, base + ".paramTags", paramTags());
     AttrTagInfo.makeReferenceHDF(data, base + ".attrRefs", comment().attrTags());
     ThrowsTagInfo.makeHDF(data, base + ".throws", throwsTags());
diff --git a/src/com/google/doclava/SinceTagger.java b/src/com/google/doclava/SinceTagger.java
index e324e95..4cf8911 100644
--- a/src/com/google/doclava/SinceTagger.java
+++ b/src/com/google/doclava/SinceTagger.java
@@ -118,7 +118,7 @@
       }
 
       versionPackage(versionName, classDoc.containingPackage());
-      versionClass(versionName, classDoc);
+      versionClass(versionName, classSpec, classDoc);
       versionConstructors(versionName, classSpec, classDoc);
       versionFields(versionName, classSpec, classDoc);
       versionMethods(versionName, classSpec, classDoc);
@@ -137,10 +137,17 @@
   /**
    * Applies version information to {@code doc} where not already present.
    */
-  private void versionClass(String versionName, ClassInfo doc) {
+  private void versionClass(String versionName, ClassInfo spec, ClassInfo doc) {
     if (doc.getSince() == null) {
       doc.setSince(versionName);
     }
+
+    // Set deprecated version
+    if (doc.isDeprecated() && doc.getDeprecatedSince() == null) {
+      if (spec.isDeprecated()) {
+        doc.setDeprecatedSince(versionName);
+      }
+    }
   }
 
   /**
@@ -152,6 +159,17 @@
           && spec.hasConstructor(constructor)) {
         constructor.setSince(versionName);
       }
+
+      // Set deprecated version
+      if (constructor.isDeprecated() && constructor.getDeprecatedSince() == null) {
+        // Find matching field from API spec
+        if (spec.allConstructorsMap().containsKey(constructor.getHashableName())) {
+          MethodInfo specConstructor = spec.allConstructorsMap().get(constructor.getHashableName());
+          if (specConstructor.isDeprecated()) {
+            constructor.setDeprecatedSince(versionName);
+          }
+        }
+      }
     }
   }
 
@@ -163,6 +181,17 @@
       if (field.getSince() == null && spec.allFields().containsKey(field.name())) {
         field.setSince(versionName);
       }
+
+      // Set deprecated version
+      if (field.isDeprecated() && field.getDeprecatedSince() == null) {
+        // Find matching field from API spec
+        if (spec.allFields().containsKey(field.name())) {
+          FieldInfo specField = spec.allFields().get(field.name());
+          if (specField.isDeprecated()) {
+            field.setDeprecatedSince(versionName);
+          }
+        }
+      }
     }
   }
 
@@ -171,6 +200,18 @@
    */
   private void versionMethods(String versionName, ClassInfo spec, ClassInfo doc) {
     for (MethodInfo method : doc.methods()) {
+
+      // Set deprecated version
+      if (method.isDeprecated() && method.getDeprecatedSince() == null) {
+        // Find matching method from API spec
+        if (spec.allMethods().containsKey(method.getHashableName())) {
+          MethodInfo specMethod = spec.allMethods().get(method.getHashableName());
+          if (specMethod.isDeprecated()) {
+            method.setDeprecatedSince(versionName);
+          }
+        }
+      }
+
       if (method.getSince() != null) {
         continue;
       }