Merge "Don't duplicate annotation set ref lists when merging."
diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java
index b7677cf..319153f 100644
--- a/dx/src/com/android/dx/merge/DexMerger.java
+++ b/dx/src/com/android/dx/merge/DexMerger.java
@@ -604,6 +604,8 @@
     private void unionAnnotationSetsAndDirectories() {
         transformAnnotationSets(dexA, aIndexMap);
         transformAnnotationSets(dexB, bIndexMap);
+        transformAnnotationSetRefLists(dexA, aIndexMap);
+        transformAnnotationSetRefLists(dexB, bIndexMap);
         transformAnnotationDirectories(dexA, aIndexMap);
         transformAnnotationDirectories(dexB, bIndexMap);
         transformStaticValues(dexA, aIndexMap);
@@ -620,12 +622,22 @@
         }
     }
 
+    private void transformAnnotationSetRefLists(DexBuffer in, IndexMap indexMap) {
+        TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists;
+        if (section.exists()) {
+            DexBuffer.Section setIn = in.open(section.off);
+            for (int i = 0; i < section.size; i++) {
+                transformAnnotationSetRefList(indexMap, setIn);
+            }
+        }
+    }
+
     private void transformAnnotationDirectories(DexBuffer in, IndexMap indexMap) {
         TableOfContents.Section section = in.getTableOfContents().annotationsDirectories;
         if (section.exists()) {
             DexBuffer.Section directoryIn = in.open(section.off);
             for (int i = 0; i < section.size; i++) {
-                transformAnnotationDirectory(in, directoryIn, indexMap);
+                transformAnnotationDirectory(directoryIn, indexMap);
             }
         }
     }
@@ -674,7 +686,7 @@
      * Transform all annotations on a class.
      */
     private void transformAnnotationDirectory(
-            DexBuffer in, DexBuffer.Section directoryIn, IndexMap indexMap) {
+            DexBuffer.Section directoryIn, IndexMap indexMap) {
         contentsOut.annotationsDirectories.size++;
         annotationsDirectoryOut.assertFourByteAligned();
         indexMap.putAnnotationDirectoryOffset(
@@ -710,22 +722,12 @@
         }
 
         for (int i = 0; i < parameterListSize; i++) {
-            contentsOut.annotationSetRefLists.size++;
-            annotationSetRefListOut.assertFourByteAligned();
-
             // method index
             annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));
 
             // annotations offset
-            annotationsDirectoryOut.writeInt(annotationSetRefListOut.getPosition());
-            DexBuffer.Section refListIn = in.open(directoryIn.readInt());
-
-            // parameters
-            int parameterCount = refListIn.readInt();
-            annotationSetRefListOut.writeInt(parameterCount);
-            for (int p = 0; p < parameterCount; p++) {
-                annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));
-            }
+            annotationsDirectoryOut.writeInt(
+                    indexMap.adjustAnnotationSetRefList(directoryIn.readInt()));
         }
     }
 
@@ -745,6 +747,22 @@
         }
     }
 
+    /**
+     * Transform all annotation set ref lists.
+     */
+    private void transformAnnotationSetRefList(IndexMap indexMap, DexBuffer.Section refListIn) {
+        contentsOut.annotationSetRefLists.size++;
+        annotationSetRefListOut.assertFourByteAligned();
+        indexMap.putAnnotationSetRefListOffset(
+                refListIn.getPosition(), annotationSetRefListOut.getPosition());
+
+        int parameterCount = refListIn.readInt();
+        annotationSetRefListOut.writeInt(parameterCount);
+        for (int p = 0; p < parameterCount; p++) {
+            annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));
+        }
+    }
+
     private void transformClassData(DexBuffer in, ClassData classData, IndexMap indexMap) {
         contentsOut.classDatas.size++;
 
diff --git a/dx/src/com/android/dx/merge/IndexMap.java b/dx/src/com/android/dx/merge/IndexMap.java
index a5c9584..89d2dd6 100644
--- a/dx/src/com/android/dx/merge/IndexMap.java
+++ b/dx/src/com/android/dx/merge/IndexMap.java
@@ -47,6 +47,7 @@
     private final HashMap<Integer, Integer> typeListOffsets;
     private final HashMap<Integer, Integer> annotationOffsets;
     private final HashMap<Integer, Integer> annotationSetOffsets;
+    private final HashMap<Integer, Integer> annotationSetRefListOffsets;
     private final HashMap<Integer, Integer> annotationDirectoryOffsets;
     private final HashMap<Integer, Integer> staticValuesOffsets;
 
@@ -60,6 +61,7 @@
         this.typeListOffsets = new HashMap<Integer, Integer>();
         this.annotationOffsets = new HashMap<Integer, Integer>();
         this.annotationSetOffsets = new HashMap<Integer, Integer>();
+        this.annotationSetRefListOffsets = new HashMap<Integer, Integer>();
         this.annotationDirectoryOffsets = new HashMap<Integer, Integer>();
         this.staticValuesOffsets = new HashMap<Integer, Integer>();
 
@@ -94,6 +96,13 @@
         annotationSetOffsets.put(oldOffset, newOffset);
     }
 
+    public void putAnnotationSetRefListOffset(int oldOffset, int newOffset) {
+        if (oldOffset <= 0 || newOffset <= 0) {
+            throw new IllegalArgumentException();
+        }
+        annotationSetRefListOffsets.put(oldOffset, newOffset);
+    }
+
     public void putAnnotationDirectoryOffset(int oldOffset, int newOffset) {
         if (oldOffset <= 0 || newOffset <= 0) {
             throw new IllegalArgumentException();
@@ -151,6 +160,10 @@
         return annotationSetOffsets.get(annotationSetOffset);
     }
 
+    public int adjustAnnotationSetRefList(int annotationSetRefListOffset) {
+        return annotationSetRefListOffsets.get(annotationSetRefListOffset);
+    }
+
     public int adjustAnnotationDirectory(int annotationDirectoryOffset) {
         return annotationDirectoryOffsets.get(annotationDirectoryOffset);
     }