public final class CustomerEditModel extends SwingEntityEditModel {

  public CustomerEditModel(EntityConnectionProvider connectionProvider) {
    super(Customer.TYPE, connectionProvider);
    editor().comboBoxModels().initialize(Customer.SUPPORTREP_FK);
    // Set a detail editor, in order to edit customer preferences alongside the customer
    SwingEntityEditor preferences = new SwingEntityEditor(Preferences.TYPE, connectionProvider);
    preferences.value(Preferences.PREFERRED_GENRE_FK).persist().set(false);
    preferences.comboBoxModels().initialize(Preferences.PREFERRED_GENRE_FK);
    editor().detail().add(EditorLink.builder()
            .editor(preferences)
            .foreignKey(Preferences.CUSTOMER_FK)
            .present(new PreferencesPresent())
            .build());
  }

  private static final class PreferencesPresent implements Predicate<Entity> {

    @Override
    public boolean test(Entity preferences) {
      // Preferences without both preferred genre and newsletter are deleted
      return !preferences.isNull(Preferences.PREFERRED_GENRE_FK) ||
              !preferences.isNull(Preferences.NEWSLETTER);
    }
  }
}
public final class ArtistEditModel extends SwingEntityEditModel {

  public static final int TAG_SLOTS = 6;
  public static final String TAG_PREFIX = "tag";

  public ArtistEditModel(EntityConnectionProvider connectionProvider) {
    super(Artist.TYPE, connectionProvider);
    TagPresent present = new TagPresent();
    for (int i = 0; i < TAG_SLOTS; i++) {
      editor().detail().add(EditorLink.builder()
              .editor(new SwingEntityEditor(ArtistTag.TYPE, connectionProvider))
              .foreignKey(ArtistTag.ARTIST_FK)
              .select(new TagSelect(i))
              .present(present)
              .name(TAG_PREFIX + i)
              .caption(String.valueOf(i + 1))
              .build());
    }
  }

  private static final class TagSelect implements DetailSelect {

    private final int index;

    private TagSelect(int index) {
      this.index = index;
    }

    @Override
    public Select get(Entity artist) {
      return Select.where(ArtistTag.ARTIST_FK.equalTo(artist))
              .orderBy(ascending(ArtistTag.TAG))
              .offset(index)
              .limit(1)
              .build();
    }
  }

  private static final class TagPresent implements Predicate<Entity> {

    @Override
    public boolean test(Entity tag) {
      return !tag.isNull(ArtistTag.TAG);
    }
  }
}