@Test
  public void TestUnregisterAndRegisterWhenUpdating()
      throws Node2BeanException, RepositoryException, RegistrationException {

    // GIVEN
    String appName = "app1";
    DefinitionProvider<AppDescriptor> appDescriptorProvider1 =
        createAppDescriptorProvider(appName, true);
    Set<DefinitionMetadata> registeredNames =
        appDescriptorRegistry.unregisterAndRegister(
            Arrays.<DefinitionMetadata>asList(), Arrays.asList(appDescriptorProvider1));

    // Change content of AppDescriptor info
    DefinitionProvider<AppDescriptor> appDescriptorProvider2 =
        createAppDescriptorProvider(appName, false);

    eventHandler.clear();

    // WHEN
    Set<DefinitionMetadata> registeredNames2 =
        appDescriptorRegistry.unregisterAndRegister(
            registeredNames, Arrays.asList(appDescriptorProvider2));

    // THEN
    // appDescriptorProvider1 should be registered.
    assertNotNull(registeredNames2);
    assertEquals(1, registeredNames2.size());
    assertEquals(appName, registeredNames2.iterator().next().getName());
    assertEquals(1, eventHandler.events.size());
    assertEquals(AppRegistryEventType.REREGISTERED, eventHandler.events.get(0).getEventType());
    assertEquals(
        appDescriptorRegistry.getProvider(appName).getMetadata(),
        eventHandler.events.get(0).getAppDescriptorMetadata());
  }
  @Test
  public void testUnregisterAndRegisterWhenAdding()
      throws Node2BeanException, RepositoryException, RegistrationException {

    // GIVEN
    final String appName1 = "app1";
    String appName2 = "app2";
    DefinitionProvider<AppDescriptor> appDescriptorProvider1 =
        createAppDescriptorProvider(appName1, true);
    DefinitionProvider<AppDescriptor> appDescriptorProvider2 =
        createAppDescriptorProvider(appName2, true);

    // Add app1
    Set<DefinitionMetadata> registeredMetadata =
        appDescriptorRegistry.unregisterAndRegister(
            Arrays.<DefinitionMetadata>asList(), Arrays.asList(appDescriptorProvider1));
    assertEquals(1, registeredMetadata.size());
    assertNotNull(appDescriptorRegistry.getProvider(appName1));

    eventHandler.clear();

    // WHEN
    Set<DefinitionMetadata> registeredNames2 =
        appDescriptorRegistry.unregisterAndRegister(
            registeredMetadata, Arrays.asList(appDescriptorProvider1, appDescriptorProvider2));

    // THEN
    assertNotNull(registeredNames2);
    assertEquals(2, registeredNames2.size());
    assertEquals(1, eventHandler.events.size());
    assertContainsEvent(AppRegistryEventType.REGISTERED, appName2);
  }
  @Test
  public void testUnregisterAndRegisterInComplexCase()
      throws RepositoryException, Node2BeanException, RegistrationException {

    // GIVEN
    DefinitionProvider<AppDescriptor> appThatStays =
        createAppDescriptorProvider("appThatStays", true);
    DefinitionProvider<AppDescriptor> appThatGoesAway =
        createAppDescriptorProvider("appThatGoesAway", true);
    DefinitionProvider<AppDescriptor> appThatAppears =
        createAppDescriptorProvider("appThatAppears", true);

    Set<DefinitionMetadata> registeredMetadata =
        appDescriptorRegistry.unregisterAndRegister(
            Arrays.<DefinitionMetadata>asList(), Arrays.asList(appThatStays, appThatGoesAway));

    assertEquals(2, registeredMetadata.size());
    assertTrue(registeredMetadata.contains(appThatStays.getMetadata()));
    assertTrue(registeredMetadata.contains(appThatGoesAway.getMetadata()));

    assertEquals(2, eventHandler.events.size());
    assertContainsEvent(AppRegistryEventType.REGISTERED, appThatStays.getMetadata().getName());
    assertContainsEvent(AppRegistryEventType.REGISTERED, appThatGoesAway.getMetadata().getName());

    eventHandler.clear();

    // WHEN
    Set<DefinitionMetadata> registeredNames2 =
        appDescriptorRegistry.unregisterAndRegister(
            registeredMetadata, Arrays.asList(appThatStays, appThatAppears));

    // THEN
    assertEquals(2, registeredNames2.size());
    assertTrue(registeredNames2.contains(appThatStays.getMetadata()));
    assertTrue(registeredNames2.contains(appThatAppears.getMetadata()));
    assertEquals(2, eventHandler.events.size());
    assertContainsEvent(AppRegistryEventType.UNREGISTERED, appThatGoesAway.getMetadata().getName());
    assertContainsEvent(AppRegistryEventType.REGISTERED, appThatAppears.getMetadata().getName());
  }
  @Test
  public void testUnregisterAndRegisterWhenRemoving()
      throws Node2BeanException, RepositoryException, RegistrationException {

    // GIVEN
    String appName1 = "app1";
    String appName2 = "app2";
    DefinitionProvider<AppDescriptor> appDescriptorProvider1 =
        createAppDescriptorProvider(appName1, true);
    DefinitionProvider<AppDescriptor> appDescriptorProvider2 =
        createAppDescriptorProvider(appName2, true);

    // Add app1
    Collection<DefinitionMetadata> registeredMetadata = Arrays.asList();
    Collection<DefinitionProvider<AppDescriptor>> providers = Arrays.asList(appDescriptorProvider1);
    registeredMetadata = appDescriptorRegistry.unregisterAndRegister(registeredMetadata, providers);
    assertEquals(appName1, registeredMetadata.iterator().next().getName());

    // Add app2
    providers = Arrays.asList(appDescriptorProvider1, appDescriptorProvider2);
    registeredMetadata = appDescriptorRegistry.unregisterAndRegister(registeredMetadata, providers);

    eventHandler.clear();

    // WHEN
    // Remove --> registeredMetadata don't contain appName2
    providers = Arrays.asList(appDescriptorProvider1);
    Set<DefinitionMetadata> res =
        appDescriptorRegistry.unregisterAndRegister(registeredMetadata, providers);

    // THEN
    // appDescriptorProvider1 should be registered.
    assertNotNull(res);
    assertEquals(1, res.size());
    assertEquals(1, eventHandler.events.size());
    assertContainsEvent(AppRegistryEventType.UNREGISTERED, appName2);
  }
  @Test
  public void testUnregisterAndRegisterWhenAddingFromMultipleSources()
      throws Node2BeanException, RepositoryException, RegistrationException {

    // GIVEN
    String appName1 = "app1";
    String appName2 = "app2";
    DefinitionProvider<AppDescriptor> appDescriptorProvider1 =
        createAppDescriptorProvider(appName1, true);

    Set<DefinitionMetadata> registeredNames =
        appDescriptorRegistry.unregisterAndRegister(
            Arrays.<DefinitionMetadata>asList(), Arrays.asList(appDescriptorProvider1));
    assertEquals(1, registeredNames.size());
    assertTrue(registeredNames.contains(appDescriptorProvider1.getMetadata()));
    eventHandler.clear();

    // WHEN
    // first app gets reregistered due to change in in active state
    appDescriptorProvider1 = createAppDescriptorProvider(appName1, false);
    // second app gets registered
    DefinitionProvider<AppDescriptor> appDescriptorProvider2 =
        createAppDescriptorProvider(appName2, true);

    Set<DefinitionMetadata> registeredNames2 =
        appDescriptorRegistry.unregisterAndRegister(
            Arrays.<DefinitionMetadata>asList(),
            Arrays.asList(appDescriptorProvider1, appDescriptorProvider2));

    // THEN
    assertNotNull(registeredNames2);
    assertEquals(2, registeredNames2.size());
    assertEquals(2, eventHandler.events.size());
    assertContainsEvent(AppRegistryEventType.REREGISTERED, appName1);
    assertContainsEvent(AppRegistryEventType.REGISTERED, appName2);
  }