diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index e1d7136..b6aad3b 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -340,6 +340,9 @@
     }
 
     void restoreLoaderNonConfig(ArrayMap<String, LoaderManager> loaderManagers) {
+        for (int i = 0, N = loaderManagers.size(); i < N; i++) {
+            ((LoaderManagerImpl) loaderManagers.valueAt(i)).updateHostController(this);
+        }
         mAllLoaderManagers = loaderManagers;
     }
 
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index c14dec9..bedf31a 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -195,6 +195,9 @@
     public static void enableDebugLogging(boolean enabled) {
         LoaderManagerImpl.DEBUG = enabled;
     }
+
+    /** @hide for internal testing only */
+    public FragmentHostCallback getFragmentHostCallback() { return null; }
 }
 
 class LoaderManagerImpl extends LoaderManager {
@@ -542,6 +545,10 @@
     void updateHostController(FragmentHostCallback host) {
         mHost = host;
     }
+
+    public FragmentHostCallback getFragmentHostCallback() {
+        return mHost;
+    }
     
     private LoaderInfo createLoader(int id, Bundle args,
             LoaderManager.LoaderCallbacks<Object> callback) {
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 2452cfd..4416402 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1147,6 +1147,8 @@
         </activity>
         <activity android:name="com.android.internal.policy.PhoneWindowActionModeTestActivity">
         </activity>
+        <activity android:name="android.app.EmptyActivity">
+        </activity>
 
         <receiver android:name="android.app.activity.AbortReceiver">
             <intent-filter android:priority="1">
diff --git a/core/tests/coretests/src/android/app/EmptyActivity.java b/core/tests/coretests/src/android/app/EmptyActivity.java
new file mode 100644
index 0000000..fefd7b7
--- /dev/null
+++ b/core/tests/coretests/src/android/app/EmptyActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.app;
+
+public class EmptyActivity extends Activity {
+}
diff --git a/core/tests/coretests/src/android/app/LoaderLifecycleTest.java b/core/tests/coretests/src/android/app/LoaderLifecycleTest.java
new file mode 100644
index 0000000..a3d51a0
--- /dev/null
+++ b/core/tests/coretests/src/android/app/LoaderLifecycleTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.app;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Parcelable;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertNotSame;
+import static junit.framework.TestCase.assertSame;
+
+@RunWith(AndroidJUnit4.class)
+public class LoaderLifecycleTest {
+    @Rule
+    public ActivityTestRule<EmptyActivity> mActivityRule =
+            new ActivityTestRule<>(EmptyActivity.class);
+    @Test
+    @MediumTest
+    public void loaderIdentityTest() throws Throwable{
+        mActivityRule.runOnUiThread(() -> {
+            final Handler h = new Handler();
+            final FragmentController fc1 = FragmentController.createController(
+                    new TestFragmentHostCallback(mActivityRule.getActivity(), h, 0));
+
+            fc1.attachHost(null);
+            fc1.dispatchCreate();
+
+            final FragmentManager fm1 = fc1.getFragmentManager();
+
+            final Fragment f1 = new Fragment();
+            fm1.beginTransaction().add(f1, "one").commitNow();
+
+            // Removing and re-adding a fragment completely will destroy its LoaderManager.
+            // Keep the first one here to confirm this later.
+            final LoaderManager lm1 = f1.getLoaderManager();
+
+            // Remove the fragment, add a second one, and re-add the first to
+            // force its internal index to change. The tests below should still remain consistent.
+            final Fragment f2 = new Fragment();
+            fm1.beginTransaction().remove(f1).commitNow();
+            fm1.beginTransaction().add(f2, "two").commitNow();
+            fm1.beginTransaction().add(f1, "one").commitNow();
+
+            // We'll check this to see if we get the same instance back later
+            // as passed through NonConfigurationInstance. If the keys stay consistent
+            // across fragment remove/re-add, this will be consistent.
+            final LoaderManager lm12 = f1.getLoaderManager();
+
+            assertNotSame("fully removed and re-added fragment got same LoaderManager", lm1, lm12);
+
+            fc1.dispatchActivityCreated();
+            fc1.noteStateNotSaved();
+            fc1.execPendingActions();
+            fc1.doLoaderStart();
+            fc1.dispatchStart();
+            fc1.reportLoaderStart();
+            fc1.dispatchResume();
+            fc1.execPendingActions();
+
+            // Bring the state back down to destroyed, simulating an activity restart
+            fc1.dispatchPause();
+            final Parcelable savedState = fc1.saveAllState();
+            fc1.doLoaderStop(true);
+            fc1.dispatchStop();
+            final FragmentManagerNonConfig nonconf = fc1.retainNestedNonConfig();
+
+            final ArrayMap<String, LoaderManager> loaderNonConfig = fc1.retainLoaderNonConfig();
+            assertNotNull("loaderNonConfig was null", loaderNonConfig);
+
+            fc1.dispatchDestroy();
+
+            // Create the new controller and restore state
+            final FragmentController fc2 = FragmentController.createController(
+                    new TestFragmentHostCallback(mActivityRule.getActivity(), h, 0));
+
+            final FragmentManager fm2 = fc2.getFragmentManager();
+
+            fc2.attachHost(null);
+            fc2.restoreLoaderNonConfig(loaderNonConfig);
+            fc2.restoreAllState(savedState, nonconf);
+            fc2.dispatchCreate();
+
+
+            fc2.dispatchActivityCreated();
+            fc2.noteStateNotSaved();
+            fc2.execPendingActions();
+            fc2.doLoaderStart();
+            fc2.dispatchStart();
+            fc2.reportLoaderStart();
+            fc2.dispatchResume();
+            fc2.execPendingActions();
+
+            // Test that the fragments are in the configuration we expect
+            final Fragment restoredOne = fm2.findFragmentByTag("one");
+            final LoaderManager lm2 = restoredOne.getLoaderManager();
+
+            assertSame("didn't get same LoaderManager instance back", lm2, lm12);
+
+            // Bring the state back down to destroyed before we finish the test
+            fc2.dispatchPause();
+            fc2.saveAllState();
+            fc2.dispatchStop();
+            fc2.dispatchDestroy();
+        });
+    }
+
+    @Test
+    @MediumTest
+    public void backStackLoaderIdentityTest() throws Throwable{
+        mActivityRule.runOnUiThread(() -> {
+            final Handler h = new Handler();
+            final FragmentHostCallback host1 =
+                    new TestFragmentHostCallback(mActivityRule.getActivity(), h, 0);
+            final FragmentController fc1 = FragmentController.createController(host1);
+
+            fc1.attachHost(null);
+            fc1.dispatchCreate();
+
+            final FragmentManager fm1 = fc1.getFragmentManager();
+
+            final Fragment f1 = new Fragment();
+            fm1.beginTransaction().add(f1, "one").commitNow();
+
+            final LoaderManager lm1 = f1.getLoaderManager();
+
+            // Put the fragment on the back stack.
+            fm1.beginTransaction().remove(f1).addToBackStack("backentry").commit();
+            fm1.executePendingTransactions();
+
+            fc1.dispatchActivityCreated();
+            fc1.noteStateNotSaved();
+            fc1.execPendingActions();
+            fc1.doLoaderStart();
+            fc1.dispatchStart();
+            fc1.reportLoaderStart();
+            fc1.dispatchResume();
+            fc1.execPendingActions();
+
+            // Bring the state back down to destroyed, simulating an activity restart
+            fc1.dispatchPause();
+            final Parcelable savedState = fc1.saveAllState();
+            fc1.doLoaderStop(true);
+            fc1.dispatchStop();
+            final FragmentManagerNonConfig nonconf = fc1.retainNestedNonConfig();
+
+            final ArrayMap<String, LoaderManager> loaderNonConfig = fc1.retainLoaderNonConfig();
+            assertNotNull("loaderNonConfig was null", loaderNonConfig);
+
+            fc1.dispatchDestroy();
+
+            // Create the new controller and restore state
+            final FragmentHostCallback host2 =
+                    new TestFragmentHostCallback(mActivityRule.getActivity(), h, 0);
+            final FragmentController fc2 = FragmentController.createController(host2);
+
+            final FragmentManager fm2 = fc2.getFragmentManager();
+
+            fc2.attachHost(null);
+            fc2.restoreLoaderNonConfig(loaderNonConfig);
+            fc2.restoreAllState(savedState, nonconf);
+            fc2.dispatchCreate();
+
+
+            fc2.dispatchActivityCreated();
+            fc2.noteStateNotSaved();
+            fc2.execPendingActions();
+            fc2.doLoaderStart();
+            fc2.dispatchStart();
+            fc2.reportLoaderStart();
+            fc2.dispatchResume();
+            fc2.execPendingActions();
+
+            assertNotSame("LoaderManager kept reference to old FragmentHostCallback",
+                    host1, lm1.getFragmentHostCallback());
+            assertSame("LoaderManager did not refrence new FragmentHostCallback",
+                    host2, lm1.getFragmentHostCallback());
+
+            // Test that the fragments are in the configuration we expect
+            final Fragment restoredOne = fm2.findFragmentByTag("one");
+            final LoaderManager lm2 = restoredOne.getLoaderManager();
+
+            assertSame("didn't get same LoaderManager instance back", lm2, lm1);
+
+            // Bring the state back down to destroyed before we finish the test
+            fc2.dispatchPause();
+            fc2.saveAllState();
+            fc2.dispatchStop();
+            fc2.dispatchDestroy();
+        });
+    }
+
+    public class TestFragmentHostCallback extends FragmentHostCallback<LoaderLifecycleTest> {
+        public TestFragmentHostCallback(Context context, Handler handler, int windowAnimations) {
+            super(context, handler, windowAnimations);
+        }
+
+        @Override
+        public LoaderLifecycleTest onGetHost() {
+            return LoaderLifecycleTest.this;
+        }
+    }
+}
