Make ResourceLoader.loadXmlResourceParser() take a resource id rather than a ResName.

Move resolveResource() down from ShadowAssetManager to ResourceLoader, split up the name / value pair and delete the holder class.
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResourceLoader.java b/robolectric-resources/src/main/java/org/robolectric/res/ResourceLoader.java
index c904c25..2d5511d 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResourceLoader.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/ResourceLoader.java
@@ -23,6 +23,11 @@
 
   public abstract XmlBlock getXml(ResName resName, String qualifiers);
 
+  public XmlBlock getXml(int resId, String qualifiers) {
+    ResName resName = resolveResName(resId, qualifiers);
+    return resName != null ? getXml(resName, qualifiers) : null;
+  }
+
   public abstract DrawableNode getDrawableNode(ResName resName, String qualifiers);
 
   public DrawableNode getDrawableNode(int resId, String qualifiers) {
@@ -38,4 +43,41 @@
   public abstract ResourceIndex getResourceIndex();
 
   public abstract boolean providesFor(String namespace);
+
+  private ResName resolveResName(int resId, String qualifiers) {
+    TypedResource value = getValue(resId, qualifiers);
+    return resolveResource(value, qualifiers, resId);
+  }
+
+  private ResName resolveResource(TypedResource value, String qualifiers, int resId) {
+    ResName resName = getResourceIndex().getResName(resId);
+    while (value != null && value.isReference()) {
+      String s = value.asString();
+      if (s.equals("@null") || s.equals("@empty")) {
+        value = null;
+      } else {
+        String refStr = s.substring(1).replace("+", "");
+        resName = ResName.qualifyResName(refStr, resName);
+        value = getValue(resName, qualifiers);
+      }
+    }
+
+    return resName;
+  }
+
+  public TypedResource resolveResourceValue(TypedResource value, String qualifiers, int resId) {
+    ResName resName = getResourceIndex().getResName(resId);
+    while (value != null && value.isReference()) {
+      String s = value.asString();
+      if (s.equals("@null") || s.equals("@empty")) {
+        value = null;
+      } else {
+        String refStr = s.substring(1).replace("+", "");
+        resName = ResName.qualifyResName(refStr, resName);
+        value = getValue(resName, qualifiers);
+      }
+    }
+
+    return value;
+  }
 }
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/TypedResource.java b/robolectric-resources/src/main/java/org/robolectric/res/TypedResource.java
index 6546a9e..39c019e 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/TypedResource.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/TypedResource.java
@@ -25,6 +25,15 @@
     return false;
   }
 
+  public boolean isReference() {
+    Object data = getData();
+    if (data instanceof String) {
+      String s = (String) data;
+      return !s.isEmpty() && s.charAt(0) == '@';
+    }
+    return false;
+  }
+
   @Override public String toString() {
     return getClass().getSimpleName() + "{" +
         "data=" + data +
diff --git a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResources.java b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResources.java
index 30f8fb5..3fd2bde 100644
--- a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResources.java
+++ b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResources.java
@@ -166,14 +166,13 @@
   }
 
   @HiddenApi @Implementation
-  public XmlResourceParser loadXmlResourceParser(int id, String type) throws Resources.NotFoundException {
+  public XmlResourceParser loadXmlResourceParser(int resId, String type) throws Resources.NotFoundException {
     ShadowAssetManager shadowAssetManager = shadowOf(realResources.getAssets());
-    ResName resName = shadowAssetManager.resolveResName(id);
-    XmlBlock block = shadowAssetManager.getResourceLoader().getXml(resName, RuntimeEnvironment.getQualifiers());
+    XmlBlock block = shadowAssetManager.getResourceLoader().getXml(resId, RuntimeEnvironment.getQualifiers());
     if (block == null) {
       throw new Resources.NotFoundException();
     }
-    return ResourceParser.from(block, resName.packageName, shadowAssetManager.getResourceLoader());
+    return ResourceParser.from(block, shadowAssetManager.getResourcePackageName(resId), shadowAssetManager.getResourceLoader());
   }
 
   @HiddenApi @Implementation
diff --git a/robolectric-shadows/shadows-core/src/main/resources/org/robolectric/shadows/ShadowAssetManager.java.vm b/robolectric-shadows/shadows-core/src/main/resources/org/robolectric/shadows/ShadowAssetManager.java.vm
index d849f38..98d4cf5 100644
--- a/robolectric-shadows/shadows-core/src/main/resources/org/robolectric/shadows/ShadowAssetManager.java.vm
+++ b/robolectric-shadows/shadows-core/src/main/resources/org/robolectric/shadows/ShadowAssetManager.java.vm
@@ -384,49 +384,7 @@
   }
 
   TypedResource resolve(TypedResource value, String qualifiers, int resId) {
-    return resolveResource(value, qualifiers, resId).value;
-  }
-
-  private ResName resolveResName(int resId, String qualifiers) {
-    TypedResource value = resourceLoader.getValue(resId, qualifiers);
-    return resolveResource(value, qualifiers, resId).resName;
-  }
-
-  private Resource resolveResource(TypedResource value, String qualifiers, int resId) {
-    ResName resName = resourceLoader.getResourceIndex().getResName(resId);
-    while (isReference(value)) {
-      String s = value.asString();
-      if (s.equals("@null") || s.equals("@empty")) {
-        value = null;
-      } else {
-        String refStr = s.substring(1).replace("+", "");
-        resName = ResName.qualifyResName(refStr, resName);
-        value = resourceLoader.getValue(resName, qualifiers);
-      }
-    }
-
-    return new Resource(value, resName);
-  }
-
-  private boolean isReference(TypedResource value) {
-    if (value != null) {
-      Object data = value.getData();
-      if (data instanceof String) {
-        String s = (String) data;
-        return !s.isEmpty() && s.charAt(0) == '@';
-      }
-    }
-    return false;
-  }
-
-  private static class Resource {
-    public final ResName resName;
-    public final TypedResource<?> value;
-
-    public Resource(TypedResource<?> value, ResName resName) {
-      this.value = value;
-      this.resName = resName;
-    }
+    return resourceLoader.resolveResourceValue(value, qualifiers, resId);
   }
 
   static class StyleResolver implements Style {
@@ -784,11 +742,6 @@
     return checkResName(id, resName);
   }
 
-  @NotNull ResName resolveResName(int id) {
-    ResName resName = resolveResName(id, RuntimeEnvironment.getQualifiers());
-    return checkResName(id, resName);
-  }
-
   private ResName checkResName(int id, ResName resName) {
     if (resName == null) {
       throw new Resources.NotFoundException("Unable to find resource ID #0x" + Integer.toHexString(id));