@Test(
      dependsOnMethods = {
        "testListEffectors",
        "testFetchApplicationsAndEntity",
        "testTriggerSampleEffector",
        "testListApplications",
        "testReadEachSensor",
        "testPolicyWhichCapitalizes",
        "testLocatedLocation"
      })
  public void testDeleteApplication() throws TimeoutException, InterruptedException {
    waitForPageFoundResponse("/v1/applications/simple-app", ApplicationSummary.class);
    Collection<Application> apps = getManagementContext().getApplications();
    log.info("Deleting simple-app from " + apps);
    int size = apps.size();

    ClientResponse response =
        client().resource("/v1/applications/simple-app").delete(ClientResponse.class);

    assertEquals(response.getStatus(), Response.Status.ACCEPTED.getStatusCode());
    TaskSummary task = response.getEntity(TaskSummary.class);
    assertTrue(task.getDescription().toLowerCase().contains("destroy"), task.getDescription());
    assertTrue(task.getDescription().toLowerCase().contains("simple-app"), task.getDescription());

    waitForPageNotFoundResponse("/v1/applications/simple-app", ApplicationSummary.class);

    log.info("App appears gone, apps are: " + getManagementContext().getApplications());
    // more logging above, for failure in the check below

    Asserts.eventually(
        EntityFunctions.applications(getManagementContext()),
        Predicates.compose(Predicates.equalTo(size - 1), CollectionFunctionals.sizeFunction()));
  }
  @Test
  public void testRebindsSubscriptions() throws Exception {
    MyEntity2 origE =
        origApp.createAndManageChild(
            EntitySpec.create(MyEntity2.class).configure("subscribe", true));

    newApp = rebind();
    MyEntity2 newE =
        (MyEntity2) Iterables.find(newApp.getChildren(), Predicates.instanceOf(MyEntity2.class));

    newApp.setAttribute(TestApplication.MY_ATTRIBUTE, "mysensorval");
    Asserts.eventually(
        Suppliers.ofInstance(newE.getEvents()),
        Predicates.<List<String>>equalTo(ImmutableList.of("mysensorval")));
    Assert.assertEquals(newE, origE);
  }
  @Test(groups = "Integration") // takes more than 4 seconds, due to assertContinually calls
  public void testSubscriptionAndPublishingOnlyActiveWhenEntityIsManaged() throws Exception {
    MyLatchingEntityImpl.latching = false;
    origApp.createAndManageChild(
        EntitySpec.create(MyLatchingEntity.class)
            .configure("subscribe", TestApplication.MY_ATTRIBUTE)
            .configure("publish", "myvaltopublish"));
    MyLatchingEntityImpl.reset(); // after origE has been managed
    MyLatchingEntityImpl.latching = true;

    // Serialize and rebind, but don't yet manage the app
    RebindTestUtils.waitForPersisted(origApp);
    RebindTestUtils.checkCurrentMementoSerializable(origApp);
    newManagementContext = new LocalManagementContext();
    Thread thread =
        new Thread() {
          public void run() {
            try {
              RebindTestUtils.rebind(newManagementContext, mementoDir, getClass().getClassLoader());
            } catch (Exception e) {
              throw Throwables.propagate(e);
            }
          }
        };
    try {
      thread.start();
      final List<Object> events = new CopyOnWriteArrayList<Object>();

      newManagementContext
          .getSubscriptionManager()
          .subscribe(
              null,
              MyLatchingEntityImpl.MY_SENSOR,
              new SensorEventListener<Object>() {
                @Override
                public void onEvent(SensorEvent<Object> event) {
                  events.add(event.getValue());
                }
              });

      // In entity's reconstruct, publishes events are queued, and subscriptions don't yet take
      // effect
      assertTrue(Durations.await(MyLatchingEntityImpl.reconstructStartedLatch, TIMEOUT_MS));
      newManagementContext
          .getSubscriptionManager()
          .publish(
              new BasicSensorEvent<String>(TestApplication.MY_ATTRIBUTE, null, "myvaltooearly"));

      Asserts.continually(
          Suppliers.ofInstance(MyLatchingEntityImpl.events),
          Predicates.equalTo(Collections.emptyList()));
      Asserts.continually(
          Suppliers.ofInstance(events), Predicates.equalTo(Collections.emptyList()));

      // When the entity is notified of "managing", then subscriptions take effect (but missed
      // events not delivered);
      // published events remain queued
      MyLatchingEntityImpl.reconstructContinuesLatch.countDown();
      assertTrue(MyLatchingEntityImpl.managingStartedLatch.getCount() > 0);

      Asserts.continually(
          Suppliers.ofInstance(events), Predicates.equalTo(Collections.emptyList()));
      Asserts.continually(
          Suppliers.ofInstance(MyLatchingEntityImpl.events),
          Predicates.equalTo(Collections.emptyList()));

      newManagementContext
          .getSubscriptionManager()
          .publish(
              new BasicSensorEvent<String>(TestApplication.MY_ATTRIBUTE, null, "myvaltoreceive"));
      Asserts.eventually(
          Suppliers.ofInstance(MyLatchingEntityImpl.events),
          Predicates.<List<Object>>equalTo(ImmutableList.of((Object) "myvaltoreceive")));

      // When the entity is notified of "managed", its events are only then delivered
      MyLatchingEntityImpl.managingContinuesLatch.countDown();
      assertTrue(Durations.await(MyLatchingEntityImpl.managedStartedLatch, TIMEOUT_MS));

      Asserts.eventually(
          Suppliers.ofInstance(MyLatchingEntityImpl.events),
          Predicates.<List<Object>>equalTo(ImmutableList.of((Object) "myvaltoreceive")));

      MyLatchingEntityImpl.managedContinuesLatch.countDown();

      Durations.join(thread, TIMEOUT_MS);
      assertFalse(thread.isAlive());

    } finally {
      thread.interrupt();
      MyLatchingEntityImpl.reset();
    }
  }