diff --git a/resources/static/common/js/modules/interaction_data.js b/resources/static/common/js/modules/interaction_data.js
index 8f36514dac7ddc5f6f13dccd4d4e6a593f105ef5..181db90d64aedef85291e5ad943019de8a4133ed 100644
--- a/resources/static/common/js/modules/interaction_data.js
+++ b/resources/static/common/js/modules/interaction_data.js
@@ -28,6 +28,7 @@ BrowserID.Modules.InteractionData = (function() {
   var bid = BrowserID,
       model = bid.Models.InteractionData,
       network = bid.Network,
+      storage = bid.Storage,
       complete = bid.Helpers.complete,
       dom = bid.DOM,
       sc;
@@ -98,13 +99,64 @@ BrowserID.Modules.InteractionData = (function() {
     if (self.sessionContextHandled) return;
     self.sessionContextHandled = true;
 
+    publishPreviousSession.call(self, result);
+  }
+
+  function publishPreviousSession(result) {
     // Publish any outstanding data.  Unless this is a continuation, previous
     // session data must be published independently of whether the current
     // dialog session is allowed to sample data. This is because the original
     // dialog session has already decided whether to collect data.
+    //
+    // beginSampling must happen afterwards, since we need to send and
+    // then scrub out the previous sessions data.
 
-    model.stageCurrent();
-    publishStored.call(self);
+    var self = this;
+
+    function onComplete() {
+      model.stageCurrent();
+      publishStored.call(self);
+      beginSampling.call(self, result);
+    }
+
+    // if we were orphaned last time, but user is now authenticated,
+    // lets see if their action end in success, and if so,
+    // remove the orphaned flag
+    //
+    // actions:
+    // - user_staged => is authenticated?
+    // - email_staged => email count is higher?
+    //
+    // See https://github.com/mozilla/browserid/issues/1827
+    var current = model.getCurrent();
+    if (current && current.orphaned) {
+      var events = current.event_stream || [];
+      if (hasEvent(events, MediatorToKPINameTable.user_staged)) {
+        network.checkAuth(function(auth) {
+          if (!!auth) {
+            current.orphaned = false;
+            model.setCurrent(current);
+          }
+          complete(onComplete);
+        });
+      } else if (hasEvent(events, MediatorToKPINameTable.email_staged)) {
+        if ((storage.getEmailCount() || 0) > (current.number_emails || 0)) {
+          current.orphaned = false;
+          model.setCurrent(current);
+        }
+        complete(onComplete);
+      } else {
+        // oh well, an orphan it is
+        complete(onComplete);
+      }
+    } else {
+      // not an orphan, move along
+      complete(onComplete);
+    }
+  }
+
+  function beginSampling(result) {
+    var self = this;
 
     // set the sample rate as defined by the server.  It's a value
     // between 0..1, integer or float, and it specifies the percentage
@@ -152,6 +204,19 @@ BrowserID.Modules.InteractionData = (function() {
     self.initialEventStream = null;
 
     self.samplesBeingStored = true;
+    
+  }
+
+  function indexOfEvent(eventStream, eventName) {
+    for(var event, i = 0; event = eventStream[i]; ++i) {
+      if(event[0] === eventName) return i;
+    }
+
+    return -1;
+  }
+
+  function hasEvent(eventStream, eventName) {
+    return indexOfEvent(eventStream, eventName) !== -1;
   }
 
   function onKPIData(msg, result) {
diff --git a/resources/static/test/cases/common/js/modules/interaction_data.js b/resources/static/test/cases/common/js/modules/interaction_data.js
index 1beb33008293d297a40f88cabcd519e042959ef8..eadf72fa0db55e4fa480598c97a47f340104f2ff 100644
--- a/resources/static/test/cases/common/js/modules/interaction_data.js
+++ b/resources/static/test/cases/common/js/modules/interaction_data.js
@@ -1,5 +1,5 @@
 /*jshint browser: true, forin: true, laxbreak: true */
-/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true */
+/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true, asyncTest:true */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -9,6 +9,7 @@
   var bid = BrowserID,
       testHelpers = bid.TestHelpers,
       network = bid.Network,
+      storage = bid.Storage,
       model = bid.Models.InteractionData,
       xhr = bid.Mocks.xhr,
       mediator = bid.Mediator,
@@ -36,18 +37,20 @@
     controller = BrowserID.Modules.InteractionData.create();
     controller.start(config);
 
-    controller.setNameTable({
-      before_session_context: null,
-      after_session_context: null,
-      session1_before_session_context: null,
-      session1_after_session_context: null,
-      session2_before_session_context: null,
-      session2_after_session_context: null,
-      initial_string_name: "translated_name",
-      initial_function_name: function(msg, data) {
-        return "function_translation." + msg;
-      }
-    });
+    if (setKPINameTable) {
+      controller.setNameTable({
+        before_session_context: null,
+        after_session_context: null,
+        session1_before_session_context: null,
+        session1_after_session_context: null,
+        session2_before_session_context: null,
+        session2_after_session_context: null,
+        initial_string_name: "translated_name",
+        initial_function_name: function(msg, data) {
+          return "function_translation." + msg;
+        }
+      });
+    }
 
   }
 
@@ -69,7 +72,7 @@
     // simulate data stored for last session
     model.push({ timestamp: new Date().getTime() });
 
-    createController();
+    createController(true);
 
     controller.addEvent("before_session_context");
 
@@ -122,7 +125,7 @@
   });
 
   asyncTest("samplingEnabled set to false - no data collection occurs", function() {
-    createController({ samplingEnabled: false });
+    createController(true, { samplingEnabled: false });
 
     // the initial with_context will send off any stored data, there should be
     // no stored data.
@@ -140,7 +143,7 @@
   });
 
   asyncTest("continue: true, data collection permitted on previous session - continue appending data to previous session", function() {
-    createController();
+    createController(true);
 
     controller.addEvent("session1_before_session_context");
     network.withContext(function() {
@@ -150,7 +153,7 @@
       // re-get session context.
       controller = null;
       network.clearContext();
-      createController({ continuation: true });
+      createController(true, { continuation: true });
 
       controller.addEvent("session2_before_session_context");
       network.withContext(function() {
@@ -257,4 +260,124 @@
     });
   });
 
+  asyncTest("kpi orphans are adopted if user.staged and user is signed in", function() {
+    // 1. user.user_staged
+    // 2. dialog is orphaned
+    // 3. user comes back, authenticated
+    // 4. the orphan found a good home
+    createController(false);
+    network.withContext(function() {
+      // user is staged
+      controller.addEvent("user_staged");
+      // dialog all done, its orphaned, oh noes! think of the kids!
+      mediator.publish("kpi_data", {
+        orphaned: true
+      });
+      network.clearContext();
+
+
+      // new page
+      createController(false);
+      // make user authenticated
+      xhr.setContextInfo("auth_level", "password");
+      network.withContext(function() {
+        var request = xhr.getLastRequest('/wsapi/interaction_data');
+        var data = JSON.parse(request.data).data[0];
+        equal(data.orphaned, false, "orphaned is not sent");
+        start();
+      });
+    });
+  });
+
+  asyncTest("kpi orphans are NOT adopted if NOT user.staged and user is signed in", function() {
+    // 1. user was not staged
+    // 2. dialog is orphaned
+    // 3. user comes back, authenticated
+    // 4. but he wasn't staged, so dont adopt
+    createController(false);
+    network.withContext(function() {
+      // dialog all done, its orphaned, oh noes! think of the kids!
+      mediator.publish("kpi_data", {
+        orphaned: true
+      });
+      network.clearContext();
+
+
+      // new page
+      createController(false);
+      // make user authenticated
+      xhr.setContextInfo("auth_level", "password");
+      network.withContext(function() {
+        var request = xhr.getLastRequest('/wsapi/interaction_data');
+        var data = JSON.parse(request.data).data[0];
+        equal(data.orphaned, true, "orphaned is sent");
+        start();
+      });
+    });
+  });
+
+    asyncTest("kpi orphans are adopted if add_email and email count increased", function() {
+    // 1. email_staged
+    // 2. dialog is orphaned
+    // 3. email is verified
+    // 4. user comes back, authenticated
+    // 5. the orphan found a good home
+    createController(false);
+    network.withContext(function() {
+      // email is staged
+      controller.addEvent("email_staged");
+      // dialog all done, its orphaned, oh noes! think of the kids!
+      mediator.publish("kpi_data", {
+        orphaned: true,
+        number_emails: storage.getEmailCount() || 0
+      });
+      network.clearContext();
+
+      // email is verified
+      storage.addSecondaryEmail("testuser@testuser.org");
+
+      // new page
+      createController(false);
+      // make user authenticated
+      xhr.setContextInfo("auth_level", "password");
+      network.withContext(function() {
+        var request = xhr.getLastRequest('/wsapi/interaction_data');
+        var data = JSON.parse(request.data).data[0];
+        equal(data.orphaned, false, "orphaned is not sent");
+        start();
+      });
+    });
+  });
+
+  asyncTest("kpi orphans are NOT adopted if add_email but email count is same", function() {
+    // 1. email staged
+    // 2. dialog is orphaned
+    // 3. user comes back, authenticated
+    // 4. but no new email, so oprhan is true
+    createController(false);
+    network.withContext(function() {
+      // user is staged
+      controller.addEvent("email_staged");
+      // dialog all done, its orphaned, oh noes! think of the kids!
+      mediator.publish("kpi_data", {
+        orphaned: true,
+        number_emails: storage.getEmailCount() || 0
+      });
+      network.clearContext();
+
+      // user never confirms
+
+      // new page
+      createController(false);
+      // make user authenticated
+      xhr.setContextInfo("auth_level", "password");
+      network.withContext(function() {
+        var request = xhr.getLastRequest('/wsapi/interaction_data');
+        var data = JSON.parse(request.data).data[0];
+        equal(data.orphaned, true, "orphaned is sent");
+        start();
+      });
+    });
+  });
+
 }());