Make sure elements are sorted by name when building an annotation in smali
diff --git a/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/AnnotationTests.smali b/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/AnnotationTests.smali
index 80e6643..711c34e 100644
--- a/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/AnnotationTests.smali
+++ b/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/AnnotationTests.smali
@@ -12,13 +12,19 @@
     stringValue = "Class Annotation Test"
 .end annotation
 
-
 .field public testField:I
     .annotation runtime LTestAnnotationClass;
         stringValue = "Field Annotation Test"
     .end annotation
 .end field
 
+.field public testAnnotationValuesOutOfOrder:I
+    .annotation runtime LTestAnnotationClass;
+        stringValue = "stringValue Value"
+        anotherStringValue = "anotherStringValue Value"
+    .end annotation
+.end field
+
 .method public testClassAnnotation()V
     .registers 2
 
@@ -71,6 +77,41 @@
     return-void
 .end method
 
+.method public testAnnotationValuesOutOfOrder()V
+    .registers 5
+
+    .annotation runtime Lorg/junit/Test;
+    .end annotation
+
+    const-class v0, LAnnotationTests;
+    const-class v1, LTestAnnotationClass;
+    const-string v2, "testAnnotationValuesOutOfOrder"
+
+    invoke-virtual {v0, v2}, Ljava/lang/Class;->getField(Ljava/lang/String;)Ljava/lang/reflect/Field;
+    move-result-object v3
+
+    invoke-virtual {v3, v1}, Ljava/lang/reflect/Field;->getAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
+    move-result-object v0
+
+    check-cast v0, LTestAnnotationClass;
+
+    invoke-interface {v0}, LTestAnnotationClass;->stringValue()Ljava/lang/String;
+    move-result-object v4
+
+    const-string v1, "stringValue Value"
+
+    invoke-static {v4, v1}, Lorg/junit/Assert;->assertEquals(Ljava/lang/Object;Ljava/lang/Object;)V
+
+    invoke-interface {v0}, LTestAnnotationClass;->anotherStringValue()Ljava/lang/String;
+    move-result-object v4
+
+    const-string v1, "anotherStringValue Value"
+
+    invoke-static {v4, v1}, Lorg/junit/Assert;->assertEquals(Ljava/lang/Object;Ljava/lang/Object;)V
+
+    return-void
+.end method
+
 .method public testMethodAnnotation()V
     .registers 4
 
diff --git a/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/TestAnnotationClass.smali b/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/TestAnnotationClass.smali
index eb2b245..fe1e823 100644
--- a/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/TestAnnotationClass.smali
+++ b/smali-integration-tests/src/test/smali/junit-tests/AnnotationTests/TestAnnotationClass.smali
@@ -2,11 +2,15 @@
 .super Ljava/lang/Object;
 .implements Ljava/lang/annotation/Annotation;
 
+.method public abstract anotherStringValue()Ljava/lang/String;
+.end method
+
 .method public abstract stringValue()Ljava/lang/String;
 .end method
 
 .annotation system Ldalvik/annotation/AnnotationDefault;
     value = .subannotation LAnnotationWithValues;
+                anotherStringValue = "Another String Value"
                 stringValue = "Test Annotation String Value"
             .end subannotation
 .end annotation
\ No newline at end of file
diff --git a/smali/build.gradle b/smali/build.gradle
index a60056f..d5f54ab 100644
--- a/smali/build.gradle
+++ b/smali/build.gradle
@@ -69,6 +69,7 @@
     compile project(':dexlib')
     compile 'org.antlr:antlr-runtime:3.2'
     compile 'commons-cli:commons-cli:1.2'
+    compile 'com.google.guava:guava:13.0.1'
 
     testCompile 'junit:junit:4.6'
 
diff --git a/smali/src/main/antlr3/smaliTreeWalker.g b/smali/src/main/antlr3/smaliTreeWalker.g
index fb14242..2fdf715 100644
--- a/smali/src/main/antlr3/smaliTreeWalker.g
+++ b/smali/src/main/antlr3/smaliTreeWalker.g
@@ -36,6 +36,7 @@
 @header {
 package org.jf.smali;
 
+import com.google.common.collect.ImmutableSortedMap;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.regex.*;
@@ -1616,23 +1617,26 @@
     };
 
 subannotation returns[TypeIdItem annotationType, StringIdItem[\] elementNames, EncodedValue[\] elementValues]
-  : {ArrayList<StringIdItem> elementNamesList = new ArrayList<StringIdItem>();
-    ArrayList<EncodedValue> elementValuesList = new ArrayList<EncodedValue>();}
+  : {ImmutableSortedMap.Builder<StringIdItem, EncodedValue> elementBuilder =
+        ImmutableSortedMap.<StringIdItem, EncodedValue>naturalOrder();}
     ^(I_SUBANNOTATION
         class_type_descriptor
         (annotation_element
         {
-          elementNamesList.add($annotation_element.elementName);
-          elementValuesList.add($annotation_element.elementValue);
+          elementBuilder.put($annotation_element.elementName, $annotation_element.elementValue);
         }
         )*
      )
     {
+      ImmutableSortedMap<StringIdItem, EncodedValue> elementMap = elementBuilder.build();
+
       $annotationType = $class_type_descriptor.type;
-      $elementNames = new StringIdItem[elementNamesList.size()];
-      elementNamesList.toArray($elementNames);
-      $elementValues = new EncodedValue[elementValuesList.size()];
-      elementValuesList.toArray($elementValues);
+
+      $elementNames = new StringIdItem[elementMap.size()];
+      $elementValues = new EncodedValue[elementMap.size()];
+
+      elementMap.keySet().toArray($elementNames);
+      elementMap.values().toArray($elementValues);
     };
 
 field_literal returns[FieldIdItem value]