Provide only one LiveData listener for work items.

There was a lot of confusion about the separate getStatus
and getOutput methods in WorkManager.  I've combined them
both into getStatus, which returns a new type, WorkStatus.
The old WorkStatus has been renamed to State (along with
all references to it, as well as the DB column name).  To
summarize the class changes:

- WorkStatus: new class, contains id, state, and output
- State: formerly known as WorkStatus (yes, I know, I'm
  sorry)
- WorkSpec.IdStateAndOutput: a POJO mapping to the DB
  columns; I'm not exposing this to the developers since
  it contains business logic they shouldn't be privy to

Because there is a DB schema change, you will have to
wipe out any existing DBs (clear data on the app); I
have not provided an upgrade step here.

Also updated WorkContinuation.getStatuses to return this
new data structure.

Test: Updated and ran tests.
Change-Id: If97110b0e946cb4a00f50a3b870951907add492e
diff --git a/background/integration-tests/testapp/src/main/java/android/arch/background/integration/testapp/sherlockholmes/AnalyzeSherlockHolmesActivity.java b/background/integration-tests/testapp/src/main/java/android/arch/background/integration/testapp/sherlockholmes/AnalyzeSherlockHolmesActivity.java
index 57ed0f5..6b6f23a 100644
--- a/background/integration-tests/testapp/src/main/java/android/arch/background/integration/testapp/sherlockholmes/AnalyzeSherlockHolmesActivity.java
+++ b/background/integration-tests/testapp/src/main/java/android/arch/background/integration/testapp/sherlockholmes/AnalyzeSherlockHolmesActivity.java
@@ -16,8 +16,8 @@
 
 package android.arch.background.integration.testapp.sherlockholmes;
 
-import static android.arch.background.workmanager.WorkStatus.FAILED;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.FAILED;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import android.arch.background.integration.testapp.R;
 import android.arch.background.integration.testapp.db.TestDatabase;
@@ -87,8 +87,8 @@
                 this,
                 status -> {
                     boolean loading = (status != null
-                            && status != SUCCEEDED
-                            && status != FAILED);
+                            && status.getState() != SUCCEEDED
+                            && status.getState() != FAILED);
                     mProgressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
                     mResultsView.setVisibility(loading ? View.GONE : View.VISIBLE);
                 }
diff --git a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/WorkSpecDaoTest.java b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/WorkSpecDaoTest.java
index f57ce9d..e10355b 100644
--- a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/WorkSpecDaoTest.java
+++ b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/WorkSpecDaoTest.java
@@ -16,7 +16,7 @@
 
 package android.arch.background.workmanager;
 
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -41,13 +41,13 @@
     public void testPruneLeaves() {
         Work enqueuedWork = new Work.Builder(TestWorker.class).build();
         Work finishedPrerequisiteWork1A =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedPrerequisiteWork1B =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedPrerequisiteWork2 =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedFinalWork =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
 
         insertWork(enqueuedWork);
         insertWork(finishedPrerequisiteWork1A);
diff --git a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkManagerImplTest.java b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkManagerImplTest.java
index 6d1b8c8..7100c37 100644
--- a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkManagerImplTest.java
+++ b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkManagerImplTest.java
@@ -21,12 +21,12 @@
 import static android.arch.background.workmanager.ExistingWorkPolicy.REPLACE;
 import static android.arch.background.workmanager.NetworkType.METERED;
 import static android.arch.background.workmanager.NetworkType.NOT_REQUIRED;
-import static android.arch.background.workmanager.WorkStatus.BLOCKED;
-import static android.arch.background.workmanager.WorkStatus.CANCELLED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.FAILED;
-import static android.arch.background.workmanager.WorkStatus.RUNNING;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.BLOCKED;
+import static android.arch.background.workmanager.State.CANCELLED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.FAILED;
+import static android.arch.background.workmanager.State.RUNNING;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
@@ -42,6 +42,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.arch.background.workmanager.Arguments;
 import android.arch.background.workmanager.BackoffPolicy;
 import android.arch.background.workmanager.BaseWork;
 import android.arch.background.workmanager.Constraints;
@@ -84,9 +85,7 @@
 import org.mockito.ArgumentCaptor;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
 public class WorkManagerImplTest extends WorkManagerTest {
@@ -218,12 +217,12 @@
         WorkContinuation workContinuation = mWorkManagerImpl.beginWith(work1);
         workContinuation.enqueue();
         WorkSpecDao workSpecDao = mDatabase.workSpecDao();
-        assertThat(workSpecDao.getWorkSpecStatus(work1.getId()), is(SUCCEEDED));
+        assertThat(workSpecDao.getWorkSpecState(work1.getId()), is(SUCCEEDED));
 
         mLifecycleOwner.mLifecycleRegistry.markState(Lifecycle.State.CREATED);
         Work work2 = new Work.Builder(TestWorker.class).build();
         workContinuation.then(work2).enqueue();
-        assertThat(workSpecDao.getWorkSpecStatus(work2.getId()), is(ENQUEUED));
+        assertThat(workSpecDao.getWorkSpecState(work2.getId()), is(ENQUEUED));
     }
 
     @Test
@@ -444,7 +443,7 @@
         final String testTag = "mytag";
 
         Work originalWork = new Work.Builder(TestWorker.class)
-                .withInitialStatus(SUCCEEDED)
+                .withInitialState(SUCCEEDED)
                 .addTag(testTag)
                 .build();
         insertWorkSpecAndTags(originalWork);
@@ -487,8 +486,8 @@
 
         WorkSpecDao workSpecDao = mDatabase.workSpecDao();
         assertThat(workSpecDao.getWorkSpec(originalWork.getId()), is(not(nullValue())));
-        assertThat(workSpecDao.getWorkSpecStatus(appendWork1.getId()), is(BLOCKED));
-        assertThat(workSpecDao.getWorkSpecStatus(appendWork2.getId()), is(BLOCKED));
+        assertThat(workSpecDao.getWorkSpecState(appendWork1.getId()), is(BLOCKED));
+        assertThat(workSpecDao.getWorkSpecState(appendWork2.getId()), is(BLOCKED));
 
         assertThat(mDatabase.dependencyDao().getDependentWorkIds(originalWork.getId()),
                 containsInAnyOrder(appendWork1.getId()));
@@ -539,8 +538,8 @@
         assertThat(workSpecDao.getWorkSpec(originalWork2.getId()), is(not(nullValue())));
         assertThat(workSpecDao.getWorkSpec(originalWork3.getId()), is(not(nullValue())));
         assertThat(workSpecDao.getWorkSpec(originalWork4.getId()), is(not(nullValue())));
-        assertThat(workSpecDao.getWorkSpecStatus(appendWork1.getId()), is(BLOCKED));
-        assertThat(workSpecDao.getWorkSpecStatus(appendWork2.getId()), is(BLOCKED));
+        assertThat(workSpecDao.getWorkSpecState(appendWork1.getId()), is(BLOCKED));
+        assertThat(workSpecDao.getWorkSpecState(appendWork2.getId()), is(BLOCKED));
 
         assertThat(dependencyDao.getPrerequisites(appendWork1.getId()),
                 containsInAnyOrder(originalWork3.getId(), originalWork4.getId()));
@@ -574,43 +573,42 @@
         insertWorkSpecAndTags(work0);
         insertWorkSpecAndTags(work1);
 
-        Observer<Map<String, WorkStatus>> mockObserver = mock(Observer.class);
+        Observer<List<WorkStatus>> mockObserver = mock(Observer.class);
 
         TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner();
-        LiveData<Map<String, WorkStatus>> liveData =
-                mWorkManagerImpl.getStatusesFor(Arrays.asList(work0.getId(), work1.getId()));
+        LiveData<List<WorkStatus>> liveData =
+                mWorkManagerImpl.getStatuses(Arrays.asList(work0.getId(), work1.getId()));
         liveData.observe(testLifecycleOwner, mockObserver);
 
-        ArgumentCaptor<Map<String, WorkStatus>> captor =
-                ArgumentCaptor.forClass(Map.class);
+        ArgumentCaptor<List<WorkStatus>> captor =
+                ArgumentCaptor.forClass(List.class);
         verify(mockObserver).onChanged(captor.capture());
         assertThat(captor.getValue(), is(not(nullValue())));
         assertThat(captor.getValue().size(), is(2));
 
-        Map expectedMap = new HashMap(2);
-        expectedMap.put(work0.getId(), ENQUEUED);
-        expectedMap.put(work1.getId(), ENQUEUED);
-        assertThat(captor.getValue(), is(expectedMap));
+        WorkStatus workStatus0 = new WorkStatus(work0.getId(), ENQUEUED, Arguments.EMPTY);
+        WorkStatus workStatus1 = new WorkStatus(work1.getId(), ENQUEUED, Arguments.EMPTY);
+        assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1));
 
         WorkSpecDao workSpecDao = mDatabase.workSpecDao();
-        workSpecDao.setStatus(RUNNING, work0.getId());
+        workSpecDao.setState(RUNNING, work0.getId());
 
         verify(mockObserver, times(2)).onChanged(captor.capture());
         assertThat(captor.getValue(), is(not(nullValue())));
         assertThat(captor.getValue().size(), is(2));
 
-        expectedMap.put(work0.getId(), RUNNING);
-        assertThat(captor.getValue(), is(expectedMap));
+        workStatus0 = new WorkStatus(work0.getId(), RUNNING, Arguments.EMPTY);
+        assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1));
 
         clearInvocations(mockObserver);
-        workSpecDao.setStatus(RUNNING, work1.getId());
+        workSpecDao.setState(RUNNING, work1.getId());
 
         verify(mockObserver).onChanged(captor.capture());
         assertThat(captor.getValue(), is(not(nullValue())));
         assertThat(captor.getValue().size(), is(2));
 
-        expectedMap.put(work1.getId(), RUNNING);
-        assertThat(captor.getValue(), is(expectedMap));
+        workStatus1 = new WorkStatus(work1.getId(), RUNNING, Arguments.EMPTY);
+        assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1));
 
         liveData.removeObservers(testLifecycleOwner);
     }
@@ -627,8 +625,8 @@
 
         mWorkManagerImpl.cancelWorkForId(work0.getId());
 
-        assertThat(workSpecDao.getWorkSpecStatus(work0.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work1.getId()), is(not(CANCELLED)));
+        assertThat(workSpecDao.getWorkSpecState(work0.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work1.getId()), is(not(CANCELLED)));
     }
 
     @Test
@@ -650,10 +648,10 @@
 
         mWorkManagerImpl.cancelAllWorkWithTag(tagToClear);
 
-        assertThat(workSpecDao.getWorkSpecStatus(work0.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work1.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work2.getId()), is(not(CANCELLED)));
-        assertThat(workSpecDao.getWorkSpecStatus(work3.getId()), is(not(CANCELLED)));
+        assertThat(workSpecDao.getWorkSpecState(work0.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work1.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work2.getId()), is(not(CANCELLED)));
+        assertThat(workSpecDao.getWorkSpecState(work3.getId()), is(not(CANCELLED)));
     }
 
     @Test
@@ -697,11 +695,11 @@
         mWorkManagerImpl.cancelAllWorkWithTag(tag);
 
         WorkSpecDao workSpecDao = mDatabase.workSpecDao();
-        assertThat(workSpecDao.getWorkSpecStatus(work0.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work1.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work2.getId()), is(CANCELLED));
-        assertThat(workSpecDao.getWorkSpecStatus(work3.getId()), is(not(CANCELLED)));
-        assertThat(workSpecDao.getWorkSpecStatus(work4.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work0.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work1.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work2.getId()), is(CANCELLED));
+        assertThat(workSpecDao.getWorkSpecState(work3.getId()), is(not(CANCELLED)));
+        assertThat(workSpecDao.getWorkSpecState(work4.getId()), is(CANCELLED));
     }
 
     @Test
@@ -709,13 +707,13 @@
     public void testPruneDatabase() {
         Work enqueuedWork = new Work.Builder(TestWorker.class).build();
         Work finishedPrerequisiteWork1A =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedPrerequisiteWork1B =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedPrerequisiteWork2 =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
         Work finishedFinalWork =
-                new Work.Builder(TestWorker.class).withInitialStatus(SUCCEEDED).build();
+                new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build();
 
         insertWorkSpecAndTags(enqueuedWork);
         insertWorkSpecAndTags(finishedPrerequisiteWork1A);
@@ -750,23 +748,23 @@
     public void testGenerateCleanupCallback_resetsRunningWorkStatuses() {
         WorkSpecDao workSpecDao = mDatabase.workSpecDao();
 
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(RUNNING).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(RUNNING).build();
         workSpecDao.insertWorkSpec(getWorkSpec(work));
 
-        assertThat(workSpecDao.getWorkSpecStatus(work.getId()), is(RUNNING));
+        assertThat(workSpecDao.getWorkSpecState(work.getId()), is(RUNNING));
 
         SupportSQLiteOpenHelper openHelper = mDatabase.getOpenHelper();
         SupportSQLiteDatabase db = openHelper.getWritableDatabase();
         WorkDatabase.generateCleanupCallback().onOpen(db);
 
-        assertThat(workSpecDao.getWorkSpecStatus(work.getId()), is(ENQUEUED));
+        assertThat(workSpecDao.getWorkSpecState(work.getId()), is(ENQUEUED));
     }
 
     @Test
     @SmallTest
     public void testGenerateCleanupCallback_deletesOldFinishedWork() {
         Work work1 = new Work.Builder(TestWorker.class)
-                .withInitialStatus(SUCCEEDED)
+                .withInitialState(SUCCEEDED)
                 .withPeriodStartTime(0L)
                 .build();
         Work work2 = new Work.Builder(TestWorker.class).withPeriodStartTime(Long.MAX_VALUE).build();
@@ -787,15 +785,15 @@
     @SmallTest
     public void testGenerateCleanupCallback_deletesDanglingBlockedDependencies() {
         Work work1 = new Work.Builder(TestWorker.class)
-                .withInitialStatus(FAILED)
+                .withInitialState(FAILED)
                 .withPeriodStartTime(0L)
                 .build();
         Work work2 = new Work.Builder(TestWorker.class)
-                .withInitialStatus(BLOCKED)
+                .withInitialState(BLOCKED)
                 .withPeriodStartTime(Long.MAX_VALUE)
                 .build();
         Work work3 = new Work.Builder(TestWorker.class)
-                .withInitialStatus(BLOCKED)
+                .withInitialState(BLOCKED)
                 .withPeriodStartTime(Long.MAX_VALUE)
                 .build();
 
diff --git a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkerWrapperTest.java b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkerWrapperTest.java
index af7684f..3d66072 100644
--- a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkerWrapperTest.java
+++ b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkerWrapperTest.java
@@ -16,12 +16,12 @@
 
 package android.arch.background.workmanager.impl;
 
-import static android.arch.background.workmanager.WorkStatus.BLOCKED;
-import static android.arch.background.workmanager.WorkStatus.CANCELLED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.FAILED;
-import static android.arch.background.workmanager.WorkStatus.RUNNING;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.BLOCKED;
+import static android.arch.background.workmanager.State.CANCELLED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.FAILED;
+import static android.arch.background.workmanager.State.RUNNING;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
@@ -96,7 +96,7 @@
                 .build()
                 .run();
         verify(mMockListener).onExecuted(work.getId(), true, false);
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(SUCCEEDED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(SUCCEEDED));
     }
 
     @Test
@@ -139,7 +139,7 @@
     @Test
     @SmallTest
     public void testNotEnqueued() throws InterruptedException {
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(RUNNING).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(RUNNING).build();
         insertWork(work);
         new WorkerWrapper.Builder(mContext, mDatabase, work.getId())
                 .withListener(mMockListener)
@@ -151,14 +151,14 @@
     @Test
     @SmallTest
     public void testCancelled() throws InterruptedException {
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(CANCELLED).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(CANCELLED).build();
         insertWork(work);
         new WorkerWrapper.Builder(mContext, mDatabase, work.getId())
                 .withListener(mMockListener)
                 .build()
                 .run();
         verify(mMockListener).onExecuted(work.getId(), false, false);
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(CANCELLED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(CANCELLED));
     }
 
     @Test
@@ -172,7 +172,7 @@
                 .build()
                 .run();
         verify(mMockListener).onExecuted(work.getId(), false, false);
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(FAILED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(FAILED));
     }
 
     @Test
@@ -186,7 +186,7 @@
                 .build()
                 .run();
         verify(mMockListener).onExecuted(work.getId(), false, false);
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(FAILED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(FAILED));
     }
 
     @Test
@@ -199,7 +199,7 @@
                 .build()
                 .run();
         verify(mMockListener).onExecuted(work.getId(), false, false);
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(FAILED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(FAILED));
     }
 
     @Test
@@ -212,7 +212,7 @@
                 .build();
         Executors.newSingleThreadExecutor().submit(wrapper);
         Thread.sleep(2000L); // Async wait duration.
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(RUNNING));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(RUNNING));
         Thread.sleep(SleepTestWorker.SLEEP_DURATION);
         verify(mMockListener).onExecuted(work.getId(), true, false);
     }
@@ -221,7 +221,7 @@
     @SmallTest
     public void testDependencies() {
         Work prerequisiteWork = new Work.Builder(TestWorker.class).build();
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(BLOCKED).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(BLOCKED).build();
         Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId());
 
         mDatabase.beginTransaction();
@@ -234,8 +234,8 @@
             mDatabase.endTransaction();
         }
 
-        assertThat(mWorkSpecDao.getWorkSpecStatus(prerequisiteWork.getId()), is(ENQUEUED));
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(BLOCKED));
+        assertThat(mWorkSpecDao.getWorkSpecState(prerequisiteWork.getId()), is(ENQUEUED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(BLOCKED));
         assertThat(mDependencyDao.hasCompletedAllPrerequisites(work.getId()), is(false));
 
         new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork.getId())
@@ -244,8 +244,8 @@
                 .build()
                 .run();
 
-        assertThat(mWorkSpecDao.getWorkSpecStatus(prerequisiteWork.getId()), is(SUCCEEDED));
-        assertThat(mWorkSpecDao.getWorkSpecStatus(work.getId()), is(ENQUEUED));
+        assertThat(mWorkSpecDao.getWorkSpecState(prerequisiteWork.getId()), is(SUCCEEDED));
+        assertThat(mWorkSpecDao.getWorkSpecState(work.getId()), is(ENQUEUED));
         assertThat(mDependencyDao.hasCompletedAllPrerequisites(work.getId()), is(true));
 
         ArgumentCaptor<WorkSpec> captor = ArgumentCaptor.forClass(WorkSpec.class);
@@ -257,7 +257,7 @@
     @SmallTest
     public void testDependencies_passesOutputs() {
         Work prerequisiteWork = new Work.Builder(ChainedArgumentWorker.class).build();
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(BLOCKED).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(BLOCKED).build();
         Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId());
 
         mDatabase.beginTransaction();
@@ -327,7 +327,7 @@
     @SmallTest
     public void testDependencies_setsPeriodStartTimesForUnblockedWork() {
         Work prerequisiteWork = new Work.Builder(TestWorker.class).build();
-        Work work = new Work.Builder(TestWorker.class).withInitialStatus(BLOCKED).build();
+        Work work = new Work.Builder(TestWorker.class).withInitialState(BLOCKED).build();
         Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId());
 
         mDatabase.beginTransaction();
@@ -416,7 +416,7 @@
         WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId);
         verify(mMockListener).onExecuted(periodicWorkId, true, false);
         assertThat(periodicWorkSpecAfterFirstRun.getRunAttemptCount(), is(0));
-        assertThat(periodicWorkSpecAfterFirstRun.getStatus(), is(ENQUEUED));
+        assertThat(periodicWorkSpecAfterFirstRun.getState(), is(ENQUEUED));
     }
 
     @Test
@@ -437,7 +437,7 @@
         WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId);
         verify(mMockListener).onExecuted(periodicWorkId, false, false);
         assertThat(periodicWorkSpecAfterFirstRun.getRunAttemptCount(), is(0));
-        assertThat(periodicWorkSpecAfterFirstRun.getStatus(), is(ENQUEUED));
+        assertThat(periodicWorkSpecAfterFirstRun.getState(), is(ENQUEUED));
     }
 
     @Test
@@ -458,7 +458,7 @@
         WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId);
         verify(mMockListener).onExecuted(periodicWorkId, false, true);
         assertThat(periodicWorkSpecAfterFirstRun.getRunAttemptCount(), is(1));
-        assertThat(periodicWorkSpecAfterFirstRun.getStatus(), is(ENQUEUED));
+        assertThat(periodicWorkSpecAfterFirstRun.getState(), is(ENQUEUED));
     }
 
     @Test
diff --git a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessorTest.java b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessorTest.java
index 5242949..cac52e9 100644
--- a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessorTest.java
+++ b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessorTest.java
@@ -15,9 +15,9 @@
  */
 package android.arch.background.workmanager.impl.foreground;
 
-import static android.arch.background.workmanager.WorkStatus.BLOCKED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.BLOCKED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -90,7 +90,7 @@
         drain();
         assertThat(mForegroundProcessor.process(work.getId()), is(true));
         drain();
-        assertThat(mDatabase.workSpecDao().getWorkSpecStatus(work.getId()), is(SUCCEEDED));
+        assertThat(mDatabase.workSpecDao().getWorkSpecState(work.getId()), is(SUCCEEDED));
     }
 
     @Test
@@ -98,7 +98,7 @@
     public void testProcess_dependentWorkers() throws TimeoutException, InterruptedException {
         Work prerequisite = new Work.Builder(TestWorker.class).build();
         Work workSpec = new Work.Builder(TestWorker.class)
-                .withInitialStatus(BLOCKED)
+                .withInitialState(BLOCKED)
                 .build();
 
         insertWork(prerequisite);
@@ -109,9 +109,9 @@
         assertThat(mForegroundProcessor.process(prerequisite.getId()), is(true));
         drain();
 
-        assertThat(mDatabase.workSpecDao().getWorkSpecStatus(prerequisite.getId()),
+        assertThat(mDatabase.workSpecDao().getWorkSpecState(prerequisite.getId()),
                 is(SUCCEEDED));
-        assertThat(mDatabase.workSpecDao().getWorkSpecStatus(workSpec.getId()),
+        assertThat(mDatabase.workSpecDao().getWorkSpecState(workSpec.getId()),
                 is(SUCCEEDED));
     }
 
@@ -125,7 +125,7 @@
         drain();
         assertThat(mForegroundProcessor.process(work.getId()), is(true));
         drain();
-        assertThat(mDatabase.workSpecDao().getWorkSpecStatus(work.getId()), is(SUCCEEDED));
+        assertThat(mDatabase.workSpecDao().getWorkSpecState(work.getId()), is(SUCCEEDED));
     }
 
     @Test
@@ -138,7 +138,7 @@
         drain();
         assertThat(mForegroundProcessor.process(work.getId()), is(false));
         drain();
-        assertThat(mDatabase.workSpecDao().getWorkSpecStatus(work.getId()), is(ENQUEUED));
+        assertThat(mDatabase.workSpecDao().getWorkSpecState(work.getId()), is(ENQUEUED));
     }
 
     private void postLifecycleEventOnMainThread(@NonNull final Lifecycle.Event event) {
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/BaseWork.java b/background/workmanager/src/main/java/android/arch/background/workmanager/BaseWork.java
index 842005c..fc3f0bb 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/BaseWork.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/BaseWork.java
@@ -98,13 +98,13 @@
         W build();
 
         /**
-         * Set the initial status for this work.  Used in testing only.
+         * Set the initial state for this work.  Used in testing only.
          *
-         * @param status The {@link WorkStatus} to set
+         * @param state The {@link State} to set
          * @return The current {@link Builder}
          */
         @VisibleForTesting
-        B withInitialStatus(@NonNull WorkStatus status);
+        B withInitialState(@NonNull State state);
 
         /**
          * Set the initial run attempt count for this work.  Used in testing only.
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/PeriodicWork.java b/background/workmanager/src/main/java/android/arch/background/workmanager/PeriodicWork.java
index c95ea43..acb17aa 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/PeriodicWork.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/PeriodicWork.java
@@ -117,8 +117,8 @@
 
         @VisibleForTesting
         @Override
-        public Builder withInitialStatus(@NonNull WorkStatus status) {
-            mInternalBuilder.withInitialStatus(status);
+        public Builder withInitialState(@NonNull State state) {
+            mInternalBuilder.withInitialState(state);
             return this;
         }
 
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/State.java b/background/workmanager/src/main/java/android/arch/background/workmanager/State.java
new file mode 100644
index 0000000..8bad92c
--- /dev/null
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/State.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 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.arch.background.workmanager;
+
+/**
+ * The current status of a unit of work.
+ */
+public enum State {
+
+    /**
+     * The status for work that is enqueued (hasn't completed and isn't running)
+     */
+    ENQUEUED,
+
+    /**
+     * The status for work that is currently being executed
+     */
+    RUNNING,
+
+    /**
+     * The status for work that has completed successfully
+     */
+    SUCCEEDED,
+
+    /**
+     * The status for work that has completed in a failure state
+     */
+    FAILED,
+
+    /**
+     * The status for work that is currently blocked because its prerequisites haven't finished
+     * successfully
+     */
+    BLOCKED,
+
+    /**
+     * The status for work that has been cancelled and will not execute
+     */
+    CANCELLED
+}
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/Work.java b/background/workmanager/src/main/java/android/arch/background/workmanager/Work.java
index 15f6197..037db19 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/Work.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/Work.java
@@ -129,8 +129,8 @@
 
         @VisibleForTesting
         @Override
-        public Builder withInitialStatus(WorkStatus status) {
-            mInternalBuilder.withInitialStatus(status);
+        public Builder withInitialState(State state) {
+            mInternalBuilder.withInitialState(state);
             return this;
         }
 
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkContinuation.java b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkContinuation.java
index 462d214..118e538 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkContinuation.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkContinuation.java
@@ -23,7 +23,6 @@
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
 
 /**
  * An opaque class that allows you to chain together {@link Work}.
@@ -51,14 +50,13 @@
     public abstract WorkContinuation then(@NonNull List<Work> work);
 
     /**
-     * Returns a {@link LiveData} mapping of work identifiers to their statuses for all work in this
-     * chain.  Whenever the status of one of the work enqueued in this chain changes, any attached
-     * {@link android.arch.lifecycle.Observer}s will trigger.
+     * Returns a {@link LiveData} list of {@link WorkStatus} that provides information about work,
+     * their progress, and any resulting output.  If status or outputs of any of the jobs in this
+     * chain changes, any attached {@link android.arch.lifecycle.Observer}s will trigger.
      *
-     * @return A {@link LiveData} containing a map of work identifiers to their corresponding
-     * {@link WorkStatus}
+     * @return A {@link LiveData} containing a list of {@link WorkStatus}es
      */
-    public abstract LiveData<Map<String, WorkStatus>> getStatuses();
+    public abstract LiveData<List<WorkStatus>> getStatuses();
 
     /**
      * Enqueues the instance of {@link WorkContinuation} on the background thread.
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkManager.java b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkManager.java
index 754504f..624851d 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkManager.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkManager.java
@@ -157,19 +157,11 @@
     public abstract void pruneDatabase();
 
     /**
-     * Gets the {@link WorkStatus} for a given work id.
+     * Gets the {@link State} for a given work id.
      *
      * @param id The id of the work
-     * @return A {@link LiveData} of the {@link WorkStatus}
+     * @return A {@link LiveData} of the {@link WorkStatus} associated with {@code id}
      */
     public abstract LiveData<WorkStatus> getStatus(@NonNull String id);
 
-    /**
-     * Gets the output for a given work id.
-     *
-     * @param id The id of the work
-     * @return A {@link LiveData} of the output
-     */
-    public abstract LiveData<Arguments> getOutput(@NonNull String id);
-
 }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkStatus.java b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkStatus.java
index c5a7427..aed836c 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/WorkStatus.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/WorkStatus.java
@@ -16,39 +16,54 @@
 
 package android.arch.background.workmanager;
 
+import android.support.annotation.NonNull;
+
 /**
- * The current status of a unit of work.
+ * A simple class with the id of a {@link BaseWork}, its current {@link State}, and its output.
+ * Note that output is only available for {@link State#SUCCEEDED}.
  */
-public enum WorkStatus {
 
-    /**
-     * The status for work that is enqueued (hasn't completed and isn't running)
-     */
-    ENQUEUED,
+public class WorkStatus {
 
-    /**
-     * The status for work that is currently being executed
-     */
-    RUNNING,
+    private String mId;
+    private State mState;
+    private Arguments mOutput;
 
-    /**
-     * The status for work that has completed successfully
-     */
-    SUCCEEDED,
+    public WorkStatus(@NonNull String id, @NonNull State state, @NonNull Arguments output) {
+        mId = id;
+        mState = state;
+        mOutput = output;
+    }
 
-    /**
-     * The status for work that has completed in a failure state
-     */
-    FAILED,
+    public @NonNull String getId() {
+        return mId;
+    }
 
-    /**
-     * The status for work that is currently blocked because its prerequisites haven't finished
-     * successfully
-     */
-    BLOCKED,
+    public @NonNull State getState() {
+        return mState;
+    }
 
-    /**
-     * The status for work that has been cancelled and will not execute
-     */
-    CANCELLED
+    public @NonNull Arguments getOutput() {
+        return mOutput;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        WorkStatus that = (WorkStatus) o;
+
+        if (!mId.equals(that.mId)) return false;
+        if (mState != that.mState) return false;
+        return mOutput.equals(that.mOutput);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = mId.hashCode();
+        result = 31 * result + mState.hashCode();
+        result = 31 * result + mOutput.hashCode();
+        return result;
+    }
 }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/PeriodicWorkImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/PeriodicWorkImpl.java
index 7a72e71..61b42e9 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/PeriodicWorkImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/PeriodicWorkImpl.java
@@ -21,7 +21,7 @@
 import android.arch.background.workmanager.BaseWork;
 import android.arch.background.workmanager.Constraints;
 import android.arch.background.workmanager.PeriodicWork;
-import android.arch.background.workmanager.WorkStatus;
+import android.arch.background.workmanager.State;
 import android.arch.background.workmanager.Worker;
 import android.arch.background.workmanager.impl.model.WorkSpec;
 import android.support.annotation.NonNull;
@@ -84,8 +84,8 @@
 
         @VisibleForTesting
         @Override
-        public Builder withInitialStatus(@NonNull WorkStatus status) {
-            mWorkSpec.setStatus(status);
+        public Builder withInitialState(@NonNull State state) {
+            mWorkSpec.setState(state);
             return this;
         }
 
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
index 38b6885..d6e097f 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
@@ -35,7 +35,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /**
  * A concrete implementation of {@link WorkContinuation}.
@@ -153,8 +152,8 @@
     }
 
     @Override
-    public LiveData<Map<String, WorkStatus>> getStatuses() {
-        return mWorkManagerImpl.getStatusesFor(mAllIds);
+    public LiveData<List<WorkStatus>> getStatuses() {
+        return mWorkManagerImpl.getStatuses(mAllIds);
     }
 
     @Override
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkDatabase.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkDatabase.java
index bcaa0ca..1fba806 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkDatabase.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkDatabase.java
@@ -16,12 +16,12 @@
 
 package android.arch.background.workmanager.impl;
 
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.BLOCKED;
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.CANCELLED;
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.ENQUEUED;
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.FAILED;
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.RUNNING;
-import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StatusIds.SUCCEEDED;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.BLOCKED;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.CANCELLED;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.ENQUEUED;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.FAILED;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.RUNNING;
+import static android.arch.background.workmanager.impl.model.EnumTypeConverters.StateIds.SUCCEEDED;
 
 import android.arch.background.workmanager.Arguments;
 import android.arch.background.workmanager.ContentUriTriggers;
@@ -44,7 +44,7 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * A Room database for keeping track of work statuses.
+ * A Room database for keeping track of work states.
  *
  * @hide
  */
@@ -55,12 +55,12 @@
 public abstract class WorkDatabase extends RoomDatabase {
 
     private static final String DB_NAME = "android.arch.background.workmanager.work";
-    private static final String CLEANUP_SQL = "UPDATE workspec SET status=" + ENQUEUED
-            + " WHERE status=" + RUNNING;
-    private static final String PRUNE_SQL_PREFIX = "DELETE FROM workspec WHERE status IN ("
+    private static final String CLEANUP_SQL = "UPDATE workspec SET state=" + ENQUEUED
+            + " WHERE state=" + RUNNING;
+    private static final String PRUNE_SQL_PREFIX = "DELETE FROM workspec WHERE state IN ("
             + SUCCEEDED + ", " + FAILED + ", " + CANCELLED + ") AND period_start_time < ";
     private static final String BLOCKED_WITHOUT_PREREQUISITES_WHERE_CLAUSE =
-            "status=" + BLOCKED + " AND id NOT IN "
+            "state=" + BLOCKED + " AND id NOT IN "
             + "(SELECT DISTINCT work_spec_id FROM dependency)";
 
     private static final long PRUNE_THRESHOLD_MILLIS = TimeUnit.DAYS.toMillis(7);
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkImpl.java
index 754e138..abe0c9e 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkImpl.java
@@ -21,8 +21,8 @@
 import android.arch.background.workmanager.Constraints;
 import android.arch.background.workmanager.InputMerger;
 import android.arch.background.workmanager.OverwritingInputMerger;
+import android.arch.background.workmanager.State;
 import android.arch.background.workmanager.Work;
-import android.arch.background.workmanager.WorkStatus;
 import android.arch.background.workmanager.Worker;
 import android.arch.background.workmanager.impl.model.WorkSpec;
 import android.support.annotation.NonNull;
@@ -77,8 +77,8 @@
 
         @VisibleForTesting
         @Override
-        public Builder withInitialStatus(@NonNull WorkStatus status) {
-            mWorkSpec.setStatus(status);
+        public Builder withInitialState(@NonNull State state) {
+            mWorkSpec.setState(state);
             return this;
         }
 
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
index ced5d6e..babbc61 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
@@ -16,7 +16,6 @@
 
 package android.arch.background.workmanager.impl;
 
-import android.arch.background.workmanager.Arguments;
 import android.arch.background.workmanager.BaseWork;
 import android.arch.background.workmanager.ExistingWorkPolicy;
 import android.arch.background.workmanager.Work;
@@ -39,9 +38,9 @@
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.ExecutorService;
 
 /**
@@ -178,34 +177,49 @@
 
     @Override
     public LiveData<WorkStatus> getStatus(@NonNull String id) {
-        return LiveDataUtils.dedupedLiveDataFor(
-                mWorkDatabase.workSpecDao().getWorkSpecLiveDataStatus(id));
-    }
-
-    @Override
-    public LiveData<Arguments> getOutput(@NonNull String id) {
-        return LiveDataUtils.dedupedLiveDataFor(mWorkDatabase.workSpecDao().getOutput(id));
-    }
-
-    LiveData<Map<String, WorkStatus>> getStatusesFor(@NonNull List<String> workSpecIds) {
         WorkSpecDao dao = mWorkDatabase.workSpecDao();
-        final MediatorLiveData<Map<String, WorkStatus>> mediatorLiveData =
-                new MediatorLiveData<>();
+        final MediatorLiveData<WorkStatus> mediatorLiveData = new MediatorLiveData<>();
         mediatorLiveData.addSource(
-                LiveDataUtils.dedupedLiveDataFor(dao.getWorkSpecStatuses(workSpecIds)),
-                new Observer<List<WorkSpec.IdAndStatus>>() {
+                LiveDataUtils.dedupedLiveDataFor(
+                        dao.getIdStateAndOutputs(Collections.singletonList(id))),
+                new Observer<List<WorkSpec.IdStateAndOutput>>() {
                     @Override
-                    public void onChanged(@Nullable List<WorkSpec.IdAndStatus> idAndStatuses) {
-                        if (idAndStatuses == null) {
-                            return;
+                    public void onChanged(
+                            @Nullable List<WorkSpec.IdStateAndOutput> idStateAndOutputs) {
+                        WorkStatus workStatus = null;
+                        if (idStateAndOutputs != null) {
+                            WorkSpec.IdStateAndOutput idStateAndOutput = idStateAndOutputs.get(0);
+                            workStatus = new WorkStatus(
+                                    idStateAndOutput.id,
+                                    idStateAndOutput.state,
+                                    idStateAndOutput.output);
                         }
+                        mediatorLiveData.setValue(workStatus);
+                    }
+                });
+        return mediatorLiveData;
+    }
 
-                        Map<String, WorkStatus> idToStatusMap =
-                                new HashMap<>(idAndStatuses.size());
-                        for (WorkSpec.IdAndStatus idAndStatus : idAndStatuses) {
-                            idToStatusMap.put(idAndStatus.id, idAndStatus.status);
+    LiveData<List<WorkStatus>> getStatuses(@NonNull List<String> workSpecIds) {
+        WorkSpecDao dao = mWorkDatabase.workSpecDao();
+        final MediatorLiveData<List<WorkStatus>> mediatorLiveData = new MediatorLiveData<>();
+        mediatorLiveData.addSource(
+                LiveDataUtils.dedupedLiveDataFor(dao.getIdStateAndOutputs(workSpecIds)),
+                new Observer<List<WorkSpec.IdStateAndOutput>>() {
+                    @Override
+                    public void onChanged(
+                            @Nullable List<WorkSpec.IdStateAndOutput> idStateAndOutputs) {
+                        List<WorkStatus> workStatuses = null;
+                        if (idStateAndOutputs != null) {
+                            workStatuses = new ArrayList<>(idStateAndOutputs.size());
+                            for (WorkSpec.IdStateAndOutput idStateAndOutput : idStateAndOutputs) {
+                                workStatuses.add(new WorkStatus(
+                                        idStateAndOutput.id,
+                                        idStateAndOutput.state,
+                                        idStateAndOutput.output));
+                            }
                         }
-                        mediatorLiveData.setValue(idToStatusMap);
+                        mediatorLiveData.setValue(workStatuses);
                     }
                 });
         return mediatorLiveData;
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkerWrapper.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkerWrapper.java
index 74dbc14..7315360 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkerWrapper.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkerWrapper.java
@@ -16,15 +16,15 @@
 
 package android.arch.background.workmanager.impl;
 
-import static android.arch.background.workmanager.WorkStatus.CANCELLED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.FAILED;
-import static android.arch.background.workmanager.WorkStatus.RUNNING;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.CANCELLED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.FAILED;
+import static android.arch.background.workmanager.State.RUNNING;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import android.arch.background.workmanager.Arguments;
 import android.arch.background.workmanager.InputMerger;
-import android.arch.background.workmanager.WorkStatus;
+import android.arch.background.workmanager.State;
 import android.arch.background.workmanager.Worker;
 import android.arch.background.workmanager.impl.logger.Logger;
 import android.arch.background.workmanager.impl.model.DependencyDao;
@@ -83,7 +83,7 @@
             return;
         }
 
-        if (mWorkSpec.getStatus() != ENQUEUED) {
+        if (mWorkSpec.getState() != ENQUEUED) {
             notifyIncorrectStatus();
             return;
         }
@@ -119,7 +119,7 @@
         try {
             checkForInterruption();
             Worker.WorkerResult result = mWorker.doWork();
-            if (mWorkSpecDao.getWorkSpecStatus(mWorkSpecId) != CANCELLED) {
+            if (mWorkSpecDao.getWorkSpecState(mWorkSpecId) != CANCELLED) {
                 checkForInterruption();
                 handleResult(result);
             }
@@ -131,7 +131,7 @@
 
     private void notifyIncorrectStatus() {
         // incorrect status is treated as a false-y attempt at execution
-        WorkStatus status = mWorkSpec.getStatus();
+        State status = mWorkSpec.getState();
         if (status == RUNNING) {
             Logger.debug(TAG, "Status for %s is RUNNING;"
                     + "not doing any work and rescheduling for later execution", mWorkSpecId);
@@ -193,7 +193,7 @@
     private void setRunning() {
         mWorkDatabase.beginTransaction();
         try {
-            mWorkSpecDao.setStatus(RUNNING, mWorkSpecId);
+            mWorkSpecDao.setState(RUNNING, mWorkSpecId);
             mWorkSpecDao.incrementWorkSpecRunAttemptCount(mWorkSpecId);
             mWorkDatabase.setTransactionSuccessful();
         } finally {
@@ -202,14 +202,14 @@
     }
 
     private void setFailedAndNotify() {
-        mWorkSpecDao.setStatus(FAILED, mWorkSpecId);
+        mWorkSpecDao.setState(FAILED, mWorkSpecId);
         notifyListener(false, false);
     }
 
     private void rescheduleAndNotify(boolean isSuccessful) {
         mWorkDatabase.beginTransaction();
         try {
-            mWorkSpecDao.setStatus(ENQUEUED, mWorkSpecId);
+            mWorkSpecDao.setState(ENQUEUED, mWorkSpecId);
             // TODO(xbhatnag): Period Start Time is confusing for non-periodic work. Rename.
             mWorkSpecDao.setPeriodStartTime(mWorkSpecId, System.currentTimeMillis());
             mWorkDatabase.setTransactionSuccessful();
@@ -225,7 +225,7 @@
             long currentPeriodStartTime = mWorkSpec.getPeriodStartTime();
             long nextPeriodStartTime = currentPeriodStartTime + mWorkSpec.getIntervalDuration();
             mWorkSpecDao.setPeriodStartTime(mWorkSpecId, nextPeriodStartTime);
-            mWorkSpecDao.setStatus(ENQUEUED, mWorkSpecId);
+            mWorkSpecDao.setState(ENQUEUED, mWorkSpecId);
             mWorkSpecDao.resetWorkSpecRunAttemptCount(mWorkSpecId);
             mWorkDatabase.setTransactionSuccessful();
         } finally {
@@ -237,7 +237,7 @@
     private void setSucceededAndNotify() {
         mWorkDatabase.beginTransaction();
         try {
-            mWorkSpecDao.setStatus(SUCCEEDED, mWorkSpecId);
+            mWorkSpecDao.setState(SUCCEEDED, mWorkSpecId);
 
             // Update Arguments as necessary.
             Arguments outputArgs = mWorker.getOutput();
@@ -252,7 +252,7 @@
             for (String dependentWorkId : dependentWorkIds) {
                 if (mDependencyDao.hasCompletedAllPrerequisites(dependentWorkId)) {
                     Logger.debug(TAG, "Setting status to enqueued for %s", dependentWorkId);
-                    mWorkSpecDao.setStatus(ENQUEUED, dependentWorkId);
+                    mWorkSpecDao.setState(ENQUEUED, dependentWorkId);
                     mWorkSpecDao.setPeriodStartTime(dependentWorkId, currentTimeMillis);
                     unblockedWorkIds.add(dependentWorkId);
                 }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/background/systemalarm/SystemAlarmServiceImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/background/systemalarm/SystemAlarmServiceImpl.java
index f022e0b..111f47d 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/background/systemalarm/SystemAlarmServiceImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/background/systemalarm/SystemAlarmServiceImpl.java
@@ -16,7 +16,7 @@
 
 package android.arch.background.workmanager.impl.background.systemalarm;
 
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
+import static android.arch.background.workmanager.State.ENQUEUED;
 
 import android.app.Service;
 import android.arch.background.workmanager.Constraints;
@@ -196,7 +196,7 @@
     }
 
     private static boolean isEnqueued(@NonNull WorkSpec workSpec) {
-        return workSpec.getStatus() == ENQUEUED;
+        return workSpec.getState() == ENQUEUED;
     }
 
     private static WorkSpec removeWorkSpecWithId(String workSpecId, List<WorkSpec> workSpecs) {
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessor.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessor.java
index f252458..675b332 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessor.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/foreground/ForegroundProcessor.java
@@ -15,7 +15,7 @@
  */
 package android.arch.background.workmanager.impl.foreground;
 
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
+import static android.arch.background.workmanager.State.ENQUEUED;
 
 import android.arch.background.workmanager.Constraints;
 import android.arch.background.workmanager.impl.Processor;
@@ -91,7 +91,7 @@
         // status as well.
         Logger.debug(TAG, "Enqueued WorkSpecs updated. Size : ", workSpecs.size());
         for (WorkSpec workSpec : workSpecs) {
-            if (workSpec.getStatus() == ENQUEUED
+            if (workSpec.getState() == ENQUEUED
                     && Constraints.NONE.equals(workSpec.getConstraints())) {
                 Logger.debug(TAG, "%s can be processed immediately", workSpec);
                 process(workSpec.getId());
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/DependencyDao.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/DependencyDao.java
index 67b25f6..375b755 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/DependencyDao.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/DependencyDao.java
@@ -44,8 +44,8 @@
      * @return {@code true} if the {@link WorkSpec} has no pending prerequisites.
      */
     @Query("SELECT COUNT(*)=0 FROM dependency WHERE work_spec_id=:id AND prerequisite_id IN "
-            + "(SELECT id FROM workspec WHERE status!="
-            + EnumTypeConverters.StatusIds.SUCCEEDED + ")")
+            + "(SELECT id FROM workspec WHERE state!="
+            + EnumTypeConverters.StateIds.SUCCEEDED + ")")
     boolean hasCompletedAllPrerequisites(String id);
 
     /**
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/EnumTypeConverters.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/EnumTypeConverters.java
index b436462..c00a586 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/EnumTypeConverters.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/EnumTypeConverters.java
@@ -18,16 +18,16 @@
 
 import static android.arch.background.workmanager.BackoffPolicy.EXPONENTIAL;
 import static android.arch.background.workmanager.BackoffPolicy.LINEAR;
-import static android.arch.background.workmanager.WorkStatus.BLOCKED;
-import static android.arch.background.workmanager.WorkStatus.CANCELLED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.FAILED;
-import static android.arch.background.workmanager.WorkStatus.RUNNING;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.BLOCKED;
+import static android.arch.background.workmanager.State.CANCELLED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.FAILED;
+import static android.arch.background.workmanager.State.RUNNING;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import android.arch.background.workmanager.BackoffPolicy;
 import android.arch.background.workmanager.NetworkType;
-import android.arch.background.workmanager.WorkStatus;
+import android.arch.background.workmanager.State;
 import android.arch.persistence.room.TypeConverter;
 
 /**
@@ -37,9 +37,9 @@
 public class EnumTypeConverters {
 
     /**
-     * Integer identifiers that map to {@link WorkStatus}.
+     * Integer identifiers that map to {@link State}.
      */
-    public interface StatusIds {
+    public interface StateIds {
         int ENQUEUED = 0;
         int RUNNING = 1;
         int SUCCEEDED = 2;
@@ -68,68 +68,68 @@
     }
 
     /**
-     * TypeConverter for a WorkStatus to an int.
+     * TypeConverter for a State to an int.
      *
-     * @param workStatus The input WorkStatus
+     * @param state The input State
      * @return The associated int constant
      */
     @TypeConverter
-    public static int workStatusToInt(WorkStatus workStatus) {
-        switch (workStatus) {
+    public static int stateToInt(State state) {
+        switch (state) {
             case ENQUEUED:
-                return StatusIds.ENQUEUED;
+                return StateIds.ENQUEUED;
 
             case RUNNING:
-                return StatusIds.RUNNING;
+                return StateIds.RUNNING;
 
             case SUCCEEDED:
-                return StatusIds.SUCCEEDED;
+                return StateIds.SUCCEEDED;
 
             case FAILED:
-                return StatusIds.FAILED;
+                return StateIds.FAILED;
 
             case BLOCKED:
-                return StatusIds.BLOCKED;
+                return StateIds.BLOCKED;
 
             case CANCELLED:
-                return StatusIds.CANCELLED;
+                return StateIds.CANCELLED;
 
             default:
                 throw new IllegalArgumentException(
-                        "Could not convert " + workStatus + " to int");
+                        "Could not convert " + state + " to int");
         }
     }
 
     /**
-     * TypeConverter for an int to a WorkStatus.
+     * TypeConverter for an int to a State.
      *
      * @param value The input integer
-     * @return The associated WorkStatus enum value
+     * @return The associated State enum value
      */
     @TypeConverter
-    public static WorkStatus intToWorkStatus(int value) {
+    public static State intToState(int value) {
         switch (value) {
-            case StatusIds.ENQUEUED:
+            case StateIds.ENQUEUED:
                 return ENQUEUED;
 
-            case StatusIds.RUNNING:
+            case StateIds.RUNNING:
                 return RUNNING;
 
-            case StatusIds.SUCCEEDED:
+            case StateIds.SUCCEEDED:
                 return SUCCEEDED;
 
-            case StatusIds.FAILED:
+            case StateIds.FAILED:
                 return FAILED;
 
-            case StatusIds.BLOCKED:
+            case StateIds.BLOCKED:
                 return BLOCKED;
 
-            case StatusIds.CANCELLED:
+            case StateIds.CANCELLED:
                 return CANCELLED;
 
             default:
                 throw new IllegalArgumentException(
-                        "Could not convert " + value + " to WorkStatus");
+                        "Could not convert " + value + " to State");
         }
     }
 
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpec.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpec.java
index 8d13f20..07ef97a 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpec.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpec.java
@@ -20,13 +20,13 @@
 import static android.arch.background.workmanager.BaseWork.MIN_BACKOFF_MILLIS;
 import static android.arch.background.workmanager.PeriodicWork.MIN_PERIODIC_FLEX_MILLIS;
 import static android.arch.background.workmanager.PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
+import static android.arch.background.workmanager.State.ENQUEUED;
 
 import android.arch.background.workmanager.Arguments;
 import android.arch.background.workmanager.BackoffPolicy;
 import android.arch.background.workmanager.BaseWork;
 import android.arch.background.workmanager.Constraints;
-import android.arch.background.workmanager.WorkStatus;
+import android.arch.background.workmanager.State;
 import android.arch.background.workmanager.impl.logger.Logger;
 import android.arch.persistence.room.ColumnInfo;
 import android.arch.persistence.room.Embedded;
@@ -46,8 +46,8 @@
     @NonNull
     String mId;
 
-    @ColumnInfo(name = "status")
-    WorkStatus mStatus = ENQUEUED;
+    @ColumnInfo(name = "state")
+    State mState = ENQUEUED;
 
     @ColumnInfo(name = "worker_class_name")
     String mWorkerClassName;
@@ -101,12 +101,12 @@
         mId = id;
     }
 
-    public WorkStatus getStatus() {
-        return mStatus;
+    public State getState() {
+        return mState;
     }
 
-    public void setStatus(WorkStatus status) {
-        mStatus = status;
+    public void setState(State state) {
+        mState = state;
     }
 
     public String getWorkerClassName() {
@@ -186,7 +186,7 @@
     }
 
     public boolean isBackedOff() {
-        return mStatus == ENQUEUED && mRunAttemptCount > 0;
+        return mState == ENQUEUED && mRunAttemptCount > 0;
     }
 
     /**
@@ -313,7 +313,7 @@
         }
         WorkSpec other = (WorkSpec) o;
         return mId.equals(other.mId)
-                && mStatus == other.mStatus
+                && mState == other.mState
                 && mInitialDelay == other.mInitialDelay
                 && mIntervalDuration == other.mIntervalDuration
                 && mFlexDuration == other.mFlexDuration
@@ -336,7 +336,7 @@
     @Override
     public int hashCode() {
         int result = mId.hashCode();
-        result = 31 * result + mStatus.hashCode();
+        result = 31 * result + mState.hashCode();
         result = 31 * result + (mWorkerClassName != null ? mWorkerClassName.hashCode() : 0);
         result = 31 * result
                 + (mInputMergerClassName != null ? mInputMergerClassName.hashCode() : 0);
@@ -358,32 +358,66 @@
     }
 
     /**
-     * A POJO containing the ID and status of a WorkSpec.
+     * A POJO containing the ID and state of a WorkSpec.
      */
-    public static class IdAndStatus {
+    public static class IdAndState {
 
         @ColumnInfo(name = "id")
         public String id;
 
-
-        @ColumnInfo(name = "status")
-        public WorkStatus status;
+        @ColumnInfo(name = "state")
+        public State state;
 
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
 
-            IdAndStatus that = (IdAndStatus) o;
+            IdAndState that = (IdAndState) o;
 
-            if (status != that.status) return false;
+            if (state != that.state) return false;
             return id.equals(that.id);
         }
 
         @Override
         public int hashCode() {
             int result = id.hashCode();
-            result = 31 * result + status.hashCode();
+            result = 31 * result + state.hashCode();
+            return result;
+        }
+    }
+
+    /**
+     * A POJO containing the ID, state, and output of a WorkSpec.
+     */
+    public static class IdStateAndOutput {
+
+        @ColumnInfo(name = "id")
+        public String id;
+
+        @ColumnInfo(name = "state")
+        public State state;
+
+        @ColumnInfo(name = "output")
+        public Arguments output;
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            IdStateAndOutput that = (IdStateAndOutput) o;
+
+            if (!id.equals(that.id)) return false;
+            if (state != that.state) return false;
+            return output != null ? output.equals(that.output) : that.output == null;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = id.hashCode();
+            result = 31 * result + state.hashCode();
+            result = 31 * result + (output != null ? output.hashCode() : 0);
             return result;
         }
     }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpecDao.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpecDao.java
index 9c6f500..f57565e 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpecDao.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/model/WorkSpecDao.java
@@ -19,7 +19,7 @@
 import static android.arch.persistence.room.OnConflictStrategy.FAIL;
 
 import android.arch.background.workmanager.Arguments;
-import android.arch.background.workmanager.WorkStatus;
+import android.arch.background.workmanager.State;
 import android.arch.lifecycle.LiveData;
 import android.arch.persistence.room.Dao;
 import android.arch.persistence.room.Insert;
@@ -72,9 +72,9 @@
      * @param tag The tag of the desired {@link WorkSpec}s.
      * @return The {@link WorkSpec}s with the requested tag.
      */
-    @Query("SELECT id, status FROM workspec WHERE id IN "
+    @Query("SELECT id, state FROM workspec WHERE id IN "
             + "(SELECT work_spec_id FROM worktag WHERE tag=:tag)")
-    List<WorkSpec.IdAndStatus> getWorkSpecIdAndStatusesForTag(String tag);
+    List<WorkSpec.IdAndState> getWorkSpecIdAndStatesForTag(String tag);
 
     /**
      * @return All WorkSpec ids in the database.
@@ -83,14 +83,14 @@
     List<String> getAllWorkSpecIds();
 
     /**
-     * Updates the status of at least one {@link WorkSpec} by ID.
+     * Updates the state of at least one {@link WorkSpec} by ID.
      *
-     * @param status The new status
+     * @param state The new state
      * @param ids The IDs for the {@link WorkSpec}s to update
      * @return The number of rows that were updated
      */
-    @Query("UPDATE workspec SET status=:status WHERE id IN (:ids)")
-    int setStatus(WorkStatus status, String... ids);
+    @Query("UPDATE workspec SET state=:state WHERE id IN (:ids)")
+    int setState(State state, String... ids);
 
     /**
      * Updates the output of a {@link WorkSpec}.
@@ -129,53 +129,42 @@
     int resetWorkSpecRunAttemptCount(String id);
 
     /**
-     * Retrieves the status of a {@link WorkSpec}.
+     * Retrieves the state of a {@link WorkSpec}.
      *
      * @param id The identifier for the {@link WorkSpec}
-     * @return The status of the {@link WorkSpec}
+     * @return The state of the {@link WorkSpec}
      */
-    @Query("SELECT status FROM workspec WHERE id=:id")
-    WorkStatus getWorkSpecStatus(String id);
+    @Query("SELECT state FROM workspec WHERE id=:id")
+    State getWorkSpecState(String id);
 
     /**
-     * For a list of {@link WorkSpec} identifiers, retrieves a {@link LiveData} list of their ids
-     * and corresponding {@link WorkStatus}.
+     * For a list of {@link WorkSpec} identifiers, retrieves a {@link LiveData} list of their
+     * {@link WorkSpec.IdStateAndOutput}.
      *
-     * @param ids The identifiers of the {@link WorkSpec}s
-     * @return A {@link LiveData} list of {@link WorkSpec.IdAndStatus} with each identifier and its
-     * status
+     * @param ids The identifier of the {@link WorkSpec}s
+     * @return A {@link LiveData} list of {@link WorkSpec.IdStateAndOutput}
      */
-    @Query("SELECT id, status FROM workspec WHERE id IN (:ids)")
-    LiveData<List<WorkSpec.IdAndStatus>> getWorkSpecStatuses(List<String> ids);
+    @Query("SELECT id, state, output FROM workspec WHERE id IN (:ids)")
+    LiveData<List<WorkSpec.IdStateAndOutput>> getIdStateAndOutputs(List<String> ids);
 
     /**
-     * Retrieves a {@link LiveData} status of a {@link WorkSpec}
-     *
-     * @param id The identifier for the {@link WorkSpec}
-     * @return The {@link LiveData} {@link WorkStatus} of the {@link WorkSpec}
-     */
-    @Query("SELECT status FROM workspec WHERE id=:id")
-    LiveData<WorkStatus> getWorkSpecLiveDataStatus(String id);
-
-    /**
-     * Retrieves {@link WorkSpec}s that have status {@code ENQUEUED} or
+     * Retrieves {@link WorkSpec}s that have state {@code ENQUEUED} or
      * {@code RUNNING}, no initial delay, and are not periodic.
      *
      * @return A {@link LiveData} list of {@link WorkSpec}s.
      */
-    @Query("SELECT * FROM workspec WHERE (status=" + EnumTypeConverters.StatusIds.ENQUEUED
-            + " OR status=" + EnumTypeConverters.StatusIds.RUNNING
+    @Query("SELECT * FROM workspec WHERE (state=" + EnumTypeConverters.StateIds.ENQUEUED
+            + " OR state=" + EnumTypeConverters.StateIds.RUNNING
             + ") AND initial_delay=0 AND interval_duration=0")
     LiveData<List<WorkSpec>> getForegroundEligibleWorkSpecs();
 
     /**
-     * Retrieves {@link WorkSpec}s that have status {@code ENQUEUED} or
-     * {@code RUNNING}
+     * Retrieves {@link WorkSpec}s that have state {@code ENQUEUED} or {@code RUNNING}
      *
      * @return A {@link LiveData} list of {@link WorkSpec}s.
      */
-    @Query("SELECT * FROM workspec WHERE status=" + EnumTypeConverters.StatusIds.ENQUEUED
-            + " OR status=" + EnumTypeConverters.StatusIds.RUNNING)
+    @Query("SELECT * FROM workspec WHERE state=" + EnumTypeConverters.StateIds.ENQUEUED
+            + " OR state=" + EnumTypeConverters.StateIds.RUNNING)
     LiveData<List<WorkSpec>> getSystemAlarmEligibleWorkSpecs();
 
     /**
@@ -204,8 +193,8 @@
      * @param tag The tag used to identify the work
      * @return A list of work ids
      */
-    @Query("SELECT id FROM workspec WHERE status!=" + EnumTypeConverters.StatusIds.SUCCEEDED
-            + " AND status!=" + EnumTypeConverters.StatusIds.FAILED
+    @Query("SELECT id FROM workspec WHERE state!=" + EnumTypeConverters.StateIds.SUCCEEDED
+            + " AND state!=" + EnumTypeConverters.StateIds.FAILED
             + " AND id IN (SELECT work_spec_id FROM worktag WHERE tag=:tag)")
     List<String> getUnfinishedWorkWithTag(@NonNull String tag);
 
@@ -216,10 +205,10 @@
      *
      * @return The number of deleted work items
      */
-    @Query("DELETE FROM workspec WHERE status IN "
-            + "(" + EnumTypeConverters.StatusIds.CANCELLED + ", "
-            + EnumTypeConverters.StatusIds.FAILED + ", "
-            + EnumTypeConverters.StatusIds.SUCCEEDED + ")"
+    @Query("DELETE FROM workspec WHERE state IN "
+            + "(" + EnumTypeConverters.StateIds.CANCELLED + ", "
+            + EnumTypeConverters.StateIds.FAILED + ", "
+            + EnumTypeConverters.StateIds.SUCCEEDED + ")"
             + " AND id NOT IN (SELECT DISTINCT prerequisite_id FROM dependency)")
     int pruneLeaves();
 }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/CancelWorkRunnable.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/CancelWorkRunnable.java
index e94257c..97e1da9 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/CancelWorkRunnable.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/CancelWorkRunnable.java
@@ -16,7 +16,7 @@
 
 package android.arch.background.workmanager.impl.utils;
 
-import static android.arch.background.workmanager.WorkStatus.CANCELLED;
+import static android.arch.background.workmanager.State.CANCELLED;
 
 import android.arch.background.workmanager.impl.WorkDatabase;
 import android.arch.background.workmanager.impl.WorkManagerImpl;
@@ -81,6 +81,6 @@
         for (String id : dependentIds) {
             recursivelyCancelWorkAndDependencies(id);
         }
-        workSpecDao.setStatus(CANCELLED, workSpecId);
+        workSpecDao.setState(CANCELLED, workSpecId);
     }
 }
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
index de06ece..c09cb9b 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
@@ -18,10 +18,10 @@
 
 import static android.arch.background.workmanager.ExistingWorkPolicy.APPEND;
 import static android.arch.background.workmanager.ExistingWorkPolicy.KEEP;
-import static android.arch.background.workmanager.WorkStatus.BLOCKED;
-import static android.arch.background.workmanager.WorkStatus.ENQUEUED;
-import static android.arch.background.workmanager.WorkStatus.RUNNING;
-import static android.arch.background.workmanager.WorkStatus.SUCCEEDED;
+import static android.arch.background.workmanager.State.BLOCKED;
+import static android.arch.background.workmanager.State.ENQUEUED;
+import static android.arch.background.workmanager.State.RUNNING;
+import static android.arch.background.workmanager.State.SUCCEEDED;
 
 import android.arch.background.workmanager.BaseWork;
 import android.arch.background.workmanager.ExistingWorkPolicy;
@@ -175,7 +175,7 @@
                     return;
                 }
                 hasCompletedAllPrerequisites &=
-                        (prerequisiteWorkSpec.getStatus() == SUCCEEDED);
+                        (prerequisiteWorkSpec.getState() == SUCCEEDED);
             }
         }
 
@@ -186,18 +186,18 @@
         boolean shouldApplyExistingWorkPolicy = hasUniqueTag && !hasPrerequisite;
         if (shouldApplyExistingWorkPolicy) {
             // Get everything with the unique tag.
-            List<WorkSpec.IdAndStatus> existingWorkSpecIdAndStatuses =
-                    workDatabase.workSpecDao().getWorkSpecIdAndStatusesForTag(uniqueTag);
+            List<WorkSpec.IdAndState> existingWorkSpecIdAndStates =
+                    workDatabase.workSpecDao().getWorkSpecIdAndStatesForTag(uniqueTag);
 
-            if (!existingWorkSpecIdAndStatuses.isEmpty()) {
+            if (!existingWorkSpecIdAndStates.isEmpty()) {
                 // If appending, these are the new prerequisites.
                 if (existingWorkPolicy == APPEND) {
                     DependencyDao dependencyDao = workDatabase.dependencyDao();
                     List<String> newPrerequisiteIds = new ArrayList<>();
-                    for (WorkSpec.IdAndStatus idAndStatus : existingWorkSpecIdAndStatuses) {
-                        if (!dependencyDao.hasDependents(idAndStatus.id)) {
-                            hasCompletedAllPrerequisites &= (idAndStatus.status == SUCCEEDED);
-                            newPrerequisiteIds.add(idAndStatus.id);
+                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
+                        if (!dependencyDao.hasDependents(idAndState.id)) {
+                            hasCompletedAllPrerequisites &= (idAndState.state == SUCCEEDED);
+                            newPrerequisiteIds.add(idAndState.id);
                         }
                     }
                     prerequisiteIds = newPrerequisiteIds.toArray(prerequisiteIds);
@@ -206,8 +206,8 @@
                     // If we're keeping existing work, make sure to do so only if something is
                     // enqueued or running.
                     if (existingWorkPolicy == KEEP) {
-                        for (WorkSpec.IdAndStatus idAndStatus : existingWorkSpecIdAndStatuses) {
-                            if (idAndStatus.status == ENQUEUED || idAndStatus.status == RUNNING) {
+                        for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
+                            if (idAndState.state == ENQUEUED || idAndState.state == RUNNING) {
                                 return;
                             }
                         }
@@ -219,8 +219,8 @@
                     cancelWorkRunnable.run();
                     // And delete all the database records.
                     WorkSpecDao workSpecDao = workDatabase.workSpecDao();
-                    for (WorkSpec.IdAndStatus idAndStatus : existingWorkSpecIdAndStatuses) {
-                        workSpecDao.delete(idAndStatus.id);
+                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
+                        workSpecDao.delete(idAndState.id);
                     }
                 }
             }
@@ -230,7 +230,7 @@
             WorkSpec workSpec = work.getWorkSpec();
 
             if (hasPrerequisite && !hasCompletedAllPrerequisites) {
-                workSpec.setStatus(BLOCKED);
+                workSpec.setState(BLOCKED);
             } else {
                 // Set scheduled times only for work without prerequisites. Dependent work
                 // will set their scheduled times when they are unblocked.