@Override
 protected List<ApplicationFeatureViewModel> getObjectsWithDifferentValue() {
   return Arrays.asList(
       pkg(ApplicationFeatureId.newPackage("com.mycompany")),
       cls(ApplicationFeatureId.newClass("com.mycompany.Foo")),
       prop(ApplicationFeatureId.newMember("com.mycompany.Foo#bar2")));
 }
    @Test
    public void givenClass_whenAddMember() throws Exception {

      // given
      final ApplicationFeatureId classId = ApplicationFeatureId.newClass("com.mycompany.Bar");
      final ApplicationFeatureId propertyId =
          ApplicationFeatureId.newMember("com.mycompany.Bar", "foo");
      final ApplicationFeatureId actionId =
          ApplicationFeatureId.newMember("com.mycompany.Bar", "boz");

      final ApplicationFeature classFeature = new ApplicationFeature(classId);
      final ApplicationFeature propertyFeature = new ApplicationFeature(propertyId);
      propertyFeature.setMemberType(ApplicationMemberType.PROPERTY);
      final ApplicationFeature actionFeature = new ApplicationFeature(actionId);
      actionFeature.setMemberType(ApplicationMemberType.ACTION);

      classFeature.addToMembers(propertyId, ApplicationMemberType.PROPERTY);
      classFeature.addToMembers(actionId, ApplicationMemberType.ACTION);

      ApplicationClass applicationClass = new ApplicationClass(classId);
      applicationClass.applicationFeatureRepository = mockApplicationFeatureRepository;
      applicationClass.container = mockContainer;

      // then
      context.checking(
          new Expectations() {
            {
              allowing(mockApplicationFeatureRepository).findFeature(classId);
              will(returnValue(classFeature));

              allowing(mockApplicationFeatureRepository).findFeature(propertyId);
              will(returnValue(propertyFeature));

              allowing(mockApplicationFeatureRepository).findFeature(actionId);
              will(returnValue(actionFeature));

              oneOf(mockContainer)
                  .newViewModelInstance(
                      ApplicationClassProperty.class, propertyId.asEncodedString());
              will(returnValue(new ApplicationClassProperty(propertyId)));

              oneOf(mockContainer)
                  .newViewModelInstance(ApplicationClassAction.class, actionId.asEncodedString());
              will(returnValue(new ApplicationClassAction(actionId)));
            }
          });

      // when
      final List<ApplicationClassProperty> properties = applicationClass.getProperties();

      // then
      assertThat(properties.size(), is(1));

      // when
      final List<ApplicationClassAction> actions = applicationClass.getActions();

      // then
      assertThat(actions.size(), is(1));
    }
 @Test
 public void whenMember() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(
           ApplicationFeatureId.newMember("com.mycompany.Bar#foo")) {};
   assertThat(applicationFeatureViewModel.hideContributed(), is(false));
 }
 @Test
 public void whenMember() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(
           ApplicationFeatureId.newMember("com.mycompany.Bar#foo")) {};
   assertThat(applicationFeatureViewModel.getType(), is(ApplicationFeatureType.MEMBER));
 }
    @Test
    public void happyCase() throws Exception {

      applicationFeatureViewModel =
          new ApplicationFeatureViewModel(
              ApplicationFeatureId.newMember("com.mycompany.Bar#foo")) {};
      assertThat(applicationFeatureViewModel.getFullyQualifiedName(), is("com.mycompany.Bar#foo"));
    }
    @Test
    public void givenPackage_whenAddPackageAndClass() throws Exception {

      // given
      final ApplicationFeatureId applicationFeatureId =
          ApplicationFeatureId.newPackage("com.mycompany");
      final ApplicationFeatureId packageFeatureId =
          ApplicationFeatureId.newPackage("com.mycompany.flob");
      final ApplicationFeatureId classFeatureId =
          ApplicationFeatureId.newClass("com.mycompany.Bar");

      final ApplicationFeature applicationFeature = new ApplicationFeature(applicationFeatureId);

      applicationFeature.addToContents(packageFeatureId);
      applicationFeature.addToContents(classFeatureId);

      ApplicationPackage applicationFeatureVM = new ApplicationPackage(applicationFeatureId);
      applicationFeatureVM.applicationFeatureRepository = mockApplicationFeatureRepository;
      applicationFeatureVM.container = mockContainer;

      // then
      context.checking(
          new Expectations() {
            {
              allowing(mockApplicationFeatureRepository).findFeature(applicationFeatureId);
              will(returnValue(applicationFeature));

              oneOf(mockContainer)
                  .newViewModelInstance(
                      ApplicationPackage.class, packageFeatureId.asEncodedString());
              will(returnValue(new ApplicationPackage()));

              oneOf(mockContainer)
                  .newViewModelInstance(ApplicationClass.class, classFeatureId.asEncodedString());
              will(returnValue(new ApplicationClass()));
            }
          });

      // when
      final List<ApplicationFeatureViewModel> contents = applicationFeatureVM.getContents();

      // then
      assertThat(contents.size(), is(2));
    }
    // should this instead fail-fast, given that the parent should always exist if the child does?
    @Test
    public void whenParentNonExistent() throws Exception {

      // given
      final ApplicationFeatureId featureId = ApplicationFeatureId.newPackage("com.mycompany");
      final ApplicationFeatureId parentId = ApplicationFeatureId.newPackage("com");
      applicationFeatureViewModel.setFeatureId(featureId);

      // then
      context.checking(
          new Expectations() {
            {
              allowing(mockApplicationFeatureRepository).findFeature(parentId);
              will(returnValue(null));

              never(mockContainer);
            }
          });

      // when
      assertThat(applicationFeatureViewModel.getParent(), is(nullValue()));
    }
    @Test
    public void whenPackage() throws Exception {
      ApplicationPackage applicationPackage =
          new ApplicationPackage(ApplicationFeatureId.newPackage("com.mycompany"));

      final String str = applicationPackage.viewModelMemento();
      final ApplicationFeatureViewModel applicationFeatureVM2 = new ApplicationPackage();
      applicationFeatureVM2.viewModelInit(str);

      assertThat(applicationFeatureVM2.getType(), CoreMatchers.is(ApplicationFeatureType.PACKAGE));
      assertThat(applicationFeatureVM2.getPackageName(), is("com.mycompany"));
      assertThat(applicationFeatureVM2.getClassName(), is(nullValue()));
      assertThat(applicationFeatureVM2.getMemberName(), is(nullValue()));
    }
    @Test
    public void whenClass() throws Exception {
      ApplicationClass applicationClass =
          new ApplicationClass(ApplicationFeatureId.newClass("com.mycompany.Bar"));

      final String str = applicationClass.viewModelMemento();
      final ApplicationFeatureViewModel applicationFeatureVM2 = new ApplicationClass();
      applicationFeatureVM2.viewModelInit(str);

      assertThat(applicationFeatureVM2.getType(), is(ApplicationFeatureType.CLASS));
      assertThat(applicationFeatureVM2.getPackageName(), is("com.mycompany"));
      assertThat(applicationFeatureVM2.getClassName(), is("Bar"));
      assertThat(applicationFeatureVM2.getMemberName(), is(nullValue()));
    }
    @Test
    public void whenMember() throws Exception {
      ApplicationClassProperty applicationClassProperty =
          new ApplicationClassProperty(ApplicationFeatureId.newMember("com.mycompany.Bar", "foo"));

      final String str = applicationClassProperty.viewModelMemento();
      final ApplicationFeatureViewModel applicationFeatureVM2 = new ApplicationClassProperty();
      applicationFeatureVM2.viewModelInit(str);

      assertThat(applicationFeatureVM2.getType(), is(ApplicationFeatureType.MEMBER));
      assertThat(applicationFeatureVM2.getPackageName(), is("com.mycompany"));
      assertThat(applicationFeatureVM2.getClassName(), is("Bar"));
      assertThat(applicationFeatureVM2.getMemberName(), is("foo"));
    }
    @Test
    public void whenMember() throws Exception {
      // given
      final ApplicationFeatureId featureId =
          ApplicationFeatureId.newMember("com.mycompany.Bar#foo");
      final ApplicationFeatureId parentId = ApplicationFeatureId.newClass("com.mycompany.Bar");
      applicationFeatureViewModel.setFeatureId(featureId);

      // then
      context.checking(
          new Expectations() {
            {
              allowing(mockApplicationFeatureRepository).findFeature(parentId);
              will(returnValue(mockApplicationFeature));

              oneOf(mockContainer)
                  .newViewModelInstance(ApplicationClass.class, parentId.asEncodedString());
              will(returnValue(parent));
            }
          });

      // when
      assertThat(applicationFeatureViewModel.getParent(), is(parent));
    }
    @Test
    public void whenPackageTopLevel() throws Exception {

      // given
      final ApplicationFeatureId featureId = ApplicationFeatureId.newPackage("com");
      applicationFeatureViewModel.setFeatureId(featureId);

      // then
      context.checking(
          new Expectations() {
            {
              never(mockApplicationFeatureRepository);

              never(mockContainer);
            }
          });

      // when
      assertThat(applicationFeatureViewModel.getParent(), is(nullValue()));
    }
    @Test
    public void delegatesToUnderlyingRepo() throws Exception {
      // given
      final ApplicationFeatureId featureId =
          ApplicationFeatureId.newMember("com.mycompany.Bar#foo");
      applicationFeatureViewModel = new ApplicationFeatureViewModel(featureId) {};
      applicationFeatureViewModel.applicationPermissionRepository =
          mockApplicationPermissionRepository;

      // then
      final List<ApplicationPermission> result = Lists.newArrayList();
      context.checking(
          new Expectations() {
            {
              oneOf(mockApplicationPermissionRepository).findByFeatureCached(featureId);
              will(returnValue(result));
            }
          });

      // when
      assertThat(applicationFeatureViewModel.getPermissions(), is(result));
    }
      @Test
      public void delegatesToUnderlyingFeature() throws Exception {
        // given
        final ApplicationFeatureId featureId =
            ApplicationFeatureId.newMember("com.mycompany.Bar#foo");
        applicationFeatureViewModel = new ApplicationFeatureViewModel(featureId) {};
        applicationFeatureViewModel.applicationFeatureRepository = mockApplicationFeatureRepository;

        // then
        context.checking(
            new Expectations() {
              {
                oneOf(mockApplicationFeatureRepository).findFeature(featureId);
                will(returnValue(mockApplicationFeature));

                oneOf(mockApplicationFeature).isContributed();
                will(returnValue(true));
              }
            });

        // when
        assertThat(applicationFeatureViewModel.isContributed(), is(true));
      }
 @Override
 protected List<ApplicationFeatureViewModel> getObjectsWithSameValue() {
   return Arrays.asList(
       prop(ApplicationFeatureId.newMember("com.mycompany.Foo#bar")),
       prop(ApplicationFeatureId.newMember("com.mycompany.Foo#bar")));
 }
 @Test
 public void whenPackage() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(ApplicationFeatureId.newPackage("com.mycompany")) {};
   assertThat(applicationFeatureViewModel.getType(), is(ApplicationFeatureType.PACKAGE));
 }
 @Test
 public void whenClass() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(ApplicationFeatureId.newClass("com.mycompany.Bar")) {};
   assertThat(applicationFeatureViewModel.hideContributed(), is(true));
 }
 @Override
 protected List<ApplicationFeatureViewModel> getObjectsWithSameValue() {
   return Arrays.asList(
       cls(ApplicationFeatureId.newClass("com.mycompany.Foo")),
       cls(ApplicationFeatureId.newClass("com.mycompany.Foo")));
 }
 @Test
 public void whenClass() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(ApplicationFeatureId.newClass("com.mycompany.Bar")) {};
   assertThat(applicationFeatureViewModel.getType(), is(ApplicationFeatureType.CLASS));
 }
 @Test
 public void whenPackage() throws Exception {
   applicationFeatureViewModel =
       new ApplicationFeatureViewModel(ApplicationFeatureId.newPackage("com.mycompany")) {};
   assertThat(applicationFeatureViewModel.hideMemberName(), is(true));
 }
 @Override
 protected List<ApplicationFeatureViewModel> getObjectsWithSameValue() {
   return Arrays.asList(
       pkg(ApplicationFeatureId.newPackage("com.mycompany")),
       pkg(ApplicationFeatureId.newPackage("com.mycompany")));
 }