ApkPackage { @NotNull public ApkPackage addSubpackage(@NotNull String name) { return mySubpackagesByName.computeIfAbsent(name, k -> new ApkPackage(name, this)); } ApkPackage(@NotNull String name, @Nullable ApkPackage parent); @NotNull Collection<ApkPackage> getSubpackages(); @Nullable ApkPackage findSubpackage(@NotNull String name); @NotNull Collection<ApkClass> getClasses(); @Nullable ApkClass findClass(@NotNull String name); @Nullable ApkPackage getParent(); @NotNull ApkPackage addSubpackage(@NotNull String name); @NotNull ApkClass addClass(@NotNull String name); @NotNull String getName(); @NotNull String getFqn(); boolean doSubpackagesHaveClasses(); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString();  }
@Test public void addSubpackage() { ApkPackage aPackage = new ApkPackage("a", null); assertEquals("a", aPackage.getName()); assertEquals("a", aPackage.getFqn()); assertNull(aPackage.getParent()); ApkPackage bPackage = aPackage.addSubpackage("b"); assertEquals("b", bPackage.getName()); assertEquals("a.b", bPackage.getFqn()); assertSame(aPackage, bPackage.getParent()); assertThat(aPackage.getSubpackages()).containsExactly(bPackage); ApkPackage cPackage = bPackage.addSubpackage("c"); assertEquals("c", cPackage.getName()); assertEquals("a.b.c", cPackage.getFqn()); assertSame(bPackage, cPackage.getParent()); assertThat(bPackage.getSubpackages()).containsExactly(cPackage); }