* Extract ResourceTable interface, ResourceTable becomes PackageResourceTable - it is a resouce table for a single package only, e.g: "android" / 0x01
* Remove EmptyResourceProvider - we can now just use a PackageResourceTable without any resources loaded.
* RoutingResourceProvider becomes RoutingResourceTable - It is a composite ResourceTable made up of PackageResourceTables.
* Remove ResourceProvider abstract class.
diff --git a/robolectric-resources/src/main/java/org/robolectric/manifest/AndroidManifest.java b/robolectric-resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
index a709558..bbe6e3b 100644
--- a/robolectric-resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
+++ b/robolectric-resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
@@ -17,8 +17,8 @@
 import com.google.common.base.Preconditions;
 import org.jetbrains.annotations.Nullable;
 import org.robolectric.res.FsFile;
-import org.robolectric.res.ResourceProvider;
 import org.robolectric.res.ResourcePath;
+import org.robolectric.res.ResourceTable;
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -409,22 +409,22 @@
   /***
    * Allows RobolectricPackageManager to provide
    * a resource index for initialising the resource attributes in all the metadata elements
-   * @param resLoader used for getting resource IDs from string identifiers
+   * @param resourceTable used for getting resource IDs from string identifiers
    */
-  public void initMetaData(ResourceProvider resLoader) {
+  public void initMetaData(ResourceTable resourceTable) {
     if (!packageNameIsOverridden()) {
       // packageName needs to be resolved
       parseAndroidManifest();
     }
 
     if (applicationMetaData != null) {
-      applicationMetaData.init(resLoader, packageName);
+      applicationMetaData.init(resourceTable, packageName);
     }
     for (PackageItemData receiver : receivers) {
-      receiver.getMetaData().init(resLoader, packageName);
+      receiver.getMetaData().init(resourceTable, packageName);
     }
     for (ServiceData service : serviceDatas.values()) {
-      service.getMetaData().init(resLoader, packageName);
+      service.getMetaData().init(resourceTable, packageName);
     }
   }
 
diff --git a/robolectric-resources/src/main/java/org/robolectric/manifest/MetaData.java b/robolectric-resources/src/main/java/org/robolectric/manifest/MetaData.java
index 4cadb55..cc7e52c 100644
--- a/robolectric-resources/src/main/java/org/robolectric/manifest/MetaData.java
+++ b/robolectric-resources/src/main/java/org/robolectric/manifest/MetaData.java
@@ -2,7 +2,7 @@
 
 import android.content.res.Resources;
 import org.robolectric.res.ResName;
-import org.robolectric.res.ResourceProvider;
+import org.robolectric.res.ResourceTable;
 import org.robolectric.res.TypedResource;
 import org.robolectric.shadows.ResourceHelper;
 import org.w3c.dom.NamedNodeMap;
@@ -34,7 +34,7 @@
     }
   }
 
-  public void init(ResourceProvider resourceProvider, String packageName) {
+  public void init(ResourceTable resourceTable, String packageName) {
     if (!initialised) {
       for (Map.Entry<String,VALUE_TYPE> entry : typeMap.entrySet()) {
         String value = valueMap.get(entry.getKey()).toString();
@@ -44,11 +44,11 @@
           switch (entry.getValue()) {
             case RESOURCE:
               // Was provided by resource attribute, store resource ID
-              valueMap.put(entry.getKey(), resourceProvider.getResourceId(resName));
+              valueMap.put(entry.getKey(), resourceTable.getResourceId(resName));
               break;
             case VALUE:
               // Was provided by value attribute, need to inferFromValue it
-              TypedResource<?> typedRes = resourceProvider.getValue(resName, "");
+              TypedResource<?> typedRes = resourceTable.getValue(resName, "");
               // The typed resource's data is always a String, so need to inferFromValue the value.
               if (typedRes == null) {
                 throw new Resources.NotFoundException(resName.getFullyQualifiedName());
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/EmptyResourceProvider.java b/robolectric-resources/src/main/java/org/robolectric/res/EmptyResourceProvider.java
deleted file mode 100644
index 6f33c23..0000000
--- a/robolectric-resources/src/main/java/org/robolectric/res/EmptyResourceProvider.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.robolectric.res;
-
-import org.jetbrains.annotations.NotNull;
-import org.robolectric.res.builder.XmlBlock;
-
-import java.io.InputStream;
-
-/**
- * A resource loader with no resources.
- */
-public class EmptyResourceProvider extends ResourceProvider {
-
-  private final ResourceTable resourceTable;
-
-  public EmptyResourceProvider(ResourceTable resourceTable) {
-    this.resourceTable = resourceTable;
-  }
-
-  @Override
-  public void receive(Visitor visitor) {
-  }
-
-  @Override
-  public TypedResource getValue(@NotNull ResName resName, String qualifiers) {
-    return null;
-  }
-
-  @Override
-  public TypedResource getValue(int resId, String qualifiers) {
-    return null;
-  }
-
-  @Override
-  public XmlBlock getXml(ResName resName, String qualifiers) {
-    return null;
-  }
-
-  @Override
-  public InputStream getRawValue(ResName resName, String qualifiers) {
-    return resourceTable.getRawValue(resName, qualifiers);
-  }
-
-  @Override
-  public Integer getResourceId(ResName resName) {
-    return resourceTable.getResourceId(resName);
-  }
-
-  @Override
-  public ResName getResName(int resourceId) {
-    return resourceTable.getResName(resourceId);
-  }
-
-}
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/PackageResourceTable.java b/robolectric-resources/src/main/java/org/robolectric/res/PackageResourceTable.java
new file mode 100644
index 0000000..ca81575
--- /dev/null
+++ b/robolectric-resources/src/main/java/org/robolectric/res/PackageResourceTable.java
@@ -0,0 +1,86 @@
+package org.robolectric.res;
+
+import org.jetbrains.annotations.NotNull;
+import org.robolectric.res.builder.XmlBlock;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A {@link ResourceTable} for a single package, e.g: "android" / ox01
+ */
+public class PackageResourceTable implements ResourceTable {
+  final ResBunch data = new ResBunch();
+  final ResBundle xmlDocuments = new ResBundle();
+  final ResBundle rawResources = new ResBundle();
+  private final ResourceIndex resourceIndex;
+
+  PackageResourceTable(String packageName) {
+    this.resourceIndex = new ResourceIndex(packageName);;
+  }
+
+  public String getPackageName() {
+    return resourceIndex.getPackageName();
+  }
+
+  @Override
+  public Integer getResourceId(ResName resName) {
+    return resourceIndex.getResourceId(resName);
+  }
+
+  @Override
+  public ResName getResName(int resourceId) {
+    return resourceIndex.getResName(resourceId);
+  }
+
+  @Override
+  public TypedResource getValue(@NotNull ResName resName, String qualifiers) {
+    return data.get(resName, qualifiers);
+  }
+
+  @Override
+  public TypedResource getValue(int resId, String qualifiers) {
+    return data.get(getResName(resId), qualifiers);
+  }
+
+  public XmlBlock getXml(ResName resName, String qualifiers) {
+    TypedResource typedResource = xmlDocuments.get(resName, qualifiers);
+    return typedResource == null ? null : (XmlBlock) typedResource.getData();
+  }
+
+  public InputStream getRawValue(ResName resName, String qualifiers) {
+    TypedResource typedResource = rawResources.get(resName, qualifiers);
+    FsFile file = typedResource == null ? null : (FsFile) typedResource.getData();
+    try {
+      return file == null ? null : file.getInputStream();
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  public InputStream getRawValue(int resId, String qualifiers) {
+    return getRawValue(getResName(resId), qualifiers);
+  }
+
+  public int getPackageIdentifier() {
+    return resourceIndex.getPackageIdentifier();
+  }
+
+  @Override
+  public void addResource(int resId, String type, String name) {
+    resourceIndex.addResource(resId, type, name);
+  }
+
+  @Override
+  public void receive(Visitor visitor) {
+
+  }
+
+  @Override
+  public boolean hasValue(ResName resName, String qualifiers) {
+    return getValue(resName, qualifiers) != null
+        || getXml(resName, qualifiers) != null
+        || getRawValue(resName, qualifiers) != null;
+  }
+}
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResBunch.java b/robolectric-resources/src/main/java/org/robolectric/res/ResBunch.java
index 6509a77..17053de 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResBunch.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/ResBunch.java
@@ -26,7 +26,7 @@
     return bundle.get(resName, qualifiers);
   }
 
-  void receive(ResourceProvider.Visitor visitor) {
+  void receive(ResourceTable.Visitor visitor) {
     for (ResBundle resBundle : types.values()) {
       resBundle.receive(visitor);
     }
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResBundle.java b/robolectric-resources/src/main/java/org/robolectric/res/ResBundle.java
index c29e300..3f370e9 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResBundle.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/ResBundle.java
@@ -15,7 +15,7 @@
     return valuesMap.pick(resName, qualifiers);
   }
 
-  public void receive(ResourceProvider.Visitor visitor) {
+  public void receive(ResourceTable.Visitor visitor) {
     for (final Map.Entry<ResName, Map<String, TypedResource>> entry : valuesMap.map.entrySet()) {
       visitor.visit(entry.getKey(), entry.getValue().values());
     }
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResourceParser.java b/robolectric-resources/src/main/java/org/robolectric/res/ResourceParser.java
index 0642079..a99e9c7 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResourceParser.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/ResourceParser.java
@@ -3,7 +3,7 @@
 import org.robolectric.util.Logger;
 
 class ResourceParser {
-  static void load(String packageName, ResourcePath resourcePath, ResourceTable resourceTable) {
+  static void load(String packageName, ResourcePath resourcePath, PackageResourceTable resourceTable) {
     if (!resourcePath.hasResources()) {
       Logger.debug("No resources for %s", packageName);
       return;
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResourceProvider.java b/robolectric-resources/src/main/java/org/robolectric/res/ResourceProvider.java
deleted file mode 100644
index 956ab36..0000000
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResourceProvider.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.robolectric.res;
-
-import org.jetbrains.annotations.NotNull;
-import org.robolectric.res.builder.XmlBlock;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-public abstract class ResourceProvider {
-
-  public abstract TypedResource getValue(@NotNull ResName resName, String qualifiers);
-
-  public abstract TypedResource getValue(int resId, String qualifiers);
-
-  public abstract XmlBlock getXml(ResName resName, String qualifiers);
-
-  public abstract InputStream getRawValue(ResName resName, String qualifiers);
-
-  public abstract Integer getResourceId(ResName resName);
-
-  public abstract ResName getResName(int resourceId);
-
-  public InputStream getRawValue(int resId, String qualifiers) {
-    return getRawValue(getResName(resId), qualifiers);
-  }
-
-  public boolean hasValue(ResName resName, String qualifiers) {
-    return getValue(resName, qualifiers) != null
-        || getXml(resName, qualifiers) != null
-        || getRawValue(resName, qualifiers) != null;
-  }
-
-  @NotNull
-  public List<TypedResource> grep(String regex) {
-      return grep(Pattern.compile(regex));
-  }
-
-  @NotNull
-  public List<TypedResource> grep(final Pattern pattern) {
-    final ArrayList<TypedResource> matches = new ArrayList<>();
-    receive(new Visitor<TypedResource>() {
-      @Override
-      public void visit(ResName resName, Iterable<TypedResource> items) {
-        boolean match = pattern.matcher(resName.getFullyQualifiedName()).find();
-        if (!match && resName.type.equals("style")) {
-          for (TypedResource typedResource : items) {
-            TypedResource<StyleData> style = (TypedResource<StyleData>) typedResource;
-            if (style.getData().grep(pattern)) {
-              match = true;
-              break;
-            }
-          }
-        }
-
-        if (match) {
-          for (TypedResource typedResource : items) {
-            matches.add(typedResource);
-          }
-        }
-      }
-    });
-    return matches;
-  }
-
-  public abstract void receive(Visitor visitor);
-
-  public interface Visitor <T> {
-    void visit(ResName key, Iterable<T> items);
-  }
-}
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/ResourceTableFactory.java b/robolectric-resources/src/main/java/org/robolectric/res/ResourceTableFactory.java
index e93ed61..9d41b6a 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/ResourceTableFactory.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/ResourceTableFactory.java
@@ -5,8 +5,8 @@
 
 public class ResourceTableFactory {
 
-  public static ResourceTable newResourceTable(String packageName, ResourcePath... resourcePaths) {
-    ResourceTable resourceTable = new ResourceTable(packageName);
+  public static PackageResourceTable newResourceTable(String packageName, ResourcePath... resourcePaths) {
+    PackageResourceTable resourceTable = new PackageResourceTable(packageName);
 
     for (ResourcePath resourcePath : resourcePaths) {
       if (resourcePath.getRClass() != null) {
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceProvider.java b/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceProvider.java
deleted file mode 100644
index 9897b9b..0000000
--- a/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceProvider.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.robolectric.res;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import org.robolectric.res.builder.XmlBlock;
-
-public class RoutingResourceProvider extends ResourceProvider {
-  private static final ResourceTable EMPTY_RESOURCE_TABLE = ResourceTableFactory.newResourceTable("");
-  private final Map<String, ResourceTable> resourceTables;
-
-  public RoutingResourceProvider(ResourceTable... resourceTables) {
-    this.resourceTables = new HashMap<>();
-
-    for (ResourceTable resourceTable : resourceTables) {
-      this.resourceTables.put(resourceTable.getPackageName(), resourceTable);
-    }
-  }
-
-  @Override public TypedResource getValue(@NotNull ResName resName, String qualifiers) {
-    return pickFor(resName).getValue(resName, qualifiers);
-  }
-
-  @Override
-  public TypedResource getValue(int resId, String qualifiers) {
-    ResName resName = pickFor(resId).getResName(resId);
-    return resName != null ? getValue(resName, qualifiers) : null;
-  }
-
-  @Override
-  public XmlBlock getXml(ResName resName, String qualifiers) {
-    return pickFor(resName).getXml(resName, qualifiers);
-  }
-
-  @Override
-  public InputStream getRawValue(ResName resName, String qualifiers) {
-    return pickFor(resName).getRawValue(resName, qualifiers);
-  }
-
-  @Override
-  public Integer getResourceId(ResName resName) {
-    return pickFor(resName).getResourceId(resName);
-  }
-
-  @Override
-  public ResName getResName(int resourceId) {
-    return pickFor(resourceId).getResName(resourceId);
-  }
-
-  @Override
-  public void receive(Visitor visitor) {
-    for (ResourceTable resourceTable : resourceTables.values()) {
-      resourceTable.data.receive(visitor);
-    }
-  }
-
-  private ResourceTable pickFor(int resId) {
-    for (ResourceTable resourceTable : resourceTables.values()) {
-      if (resourceTable.getPackageIdentifier() == ResourceIds.getPackageIdentifier(resId)) {
-        return resourceTable;
-      }
-    }
-    return EMPTY_RESOURCE_TABLE;
-  }
-
-  private ResourceTable pickFor(ResName resName) {
-    if (resName == null) return EMPTY_RESOURCE_TABLE;
-    return pickFor(resName.packageName);
-  }
-
-  private ResourceTable pickFor(String namespace) {
-    if (namespace.equals("android.internal")) {
-      return EMPTY_RESOURCE_TABLE;
-    }
-    ResourceTable resourceTable = resourceTables.get(namespace);
-    if (resourceTable == null) {
-      resourceTable = whichProvidesFor(namespace);
-      return (resourceTable != null) ? resourceTable : EMPTY_RESOURCE_TABLE;
-    }
-    return resourceTable;
-  }
-
-  private ResourceTable whichProvidesFor(String namespace) {
-    for (ResourceTable resourceTable : resourceTables.values()) {
-      if (resourceTable.getPackageName().equals(namespace)) {
-        return resourceTable;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    return resourceTables.keySet().toString();
-  }
-}
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceTable.java b/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceTable.java
new file mode 100644
index 0000000..00b5790
--- /dev/null
+++ b/robolectric-resources/src/main/java/org/robolectric/res/RoutingResourceTable.java
@@ -0,0 +1,143 @@
+package org.robolectric.res;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.robolectric.res.builder.XmlBlock;
+
+public class RoutingResourceTable implements ResourceTable {
+  private static final PackageResourceTable EMPTY_RESOURCE_TABLE = ResourceTableFactory.newResourceTable("");
+  private final Map<String, PackageResourceTable> resourceTables;
+
+  public RoutingResourceTable(PackageResourceTable... resourceTables) {
+    this.resourceTables = new HashMap<>();
+
+    for (PackageResourceTable resourceTable : resourceTables) {
+      this.resourceTables.put(resourceTable.getPackageName(), resourceTable);
+    }
+  }
+
+  public InputStream getRawValue(int resId, String qualifiers) {
+    return getRawValue(getResName(resId), qualifiers);
+  }
+
+  public boolean hasValue(ResName resName, String qualifiers) {
+    return pickFor(resName).hasValue(resName, qualifiers);
+  }
+
+  @NotNull
+  public List<TypedResource> grep(String regex) {
+    return grep(Pattern.compile(regex));
+  }
+
+  @NotNull
+  public List<TypedResource> grep(final Pattern pattern) {
+    final ArrayList<TypedResource> matches = new ArrayList<>();
+    receive(new Visitor<TypedResource>() {
+      @Override
+      public void visit(ResName resName, Iterable<TypedResource> items) {
+        boolean match = pattern.matcher(resName.getFullyQualifiedName()).find();
+        if (!match && resName.type.equals("style")) {
+          for (TypedResource typedResource : items) {
+            TypedResource<StyleData> style = (TypedResource<StyleData>) typedResource;
+            if (style.getData().grep(pattern)) {
+              match = true;
+              break;
+            }
+          }
+        }
+
+        if (match) {
+          for (TypedResource typedResource : items) {
+            matches.add(typedResource);
+          }
+        }
+      }
+    });
+    return matches;
+  }
+
+  @Override public TypedResource getValue(@NotNull ResName resName, String qualifiers) {
+    return pickFor(resName).getValue(resName, qualifiers);
+  }
+
+  @Override
+  public void addResource(int resId, String type, String name) {
+    pickFor(resId).addResource(resId, type, name);
+  }
+
+  public TypedResource getValue(int resId, String qualifiers) {
+    ResName resName = pickFor(resId).getResName(resId);
+    return resName != null ? getValue(resName, qualifiers) : null;
+  }
+
+  public XmlBlock getXml(ResName resName, String qualifiers) {
+    return pickFor(resName).getXml(resName, qualifiers);
+  }
+
+  public InputStream getRawValue(ResName resName, String qualifiers) {
+    return pickFor(resName).getRawValue(resName, qualifiers);
+  }
+
+  @Override
+  public Integer getResourceId(ResName resName) {
+    return pickFor(resName).getResourceId(resName);
+  }
+
+  @Override
+  public ResName getResName(int resourceId) {
+    return pickFor(resourceId).getResName(resourceId);
+  }
+
+  public void receive(Visitor visitor) {
+    for (PackageResourceTable resourceTable : resourceTables.values()) {
+      resourceTable.data.receive(visitor);
+    }
+  }
+
+  private ResourceTable pickFor(int resId) {
+    for (PackageResourceTable resourceTable : resourceTables.values()) {
+      if (resourceTable.getPackageIdentifier() == ResourceIds.getPackageIdentifier(resId)) {
+        return resourceTable;
+      }
+    }
+    return EMPTY_RESOURCE_TABLE;
+  }
+
+  private PackageResourceTable pickFor(ResName resName) {
+    if (resName == null) return EMPTY_RESOURCE_TABLE;
+    return pickFor(resName.packageName);
+  }
+
+  private PackageResourceTable pickFor(String namespace) {
+    if (namespace.equals("android.internal")) {
+      return EMPTY_RESOURCE_TABLE;
+    }
+    PackageResourceTable resourceTable = resourceTables.get(namespace);
+    if (resourceTable == null) {
+      resourceTable = whichProvidesFor(namespace);
+      return (resourceTable != null) ? resourceTable : EMPTY_RESOURCE_TABLE;
+    }
+    return resourceTable;
+  }
+
+  private PackageResourceTable whichProvidesFor(String namespace) {
+    for (PackageResourceTable resourceTable : resourceTables.values()) {
+      if (resourceTable.getPackageName().equals(namespace)) {
+        return resourceTable;
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    return resourceTables.keySet().toString();
+  }
+}
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/StyleResolver.java b/robolectric-resources/src/main/java/org/robolectric/res/StyleResolver.java
index 0eace81..73d0013 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/StyleResolver.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/StyleResolver.java
@@ -7,16 +7,16 @@
 
 public class StyleResolver implements Style {
   private final List<StyleData> styles = new ArrayList<>();
-  private final ResourceProvider appResourceProvider;
-  private final ResourceProvider systemResourceProvider;
+  private final ResourceTable appResourceTable;
+  private final ResourceTable systemResourceTable;
   private final Style theme;
   private final ResName myResName;
   private final String qualifiers;
 
-  public StyleResolver(ResourceProvider appResourceProvider, ResourceProvider systemResourceProvider, StyleData styleData,
+  public StyleResolver(ResourceTable appResourceTable, ResourceTable systemResourceTable, StyleData styleData,
                        Style theme, ResName myResName, String qualifiers) {
-    this.appResourceProvider = appResourceProvider;
-    this.systemResourceProvider = systemResourceProvider;
+    this.appResourceTable = appResourceTable;
+    this.systemResourceTable = systemResourceTable;
     this.theme = theme;
     this.myResName = myResName;
     this.qualifiers = qualifiers;
@@ -88,7 +88,7 @@
     styleRef = dereferenceResName(styleRef);
 
     // TODO: Refactor this to a ResourceLoaderChooser
-    ResourceProvider resourceProvider = "android".equals(styleRef.packageName) ? systemResourceProvider : appResourceProvider;
+    ResourceTable resourceProvider = "android".equals(styleRef.packageName) ? systemResourceTable : appResourceTable;
     TypedResource typedResource = resourceProvider.getValue(styleRef, qualifiers);
 
     if (typedResource == null) {
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlBlock.java b/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlBlock.java
index 6d90a4b..8d7742f 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlBlock.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlBlock.java
@@ -1,11 +1,9 @@
 package org.robolectric.res.builder;
 
 import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
 import org.jetbrains.annotations.NotNull;
 import org.robolectric.res.Fs;
 import org.robolectric.res.FsFile;
-import org.robolectric.res.ResourceProvider;
 import org.robolectric.res.XmlBlockLoader;
 import org.w3c.dom.Document;
 
diff --git a/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlResourceParserImpl.java b/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlResourceParserImpl.java
index d2b066c..c9e76be 100644
--- a/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlResourceParserImpl.java
+++ b/robolectric-resources/src/main/java/org/robolectric/res/builder/XmlResourceParserImpl.java
@@ -5,7 +5,7 @@
 import com.android.internal.util.XmlUtils;
 import org.robolectric.res.AttributeResource;
 import org.robolectric.res.ResName;
-import org.robolectric.res.ResourceProvider;
+import org.robolectric.res.ResourceTable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -50,7 +50,7 @@
   private final Document document;
   private final String fileName;
   private final String packageName;
-  private final ResourceProvider resourceProvider;
+  private final ResourceTable resourceTable;
   private final String applicationNamespace;
 
   private Node currentNode;
@@ -61,11 +61,11 @@
   private int mEventType = START_DOCUMENT;
 
   public XmlResourceParserImpl(Document document, String fileName, String packageName,
-                               String applicationPackageName, ResourceProvider resourceProvider) {
+                               String applicationPackageName, ResourceTable resourceTable) {
     this.document = document;
     this.fileName = fileName;
     this.packageName = packageName;
-    this.resourceProvider = resourceProvider;
+    this.resourceTable = resourceTable;
     this.applicationNamespace = AttributeResource.ANDROID_RES_NS_PREFIX + applicationPackageName;
   }
 
@@ -767,7 +767,7 @@
 
     if (AttributeResource.isStyleReference(possiblyQualifiedResourceName)) {
       ResName styleReference = AttributeResource.getStyleReference(possiblyQualifiedResourceName, defaultPackageName, "attr");
-      Integer resourceId = resourceProvider.getResourceId(styleReference);
+      Integer resourceId = resourceTable.getResourceId(styleReference);
       if (resourceId == null) {
         throw new Resources.NotFoundException(styleReference.getFullyQualifiedName());
       }
@@ -776,7 +776,7 @@
 
     if (AttributeResource.isResourceReference(possiblyQualifiedResourceName)) {
       ResName resourceReference = AttributeResource.getResourceReference(possiblyQualifiedResourceName, defaultPackageName, defaultType);
-      Integer resourceId = resourceProvider.getResourceId(resourceReference);
+      Integer resourceId = resourceTable.getResourceId(resourceReference);
       if (resourceId == null) {
         throw new Resources.NotFoundException(resourceReference.getFullyQualifiedName());
       }
@@ -784,7 +784,7 @@
     }
     possiblyQualifiedResourceName = removeLeadingSpecialCharsIfAny(possiblyQualifiedResourceName);
     ResName resName = ResName.qualifyResName(possiblyQualifiedResourceName, defaultPackageName, defaultType);
-    Integer resourceId = resourceProvider.getResourceId(resName);
+    Integer resourceId = resourceTable.getResourceId(resName);
     return resourceId == null ? 0 : resourceId;
   }
 
diff --git a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/fakes/RoboAttributeSet.java b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/fakes/RoboAttributeSet.java
index 34f5855..03d55cc 100644
--- a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/fakes/RoboAttributeSet.java
+++ b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/fakes/RoboAttributeSet.java
@@ -5,7 +5,7 @@
 import com.google.android.collect.Lists;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.res.Attribute;
-import org.robolectric.res.ResourceProvider;
+import org.robolectric.res.ResourceTable;
 import org.robolectric.res.builder.XmlResourceParserImpl;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -37,7 +37,7 @@
    */
   @Deprecated
   public static AttributeSet create(Context context, List<Attribute> attributesList) {
-    return create(context, attributesList, shadowOf(context.getAssets()).getResourceProvider());
+    return create(context, attributesList, shadowOf(context.getAssets()).getResourceTable());
   }
 
   /**
@@ -45,7 +45,7 @@
    * @deprecated Use {@link Robolectric#buildAttributeSet()}
    */
   @Deprecated
-  public static AttributeSet create(Context context, List<Attribute> attributesList, ResourceProvider resourceProvider) {
+  public static AttributeSet create(Context context, List<Attribute> attributesList, ResourceTable resourceTable) {
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     factory.setNamespaceAware(true);
     factory.setIgnoringComments(true);
@@ -64,7 +64,7 @@
       }
       document.appendChild(dummy);
 
-      XmlResourceParserImpl parser = new XmlResourceParserImpl(document, null, context.getPackageName(), context.getPackageName(), resourceProvider);
+      XmlResourceParserImpl parser = new XmlResourceParserImpl(document, null, context.getPackageName(), context.getPackageName(), resourceTable);
       parser.next(); // Root document element
       parser.next(); // "dummy" element
       return parser;
diff --git a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowAssetManager.java b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowAssetManager.java
index 1ce94a5..7cde912 100644
--- a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowAssetManager.java
+++ b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowAssetManager.java
@@ -50,7 +50,7 @@
 
   private static long nextInternalThemeId = 1000;
   private static final Map<Long, NativeTheme> nativeThemes = new HashMap<>();
-  private ResourceProvider resourceProvider;
+  private ResourceTable resourceTable;
 
   class NativeTheme {
     private ThemeStyleSet themeStyleSet;
@@ -92,7 +92,7 @@
       if (attribute.getReferenceResId() != null) {
         resourceId = attribute.getReferenceResId();
       } else {
-        resourceId = resourceProvider.getResourceId(resName);
+        resourceId = resourceTable.getResourceId(resName);
       }
 
       if (resourceId == null) {
@@ -107,7 +107,7 @@
 
       outValue.resourceId = resourceId;
 
-      TypedResource dereferencedRef = resourceProvider.getValue(resName, qualifiers);
+      TypedResource dereferencedRef = resourceTable.getValue(resName, qualifiers);
 
       if (dereferencedRef == null) {
         Logger.strict("couldn't resolve %s from %s", resName.getFullyQualifiedName(), attribute);
@@ -128,7 +128,7 @@
           return;
         } else if (DrawableResourceLoader.isStillHandledHere(resName.type)) {
           // wtf. color and drawable references reference are all kinds of stupid.
-          TypedResource drawableResource = resourceProvider.getValue(resName, qualifiers);
+          TypedResource drawableResource = resourceTable.getValue(resName, qualifiers);
           if (drawableResource == null) {
             throw new Resources.NotFoundException("can't find file for " + resName);
           } else {
@@ -167,7 +167,7 @@
       return;
     }
 
-    TypedResource attrTypeData = resourceProvider.getValue(attribute.resName, qualifiers);
+    TypedResource attrTypeData = resourceTable.getValue(attribute.resName, qualifiers);
     if (attrTypeData != null) {
       AttrData attrData = (AttrData) attrTypeData.getData();
       String format = attrData.getFormat();
@@ -196,15 +196,15 @@
   }
 
   public void __constructor__() {
-    resourceProvider = RuntimeEnvironment.getAppResourceProvider();
+    resourceTable = RuntimeEnvironment.getAppResourceProvider();
   }
 
   public void __constructor__(boolean isSystem) {
-    resourceProvider = isSystem ? RuntimeEnvironment.getSystemResourceProvider() : RuntimeEnvironment.getAppResourceProvider();
+    resourceTable = isSystem ? RuntimeEnvironment.getSystemResourceProvider() : RuntimeEnvironment.getAppResourceProvider();
   }
 
-  public ResourceProvider getResourceProvider() {
-    return resourceProvider;
+  public ResourceTable getResourceTable() {
+    return resourceTable;
   }
 
   @HiddenApi @Implementation
@@ -236,11 +236,11 @@
 
     // If the resource does not exist then return 0, otherwise ResourceIndex.getResourceId() will generate a placeholder.
     if (!ResName.ID_TYPE.equals(resName.type)
-        && !resourceProvider.hasValue(resName, RuntimeEnvironment.getQualifiers())) {
+        && !resourceTable.hasValue(resName, RuntimeEnvironment.getQualifiers())) {
       return 0;
     }
 
-    Integer resourceId = resourceProvider.getResourceId(resName);
+    Integer resourceId = resourceTable.getResourceId(resName);
     return resourceId == null ? 0 : resourceId;
   }
 
@@ -282,7 +282,7 @@
 
   @HiddenApi @Implementation(minSdk = LOLLIPOP)
   public boolean getThemeValue(long themePtr, int ident, TypedValue outValue, boolean resolveRefs) {
-    ResName resName = resourceProvider.getResName(ident);
+    ResName resName = resourceTable.getResName(ident);
 
     ThemeStyleSet themeStyleSet = getNativeTheme(themePtr).themeStyleSet;
     AttributeResource attrValue = themeStyleSet.getAttrValue(resName);
@@ -336,7 +336,7 @@
     final ResName resName = qualifyFromNonAssetFileName(fileName);
 
     final FileTypedResource typedResource =
-        (FileTypedResource) resourceProvider.getValue(resName, RuntimeEnvironment.getQualifiers());
+        (FileTypedResource) resourceTable.getValue(resName, RuntimeEnvironment.getQualifiers());
 
     if (typedResource == null) {
       throw new IOException("Unable to find resource for " + fileName);
@@ -376,17 +376,17 @@
     }
     resName = resolvedResName;
 
-    XmlBlock block = resourceProvider.getXml(resName, RuntimeEnvironment.getQualifiers());
+    XmlBlock block = resourceTable.getXml(resName, RuntimeEnvironment.getQualifiers());
     if (block == null) {
       throw new Resources.NotFoundException(resName.getFullyQualifiedName());
     }
 
-    ResourceProvider resourceProvider = ResourceIds.isFrameworkResource(resId) ? RuntimeEnvironment.getSystemResourceProvider() : RuntimeEnvironment.getCompileTimeResourceProvider();
+    ResourceTable resourceProvider = ResourceIds.isFrameworkResource(resId) ? RuntimeEnvironment.getSystemResourceProvider() : RuntimeEnvironment.getCompiletimeResourceProvider();
 
     return getXmlResourceParser(resourceProvider, block, resName.packageName);
   }
 
-  private XmlResourceParser getXmlResourceParser(ResourceProvider resourceProvider, XmlBlock block, String packageName) {
+  private XmlResourceParser getXmlResourceParser(ResourceTable resourceProvider, XmlBlock block, String packageName) {
     return new XmlResourceParserImpl(block.getDocument(), block.getFilename(), block.getPackageName(),
         packageName, resourceProvider);
   }
@@ -498,17 +498,17 @@
   }
 
   private Style resolveStyle(@NotNull ResName themeStyleName, Style themeStyleSet) {
-    TypedResource themeStyleResource = resourceProvider.getValue(themeStyleName, RuntimeEnvironment.getQualifiers());
+    TypedResource themeStyleResource = resourceTable.getValue(themeStyleName, RuntimeEnvironment.getQualifiers());
     if (themeStyleResource == null) return null;
     StyleData themeStyleData = (StyleData) themeStyleResource.getData();
     if (themeStyleSet == null) {
       themeStyleSet = new ThemeStyleSet();
     }
-    return new StyleResolver(resourceProvider, shadowOf(AssetManager.getSystem()).getResourceProvider(), themeStyleData, themeStyleSet, themeStyleName, RuntimeEnvironment.getQualifiers());
+    return new StyleResolver(resourceTable, shadowOf(AssetManager.getSystem()).getResourceTable(), themeStyleData, themeStyleSet, themeStyleName, RuntimeEnvironment.getQualifiers());
   }
 
   private TypedResource getAndResolve(int resId, String qualifiers, boolean resolveRefs) {
-    TypedResource value = resourceProvider.getValue(resId, qualifiers);
+    TypedResource value = resourceTable.getValue(resId, qualifiers);
     if (resolveRefs) {
       value = resolve(value, qualifiers, resId);
     }
@@ -516,7 +516,7 @@
     // todo: make the drawable loader put stuff into the normal spot...
     String resourceTypeName = getResourceTypeName(resId);
     if (value == null && DrawableResourceLoader.isStillHandledHere(resourceTypeName)) {
-      FileTypedResource typedResource = (FileTypedResource) resourceProvider.getValue(resId, qualifiers);
+      FileTypedResource typedResource = (FileTypedResource) resourceTable.getValue(resId, qualifiers);
       return new TypedResource<>(typedResource.getFsFile(), ResType.FILE, typedResource.getXmlContext());
     }
 
@@ -533,7 +533,7 @@
   }
 
   public ResName resolveResName(ResName resName, String qualifiers) {
-    TypedResource value = resourceProvider.getValue(resName, qualifiers);
+    TypedResource value = resourceTable.getValue(resName, qualifiers);
     return resolveResource(value, qualifiers, resName);
   }
 
@@ -546,7 +546,7 @@
       } else {
         String refStr = s.substring(1).replace("+", "");
         resName = ResName.qualifyResName(refStr, resName);
-        value = resourceProvider.getValue(resName, qualifiers);
+        value = resourceTable.getValue(resName, qualifiers);
       }
     }
 
@@ -561,7 +561,7 @@
       } else {
         String refStr = s.substring(1).replace("+", "");
         resName = ResName.qualifyResName(refStr, resName);
-        value = resourceProvider.getValue(resName, qualifiers);
+        value = resourceTable.getValue(resName, qualifiers);
       }
     }
 
@@ -648,7 +648,7 @@
         Logger.info("huh... circular reference for %s?", attribute.resName.getFullyQualifiedName());
         return null;
       }
-      ResName resName = resourceProvider.getResName(resId);
+      ResName resName = resourceTable.getResName(resId);
 
       AttributeResource otherAttr = themeStyleSet.getAttrValue(otherAttrName);
       if (otherAttr == null) {
@@ -730,7 +730,7 @@
       }
     }
 
-    ResName attrName = resourceProvider.getResName(resId);
+    ResName attrName = resourceTable.getResName(resId);
     if (attrName == null) return null;
 
     if (styleAttrStyle != null) {
@@ -760,10 +760,10 @@
   }
 
   @NotNull private ResName getResName(int id) {
-    ResName resName = resourceProvider.getResName(id);
+    ResName resName = resourceTable.getResName(id);
     if (resName == null) {
       throw new Resources.NotFoundException("Unable to find resource ID #0x" + Integer.toHexString(id)
-          + " in packages " + resourceProvider);
+          + " in packages " + resourceTable);
     }
     return resName;
   }
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 234289d..7a0f0f9 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
@@ -107,7 +107,7 @@
   public String getQuantityString(int resId, int quantity) throws Resources.NotFoundException {
     ShadowAssetManager shadowAssetManager = shadowOf(realResources.getAssets());
 
-    TypedResource typedResource = shadowAssetManager.getResourceProvider().getValue(resId, RuntimeEnvironment.getQualifiers());
+    TypedResource typedResource = shadowAssetManager.getResourceTable().getValue(resId, RuntimeEnvironment.getQualifiers());
     if (typedResource != null && typedResource instanceof PluralResourceLoader.PluralRules) {
       PluralResourceLoader.PluralRules pluralRules = (PluralResourceLoader.PluralRules) typedResource;
       Plural plural = pluralRules.find(quantity);
@@ -127,7 +127,7 @@
 
   @Implementation
   public InputStream openRawResource(int id) throws Resources.NotFoundException {
-    return shadowOf(realResources.getAssets()).getResourceProvider().getRawValue(id, RuntimeEnvironment.getQualifiers());
+    return shadowOf(realResources.getAssets()).getResourceTable().getRawValue(id, RuntimeEnvironment.getQualifiers());
   }
 
   @Implementation
diff --git a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResourcesImpl.java b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResourcesImpl.java
index 74082b5..cbc27ec 100644
--- a/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResourcesImpl.java
+++ b/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowResourcesImpl.java
@@ -91,7 +91,7 @@
   public String getQuantityString(int resId, int quantity) throws Resources.NotFoundException {
     ShadowAssetManager shadowAssetManager = shadowOf(realResourcesImpl.getAssets());
 
-    TypedResource typedResource = shadowAssetManager.getResourceProvider().getValue(resId, RuntimeEnvironment.getQualifiers());
+    TypedResource typedResource = shadowAssetManager.getResourceTable().getValue(resId, RuntimeEnvironment.getQualifiers());
     if (typedResource != null && typedResource instanceof PluralResourceLoader.PluralRules) {
       PluralResourceLoader.PluralRules pluralRules = (PluralResourceLoader.PluralRules) typedResource;
       Plural plural = pluralRules.find(quantity);
@@ -110,7 +110,7 @@
 
   @Implementation
   public InputStream openRawResource(int id) throws Resources.NotFoundException {
-    return shadowOf(realResourcesImpl.getAssets()).getResourceProvider().getRawValue(id, RuntimeEnvironment.getQualifiers());
+    return shadowOf(realResourcesImpl.getAssets()).getResourceTable().getRawValue(id, RuntimeEnvironment.getQualifiers());
   }
 
   @Implementation
diff --git a/robolectric/src/main/java/org/robolectric/Robolectric.java b/robolectric/src/main/java/org/robolectric/Robolectric.java
index 2e39f7e..30682d9 100644
--- a/robolectric/src/main/java/org/robolectric/Robolectric.java
+++ b/robolectric/src/main/java/org/robolectric/Robolectric.java
@@ -11,7 +11,7 @@
 import android.view.View;
 import org.robolectric.internal.ShadowProvider;
 import org.robolectric.res.ResName;
-import org.robolectric.res.ResourceProvider;
+import org.robolectric.res.ResourceTable;
 import org.robolectric.res.builder.XmlResourceParserImpl;
 import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.util.*;
@@ -132,15 +132,15 @@
   public static class AttributeSetBuilder {
 
     private Document doc;
-    private ResourceProvider appResourceProvider;
+    private ResourceTable appResourceTable;
 
-    AttributeSetBuilder(Document doc, ResourceProvider resourceProvider) {
+    AttributeSetBuilder(Document doc, ResourceTable resourceTable) {
       this.doc = doc;
-      this.appResourceProvider = resourceProvider;
+      this.appResourceTable = resourceTable;
     }
 
     public AttributeSetBuilder addAttribute(int resId, String value) {
-      ResName resName = appResourceProvider.getResName(resId);
+      ResName resName = appResourceTable.getResName(resId);
       if ("style".equals(resName.name)) {
         ((Element)doc.getFirstChild()).setAttribute(resName.name, value);
       } else {
@@ -155,7 +155,7 @@
     }
 
     public AttributeSet build() {
-      XmlResourceParserImpl parser = new XmlResourceParserImpl(doc, null, RuntimeEnvironment.application.getPackageName(), RuntimeEnvironment.application.getPackageName(), appResourceProvider);
+      XmlResourceParserImpl parser = new XmlResourceParserImpl(doc, null, RuntimeEnvironment.application.getPackageName(), RuntimeEnvironment.application.getPackageName(), appResourceTable);
       try {
         parser.next(); // Root document element
         parser.next(); // "dummy" element
diff --git a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
index 37a9c37..c47b0ec 100644
--- a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
+++ b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
@@ -22,7 +22,6 @@
 import org.robolectric.internal.dependency.*;
 import org.robolectric.manifest.AndroidManifest;
 import org.robolectric.res.*;
-import org.robolectric.res.ResourceTable;
 import org.robolectric.util.Logger;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -37,14 +36,15 @@
 
 /**
  * Installs a {@link org.robolectric.internal.bytecode.InstrumentingClassLoader} and
- * {@link ResourceProvider} in order to provide a simulation of the Android runtime environment.
+ * {@link ResourceTable} in order to provide a simulation of the Android runtime environment.
  */
 public class RobolectricTestRunner extends BlockJUnit4ClassRunner {
 
   public static final String CONFIG_PROPERTIES = "robolectric.properties";
-  private static final Map<AndroidManifest, ResourceTable> appResourceTableCache = new HashMap<>();
+  
+  private static final Map<AndroidManifest, PackageResourceTable> appResourceTableCache = new HashMap<>();
   private static final Map<ManifestIdentifier, AndroidManifest> appManifestsCache = new HashMap<>();
-  private static ResourceTable compiletimeSdkResourceTable;
+  private static PackageResourceTable compiletimeSdkResourceTable;
 
   private final SdkPicker sdkPicker;
   private final ConfigMerger configMerger;
@@ -265,7 +265,7 @@
    * Returns the ResourceProvider for the compile time SDK.
    */
   @NotNull
-  private static ResourceTable getCompiletimeSdkResourceTable() {
+  private static PackageResourceTable getCompiletimeSdkResourceTable() {
     if (compiletimeSdkResourceTable == null) {
       compiletimeSdkResourceTable = ResourceTableFactory.newResourceTable("android", new ResourcePath(android.R.class, null, null));
     }
@@ -317,10 +317,10 @@
             ReflectionHelpers.setStaticField(androidBuildVersionClass, "SDK_INT", sdkConfig.getApiLevel());
             ReflectionHelpers.setStaticField(androidBuildVersionClass, "RELEASE", sdkConfig.getAndroidVersion());
 
-            ResourceTable systemResourceTable = sdkEnvironment.getSystemResourceTable(getJarResolver());
-            ResourceTable appResourceTable = getAppResourceTable(appManifest);
+            PackageResourceTable systemResourceTable = sdkEnvironment.getSystemResourceTable(getJarResolver());
+            PackageResourceTable appResourceTable = getAppResourceTable(appManifest);
 
-            parallelUniverseInterface.setUpApplicationState(bootstrappedMethod, testLifecycle, appManifest, config, new RoutingResourceProvider(getCompiletimeSdkResourceTable(), appResourceTable), new RoutingResourceProvider(systemResourceTable, appResourceTable), new RoutingResourceProvider(systemResourceTable));
+            parallelUniverseInterface.setUpApplicationState(bootstrappedMethod, testLifecycle, appManifest, config, new RoutingResourceTable(getCompiletimeSdkResourceTable(), appResourceTable), new RoutingResourceTable(systemResourceTable, appResourceTable), new RoutingResourceTable(systemResourceTable));
             testLifecycle.beforeTest(bootstrappedMethod);
           } catch (Exception e) {
             throw new RuntimeException(e);
@@ -491,8 +491,8 @@
     throw new UnsupportedOperationException("this should always be invoked on the HelperTestRunner!");
   }
 
-  private final ResourceTable getAppResourceTable(final AndroidManifest appManifest) {
-    ResourceTable resourceTable = appResourceTableCache.get(appManifest);
+  private final PackageResourceTable getAppResourceTable(final AndroidManifest appManifest) {
+    PackageResourceTable resourceTable = appResourceTableCache.get(appManifest);
     if (resourceTable == null) {
       resourceTable = ResourceMerger.buildResourceTable(appManifest);
 
diff --git a/robolectric/src/main/java/org/robolectric/internal/ParallelUniverseInterface.java b/robolectric/src/main/java/org/robolectric/internal/ParallelUniverseInterface.java
index 76625cd..c2ee1a0 100644
--- a/robolectric/src/main/java/org/robolectric/internal/ParallelUniverseInterface.java
+++ b/robolectric/src/main/java/org/robolectric/internal/ParallelUniverseInterface.java
@@ -4,16 +4,14 @@
 import org.robolectric.manifest.AndroidManifest;
 import org.robolectric.TestLifecycle;
 import org.robolectric.annotation.Config;
-import org.robolectric.res.ResourceProvider;
 import org.robolectric.res.ResourceTable;
-import org.robolectric.res.RoutingResourceProvider;
 
 public interface ParallelUniverseInterface {
   void resetStaticState(Config config);
 
   void setUpApplicationState(Method method, TestLifecycle testLifecycle, AndroidManifest appManifest, Config config,
-                             ResourceProvider compiletimeResourceProvider, ResourceProvider appResourceProvider,
-                             ResourceProvider systemResourceProvider);
+                             ResourceTable compiletimeResourceTable, ResourceTable appResourceTable,
+                             ResourceTable systemResourceTable);
 
   Thread getMainThread();
 
diff --git a/robolectric/src/main/java/org/robolectric/internal/SdkEnvironment.java b/robolectric/src/main/java/org/robolectric/internal/SdkEnvironment.java
index c4f7257..bd46df4 100644
--- a/robolectric/src/main/java/org/robolectric/internal/SdkEnvironment.java
+++ b/robolectric/src/main/java/org/robolectric/internal/SdkEnvironment.java
@@ -11,7 +11,7 @@
   private final ClassLoader robolectricClassLoader;
   private final ShadowInvalidator shadowInvalidator;
   private ShadowMap shadowMap = ShadowMap.EMPTY;
-  private ResourceTable systemResourceTable;
+  private PackageResourceTable systemResourceTable;
   public static final String ANDROID_PACKAGE_NAME = android.R.class.getPackage().getName();
 
   public SdkEnvironment(SdkConfig sdkConfig, ClassLoader robolectricClassLoader) {
@@ -20,7 +20,7 @@
     shadowInvalidator = new ShadowInvalidator();
   }
 
-  public synchronized ResourceTable getSystemResourceTable(DependencyResolver dependencyResolver) {
+  public synchronized PackageResourceTable getSystemResourceTable(DependencyResolver dependencyResolver) {
     if (systemResourceTable == null) {
       ResourcePath resourcePath = createRuntimeSdkResourcePath(dependencyResolver);
       systemResourceTable = ResourceTableFactory.newResourceTable(ANDROID_PACKAGE_NAME, resourcePath);
diff --git a/robolectric/src/main/java/org/robolectric/internal/bytecode/InstrumentationConfiguration.java b/robolectric/src/main/java/org/robolectric/internal/bytecode/InstrumentationConfiguration.java
index 9a1b9b5..5797a54 100644
--- a/robolectric/src/main/java/org/robolectric/internal/bytecode/InstrumentationConfiguration.java
+++ b/robolectric/src/main/java/org/robolectric/internal/bytecode/InstrumentationConfiguration.java
@@ -17,8 +17,8 @@
 import org.robolectric.internal.fakes.RoboExtendedResponseCache;
 import org.robolectric.internal.fakes.RoboResponseSource;
 import org.robolectric.manifest.AndroidManifest;
-import org.robolectric.res.ResourceProvider;
 import org.robolectric.res.ResourcePath;
+import org.robolectric.res.ResourceTable;
 import org.robolectric.res.builder.XmlBlock;
 import org.robolectric.util.TempDirectory;
 import org.robolectric.util.Transcript;
@@ -109,7 +109,7 @@
           RobolectricTestRunner.class,
           RobolectricTestRunner.HelperTestRunner.class,
           ResourcePath.class,
-          ResourceProvider.class,
+          ResourceTable.class,
           XmlBlock.class,
           ClassHandler.class,
           ClassHandler.Plan.class,
diff --git a/robolectric/src/test/java/org/robolectric/ParallelUniverseTest.java b/robolectric/src/test/java/org/robolectric/ParallelUniverseTest.java
index d7e27a4..d9ec31e 100644
--- a/robolectric/src/test/java/org/robolectric/ParallelUniverseTest.java
+++ b/robolectric/src/test/java/org/robolectric/ParallelUniverseTest.java
@@ -43,12 +43,12 @@
   }
 
   private void setUpApplicationState(Config defaultConfig) {
-    ResourceProvider sdkResourceProvider = new EmptyResourceProvider(ResourceTableFactory.newResourceTable("android", new ResourcePath(android.R.class, null, null)));
-    final RoutingResourceProvider routingResourceProvider = new RoutingResourceProvider(ResourceTableFactory.newResourceTable("org.robolectric", new ResourcePath(R.class, null, null)));
+    ResourceTable sdkResourceProvider = ResourceTableFactory.newResourceTable("android", new ResourcePath(android.R.class, null, null));
+    final RoutingResourceTable routingResourceTable = new RoutingResourceTable(ResourceTableFactory.newResourceTable("org.robolectric", new ResourcePath(R.class, null, null)));
     pu.setUpApplicationState(null, new DefaultTestLifecycle(),
         new AndroidManifest(null, null, null, "package"), defaultConfig,
         sdkResourceProvider,
-        routingResourceProvider,
+        routingResourceTable,
         RuntimeEnvironment.getSystemResourceProvider());
   }
 
diff --git a/robolectric/src/test/java/org/robolectric/manifest/MetaDataTest.java b/robolectric/src/test/java/org/robolectric/manifest/MetaDataTest.java
index 3236c72..49bee5c 100644
--- a/robolectric/src/test/java/org/robolectric/manifest/MetaDataTest.java
+++ b/robolectric/src/test/java/org/robolectric/manifest/MetaDataTest.java
@@ -8,7 +8,7 @@
 import org.junit.runners.JUnit4;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.res.ResourceProvider;
+import org.robolectric.res.ResourceTable;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -24,8 +24,7 @@
 @RunWith(JUnit4.class)
 public class MetaDataTest {
 
-  @Mock
-  ResourceProvider resourceProvider;
+  @Mock private ResourceTable resourceProvider;
 
   @Before
   public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/res/ResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/res/ResourceLoaderTest.java
index a271ade..740ffd5 100644
--- a/robolectric/src/test/java/org/robolectric/res/ResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/res/ResourceLoaderTest.java
@@ -57,7 +57,7 @@
 
   @Test
   public void shouldMakeInternalResourcesAvailable() throws Exception {
-    ResourceProvider resourceProvider = RuntimeEnvironment.getSystemResourceProvider();
+    ResourceTable resourceProvider = RuntimeEnvironment.getSystemResourceProvider();
     ResName internalResource = new ResName("android", "string", "badPin");
     Integer resId = resourceProvider.getResourceId(internalResource);
     assertThat(resId).isNotNull();
diff --git a/robolectric/src/test/java/org/robolectric/res/ResourceTableTest.java b/robolectric/src/test/java/org/robolectric/res/ResourceTableTest.java
index a9447f4..f1aae6a 100644
--- a/robolectric/src/test/java/org/robolectric/res/ResourceTableTest.java
+++ b/robolectric/src/test/java/org/robolectric/res/ResourceTableTest.java
@@ -10,7 +10,7 @@
 @RunWith(JUnit4.class)
 public class ResourceTableTest {
 
-  private ResourceTable resourceTable;
+  private PackageResourceTable resourceTable;
 
   @Before
   public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/res/builder/XmlResourceParserImplTest.java b/robolectric/src/test/java/org/robolectric/res/builder/XmlResourceParserImplTest.java
index 7ffdc49..bea8006 100644
--- a/robolectric/src/test/java/org/robolectric/res/builder/XmlResourceParserImplTest.java
+++ b/robolectric/src/test/java/org/robolectric/res/builder/XmlResourceParserImplTest.java
@@ -50,7 +50,7 @@
 
   private static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
   private XmlResourceParserImpl parser;
-  private ResourceProvider resourceProvider;
+  private ResourceTable resourceTable;
 
   @Before
   public void setUp() throws Exception {
@@ -60,9 +60,9 @@
 
     ResName resName = new ResName(TEST_PACKAGE, "xml", "preferences");
     XmlBlock xmlBlock = (XmlBlock) resBundle.get(resName, "").getData();
-    resourceProvider = new EmptyResourceProvider(ResourceTableFactory.newResourceTable("org.robolectric", testResources()));
+    resourceTable = ResourceTableFactory.newResourceTable("org.robolectric", testResources());
     parser = new XmlResourceParserImpl(xmlBlock.getDocument(), xmlBlock.getFilename(), xmlBlock.getPackageName(),
-        TEST_PACKAGE, resourceProvider);
+        TEST_PACKAGE, resourceTable);
   }
 
   @After
@@ -90,7 +90,7 @@
           new ByteArrayInputStream(xmlValue.getBytes()));
 
       parser = new XmlResourceParserImpl(document, "file", R.class.getPackage().getName(),
-          TEST_PACKAGE, resourceProvider);
+          TEST_PACKAGE, resourceTable);
       // Navigate to the root element
       parseUntilNext(XmlResourceParser.START_TAG);
     } catch (Exception parsingException) {