gt:         new FilterGroup(checkAllEdge, edgeFilterCheckboxes);
context: package edu.kit.student.gui;
  
  import edu.kit.student.plugin.EdgeFilter;
  import edu.kit.student.plugin.Filter;
  import edu.kit.student.plugin.PluginManager;
  import edu.kit.student.plugin.VertexFilter;
  import edu.kit.student.util.LanguageManager;
  import javafx.beans.value.ChangeListener;
  import javafx.collections.ListChangeListener;
  import javafx.fxml.FXML;
  import javafx.fxml.FXMLLoader;
  import javafx.geometry.Insets;
  import javafx.geometry.Pos;
  import javafx.scene.Node;
  import javafx.scene.control.Button;
  import javafx.scene.control.ButtonBar;
  import javafx.scene.control.ButtonType;
  import javafx.scene.control.CheckBox;
  import javafx.scene.control.Dialog;
  import javafx.scene.control.DialogPane;
  import javafx.scene.control.ScrollPane;
  import javafx.scene.control.Tab;
  import javafx.scene.image.Image;
  import javafx.scene.layout.Pane;
  import javafx.scene.layout.TilePane;
  import javafx.scene.layout.VBox;
  import javafx.stage.Stage;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.IOException;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.ResourceBundle;
  import java.util.function.Function;
  import java.util.stream.Collectors;
  
  /**
   * A dialog for selecting the vertex and edge filter.
   * Accepts a preselected set of filter.
   * Up on selection and removal of a filter by the user
   * through a check box, the filter will be removed
   * from the initial set of filters.
   *
   * @author Lucas Steinmann, Nicolas Boltz
   */
  public class FilterDialogController extends Dialog<ButtonType> {
  
  
      private final Logger logger = LoggerFactory.getLogger(GraphViewSelectionModel.class);
  
      private static final int minWindowWidth = 500;
      private static final int minWindowHeight = 400;
  
      private enum Props { filterdialog_x, filterdialog_y, filterdialog_width, filterdialog_height }
  
      public static final ButtonType APPLYANDLAYOUT = new ButtonType("Apply and Layout", ButtonBar.ButtonData.APPLY);
  
      private FilterModel model;
  
      @FXML
      private Tab edgeTab;
  
      @FXML
      private Tab vertexTab;
  
      @FXML
      private DialogPane dialogPane;
  
      @FXML
      private CheckBox cbFixVertices;
  
      /**
       * Initializes the filter model belonging to the filter dialog controlled by this controller.
       *
       * @param model the model holding the state of activated and possible filter options
       */
      public void initModel(FilterModel model) {
          if (this.model != null)
              throw new IllegalStateException("Cannot init model twice.");
          this.model = model;
          fillDialog();
          this.setDialogPane(dialogPane);
  
          // Disable apply (and layout) button when needed as described in shouldDisable* described.
          final Button btnApply = (Button) getDialogPane().lookupButton(ButtonType.APPLY);
          final Button btnApplyAndLayout = (Button) getDialogPane().lookupButton(FilterDialogController.APPLYANDLAYOUT);
          btnApply.setDisable(shouldDisableBtnApply());
          btnApplyAndLayout.setDisable(shouldDisableBtnApplyAndLayout());
  
          ListChangeListener<Object> checkApplyBtn = observable -> {
              btnApply.setDisable(shouldDisableBtnApply());
              btnApplyAndLayout.setDisable(shouldDisableBtnApplyAndLayout());
          };
          model.observableEdgeFilters().addListener(checkApplyBtn);
          model.observableVertexFilters().addListener(checkApplyBtn);
  
          model.needLayoutProperty.addListener((observable, oldValue, newValue) -> btnApply.setDisable(shouldDisableBtnApply()));
  
          // Disable ad deselect the fix vertex check box if appropriate.
          model.layoutCanOptimizeProperty.addListener((observable, oldValue, newValue)
                  -> cbFixVertices.setDisable(model.canOptimize()));
          model.needLayoutProperty.addListener((observable, oldValue, newValue) -> {
              cbFixVertices.setDisable(!model.canOptimize());
              if (!model.canOptimize())
                  cbFixVertices.setSelected(false);
          });
          cbFixVertices.setDisable(!model.layoutCanOptimizeProperty.getValue());
          cbFixVertices.selectedProperty().addListener((observable, oldValue, newValue) -> model.setFixVertices(newValue));
          cbFixVertices.setSelected(model.isFixVertices());
      }
  
      /**
       * Returns if btnApply should be disabled.
       * @return true if btnApply should be disabled, false otherwise.
       */
      private boolean shouldDisableBtnApply() {
          return model.needLayoutProperty.get();
      }
  
      /**
       * Returns if btnApplyAndLayout should be disabled.
       * @return true if btnApplyAndLayout should be disabled, false otherwise.
       */
      private boolean shouldDisableBtnApplyAndLayout() {
          return false; //!model.changedSinceBackup();
      }
  
      public static FilterDialogController showDialog(FilterModel model) {
          FilterDialogController dialogController = new FilterDialogController();
          ResourceBundle bundle = ResourceBundle.getBundle("language.Lang");
          FXMLLoader loader = new FXMLLoader( dialogController.getClass().getResource("/fxml/filterdialog.fxml"), bundle);
          try {
              loader.load();
          } catch (IOException e) {
              e.printStackTrace();
          }
          final FilterDialogController fdc = loader.getController();
          fdc.initModel(model);
  
          Stage stage = (Stage) fdc.getDialogPane().getScene().getWindow();
          stage.getIcons().add(new Image("gans_icon.png"));
          stage.setMinWidth(minWindowWidth);
          stage.setMinHeight(minWindowHeight);
  
          fdc.setOnCloseRequest(e -> fdc.saveSettings());
          fdc.loadConfig();
          fdc.setTitle(LanguageManager.getInstance().get("wind_filter_title"));
          fdc.setHeaderText(null);
          fdc.setGraphic(null);
          fdc.setResizable(true);
  
  
          return fdc;
      }
  
      private void loadConfig() {
          Stage stage = (Stage) getDialogPane().getScene().getWindow();
          ApplicationSettings settings = ApplicationSettings.getInstance();
          if (settings.hasProperty(Props.filterdialog_x.name())
                  && settings.hasProperty(Props.filterdialog_y.name())) {
              setX(settings.getPropertyAsDouble(Props.filterdialog_x.name()));
              setY(settings.getPropertyAsDouble(Props.filterdialog_y.name()));
          }
          if (settings.hasProperty(Props.filterdialog_width.name())
                  && settings.hasProperty(Props.filterdialog_height.name())) {
              getDialogPane().setPrefSize(settings.getPropertyAsDouble(Props.filterdialog_width.name()),
                                          settings.getPropertyAsDouble(Props.filterdialog_height.name()));
          }
      }
  
      private void saveSettings() {
          Stage stage = (Stage) getDialogPane().getScene().getWindow();
          ApplicationSettings settings = ApplicationSettings.getInstance();
          settings.setProperty(Props.filterdialog_x.name(), this.getX());
          settings.setProperty(Props.filterdialog_y.name(), this.getY());
          settings.setProperty(Props.filterdialog_width.name(), getDialogPane().getWidth());
          settings.setProperty(Props.filterdialog_height.name(), getDialogPane().getHeight());
          settings.saveSettings();
      }
  
      private void fillDialog() {
  
          // The box controlling the state of all vertices
          CheckBox checkAllVertex = new CheckBox(LanguageManager.getInstance().get("filter_select_all"));
          checkAllVertex.setPadding(new Insets(0, 0, 0, 12));
          CheckBox checkAllEdge = new CheckBox(LanguageManager.getInstance().get("filter_select_all"));
          checkAllEdge.setPadding(new Insets(0, 0, 0, 12));
  
  
          List<FilterCheckBox> vertexFilterCheckboxes = new LinkedList<>();
          for (VertexFilter filter : PluginManager.getPluginManager().getVertexFilter())
              vertexFilterCheckboxes.add(new FilterCheckBox<>(filter, model.getVertexFilters()));
          List<FilterCheckBox> edgeFilterCheckboxes = new LinkedList<>();
          for (EdgeFilter filter : PluginManager.getPluginManager().getEdgeFilter())
              edgeFilterCheckboxes.add(new FilterCheckBox<>(filter, model.getEdgeFilters()));
  
  
          // Fill with groups of checkboxes
          Pane vertexCheckboxes = createCheckboxSetPane(vertexFilterCheckboxes, Filter::getGroup);
          Pane edgeCheckboxes = createCheckboxSetPane(edgeFilterCheckboxes, Filter::getGroup);
  
  
          new FilterGroup(checkAllVertex, vertexFilterCheckboxes);
  