public Component getCustomOptionComponent() {

    /* DEPTH */
    final JSpinner jspnMaxDepth = new JSpinner(new SpinnerNumberModel(s_maxDepth + 1, 1, 100, 1));
    jspnMaxDepth.addChangeListener(
        new ChangeListener() {

          public void stateChanged(ChangeEvent e) {
            Integer value = (Integer) ((JSpinner) e.getSource()).getValue();
            s_maxDepth = value - 1;

            logger.debug("maxDepth " + (s_maxDepth + 1));
          }
        });
    final JRadioButton jrbMaxDepth = new JRadioButton("Depth");
    final JLabel lblMaxDepth = new JLabel("Depth: ");

    final JPanel jpMaxDepthSub =
        new JPanel() {
          @Override
          public void setEnabled(boolean b) {
            super.setEnabled(b);
            jspnMaxDepth.setEnabled(b);
            lblMaxDepth.setEnabled(b);
          }
        };
    jpMaxDepthSub.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
    jpMaxDepthSub.add(lblMaxDepth);
    jpMaxDepthSub.add(jspnMaxDepth);

    ///
    final JPanel jpMaxDepth =
        new JPanel() {
          @Override
          public void setEnabled(boolean b) {
            super.setEnabled(b);
            jrbMaxDepth.setEnabled(b);
            jpMaxDepthSub.setEnabled(b);
          }
        };

    jpMaxDepth.setLayout(new BoxLayout(jpMaxDepth, BoxLayout.Y_AXIS));

    jpMaxDepth.add(GuiUtil.addComponentAsFlow(jrbMaxDepth, FlowLayout.LEFT));
    jpMaxDepth.add(GuiUtil.addComponentAsFlow(jpMaxDepthSub, FlowLayout.RIGHT));

    /* REPETITION */
    final JSpinner jspnMaxRept = new JSpinner(new SpinnerNumberModel(s_maxRept, 1, 100, 1));
    jspnMaxRept.addChangeListener(
        new ChangeListener() {

          public void stateChanged(ChangeEvent e) {
            s_maxRept = (Integer) ((JSpinner) e.getSource()).getValue();

            logger.debug("maxRept " + s_maxRept);
          }
        });

    final JRadioButton jrbMaxRept = new JRadioButton("Repetition");

    final JLabel lblMaxRept = new JLabel("Count: ");

    final JPanel jpMaxReptSub =
        new JPanel() {
          @Override
          public void setEnabled(boolean b) {
            super.setEnabled(b);
            jspnMaxRept.setEnabled(b);
            lblMaxRept.setEnabled(b);
          }
        };
    jpMaxReptSub.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
    jpMaxReptSub.add(lblMaxRept);
    jpMaxReptSub.add(jspnMaxRept);

    final JPanel jpMaxRept =
        new JPanel() {
          @Override
          public void setEnabled(boolean b) {
            super.setEnabled(b);
            jrbMaxRept.setEnabled(b);
            jpMaxReptSub.setEnabled(b);
          }
        };
    jpMaxRept.setLayout(new BoxLayout(jpMaxRept, BoxLayout.Y_AXIS));

    jpMaxRept.add(GuiUtil.addComponentAsFlow(jrbMaxRept, FlowLayout.LEFT));
    jpMaxRept.add(GuiUtil.addComponentAsFlow(jpMaxReptSub, FlowLayout.RIGHT));

    ///////////////////////////////////////
    final JLabel lbl = new JLabel("Limit search by:", SwingConstants.LEFT);

    final JPanel panel =
        new JPanel() {
          @Override
          public void setEnabled(boolean b) {
            super.setEnabled(b);
            lbl.setEnabled(b);
            jpMaxDepth.setEnabled(b);
            jpMaxRept.setEnabled(b);
          }

          @Override
          public void setVisible(boolean b) {
            super.setVisible(b);
            final JPanel p = this;
            //                SwingUtilities.invokeLater( new Runnable() {
            //                    public void run() {
            Window win = SwingUtilities.getWindowAncestor(p);
            System.err.println(win);
            if (win != null) {
              System.err.println("packing");
              win.pack();
            }
            //                    }
            //                } );
          }
        };
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
    panel.add(GuiUtil.addComponentAsFlow(lbl, FlowLayout.LEFT));
    panel.add(jpMaxDepth);
    panel.add(jpMaxRept);

    ButtonGroup bg = new ButtonGroup();
    bg.add(jrbMaxDepth);
    bg.add(jrbMaxRept);

    /* CHECKBOX */
    final JCheckBox chboxRepeat =
        new JCheckBox("Allow subtask recursive repetition", s_isSubtaskRepetitionAllowed);

    chboxRepeat.addChangeListener(
        new ChangeListener() {

          public void stateChanged(ChangeEvent e) {
            if (s_isSubtaskRepetitionAllowed == chboxRepeat.isSelected()) return;

            s_isSubtaskRepetitionAllowed = chboxRepeat.isSelected();
            panel.setVisible(s_isSubtaskRepetitionAllowed);

            logger.debug("m_isSubtaskRepetitionAllowed " + s_isSubtaskRepetitionAllowed);
          }
        });

    panel.setVisible(s_isSubtaskRepetitionAllowed);

    final JCheckBox chboxIncremental = new JCheckBox("Incremental", s_isIncremental);
    chboxIncremental.setToolTipText("Incremental depth-first search");

    chboxIncremental.addChangeListener(
        new ChangeListener() {

          public void stateChanged(ChangeEvent e) {

            if (s_isIncremental == chboxIncremental.isSelected()) return;

            s_isIncremental = chboxIncremental.isSelected();

            logger.debug("isIncremental " + s_isIncremental);
          }
        });

    final JCheckBox chboxOptimize =
        new JCheckBox("Disable optimization in subtasks", s_disableOptimizationInSubtasks);
    chboxOptimize.setToolTipText("Use for debugging purposes");

    chboxOptimize.addChangeListener(
        new ChangeListener() {

          public void stateChanged(ChangeEvent e) {

            if (s_disableOptimizationInSubtasks == chboxOptimize.isSelected()) return;

            s_disableOptimizationInSubtasks = chboxOptimize.isSelected();

            logger.debug("disableOptimizationInSubtasks " + s_disableOptimizationInSubtasks);
          }
        });

    JPanel container1 = new JPanel();
    container1.setLayout(new BoxLayout(container1, BoxLayout.Y_AXIS));
    container1.setBorder(BorderFactory.createTitledBorder("Planning settings"));
    container1.add(GuiUtil.addComponentAsFlow(chboxOptimize, FlowLayout.LEFT));
    container1.add(GuiUtil.addComponentAsFlow(chboxIncremental, FlowLayout.LEFT));
    container1.add(GuiUtil.addComponentAsFlow(chboxRepeat, FlowLayout.LEFT));
    container1.add(GuiUtil.addComponentAsFlow(panel, FlowLayout.LEFT));

    JPanel container2 = new JPanel(new GridLayout(2, 0));
    container2.setBorder(BorderFactory.createTitledBorder("Logging options"));

    final JCheckBox linear = new JCheckBox("Detailed linear planning", isLinearLoggingOn());
    linear.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            setLinearLoggingOn(linear.isSelected());
          }
        });
    container2.add(linear);
    final JCheckBox subtask = new JCheckBox("Detailed subtask planning", isSubtaskLoggingOn());
    subtask.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            setSubtaskLoggingOn(subtask.isSelected());
          }
        });
    container2.add(subtask);

    JPanel main = new JPanel();
    main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
    main.add(container1);
    main.add(container2);

    return main;
  }
  private void init() {
    input = new JTextField[nInputs];

    double[] rowWeights =
        new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
    rowWeights[nInputs + 2] = 1.0;

    GridBagLayout gbl_functionPanel = new GridBagLayout();
    gbl_functionPanel.columnWidths = new int[] {5, 0, 50, 50, 30, 25, 5, 0};
    gbl_functionPanel.rowHeights = new int[] {10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10};
    gbl_functionPanel.columnWeights =
        new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
    gbl_functionPanel.rowWeights = rowWeights;
    this.setLayout(gbl_functionPanel);

    // Function input field.
    for (int i = 0; i < nInputs; i++) {
      // Creation.
      input[i] = new JTextField();
      GridBagConstraints gbc_stdFuncInput = new GridBagConstraints();
      gbc_stdFuncInput.gridwidth = 4;
      gbc_stdFuncInput.insets = new Insets(0, 0, 5, 5);
      gbc_stdFuncInput.fill = GridBagConstraints.HORIZONTAL;
      gbc_stdFuncInput.anchor = GridBagConstraints.NORTH;
      gbc_stdFuncInput.gridx = 2;
      gbc_stdFuncInput.gridy = i + 1;

      // Setup.
      GuiUtil.setupUndoListener(input[i]);
      setupInputListeners(input[i]);
      this.add(input[i], gbc_stdFuncInput);
    }

    // Labels for the input fields
    String[] labelNames = labelNames();
    for (int i = 0; i < labelNames.length; i++) {
      GridBagConstraints gbc_FuncLabel = new GridBagConstraints();
      gbc_FuncLabel.gridwidth = 1;
      gbc_FuncLabel.insets = new Insets(0, 0, 5, 5);
      gbc_FuncLabel.fill = GridBagConstraints.HORIZONTAL;
      gbc_FuncLabel.anchor = GridBagConstraints.CENTER;
      gbc_FuncLabel.gridx = 1;
      gbc_FuncLabel.gridy = i + 1;

      JLabel label = new JLabel(labelNames[i]);
      this.add(label, gbc_FuncLabel);
    }

    // OptionPanel.
    mainOP = new JPanel();
    mainOP.setBorder(BorderFactory.createEtchedBorder());
    GridBagConstraints gbc_mainOP = new GridBagConstraints();
    gbc_mainOP.fill = GridBagConstraints.BOTH;
    gbc_mainOP.gridwidth = 5;
    gbc_mainOP.insets = new Insets(0, 0, 5, 5);
    gbc_mainOP.gridx = 1;
    gbc_mainOP.gridy = nInputs + 1;
    this.add(mainOP, gbc_mainOP);

    gridOP = getGridOptionPanel();
    gridOP.addFunctionListener(createGridOptionPanelListener());
    apperanceOP = new AppearanceOptionPanel(colorList, map);
    mainOP.setLayout(new BoxLayout(mainOP, BoxLayout.Y_AXIS));
    mainOP.add((Component) gridOP);
    mainOP.add(apperanceOP);

    // The standard function list
    outerFuncTab = new JPanel();
    funcPanelWrapper = new JScrollPane(outerFuncTab);
    funcPanelWrapper.setBorder(BorderFactory.createEtchedBorder());
    funcPanelWrapper.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    funcPanelWrapper.setMinimumSize(new Dimension(310, 500));
    GridBagConstraints gbc_funcPanelWrapper = new GridBagConstraints();
    gbc_funcPanelWrapper.fill = GridBagConstraints.BOTH;
    gbc_funcPanelWrapper.gridwidth = 5;
    gbc_funcPanelWrapper.insets = new Insets(0, 0, 5, 5);
    gbc_funcPanelWrapper.gridx = 1;
    gbc_funcPanelWrapper.gridy = nInputs + 2;
    ;
    this.add(funcPanelWrapper, gbc_funcPanelWrapper);

    GridBagLayout gbl_stdFuncPanel = new GridBagLayout();
    gbl_stdFuncPanel.columnWidths = new int[] {0, 0};
    gbl_stdFuncPanel.rowHeights = new int[] {0, 0};
    gbl_stdFuncPanel.columnWeights = new double[] {1.0, Double.MIN_VALUE};
    gbl_stdFuncPanel.rowWeights = new double[] {1.0, Double.MIN_VALUE};
    outerFuncTab.setLayout(gbl_stdFuncPanel);

    innerFuncTab = new JPanel();
    GridBagConstraints gbc_innerFuncPanel = new GridBagConstraints();
    gbc_innerFuncPanel.anchor = GridBagConstraints.NORTH;
    gbc_innerFuncPanel.fill = GridBagConstraints.HORIZONTAL;
    gbc_innerFuncPanel.gridx = 0;
    gbc_innerFuncPanel.gridy = 0;
    outerFuncTab.add(innerFuncTab, gbc_innerFuncPanel);
    innerFuncTab.setLayout(new BoxLayout(innerFuncTab, BoxLayout.Y_AXIS));
  }