eu.crisis_economics.abm.dashboard.Page_Parameters.java Source code

Java tutorial

Introduction

Here is the source code for eu.crisis_economics.abm.dashboard.Page_Parameters.java

Source

/*
 * This file is part of CRISIS, an economics simulator.
 * 
 * Copyright (C) 2015 AITIA International, Inc.
 * Copyright (C) 2015 Ross Richardson
 * Copyright (C) 2015 John Kieran Phillips
 * Copyright (C) 2015 Ariel Y. Hoffman
 *
 * CRISIS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CRISIS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CRISIS.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.crisis_economics.abm.dashboard;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.xml.bind.JAXBElement;

import org.apache.commons.lang3.StringUtils;
import org.jdesktop.swingx.JXLabel;
import org.reflections.ReflectionUtils;
import org.reflections.Reflections;
import org.reflections.ReflectionsException;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ai.aitia.meme.gui.Wizard;
import ai.aitia.meme.gui.Wizard.Button;
import ai.aitia.meme.gui.Wizard.IWizardPage;
import ai.aitia.meme.paramsweep.batch.IModelInformation.ModelInformationException;
import ai.aitia.meme.paramsweep.batch.output.RecordableInfo;
import ai.aitia.meme.paramsweep.batch.param.AbstractParameterInfo;
import ai.aitia.meme.paramsweep.batch.param.IncrementalParameterInfo;
import ai.aitia.meme.paramsweep.batch.param.ParameterNode;
import ai.aitia.meme.paramsweep.batch.param.ParameterTree;
import ai.aitia.meme.paramsweep.gui.info.ISubmodelGUIInfo;
import ai.aitia.meme.paramsweep.gui.info.MasonChooserParameterInfo;
import ai.aitia.meme.paramsweep.gui.info.MasonIntervalParameterInfo;
import ai.aitia.meme.paramsweep.gui.info.ParameterInfo;
import ai.aitia.meme.paramsweep.gui.info.SubmodelInfo;
import ai.aitia.meme.paramsweep.internal.platform.IGUIController.RunOption;
import ai.aitia.meme.paramsweep.internal.platform.InfoConverter;
import ai.aitia.meme.paramsweep.internal.platform.PlatformSettings;
import ai.aitia.meme.paramsweep.plugin.IIntelliContext;
import ai.aitia.meme.paramsweep.plugin.IIntelliDynamicMethodPlugin;
import ai.aitia.meme.paramsweep.utils.Utilities;
import ai.aitia.meme.utils.GUIUtils;
import ai.aitia.meme.utils.Utils.Pair;
import aurelienribon.ui.css.Style;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.looks.common.RGBGrayFilter;
import com.wordpress.tips4java.ListAction;

import eu.crisis_economics.abm.dashboard.ga.DashboardIntelliContext;
import eu.crisis_economics.abm.dashboard.generated.Combination;
import eu.crisis_economics.abm.dashboard.generated.DefaultParameter;
import eu.crisis_economics.abm.dashboard.generated.GeneralParameter;
import eu.crisis_economics.abm.dashboard.generated.Model;
import eu.crisis_economics.abm.dashboard.generated.ModelType;
import eu.crisis_economics.abm.dashboard.generated.ObjectFactory;
import eu.crisis_economics.abm.dashboard.generated.Parameter;
import eu.crisis_economics.abm.dashboard.generated.ParameterType;
import eu.crisis_economics.abm.dashboard.generated.SubmodelParameter;
import eu.crisis_economics.abm.model.ConfigurationComponent;
import eu.crisis_economics.abm.model.Layout;

/**
 * @author Tams Mhr
 *
 */
public class Page_Parameters implements IWizardPage, IIconsInHeader, ActionListener {

    //====================================================================================================
    // members

    private static final String CSS_ID_BREADCRUMB = "#breadcrumb";
    private static final String LOADING_MODEL_ID = "LOADING_MODEL";
    private static final String PARAMETERS_PANEL_ID = "PARAMETERS_PANEL";
    private static final String UPDATE_CHARTS_LABEL_TEXT = " Update charts in real-time";
    private static final String DISPLAY_ADVANCED_CHARTS_LABEL_TEXT = " Show individual agents' measures";
    private static final String NUMBER_OF_TURNS_LABEL_TEXT = " Terminate simulation at time-step";
    private static final String NUMBER_OF_TIMESTEPS_TO_IGNORE_LABEL_TEXT = " Start charting after time-step";

    static final String BROWSE_BUTTON_TEXT = "Browse";

    private static final String DECORATION_IMAGE = "Audio_mixer_faders.jpg";
    static final int DECORATION_IMAGE_WIDTH = 300;
    private static final int PARAMETER_DESCRIPTION_LABEL_HEIGHT = 200;
    private static final int PARAMETER_DESCRIPTION_LABEL_WIDTH = 400;

    private static final int MAX_SIZE_OF_SUBPARAMETER_COMBOBOX = 100;

    static final int ICON_WIDTH_AND_HEIGHT = 25;

    private static final ImageIcon PARAMETER_ADD_ICON_DIS = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_silver_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_ADD_ICON = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_green_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_ADD_ICON_RO = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_red_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final ImageIcon PARAMETER_REMOVE_ICON_DIS = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_silver_left.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_REMOVE_ICON = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_green_left.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_REMOVE_ICON_RO = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_red_left.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final ImageIcon PARAMETER_UP_ICON_DIS = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_silver_up.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_UP_ICON = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_green_up.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_UP_ICON_RO = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_red_up.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final ImageIcon PARAMETER_DOWN_ICON_DIS = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_silver_down.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_DOWN_ICON = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_green_down.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon PARAMETER_DOWN_ICON_RO = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_red_down.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final ImageIcon PARAMETER_BOX_REMOVE = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/remove_box.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final ImageIcon SHOW_SUBMODEL_ICON_DIS = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_silver_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon SHOW_SUBMODEL_ICON = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_green_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));
    private static final ImageIcon SHOW_SUBMODEL_ICON_RO = new ImageIcon(
            new ImageIcon(Dashboard.class.getResource("icons/arrow_button_metal_red_right.png")).getImage()
                    .getScaledInstance(ICON_WIDTH_AND_HEIGHT, ICON_WIDTH_AND_HEIGHT, Image.SCALE_SMOOTH));

    private static final int GASEARCH_GUI_TABINDEX = 2;
    private static final int PARAMSWEEP_GUI_TABINDEX = 1;
    private static final int SINGLE_RUN_GUI_TABINDEX = 0;

    private static final String ACTIONCOMMAND_ADD_PARAM = "ADD_PARAM", ACTIONCOMMAND_REMOVE_PARAM = "REMOVE_PARAM",
            ACTIONCOMMAND_ADD_BOX = "ADD_BOX", ACTIONCOMMAND_REMOVE_BOX = "REMOVE_BOX",
            ACTIONCOMMAND_MOVE_UP = "MOVE_UP", ACTIONCOMMAND_MOVE_DOWN = "MOVE_DOWN", ACTIONCOMMAND_EDIT = "EDIT",
            ACTIONCOMMAND_BROWSE = "BROWSE", ACTIONCOMMAND_SHOW_SUBMODEL = "SHOW_SUBMODEL";

    private static final String TITLE = "Parameters";
    private static final String ORIGINAL_TEXT = "Select a parameter to modify its settings.";
    private static final String INFO_TEXT = "Please select the parameters to run";

    private static Logger log = LoggerFactory.getLogger(Page_Parameters.class);

    private final Dashboard dashboard;
    private IModelHandler currentModelHandler;
    private final DWizard wizard;
    private final Container container;
    private JScrollPane parametersScrollPane;

    private DefaultMutableTreeNode parameterValueComponentTree = new DefaultMutableTreeNode();
    private final Map<String, List<Class<?>>> possibleTypesCache = new HashMap<String, List<Class<?>>>();

    private JFormattedTextField numberOfTurnsField;
    private JFormattedTextField numberOfTurnsFieldPSW;
    private JFormattedTextField numberTimestepsIgnored;
    private JFormattedTextField numberTimestepsIgnoredPSW;
    private JCheckBox onLineChartsCheckBox;
    private JCheckBox advancedChartsCheckBox;
    //   private JCheckBox onLineChartsCheckBoxPSW;

    private Popup errorPopup;

    private JRadioButton constDef;
    private JRadioButton listDef;
    private JRadioButton incrDef;
    private JTextField constDefField;
    private JTextArea listDefArea;
    private JTextField incrStartValueField;
    private JTextField incrEndValueField;
    private JTextField incrStepField;
    private JComboBox enumDefBox;
    private JComboBox submodelTypeBox;
    private JButton cancelButton;
    private JButton modifyButton;
    private JTextField fileTextField;
    private JButton fileBrowseButton;

    private JLabel editedParameterText;
    private JPanel sweepPanel;
    private JPanel rightMiddle;
    private JTabbedPane tabbedPane;

    private JList parameterList;
    private JXLabel parameterDescriptionLabel;

    private GASearchPanelModel gaSearchHandler;
    private GASearchPanel gaSearchPanel;

    private JPanel singleRunParametersPanel;

    private DefaultMutableTreeNode editedNode;
    private JTree editedTree;
    private List<ParameterCombinationGUI> parameterTreeBranches = new ArrayList<ParameterCombinationGUI>(5);
    private List<ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>> batchParameters;

    private JPanel combinationsPanel;
    private JScrollPane combinationsScrPane;

    protected String currentDirectory = "";
    protected Breadcrumb breadcrumb;

    /**
     * The list of active submodel buttons that need to be turned red. The index in the list corresponds to the submodel level.
     */
    protected List<JButton> submodelButtons = new ArrayList<JButton>();

    //====================================================================================================
    // methods

    //----------------------------------------------------------------------------------------------------
    public Page_Parameters(final DWizard wizard, final Dashboard dashboard) {
        this.wizard = wizard;
        this.dashboard = dashboard;

        container = initContainer();

        Style.apply(container, dashboard.getCssStyle());
    }

    //----------------------------------------------------------------------------------------------------
    /** {@inheritDoc} 
     */
    @Override
    public String getInfoText(final Wizard w) {
        return w.getArrowsHeader(INFO_TEXT);
    }

    //----------------------------------------------------------------------------------------------------
    @Override
    public Icon getIcon() {
        return new ImageIcon(getClass().getResource("icons/params.png"));
    }

    //----------------------------------------------------------------------------------------------------
    /** {@inheritDoc} 
     */
    @Override
    public Container getPanel() {

        return container;
    }

    //----------------------------------------------------------------------------------------------------
    private Container initContainer() {
        JPanel containerPanel = new JPanel(new CardLayout());
        JLabel loadingModelLabel = new JLabel("Loading model...");
        loadingModelLabel.setHorizontalAlignment(SwingConstants.CENTER);
        containerPanel.add(loadingModelLabel, LOADING_MODEL_ID);
        tabbedPane = new JTabbedPane();
        containerPanel.add(tabbedPane, PARAMETERS_PANEL_ID);

        // create two number of turns field
        numberOfTurnsField = new JFormattedTextField();
        numberOfTurnsField.setFocusLostBehavior(JFormattedTextField.COMMIT);
        numberOfTurnsField.setInputVerifier(new InputVerifier() {

            @Override
            public boolean verify(final JComponent input) {
                if (!checkNumberOfTurnsField(true)) {
                    final PopupFactory popupFactory = PopupFactory.getSharedInstance();
                    final Point locationOnScreen = numberOfTurnsField.getLocationOnScreen();
                    final JLabel message = new JLabel("Please specify a (possibly floating point) number!");
                    message.setBorder(new LineBorder(Color.RED, 2, true));
                    if (errorPopup != null)
                        errorPopup.hide();
                    errorPopup = popupFactory.getPopup(numberOfTurnsField, message, locationOnScreen.x - 10,
                            locationOnScreen.y - 30);

                    errorPopup.show();

                    return false;
                } else {
                    if (errorPopup != null) {
                        errorPopup.hide();
                        errorPopup = null;
                    }
                    return true;
                }
            }
        });
        numberOfTurnsField.setText(String.valueOf(Dashboard.NUMBER_OF_TURNS));
        numberOfTurnsField
                .setToolTipText("The turn when the simulation should stop specified as an integer value.");
        numberOfTurnsField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                wizard.clickDefaultButton();
            }
        });

        numberOfTurnsFieldPSW = new JFormattedTextField();
        numberOfTurnsFieldPSW.setFocusLostBehavior(JFormattedTextField.COMMIT);
        numberOfTurnsFieldPSW.setInputVerifier(new InputVerifier() {

            @Override
            public boolean verify(final JComponent input) {
                if (!checkNumberOfTurnsField(false)) {
                    final PopupFactory popupFactory = PopupFactory.getSharedInstance();
                    final Point locationOnScreen = numberOfTurnsFieldPSW.getLocationOnScreen();
                    final JLabel message = new JLabel("Please specify a (possibly floating point) number!");
                    message.setBorder(new LineBorder(Color.RED, 2, true));
                    if (errorPopup != null)
                        errorPopup.hide();
                    errorPopup = popupFactory.getPopup(numberOfTurnsFieldPSW, message, locationOnScreen.x - 10,
                            locationOnScreen.y - 30);

                    errorPopup.show();

                    return false;
                } else {
                    if (errorPopup != null) {
                        errorPopup.hide();
                        errorPopup = null;
                    }
                    return true;
                }
            }
        });
        numberOfTurnsFieldPSW.setText(String.valueOf(Dashboard.NUMBER_OF_TURNS));
        numberOfTurnsFieldPSW
                .setToolTipText("The turn when the simulation should stop specified as an integer value.");
        numberOfTurnsFieldPSW.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                wizard.clickDefaultButton();
            }
        });

        // create two number of time-steps to ignore field
        numberTimestepsIgnored = new JFormattedTextField();
        numberTimestepsIgnored.setFocusLostBehavior(JFormattedTextField.COMMIT);
        numberTimestepsIgnored.setInputVerifier(new InputVerifier() {

            @Override
            public boolean verify(final JComponent input) {
                if (!checkNumberTimestepsIgnored(true)) {
                    final PopupFactory popupFactory = PopupFactory.getSharedInstance();
                    final Point locationOnScreen = numberTimestepsIgnored.getLocationOnScreen();
                    final JLabel message = new JLabel("Please specify an integer number!");
                    message.setBorder(new LineBorder(Color.RED, 2, true));
                    if (errorPopup != null)
                        errorPopup.hide();
                    errorPopup = popupFactory.getPopup(numberTimestepsIgnored, message, locationOnScreen.x - 10,
                            locationOnScreen.y - 30);

                    errorPopup.show();

                    return false;
                } else {
                    if (errorPopup != null) {
                        errorPopup.hide();
                        errorPopup = null;
                    }
                    return true;
                }
            }
        });
        numberTimestepsIgnored.setText(String.valueOf(Dashboard.NUMBER_OF_TIMESTEPS_TO_IGNORE));
        numberTimestepsIgnored.setToolTipText(
                "The turn when the simulation should start charting specified as an integer value.");
        numberTimestepsIgnored.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                wizard.clickDefaultButton();
            }
        });

        numberTimestepsIgnoredPSW = new JFormattedTextField();
        numberTimestepsIgnoredPSW.setFocusLostBehavior(JFormattedTextField.COMMIT);
        numberTimestepsIgnoredPSW.setInputVerifier(new InputVerifier() {

            @Override
            public boolean verify(final JComponent input) {
                if (!checkNumberTimestepsIgnored(false)) {
                    final PopupFactory popupFactory = PopupFactory.getSharedInstance();
                    final Point locationOnScreen = numberTimestepsIgnoredPSW.getLocationOnScreen();
                    final JLabel message = new JLabel("Please specify an integer number!");
                    message.setBorder(new LineBorder(Color.RED, 2, true));
                    if (errorPopup != null)
                        errorPopup.hide();
                    errorPopup = popupFactory.getPopup(numberTimestepsIgnoredPSW, message, locationOnScreen.x - 10,
                            locationOnScreen.y - 30);

                    errorPopup.show();

                    return false;
                } else {
                    if (errorPopup != null) {
                        errorPopup.hide();
                        errorPopup = null;
                    }
                    return true;
                }
            }
        });
        numberTimestepsIgnoredPSW.setText(String.valueOf(Dashboard.NUMBER_OF_TIMESTEPS_TO_IGNORE));
        numberTimestepsIgnoredPSW.setToolTipText(
                "The turn when the simulation should start charting specified as an integer value.");
        numberTimestepsIgnoredPSW.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                wizard.clickDefaultButton();
            }
        });

        onLineChartsCheckBox = new JCheckBox();
        //      onLineChartsCheckBoxPSW = new JCheckBox();
        advancedChartsCheckBox = new JCheckBox();
        advancedChartsCheckBox.setSelected(true);

        // create the scroll pane for the simple parameter setting page
        JLabel label = null;
        label = new JLabel(new ImageIcon(new ImageIcon(getClass().getResource(DECORATION_IMAGE)).getImage()
                .getScaledInstance(DECORATION_IMAGE_WIDTH, -1, Image.SCALE_SMOOTH)));
        Style.registerCssClasses(label, Dashboard.CSS_CLASS_COMMON_PANEL);
        parametersScrollPane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        parametersScrollPane.setBorder(null);
        parametersScrollPane.setViewportBorder(null);

        breadcrumb = new Breadcrumb();
        Style.registerCssClasses(breadcrumb, CSS_ID_BREADCRUMB);

        singleRunParametersPanel = new ScrollableJPanel(new SizeProvider() {

            @Override
            public int getHeight() {
                Component component = tabbedPane.getSelectedComponent();
                if (component == null) {
                    return 0;
                }
                JScrollBar scrollBar = parametersScrollPane.getHorizontalScrollBar();
                return component.getSize().height - breadcrumb.getHeight()
                        - (scrollBar.isVisible() ? scrollBar.getPreferredSize().height : 0);
            }

            @Override
            public int getWidth() {
                final int hScrollBarWidth = parametersScrollPane.getHorizontalScrollBar().getPreferredSize().width;
                final int width = dashboard.getSize().width - Page_Parameters.DECORATION_IMAGE_WIDTH
                        - hScrollBarWidth;
                return width;
            }
        });
        BoxLayout boxLayout = new BoxLayout(singleRunParametersPanel, BoxLayout.X_AXIS);
        singleRunParametersPanel.setLayout(boxLayout);
        parametersScrollPane.setViewportView(singleRunParametersPanel);

        JPanel breadcrumbPanel = new JPanel(new BorderLayout());
        breadcrumbPanel.add(breadcrumb, BorderLayout.NORTH);
        breadcrumbPanel.add(parametersScrollPane, BorderLayout.CENTER);

        final JPanel simpleForm = FormsUtils.build("p ~ p:g", "01 t:p", label, breadcrumbPanel).getPanel();
        Style.registerCssClasses(simpleForm, Dashboard.CSS_CLASS_COMMON_PANEL);

        tabbedPane.add("Single run", simpleForm);

        // create the form for the parameter sweep setting page
        tabbedPane.add("Parameter sweep", createParamsweepGUI());

        gaSearchHandler = new GASearchHandler(currentModelHandler);
        gaSearchPanel = new GASearchPanel(gaSearchHandler, this);
        tabbedPane.add("Genetic Algorithm Search", gaSearchPanel);

        return containerPanel;
    }

    //----------------------------------------------------------------------------------------------------
    @SuppressWarnings("serial")
    private JPanel createParamsweepGUI() {

        // left
        parameterList = new JList();
        parameterList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        new ListAction(parameterList, new AbstractAction() {
            public void actionPerformed(final ActionEvent event) {
                final AvailableParameter selectedParameter = (AvailableParameter) parameterList.getSelectedValue();
                addParameterToTree(new AvailableParameter[] { selectedParameter }, parameterTreeBranches.get(0));
                enableDisableParameterCombinationButtons();
            }
        });
        parameterList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                if (!parameterList.isSelectionEmpty()) {
                    boolean success = true;
                    if (editedNode != null)
                        success = modify();

                    if (success) {
                        cancelAllSelectionBut(parameterList);
                        resetSettings();
                        updateDescriptionField(parameterList.getSelectedValues());
                        enableDisableParameterCombinationButtons();
                    } else
                        parameterList.clearSelection();
                }
            }
        });

        final JScrollPane parameterListPane = new JScrollPane(parameterList);
        parameterListPane.setBorder(BorderFactory.createTitledBorder("")); // for rounded border
        parameterListPane.setPreferredSize(new Dimension(300, 300));

        final JPanel parametersPanel = FormsUtils.build("p ' p:g", "[DialogBorder]00||" + "12||" + "34||" +
        //                                          "56||" + 
                "55||" + "66 f:p:g", new FormsUtils.Separator("<html><b>General parameters</b></html>"),
                NUMBER_OF_TURNS_LABEL_TEXT, numberOfTurnsFieldPSW, NUMBER_OF_TIMESTEPS_TO_IGNORE_LABEL_TEXT,
                numberTimestepsIgnoredPSW,
                //                                          UPDATE_CHARTS_LABEL_TEXT,onLineChartsCheckBoxPSW,
                new FormsUtils.Separator("<html><b>Model parameters</b></html>"), parameterListPane).getPanel();

        combinationsPanel = new JPanel(new GridLayout(0, 1, 5, 5));
        combinationsScrPane = new JScrollPane(combinationsPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        combinationsScrPane.setBorder(null);
        combinationsScrPane.setPreferredSize(new Dimension(550, 500));

        parameterDescriptionLabel = new JXLabel();
        parameterDescriptionLabel.setLineWrap(true);
        parameterDescriptionLabel.setVerticalAlignment(SwingConstants.TOP);
        final JScrollPane descriptionScrollPane = new JScrollPane(parameterDescriptionLabel);
        descriptionScrollPane.setBorder(BorderFactory.createTitledBorder(null, "Description", TitledBorder.LEADING,
                TitledBorder.BELOW_TOP));
        descriptionScrollPane.setPreferredSize(
                new Dimension(PARAMETER_DESCRIPTION_LABEL_WIDTH, PARAMETER_DESCRIPTION_LABEL_HEIGHT));
        descriptionScrollPane.setViewportBorder(null);

        final JButton addNewBoxButton = new JButton("Add new combination");
        addNewBoxButton.setActionCommand(ACTIONCOMMAND_ADD_BOX);

        final JPanel left = FormsUtils.build("p ~ f:p:g ~ p", "011 f:p:g ||" + "0_2 p", parametersPanel,
                combinationsScrPane, addNewBoxButton).getPanel();
        left.setBorder(BorderFactory.createTitledBorder(null, "Specify parameter combinations",
                TitledBorder.LEADING, TitledBorder.BELOW_TOP));
        Style.registerCssClasses(left, Dashboard.CSS_CLASS_COMMON_PANEL);

        final JPanel leftAndDesc = new JPanel(new BorderLayout());
        leftAndDesc.add(left, BorderLayout.CENTER);
        leftAndDesc.add(descriptionScrollPane, BorderLayout.SOUTH);
        Style.registerCssClasses(leftAndDesc, Dashboard.CSS_CLASS_COMMON_PANEL);

        // right
        editedParameterText = new JLabel(ORIGINAL_TEXT);
        editedParameterText.setPreferredSize(new Dimension(280, 40));
        constDef = new JRadioButton("Constant");
        listDef = new JRadioButton("List");
        incrDef = new JRadioButton("Increment");

        final JPanel rightTop = FormsUtils.build("p:g", "[DialogBorder]0||" + "1||" + "2||" + "3",
                editedParameterText, constDef, listDef, incrDef).getPanel();

        Style.registerCssClasses(rightTop, Dashboard.CSS_CLASS_COMMON_PANEL);

        constDefField = new JTextField();
        final JPanel constDefPanel = FormsUtils
                .build("p ~ p:g", "[DialogBorder]01 p", "Constant value: ", CellConstraints.TOP, constDefField)
                .getPanel();

        listDefArea = new JTextArea();
        final JScrollPane listDefScr = new JScrollPane(listDefArea,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        final JPanel listDefPanel = FormsUtils.build("p ~ p:g", "[DialogBorder]01|" + "_1 f:p:g||" + "_2 p",
                "Value list: ", listDefScr, "(Separate values with spaces!)").getPanel();

        incrStartValueField = new JTextField();
        incrEndValueField = new JTextField();
        incrStepField = new JTextField();

        final JPanel incrDefPanel = FormsUtils.build("p ~ p:g", "[DialogBorder]01||" + "23||" + "45",
                "Start value: ", incrStartValueField, "End value: ", incrEndValueField, "Step: ", incrStepField)
                .getPanel();

        enumDefBox = new JComboBox(new DefaultComboBoxModel());
        final JPanel enumDefPanel = FormsUtils
                .build("p ~ p:g", "[DialogBorder]01 p", "Constant value:", CellConstraints.TOP, enumDefBox)
                .getPanel();

        submodelTypeBox = new JComboBox();
        final JPanel submodelTypePanel = FormsUtils
                .build("p ~ p:g", "[DialogBorder]01", "Constant value:", CellConstraints.TOP, submodelTypeBox)
                .getPanel();

        fileTextField = new JTextField();
        fileTextField.addKeyListener(new KeyAdapter() {
            public void keyTyped(final KeyEvent e) {
                final char character = e.getKeyChar();
                final File file = new File(Character.isISOControl(character) ? fileTextField.getText()
                        : fileTextField.getText() + character);
                fileTextField.setToolTipText(file.getAbsolutePath());
            }
        });
        fileBrowseButton = new JButton(BROWSE_BUTTON_TEXT);
        fileBrowseButton.setActionCommand(ACTIONCOMMAND_BROWSE);
        final JPanel fileDefPanel = FormsUtils
                .build("p ~ p:g ~p", "[DialogBorder]012", "File:", fileTextField, fileBrowseButton).getPanel();

        constDefPanel.setName("CONST");
        listDefPanel.setName("LIST");
        incrDefPanel.setName("INCREMENT");
        enumDefPanel.setName("ENUM");
        submodelTypePanel.setName("SUBMODEL");
        fileDefPanel.setName("FILE");

        Style.registerCssClasses(constDefPanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        Style.registerCssClasses(listDefPanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        Style.registerCssClasses(incrDefPanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        Style.registerCssClasses(enumDefPanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        Style.registerCssClasses(submodelTypePanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        Style.registerCssClasses(fileDefPanel, Dashboard.CSS_CLASS_COMMON_PANEL);

        rightMiddle = new JPanel(new CardLayout());
        Style.registerCssClasses(rightMiddle, Dashboard.CSS_CLASS_COMMON_PANEL);
        rightMiddle.add(constDefPanel, constDefPanel.getName());
        rightMiddle.add(listDefPanel, listDefPanel.getName());
        rightMiddle.add(incrDefPanel, incrDefPanel.getName());
        rightMiddle.add(enumDefPanel, enumDefPanel.getName());
        rightMiddle.add(submodelTypePanel, submodelTypePanel.getName());
        rightMiddle.add(fileDefPanel, fileDefPanel.getName());

        modifyButton = new JButton("Modify");
        cancelButton = new JButton("Cancel");

        final JPanel rightBottom = FormsUtils
                .build("p:g p ~ p ~ p:g", "[DialogBorder]_01_ p", modifyButton, cancelButton).getPanel();

        Style.registerCssClasses(rightBottom, Dashboard.CSS_CLASS_COMMON_PANEL);

        final JPanel right = new JPanel(new BorderLayout());
        right.add(rightTop, BorderLayout.NORTH);
        right.add(rightMiddle, BorderLayout.CENTER);
        right.add(rightBottom, BorderLayout.SOUTH);
        right.setBorder(BorderFactory.createTitledBorder(null, "Parameter settings", TitledBorder.LEADING,
                TitledBorder.BELOW_TOP));

        Style.registerCssClasses(right, Dashboard.CSS_CLASS_COMMON_PANEL);

        // the whole paramsweep panel

        final JPanel content = FormsUtils.build("p:g p", "01 f:p:g", leftAndDesc, right).getPanel();
        Style.registerCssClasses(content, Dashboard.CSS_CLASS_COMMON_PANEL);

        sweepPanel = new JPanel();
        Style.registerCssClasses(sweepPanel, Dashboard.CSS_CLASS_COMMON_PANEL);
        sweepPanel.setLayout(new BorderLayout());
        final JScrollPane sp = new JScrollPane(content);
        sp.setBorder(null);
        sp.setViewportBorder(null);
        sweepPanel.add(sp, BorderLayout.CENTER);

        GUIUtils.createButtonGroup(constDef, listDef, incrDef);
        constDef.setSelected(true);
        constDef.setActionCommand("CONST");
        listDef.setActionCommand("LIST");
        incrDef.setActionCommand("INCREMENT");

        constDefField.setActionCommand("CONST_FIELD");
        incrStartValueField.setActionCommand("START_FIELD");
        incrEndValueField.setActionCommand("END_FIELD");
        incrStepField.setActionCommand("STEP_FIELD");

        modifyButton.setActionCommand("EDIT");
        cancelButton.setActionCommand("CANCEL");

        listDefArea.setLineWrap(true);
        listDefArea.setWrapStyleWord(true);
        listDefScr.setPreferredSize(new Dimension(100, 200));

        GUIUtils.addActionListener(this, modifyButton, cancelButton, constDef, listDef, incrDef, constDefField,
                incrStartValueField, incrEndValueField, incrStepField, addNewBoxButton, submodelTypeBox,
                fileBrowseButton);

        return sweepPanel;
    }

    //----------------------------------------------------------------------------------------------------
    private JPanel createAParameterBox(final boolean first) {

        final JLabel runLabel = new JLabel("<html><b>Number of runs:</b> 0</html>");
        final JLabel warningLabel = new JLabel();

        final JButton closeButton = new JButton();
        closeButton.setOpaque(false);
        closeButton.setBorder(null);
        closeButton.setFocusable(false);

        if (!first) {
            closeButton.setRolloverIcon(PARAMETER_BOX_REMOVE);
            closeButton.setRolloverEnabled(true);
            closeButton.setIcon(RGBGrayFilter.getDisabledIcon(closeButton, PARAMETER_BOX_REMOVE));
            closeButton.setActionCommand(ACTIONCOMMAND_REMOVE_BOX);
        }

        final JScrollPane treeScrPane = new JScrollPane();
        final DefaultMutableTreeNode treeRoot = new DefaultMutableTreeNode();
        final JTree tree = new JTree(treeRoot);
        ToolTipManager.sharedInstance().registerComponent(tree);

        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.setCellRenderer(new ParameterBoxTreeRenderer());
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(final TreeSelectionEvent e) {
                final TreePath selectionPath = tree.getSelectionPath();
                boolean success = true;
                if (editedNode != null
                        && (selectionPath == null || !editedNode.equals(selectionPath.getLastPathComponent())))
                    success = modify();

                if (success) {
                    if (selectionPath != null) {
                        cancelAllSelectionBut(tree);
                        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath
                                .getLastPathComponent();
                        if (!node.equals(editedNode)) {
                            ParameterInATree userObj = null;
                            final DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
                            if (!node.isRoot()
                                    && selectionPath.getPathCount() == model.getPathToRoot(node).length) {
                                userObj = (ParameterInATree) node.getUserObject();
                                final ParameterInfo info = userObj.info;
                                editedNode = node;
                                editedTree = tree;
                                edit(info);
                            } else {
                                tree.setSelectionPath(null);
                                if (cancelButton.isEnabled())
                                    cancelButton.doClick();
                                resetSettings();
                                enableDisableSettings(false);
                                editedNode = null;
                                editedTree = null;
                            }

                            updateDescriptionField(userObj);
                        } else
                            updateDescriptionField();

                    } else
                        updateDescriptionField();

                    enableDisableParameterCombinationButtons();
                } else {
                    final DefaultTreeModel model = (DefaultTreeModel) editedTree.getModel();
                    final DefaultMutableTreeNode storedEditedNode = editedNode;
                    editedNode = null;
                    tree.setSelectionPath(null);
                    editedNode = storedEditedNode;
                    editedTree.setSelectionPath(new TreePath(model.getPathToRoot(editedNode)));
                }
            }
        });

        treeScrPane.setViewportView(tree);
        treeScrPane.setBorder(null);
        treeScrPane.setViewportBorder(null);
        treeScrPane.setPreferredSize(new Dimension(450, 250));

        final JButton upButton = new JButton();
        upButton.setOpaque(false);
        upButton.setRolloverEnabled(true);
        upButton.setIcon(PARAMETER_UP_ICON);
        upButton.setRolloverIcon(PARAMETER_UP_ICON_RO);
        upButton.setDisabledIcon(PARAMETER_UP_ICON_DIS);
        upButton.setBorder(null);
        upButton.setToolTipText("Move up the selected parameter");
        upButton.setActionCommand(ACTIONCOMMAND_MOVE_UP);

        final JButton downButton = new JButton();
        downButton.setOpaque(false);
        downButton.setRolloverEnabled(true);
        downButton.setIcon(PARAMETER_DOWN_ICON);
        downButton.setRolloverIcon(PARAMETER_DOWN_ICON_RO);
        downButton.setDisabledIcon(PARAMETER_DOWN_ICON_DIS);
        downButton.setBorder(null);
        downButton.setToolTipText("Move down the selected parameter");
        downButton.setActionCommand(ACTIONCOMMAND_MOVE_DOWN);

        final JPanel mainPanel = FormsUtils.build("~ f:p:g ~ p ~ r:p",
                "012||" + "333||" + "44_||" + "445||" + "446||" + "44_ f:p:g", runLabel, first ? "" : warningLabel,
                first ? warningLabel : closeButton, new FormsUtils.Separator(""), treeScrPane, upButton, downButton)
                .getPanel();

        mainPanel.setBorder(BorderFactory.createTitledBorder(""));

        final JButton addButton = new JButton();
        addButton.setOpaque(false);
        addButton.setRolloverEnabled(true);
        addButton.setIcon(PARAMETER_ADD_ICON);
        addButton.setRolloverIcon(PARAMETER_ADD_ICON_RO);
        addButton.setDisabledIcon(PARAMETER_ADD_ICON_DIS);
        addButton.setBorder(null);
        addButton.setToolTipText("Add selected parameter");
        addButton.setActionCommand(ACTIONCOMMAND_ADD_PARAM);

        final JButton removeButton = new JButton();
        removeButton.setOpaque(false);
        removeButton.setRolloverEnabled(true);
        removeButton.setIcon(PARAMETER_REMOVE_ICON);
        removeButton.setRolloverIcon(PARAMETER_REMOVE_ICON_RO);
        removeButton.setDisabledIcon(PARAMETER_REMOVE_ICON_DIS);
        removeButton.setBorder(null);
        removeButton.setToolTipText("Remove selected parameter");
        removeButton.setActionCommand(ACTIONCOMMAND_REMOVE_PARAM);

        final JPanel result = FormsUtils.build("p ~ f:p:g", "_0 f:p:g||" + "10 p ||" + "20 p||" + "_0 f:p:g",
                mainPanel, addButton, removeButton).getPanel();

        Style.registerCssClasses(result, Dashboard.CSS_CLASS_COMMON_PANEL);

        final ParameterCombinationGUI pcGUI = new ParameterCombinationGUI(tree, treeRoot, runLabel, warningLabel,
                addButton, removeButton, upButton, downButton);
        parameterTreeBranches.add(pcGUI);

        final ActionListener boxActionListener = new ActionListener() {

            //====================================================================================================
            // methods

            //----------------------------------------------------------------------------------------------------
            public void actionPerformed(final ActionEvent e) {
                final String cmd = e.getActionCommand();

                if (ACTIONCOMMAND_ADD_PARAM.equals(cmd))
                    handleAddParameter(pcGUI);
                else if (ACTIONCOMMAND_REMOVE_PARAM.equals(cmd))
                    handleRemoveParameter(tree);
                else if (ACTIONCOMMAND_REMOVE_BOX.equals(cmd))
                    handleRemoveBox(tree);
                else if (ACTIONCOMMAND_MOVE_UP.equals(cmd))
                    handleMoveUp();
                else if (ACTIONCOMMAND_MOVE_DOWN.equals(cmd))
                    handleMoveDown();
            }

            //----------------------------------------------------------------------------------------------------
            private void handleAddParameter(final ParameterCombinationGUI pcGUI) {
                final Object[] selectedValues = parameterList.getSelectedValues();
                if (selectedValues != null && selectedValues.length > 0) {
                    final AvailableParameter[] params = new AvailableParameter[selectedValues.length];
                    System.arraycopy(selectedValues, 0, params, 0, selectedValues.length);
                    addParameterToTree(params, pcGUI);
                    enableDisableParameterCombinationButtons();
                }
            }

            //----------------------------------------------------------------------------------------------------
            private void handleRemoveParameter(final JTree tree) {
                final TreePath selectionPath = tree.getSelectionPath();
                if (selectionPath != null) {
                    cancelButton.doClick();

                    final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath
                            .getLastPathComponent();
                    if (!node.isRoot()) {
                        final DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) node.getParent();
                        if (parentNode.isRoot()) {
                            removeParameter(tree, node, parentNode);
                            enableDisableParameterCombinationButtons();
                        }
                    }
                }
            }

            //----------------------------------------------------------------------------------------------------
            private void handleRemoveBox(final JTree tree) {
                final int answer = Utilities.askUser(dashboard, false, "Comfirmation",
                        "This operation deletes the combination.",
                        "All related parameter returns back to the list on the left side.", "Are you sure?");
                if (answer == 1) {
                    final DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();

                    if (tree.getSelectionCount() > 0) {
                        editedNode = null;
                        tree.setSelectionPath(null);
                        if (cancelButton.isEnabled())
                            cancelButton.doClick();
                    }

                    final DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
                    for (int i = 0; i < root.getChildCount(); ++i) {
                        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
                        removeParameter(tree, node, root);
                    }

                    enableDisableParameterCombinationButtons();

                    parameterTreeBranches.remove(pcGUI);
                    combinationsPanel.remove(result);
                    combinationsPanel.revalidate();

                    updateNumberOfRuns();
                }
            }

            //----------------------------------------------------------------------------------------------------
            private void removeParameter(final JTree tree, final DefaultMutableTreeNode node,
                    final DefaultMutableTreeNode parentNode) {
                final ParameterInATree userObj = (ParameterInATree) node.getUserObject();
                final ParameterInfo originalInfo = findOriginalInfo(userObj.info);
                if (originalInfo != null) {
                    final DefaultListModel model = (DefaultListModel) parameterList.getModel();
                    model.addElement(new AvailableParameter(originalInfo, currentModelHandler.getModelClass()));
                    final DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
                    treeModel.removeNodeFromParent(node);
                    updateNumberOfRuns();
                    tree.expandPath(new TreePath(treeModel.getPathToRoot(parentNode)));
                } else
                    throw new IllegalStateException(
                            "Parameter " + userObj.info.getName() + " is not found in the model.");
            }

            //----------------------------------------------------------------------------------------------------
            private void handleMoveUp() {
                final TreePath selectionPath = tree.getSelectionPath();
                if (selectionPath != null) {
                    boolean success = true;
                    if (editedNode != null)
                        success = modify();

                    if (success) {
                        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath
                                .getLastPathComponent();
                        final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();

                        if (parent == null || parent.getFirstChild().equals(node)) {
                            tree.setSelectionPath(null); // we need this to preserve the state of the parameter settings panel
                            tree.setSelectionPath(new TreePath(node.getPath()));
                            return;
                        }

                        final int index = parent.getIndex(node);
                        final DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
                        treemodel.removeNodeFromParent(node);
                        treemodel.insertNodeInto(node, parent, index - 1);
                        tree.setSelectionPath(new TreePath(node.getPath()));
                    }

                }
            }

            //----------------------------------------------------------------------------------------------------
            private void handleMoveDown() {
                final TreePath selectionPath = tree.getSelectionPath();
                if (selectionPath != null) {
                    boolean success = true;
                    if (editedNode != null)
                        success = modify();

                    if (success) {
                        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath
                                .getLastPathComponent();
                        final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();

                        if (parent == null || parent.getLastChild().equals(node)) {
                            tree.setSelectionPath(null); // we need this to preserve the state of the parameter settings panel
                            tree.setSelectionPath(new TreePath(node.getPath()));
                            return;
                        }

                        final int index = parent.getIndex(node);
                        final DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
                        treemodel.removeNodeFromParent(node);
                        treemodel.insertNodeInto(node, parent, index + 1);
                        tree.setSelectionPath(new TreePath(node.getPath()));
                    }
                }
            }
        };

        GUIUtils.addActionListener(boxActionListener, closeButton, upButton, downButton, addButton, removeButton);

        result.setPreferredSize(new Dimension(500, 250));
        enableDisableParameterCombinationButtons();

        Style.apply(result, dashboard.getCssStyle());

        return result;
    }

    //----------------------------------------------------------------------------------------------------
    private void addParameterToTree(final AvailableParameter[] parameters, final ParameterCombinationGUI pcGUI) {
        final DefaultListModel listModel = (DefaultListModel) parameterList.getModel();
        final DefaultTreeModel treeModel = (DefaultTreeModel) pcGUI.tree.getModel();
        final DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();

        for (final AvailableParameter parameter : parameters) {
            listModel.removeElement(parameter);
            final ParameterInfo selectedInfo = parameter.info;
            final DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
                    new ParameterInATree(selectedInfo, currentModelHandler.getModelClass()));
            treeModel.insertNodeInto(newNode, root, root.getChildCount());

            if (selectedInfo instanceof SubmodelInfo) {
                final SubmodelInfo sInfo = (SubmodelInfo) selectedInfo;
                if (sInfo.getActualType() != null) {
                    addSubParametersToTree(sInfo, pcGUI.tree, newNode);
                    pcGUI.tree.expandPath(new TreePath(treeModel.getPathToRoot(newNode)));
                }
            }
        }

        updateNumberOfRuns();
        pcGUI.tree.expandPath(new TreePath(treeModel.getPathToRoot(root)));
    }

    //----------------------------------------------------------------------------------------------------
    public void resetParamsweepGUI() {
        changeText(null, null);
        constDef.setSelected(true);
        constDefField.setText(null);
        incrStartValueField.setText(null);
        incrEndValueField.setText(null);
        incrStepField.setText(null);
        listDefArea.setText(null);
        fileTextField.setText(null);
        fileTextField.setToolTipText(null);
        combinationsPanel.removeAll();
        parameterTreeBranches.clear();
        combinationsPanel.add(createAParameterBox(true));
        combinationsPanel.revalidate();
    }

    //----------------------------------------------------------------------------------------------------
    /** {@inheritDoc} 
     */
    @Override
    public boolean isEnabled(final Button button) {
        switch (button) {
        case BACK:
            return true;

        case NEXT:
            return true;

        case CANCEL: // this is the charts page
            return true;

        case FINISH:
            return false;

        case CUSTOM:
            return false;
        }
        return false;
    }

    //----------------------------------------------------------------------------------------------------
    /** {@inheritDoc} 
     */
    @Override
    public boolean onButtonPress(final Button button) {
        if (Button.NEXT.equals(button)) {
            ParameterTree parameterTree = null;
            if (tabbedPane.getSelectedIndex() == SINGLE_RUN_GUI_TABINDEX) {
                currentModelHandler.setIntelliMethodPlugin(null);
                parameterTree = new ParameterTree();
                final Set<ParameterInfo> invalids = new HashSet<ParameterInfo>();

                @SuppressWarnings("rawtypes")
                final Enumeration treeValues = parameterValueComponentTree.breadthFirstEnumeration();
                treeValues.nextElement(); // root element
                while (treeValues.hasMoreElements()) {
                    final DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeValues.nextElement();
                    @SuppressWarnings("unchecked")
                    final Pair<ParameterInfo, JComponent> userData = (Pair<ParameterInfo, JComponent>) node
                            .getUserObject();
                    final ParameterInfo parameterInfo = userData.getFirst();
                    final JComponent valueContainer = userData.getSecond();

                    if (parameterInfo instanceof ISubmodelGUIInfo) {
                        final ISubmodelGUIInfo sgi = (ISubmodelGUIInfo) parameterInfo;
                        if (sgi.getParent() != null) {
                            final DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) node.getParent();
                            @SuppressWarnings("unchecked")
                            final Pair<ParameterInfo, JComponent> parentUserData = (Pair<ParameterInfo, JComponent>) parentNode
                                    .getUserObject();
                            final SubmodelInfo parentParameterInfo = (SubmodelInfo) parentUserData.getFirst();
                            if (invalids.contains(parentParameterInfo)
                                    || !classEquals(parentParameterInfo.getActualType(), sgi.getParentValue())) {
                                invalids.add(parameterInfo);
                                continue;
                            }
                        }
                    }

                    if (parameterInfo.isBoolean()) {
                        final JCheckBox checkBox = (JCheckBox) valueContainer;
                        parameterInfo.setValue(checkBox.isSelected());
                    } else if (parameterInfo.isEnum()) {
                        final JComboBox comboBox = (JComboBox) valueContainer;
                        parameterInfo.setValue(comboBox.getSelectedItem());
                    } else if (parameterInfo instanceof MasonChooserParameterInfo) {
                        final JComboBox comboBox = (JComboBox) valueContainer;
                        parameterInfo.setValue(comboBox.getSelectedIndex());
                    } else if (parameterInfo instanceof SubmodelInfo) {
                        // we don't need the SubmodelInfo parameters anymore (all descendant parameters are in the tree too)
                        // but we need to check that an actual type is provided
                        final SubmodelInfo smi = (SubmodelInfo) parameterInfo;
                        final JComboBox comboBox = (JComboBox) ((JPanel) valueContainer).getComponent(0);
                        final ClassElement selected = (ClassElement) comboBox.getSelectedItem();
                        smi.setActualType(selected.clazz, selected.instance);

                        if (smi.getActualType() == null) {
                            final String errorMsg = "Please select a type from the dropdown list of "
                                    + smi.getName().replaceAll("([A-Z])", " $1");
                            JOptionPane.showMessageDialog(wizard, new JLabel(errorMsg), "Error",
                                    JOptionPane.ERROR_MESSAGE);
                            return false;
                        }

                        //continue;
                    } else if (parameterInfo.isFile()) {
                        final JTextField textField = (JTextField) valueContainer.getComponent(0);
                        if (textField.getText().trim().isEmpty())
                            log.warn("Empty string was specified as file parameter "
                                    + parameterInfo.getName().replaceAll("([A-Z])", " $1"));

                        final File file = new File(textField.getToolTipText());
                        if (!file.exists()) {
                            final String errorMsg = "Please specify an existing file parameter "
                                    + parameterInfo.getName().replaceAll("([A-Z])", " $1");
                            JOptionPane.showMessageDialog(wizard, new JLabel(errorMsg), "Error",
                                    JOptionPane.ERROR_MESSAGE);
                            return false;
                        }

                        parameterInfo.setValue(
                                ParameterInfo.getValue(textField.getToolTipText(), parameterInfo.getType()));
                    } else if (parameterInfo instanceof MasonIntervalParameterInfo) {
                        final JTextField textField = (JTextField) valueContainer.getComponent(0);
                        parameterInfo.setValue(
                                ParameterInfo.getValue(textField.getText().trim(), parameterInfo.getType()));
                    } else {
                        final JTextField textField = (JTextField) valueContainer;
                        parameterInfo
                                .setValue(ParameterInfo.getValue(textField.getText(), parameterInfo.getType()));
                        if ("String".equals(parameterInfo.getType()) && parameterInfo.getValue() == null)
                            parameterInfo.setValue(textField.getText().trim());
                    }

                    final AbstractParameterInfo<?> batchParameterInfo = InfoConverter
                            .parameterInfo2ParameterInfo(parameterInfo);
                    parameterTree.addNode(batchParameterInfo);
                }

                dashboard.setOnLineCharts(onLineChartsCheckBox.isSelected());
                dashboard.setDisplayAdvancedCharts(advancedChartsCheckBox.isSelected());
            }

            if (tabbedPane.getSelectedIndex() == PARAMSWEEP_GUI_TABINDEX) {
                currentModelHandler.setIntelliMethodPlugin(null);
                boolean success = true;
                if (editedNode != null)
                    success = modify();

                if (success) {
                    String invalidInfoName = checkInfos(true);
                    if (invalidInfoName != null) {
                        Utilities.userAlert(sweepPanel,
                                "Please select a type from the dropdown list of " + invalidInfoName);
                        return false;
                    }

                    invalidInfoName = checkInfos(false);
                    if (invalidInfoName != null) {
                        Utilities.userAlert(sweepPanel, "Please specify a file for parameter " + invalidInfoName);
                        return false;
                    }

                    if (needWarning()) {
                        final int result = Utilities.askUser(sweepPanel, false, "Warning",
                                "There are two or more combination boxes that contains non-constant parameters."
                                        + " Parameters are unsynchronized:",
                                "simulation may exit before all parameter values are assigned.", " ",
                                "To explore all possible combinations you must use only one combination box.", " ",
                                "Do you want to run simulation with these parameter settings?");
                        if (result == 0) {
                            return false;
                        }
                    }

                    try {
                        parameterTree = createParameterTreeFromParamSweepGUI();

                        final ParameterNode rootNode = parameterTree.getRoot();
                        dumpParameterTree(rootNode);

                        //                  dashboard.setOnLineCharts(onLineChartsCheckBoxPSW.isSelected());
                    } catch (final ModelInformationException e) {
                        JOptionPane.showMessageDialog(wizard, new JLabel(e.getMessage()),
                                "Error while creating runs", JOptionPane.ERROR_MESSAGE);
                        e.printStackTrace();
                        return false;
                    }
                } else
                    return false;
            }

            if (tabbedPane.getSelectedIndex() == GASEARCH_GUI_TABINDEX) {
                final IIntelliDynamicMethodPlugin gaPlugin = (IIntelliDynamicMethodPlugin) gaSearchHandler;
                currentModelHandler.setIntelliMethodPlugin(gaPlugin);
                boolean success = gaSearchPanel.closeActiveModification();

                if (success) {
                    String invalidInfoName = checkInfosInGeneTree();
                    if (invalidInfoName != null) {
                        Utilities.userAlert(sweepPanel,
                                "Please select a type from the dropdown list of " + invalidInfoName);
                        return false;
                    }

                    final String[] errors = gaSearchHandler.checkGAModel();
                    if (errors != null) {
                        Utilities.userAlert(sweepPanel, (Object[]) errors);
                        return false;
                    }

                    final DefaultMutableTreeNode parameterTreeRootNode = new DefaultMutableTreeNode();
                    final IIntelliContext ctx = new DashboardIntelliContext(parameterTreeRootNode,
                            gaSearchHandler.getChromosomeTree());
                    gaPlugin.alterParameterTree(ctx);
                    parameterTree = InfoConverter.node2ParameterTree(parameterTreeRootNode);
                    dashboard.setOptimizationDirection(gaSearchHandler.getFitnessFunctionDirection());

                } else
                    return false;
            }

            currentModelHandler.setParameters(parameterTree);
        }

        return true;
    }

    //----------------------------------------------------------------------------------------------------
    public Model saveConfiguration() throws IOException {
        final ObjectFactory factory = new ObjectFactory();

        final Model result = factory.createModel();
        result.setClazz(currentModelHandler.getModelClass().getName());

        if (tabbedPane.getSelectedIndex() == SINGLE_RUN_GUI_TABINDEX) {
            result.setRunStrategy(ModelType.SINGLE);

            final List<GeneralParameter> generalParameters = result.getGeneralParameterList();

            GeneralParameter gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.NUMBER_OF_TURNS_XML_NAME);
            gp.setValue(numberOfTurnsField.getText());
            generalParameters.add(gp);

            gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.NUMBER_OF_TIMESTEPS_TO_IGNORE_XML_NAME);
            gp.setValue(numberTimestepsIgnored.getText());
            generalParameters.add(gp);

            gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.UPDATE_CHARTS_XML_NAME);
            gp.setValue(String.valueOf(onLineChartsCheckBox.isSelected()));
            generalParameters.add(gp);

            gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.DISPLAY_ADVANCED_CHARTS_XML_NAME);
            gp.setValue(String.valueOf(advancedChartsCheckBox.isSelected()));
            generalParameters.add(gp);

            final Set<ParameterInfo> invalids = new HashSet<ParameterInfo>();

            final List<Parameter> parameterList = result.getParameterList();
            final List<SubmodelParameter> submodelParameterList = result.getSubmodelParameterList();

            @SuppressWarnings("rawtypes")
            final Enumeration firstLevelParameters = parameterValueComponentTree.children();
            saveSubTree(firstLevelParameters, parameterList, submodelParameterList, invalids);
        } else if (tabbedPane.getSelectedIndex() == PARAMSWEEP_GUI_TABINDEX) {
            result.setRunStrategy(ModelType.PARAMETER_SWEEP);

            //calculate the number of runs, which is the minimum of the number of runs in the parameter combination boxes
            int validMin = Integer.MAX_VALUE;
            for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
                final int run = Page_Parameters.calculateNumberOfRuns(pGUI.combinationRoot);
                if (run > 1 && run < validMin)
                    validMin = run;
            }

            result.setNumberOfRuns(validMin);

            final List<GeneralParameter> generalParameters = result.getGeneralParameterList();

            GeneralParameter gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.NUMBER_OF_TURNS_XML_NAME);
            gp.setValue(numberOfTurnsFieldPSW.getText());
            generalParameters.add(gp);

            gp = factory.createGeneralParameter();
            gp.setName(ParameterTreeUtils.NUMBER_OF_TIMESTEPS_TO_IGNORE_XML_NAME);
            gp.setValue(numberTimestepsIgnoredPSW.getText());
            generalParameters.add(gp);

            savePSParameterList(factory, result);

            for (int i = 0; i < parameterTreeBranches.size(); ++i)
                savePSBranch(factory, result, parameterTreeBranches.get(i), i + 1);
        } else {
            result.setRunStrategy(ModelType.GA);
            gaSearchHandler.saveConfiguration(factory, result);
        }

        return result;
    }

    //----------------------------------------------------------------------------------------------------
    private void saveSubTree(@SuppressWarnings("rawtypes") final Enumeration children,
            final List<Parameter> parameterList, final List<SubmodelParameter> submodelParameterList,
            final Set<ParameterInfo> invalids) throws IOException {

        final ObjectFactory factory = new ObjectFactory();
        while (children.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement();

            @SuppressWarnings("unchecked")
            final Pair<ParameterInfo, JComponent> userData = (Pair<ParameterInfo, JComponent>) node.getUserObject();
            final ParameterInfo parameterInfo = userData.getFirst();
            final JComponent valueContainer = userData.getSecond();

            Parameter parameter = null;
            SubmodelParameter submodelParameter = null;
            if (parameterInfo instanceof ISubmodelGUIInfo) {
                final ISubmodelGUIInfo sgi = (ISubmodelGUIInfo) parameterInfo;
                if (sgi.getParent() != null) {
                    final DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) node.getParent();
                    @SuppressWarnings("unchecked")
                    final Pair<ParameterInfo, JComponent> parentUserData = (Pair<ParameterInfo, JComponent>) parentNode
                            .getUserObject();
                    final SubmodelInfo parentParameterInfo = (SubmodelInfo) parentUserData.getFirst();
                    if (invalids.contains(parentParameterInfo)
                            || !classEquals(parentParameterInfo.getActualType(), sgi.getParentValue())) {
                        invalids.add(parameterInfo);
                        continue;
                    }
                }
            }

            if (parameterInfo instanceof SubmodelInfo) {
                submodelParameter = factory.createSubmodelParameter();
                submodelParameter.setName(parameterInfo.getName());
            } else {
                parameter = factory.createParameter();
                parameter.setName(parameterInfo.getName());
            }

            if (parameterInfo.isBoolean()) {
                final JCheckBox checkBox = (JCheckBox) valueContainer;
                parameter.getContent().add(String.valueOf(checkBox.isSelected()));
            } else if (parameterInfo.isEnum()) {
                final JComboBox comboBox = (JComboBox) valueContainer;
                parameter.getContent().add(String.valueOf(comboBox.getSelectedItem()));
            } else if (parameterInfo instanceof MasonChooserParameterInfo) {
                final JComboBox comboBox = (JComboBox) valueContainer;
                parameter.getContent().add(String.valueOf(comboBox.getSelectedIndex()));
            } else if (parameterInfo instanceof SubmodelInfo) {
                final JComboBox comboBox = (JComboBox) ((JPanel) valueContainer).getComponent(0);
                final ClassElement selectedElement = (ClassElement) comboBox.getSelectedItem();

                if (selectedElement.clazz == null)
                    throw new IOException("No type is selected for parameter "
                            + parameterInfo.getName().replaceAll("([A-Z])", " $1") + ".");

                submodelParameter.setType(selectedElement.clazz.getName());
                saveSubTree(node.children(), submodelParameter.getParameterList(),
                        submodelParameter.getSubmodelParameterList(), invalids);
            } else if (parameterInfo.isFile()) {
                final JTextField textField = (JTextField) valueContainer.getComponent(0);
                parameter.getContent().add(textField.getToolTipText());
            } else if (parameterInfo instanceof MasonIntervalParameterInfo) {
                final JTextField textField = (JTextField) valueContainer.getComponent(0);
                parameter.getContent().add(textField.getText().trim());
            } else {
                final JTextField textField = (JTextField) valueContainer;
                String text = String.valueOf(ParameterInfo.getValue(textField.getText(), parameterInfo.getType()));
                if ("String".equals(parameterInfo.getType()) && parameterInfo.getValue() == null)
                    text = textField.getText().trim();
                parameter.getContent().add(text);
            }

            if (parameter != null)
                parameterList.add(parameter);
            else if (submodelParameter != null)
                submodelParameterList.add(submodelParameter);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void savePSParameterList(final ObjectFactory factory, final Model model) {
        final DefaultListModel listModel = (DefaultListModel) parameterList.getModel();

        if (!listModel.isEmpty()) {
            for (int i = 0; i < listModel.getSize(); ++i) {
                final AvailableParameter availableParameter = (AvailableParameter) listModel.get(i);

                final DefaultParameter defaultParameter = factory.createDefaultParameter();
                defaultParameter.setName(availableParameter.info.getName());
                model.getDefaultParameterList().add(defaultParameter);
            }
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void savePSBranch(final ObjectFactory factory, final Model model,
            final ParameterCombinationGUI combinationGUI, final int position) {
        final Combination combination = factory.createCombination();
        combination.setPosition(BigInteger.valueOf(position));
        model.getCombination().add(combination);

        int pPosition = 1;
        @SuppressWarnings("rawtypes")
        final Enumeration paramNodes = combinationGUI.combinationRoot.children();
        while (paramNodes.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) paramNodes.nextElement();
            savePSParameter(node, factory, combination, pPosition++);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void savePSParameter(final DefaultMutableTreeNode node, final ObjectFactory factory,
            final Object parent, final int position) {
        final ParameterInATree userObj = (ParameterInATree) node.getUserObject();
        final ParameterInfo info = userObj.info;

        if (info instanceof SubmodelInfo) {
            final SubmodelInfo sInfo = (SubmodelInfo) info;

            final SubmodelParameter parameter = factory.createSubmodelParameter();
            parameter.setName(info.getName());
            parameter.setType(sInfo.getActualType() == null ? "null" : sInfo.getActualType().getName());
            parameter.setPosition(BigInteger.valueOf(position));

            if (parent instanceof Combination) {
                final Combination combination = (Combination) parent;
                combination.getSubmodelParameterList().add(parameter);
            } else if (parent instanceof SubmodelParameter) {
                final SubmodelParameter submodelParameter = (SubmodelParameter) parent;
                submodelParameter.getSubmodelParameterList().add(parameter);
            }

            if (node.getChildCount() > 0) {
                @SuppressWarnings("rawtypes")
                final Enumeration childNodes = node.children();
                int childPosition = 1;
                while (childNodes.hasMoreElements()) {
                    final DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) childNodes.nextElement();
                    savePSParameter(childNode, factory, parameter, childPosition++);
                }
            }
        } else {
            final Parameter parameter = factory.createParameter();
            parameter.setName(info.getName());
            parameter.setPosition(BigInteger.valueOf(position));

            switch (info.getDefinitionType()) {
            case ParameterInfo.CONST_DEF:
                parameter.setParameterType(ParameterType.CONSTANT);
                parameter.getContent().add(info.getValue().toString());
                break;

            case ParameterInfo.LIST_DEF:
                parameter.setParameterType(ParameterType.LIST);
                savePSListParameter(info, parameter, factory);
                break;

            case ParameterInfo.INCR_DEF:
                parameter.setParameterType(ParameterType.INCREMENT);
                savePSIncrementParameter(info, parameter, factory);
                break;
            }

            if (parent instanceof Combination) {
                final Combination combination = (Combination) parent;
                combination.getParameterList().add(parameter);
            } else if (parent instanceof SubmodelParameter) {
                final SubmodelParameter submodelParameter = (SubmodelParameter) parent;
                submodelParameter.getParameterList().add(parameter);
            }
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void savePSListParameter(final ParameterInfo info, final Parameter parameter,
            final ObjectFactory factory) {
        for (final Object listElement : info.getValues()) {
            final JAXBElement<String> element = factory.createParameterParameterValue(listElement.toString());
            parameter.getContent().add(element);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void savePSIncrementParameter(final ParameterInfo info, final Parameter parameter,
            final ObjectFactory factory) {
        JAXBElement<String> element = factory.createParameterStartValue(info.getStartValue().toString());
        parameter.getContent().add(element);
        element = factory.createParameterEndValue(info.getEndValue().toString());
        parameter.getContent().add(element);
        element = factory.createParameterStepValue(info.getStep().toString());
        parameter.getContent().add(element);
    }

    //----------------------------------------------------------------------------------------------------
    public void loadConfiguration(final Model model) {
        try {
            currentModelHandler = dashboard.getModelHandler();
            singleRunParametersPanel.removeAll();

            parameterValueComponentTree = new DefaultMutableTreeNode();
            possibleTypesCache.clear();
            batchParameters = currentModelHandler.getParameters();

            final ModelType runStrategy = model.getRunStrategy();

            if (ModelType.SINGLE == runStrategy)
                fillParameterValueComponentTree(model);

            final List<ParameterInfo> modelParameters = createAndDisplayAParameterPanel(batchParameters,
                    "Model parameters", null, true, currentModelHandler);

            parametersScrollPane.setViewportView(singleRunParametersPanel);
            singleRunParametersPanel.revalidate();

            if (ModelType.SINGLE == runStrategy) {
                tabbedPane.setSelectedIndex(SINGLE_RUN_GUI_TABINDEX);
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        numberOfTurnsField.grabFocus();
                    }
                });
            }

            // initialize paramsweep panel
            Collections.sort(modelParameters);
            enableDisableSettings(false);
            modifyButton.setEnabled(false);
            resetParamsweepGUI();

            if (ModelType.PARAMETER_SWEEP == runStrategy) {
                fillParameterSweepPage(model);
                tabbedPane.setSelectedIndex(PARAMSWEEP_GUI_TABINDEX);
            } else
                createDefaultParameterList(modelParameters);

            updateNumberOfRuns();

            // initialize the GA seach panel
            gaSearchHandler.init(currentModelHandler);
            gaSearchHandler.removeAllFitnessFunctions();
            final List<RecordableInfo> recordables = dashboard.getModelHandler().getRecorders().get(0)
                    .getRecordables();
            for (final RecordableInfo recordableInfo : recordables) {
                if (gaSearchHandler.canBeFitnessFunction(recordableInfo))
                    gaSearchHandler.addFitnessFunction(recordableInfo);
            }

            if (ModelType.GA == runStrategy) {
                gaSearchHandler.loadConfiguration(model, modelParameters);
                tabbedPane.setSelectedIndex(GASEARCH_GUI_TABINDEX);
                //            gaSearchPanel.setSelectedFitnessFunction(gaSearchHandler); this is handled by gaSearchPanel.reset()
            }

            gaSearchPanel.reset(gaSearchHandler);
        } catch (final ModelInformationException e) {
            JOptionPane.showMessageDialog(wizard, new JLabel(e.getMessage()),
                    "Error while analyizing model and/or configuration file", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        } finally {
            ((CardLayout) container.getLayout()).show(container, PARAMETERS_PANEL_ID);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void fillParameterValueComponentTree(final Model model) throws ModelInformationException {
        final List<GeneralParameter> generalParameters = model.getGeneralParameterList();
        for (final GeneralParameter gp : generalParameters) {
            if (NUMBER_OF_TURNS_LABEL_TEXT.equals(gp.getName()))
                numberOfTurnsField.setText(gp.getValue());
            else if (NUMBER_OF_TIMESTEPS_TO_IGNORE_LABEL_TEXT.equals(gp.getName()))
                numberTimestepsIgnored.setText(gp.getValue());
            else if (UPDATE_CHARTS_LABEL_TEXT.equals(gp.getName())) {
                final boolean selected = Boolean.parseBoolean(gp.getValue());
                onLineChartsCheckBox.setSelected(selected);
            } else if (DISPLAY_ADVANCED_CHARTS_LABEL_TEXT.equals(gp.getName())) {
                final boolean selected = Boolean.parseBoolean(gp.getValue());
                advancedChartsCheckBox.setSelected(selected);
            }
        }

        final DefaultMutableTreeNode infoValueTree = ParameterTreeUtils
                .loadSingleRunParameterIntoInfoValueTree(model, batchParameters, currentModelHandler);
        parameterValueComponentTree = convertInfoValueTreeToInfoComponentTree(infoValueTree);
    }

    //----------------------------------------------------------------------------------------------------
    private DefaultMutableTreeNode convertInfoValueTreeToInfoComponentTree(DefaultMutableTreeNode infoValueTree)
            throws ModelInformationException {
        @SuppressWarnings("rawtypes")
        final Enumeration nodes = infoValueTree.breadthFirstEnumeration();
        nodes.nextElement(); // root

        while (nodes.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
            if (node.getUserObject() != null) {
                @SuppressWarnings("unchecked")
                final Pair<ParameterInfo, String> userObj = (Pair<ParameterInfo, String>) node.getUserObject();
                final JComponent component = convertStringToComponent(userObj.getKey(), userObj.getValue());
                final Pair<ParameterInfo, JComponent> newUserObj = new Pair<ParameterInfo, JComponent>(
                        userObj.getKey(), component);
                node.setUserObject(newUserObj);
            }
        }

        return infoValueTree;
    }

    //----------------------------------------------------------------------------------------------------
    private JComponent convertStringToComponent(final ParameterInfo info, final String value)
            throws ModelInformationException {
        if (info instanceof SubmodelInfo)
            return initializeJComponentForSubmodelParameter(value, (SubmodelInfo) info);

        return initializeJComponentForParameter(value, info);
    }

    //----------------------------------------------------------------------------------------------------
    @SuppressWarnings("unchecked")
    private JComponent initializeJComponentForParameter(final String strValue, final ParameterInfo info)
            throws ModelInformationException {
        JComponent field = null;

        if (info.isBoolean()) {
            field = new JCheckBox();
            boolean value = Boolean.parseBoolean(strValue);
            ((JCheckBox) field).setSelected(value);
        } else if (info.isEnum() || info instanceof MasonChooserParameterInfo) {
            Object[] elements = null;
            if (info.isEnum()) {
                final Class<Enum<?>> type = (Class<Enum<?>>) info.getJavaType();
                elements = type.getEnumConstants();
            } else {
                final MasonChooserParameterInfo chooserInfo = (MasonChooserParameterInfo) info;
                elements = chooserInfo.getValidStrings();
            }
            final JComboBox list = new JComboBox(elements);

            if (info.isEnum()) {
                try {
                    @SuppressWarnings("rawtypes")
                    final Object value = Enum.valueOf((Class<? extends Enum>) info.getJavaType(), strValue);
                    list.setSelectedItem(value);
                } catch (final IllegalArgumentException e) {
                    throw new ModelInformationException(e.getMessage() + " for parameter: " + info.getName() + ".");
                }
            } else {
                try {
                    final int value = Integer.parseInt(strValue);
                    list.setSelectedIndex(value);
                } catch (final NumberFormatException e) {
                    throw new ModelInformationException(
                            "Invalid value for parameter " + info.getName() + " (not a number).");
                }
            }
            field = list;
        } else if (info.isFile()) {
            field = new JPanel();
            final JTextField textField = new JTextField();

            if (!strValue.isEmpty()) {
                final File file = new File(strValue);
                textField.setText(file.getName());
                textField.setToolTipText(file.getAbsolutePath());
            }

            field.add(textField);
        } else if (info instanceof MasonIntervalParameterInfo) {
            field = new JPanel();
            final JTextField textField = new JTextField(strValue);
            field.add(textField);
        } else {
            field = new JTextField(strValue);
        }

        return field;
    }

    //----------------------------------------------------------------------------------------------------
    private JComponent initializeJComponentForSubmodelParameter(final String type, final SubmodelInfo submodelInfo)
            throws ModelInformationException {
        try {
            final Class<?> clazz = Class.forName(type, true, currentModelHandler.getCustomClassLoader());
            final Object value = new ClassElement(clazz, null);
            submodelInfo.setActualType(clazz, null);
            final Object[] elements = new Object[] { value };
            final JComboBox list = new JComboBox(elements);
            list.setSelectedIndex(0);
            JPanel panel = new JPanel();
            panel.add(list);

            return panel;
        } catch (final ClassNotFoundException e) {
            throw new ModelInformationException(
                    "Invalid actual type " + type + " for submodel parameter: " + submodelInfo.getName(), e);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void fillParameterSweepPage(final Model model) throws ModelInformationException {
        final List<GeneralParameter> generalParameters = model.getGeneralParameterList();
        for (final GeneralParameter gp : generalParameters) {
            if (NUMBER_OF_TURNS_LABEL_TEXT.equals(gp.getName()))
                numberOfTurnsFieldPSW.setText(gp.getValue());
            else if (NUMBER_OF_TIMESTEPS_TO_IGNORE_LABEL_TEXT.equals(gp.getName()))
                numberTimestepsIgnoredPSW.setText(gp.getValue());
        }

        final DefaultListModel listModel = new DefaultListModel();
        final List<DefaultParameter> defaultParameters = model.getDefaultParameterList();
        ParameterTreeUtils.loadPSDefaultParameters(listModel, defaultParameters, batchParameters,
                currentModelHandler.getModelClass());
        parameterList.setModel(listModel);

        // creating combination boxes
        for (int i = 0; i < model.getCombination().size() - 1; addBox(), ++i)
            ;

        final List<Combination> sortedCombinations = new ArrayList<Combination>(model.getCombination());
        Collections.sort(sortedCombinations, new Comparator<Combination>() {
            public int compare(final Combination o1, final Combination o2) {
                return o1.getPosition().compareTo(o2.getPosition());
            }
        });

        for (int i = 0; i < sortedCombinations.size(); ++i) {
            final ParameterCombinationGUI pGUI = parameterTreeBranches.get(i);
            final DefaultTreeModel treeModel = (DefaultTreeModel) pGUI.tree.getModel();
            final DefaultMutableTreeNode combinationRoot = pGUI.combinationRoot;
            ParameterTreeUtils.loadAPSCombinationTree(treeModel, combinationRoot, batchParameters,
                    currentModelHandler, sortedCombinations.get(i));

            for (int j = 0; j < pGUI.tree.getRowCount(); ++j)
                pGUI.tree.expandRow(j);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void dumpParameterTree(final ParameterNode rootNode) {
        dumpParameterTreeBranch(rootNode, "");
    }

    //----------------------------------------------------------------------------------------------------
    private void dumpParameterTreeBranch(final ParameterNode node, final String prefix) {
        @SuppressWarnings("unchecked")
        final Enumeration<ParameterNode> children = node.children();

        while (children.hasMoreElements()) {
            final ParameterNode child = children.nextElement();
            final ai.aitia.meme.paramsweep.batch.param.AbstractParameterInfo<?> info = (ai.aitia.meme.paramsweep.batch.param.AbstractParameterInfo<?>) child
                    .getUserObject();
            if (info instanceof IncrementalParameterInfo<?>) {
                final IncrementalParameterInfo<?> incrementalInfo = (IncrementalParameterInfo<?>) info;
                log.debug(prefix + info.getName() + ": start = " + incrementalInfo.getStart() + "; end = "
                        + incrementalInfo.getEnd() + "; increment = " + incrementalInfo.getIncrement() + "; run = "
                        + incrementalInfo.getRunNumber());
            } else if (info instanceof ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>) {
                final ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> simpleInfo = (ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>) info;
                log.debug(prefix + info.getName() + ": " + simpleInfo.getValues() + "; run = "
                        + simpleInfo.getRunNumber());
            } else {
                throw new IllegalStateException("Trying to dump unknown parameterinfo: " + info);
            }

            if (info.getMultiplicity() > 1) {
                dumpParameterTreeBranch(child, prefix + "\t");
            }
        }
    }

    //----------------------------------------------------------------------------------------------------
    /** {@inheritDoc} 
     */
    @Override
    public void onPageChange(final boolean show) {
        if (show) {
            dashboard.getSaveConfigMenuItem().setEnabled(true);
            if (currentModelHandler == null || !currentModelHandler.equals(dashboard.getModelHandler())) {
                ((CardLayout) container.getLayout()).show(container, LOADING_MODEL_ID);

                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            currentModelHandler = dashboard.getModelHandler();

                            breadcrumb.setRoot(
                                    currentModelHandler.getModelClassSimpleName().replaceAll("([A-Z])", " $1"));
                            Style.apply(breadcrumb, dashboard.getCssStyle());
                            parameterValueComponentTree = new DefaultMutableTreeNode();
                            possibleTypesCache.clear();
                            singleRunParametersPanel.removeAll();
                            batchParameters = currentModelHandler.getParameters();
                            final List<ParameterInfo> modelParameters = createAndDisplayAParameterPanel(
                                    batchParameters, "Model parameters", null, true, currentModelHandler);

                            //parametersScrollPane.setViewportView(singleRunParametersPanel);

                            singleRunParametersPanel.revalidate();

                            // initialize paramsweep panel
                            Collections.sort(modelParameters);
                            createDefaultParameterList(modelParameters);
                            enableDisableSettings(false);
                            modifyButton.setEnabled(false);
                            updateNumberOfRuns();
                            resetParamsweepGUI();

                            // initialize the GA seach panel
                            gaSearchHandler.init(currentModelHandler);
                            gaSearchPanel.reset(gaSearchHandler);
                            gaSearchHandler.removeAllFitnessFunctions();
                            final List<RecordableInfo> recordables = dashboard.getModelHandler().getRecorders()
                                    .get(0).getRecordables();
                            for (final RecordableInfo recordableInfo : recordables) {
                                if (gaSearchHandler.canBeFitnessFunction(recordableInfo))
                                    gaSearchHandler.addFitnessFunction(recordableInfo);
                            }

                            gaSearchHandler.removeAllParameters();
                            for (final ParameterInfo parameterInfo : modelParameters)
                                gaSearchHandler.addParameter(new ParameterOrGene(parameterInfo));
                        } catch (final ModelInformationException e) {
                            JOptionPane.showMessageDialog(wizard, new JLabel(e.getMessage()),
                                    "Error while analyizing model", JOptionPane.ERROR_MESSAGE);
                            e.printStackTrace();
                        } finally {
                            ((CardLayout) container.getLayout()).show(container, PARAMETERS_PANEL_ID);
                        }
                    }
                });
            }
        } else { // this should only run when moving onto Page_Run
        }

    }

    //----------------------------------------------------------------------------------------------------
    @Override
    public String getTitle() {
        return TITLE;
    }

    //-----------------------------------------------------------------------------------

    private final static class ParameterMetaData implements Comparable<ParameterMetaData> {
        String banner = "", verboseDescription = "", fieldName = "", imageFileName = "";
        double layoutOrder = Double.MIN_VALUE;
        ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> parameter;

        @Override
        public int compareTo(final ParameterMetaData other) {
            if (layoutOrder != other.layoutOrder)
                return Double.compare(layoutOrder, other.layoutOrder);
            return parameter.getName().compareTo(other.parameter.getName());
        }

        static void createAndRegisterUnknown(final String expecteFieldName,
                final ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> paramter,
                final List<ParameterMetaData> collection) {
            System.err.println("Dashboard: no field with name " + expecteFieldName + " is present.");
            System.err.flush();
            final ParameterMetaData datum = new ParameterMetaData();
            datum.parameter = paramter;
            datum.fieldName = paramter.getName().replaceAll("([A-Z])", " $1");
            datum.imageFileName = "";
            collection.add(datum);
        }
    }

    private void appendMinimumWidthHintToPresentation(final DefaultFormBuilder formBuilder, final int widthInPt) {
        formBuilder.append(new JLabel("<html><div style=\"margin: 0pt; display: block; width:" + widthInPt
                + "pt; height:0pt\"></div></html>") {
            private static final long serialVersionUID = -722208290456978697L;
        }, 3);
    }

    private void appendTextToPresentation(DefaultFormBuilder formBuilder, final String text) {
        if (text == null || text.isEmpty())
            return;
        /*
         * Subclass JLabel to lie about the with of the component. We understate the preferred 
         * width to avoid that this component influences the width of the columns. It is unclear 
         * why we need to use colspan = 3 here.
         */
        formBuilder.append(new JLabel("<html><div style=\"margin-bottom: 8pt; margin-left: 4pt; margin-top: 12pt;"
                + "line-height:1.5; color:#555555\"><i>" + text.replace("\n", "<br/>") + "</i></div></html>") {
            private static final long serialVersionUID = 1L;

            @Override
            public Dimension getPreferredSize() {
                Dimension preferredSize = super.getPreferredSize();
                return new Dimension(10, preferredSize.height);
            }
        }, 3);
    }

    private void appendImageToPresentation(DefaultFormBuilder formBuilder, final String imageFilename) {
        if (imageFilename == null || imageFilename.isEmpty())
            return;
        ImageIcon icon = null;
        try {
            final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            final InputStream imageStream = classLoader.getResourceAsStream(imageFilename);
            final Image image = ImageIO.read(imageStream);
            icon = new ImageIcon(image);
        } catch (final IOException e) {
            icon = new ImageIcon(imageFilename);
        }

        final JLabel component = new JLabel("<html><div style=\"margin: 8pt\"></div></html>");
        component.setIcon(icon);
        formBuilder.append(component, 3);
    }

    private void appendHeaderTextToPresentation(DefaultFormBuilder formBuilder, final String text) {
        if (text == null || text.isEmpty())
            return;

        formBuilder.append(new JLabel("<html><div style=\"margin-bottom: 8pt; margin-left: 4pt; margin-top: 12pt;"
                + " display: block; color:#666666; display: block\"><i>" + text.replace("\n", "<br/>")
                + "</i></div></html>") {
            private static final long serialVersionUID = 1L;

            @Override
            public Dimension getPreferredSize() {
                Dimension preferredSize = super.getPreferredSize();
                return new Dimension(10, preferredSize.height);
            }
        }, 3);
    }

    private void appendBannerToPresentation(DefaultFormBuilder formBuilder, final String text) {
        if (text == null || text.isEmpty())
            return;
        formBuilder.appendSeparator(text);
    }

    private void appendVerticalSpaceToPresentation(DefaultFormBuilder formBuilder) {
        formBuilder.append("", new JPanel());
    }

    private void appendCheckBoxFieldToPresentation(DefaultFormBuilder formBuilder, final String fieldText,
            final JCheckBox checkBox) {
        formBuilder.append("<html><div style=\"margin-bottom: 4pt; margin-top: 6pt; margin-left: 4pt\">" + fieldText
                + "</div></html>", checkBox);
    }

    @SuppressWarnings("unchecked")
    private List<ParameterInfo> createAndDisplayAParameterPanel(
            final List<ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>> batchParameters, final String title,
            final SubmodelInfo parent, final boolean submodelSelectionWithoutNotify,
            final IModelHandler currentModelHandler) {
        final List<ParameterMetaData> metadata = new LinkedList<ParameterMetaData>(),
                unknownFields = new ArrayList<ParameterMetaData>();
        for (final ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> record : batchParameters) {
            final String parameterName = record.getName(), fieldName = StringUtils.uncapitalize(parameterName);
            Class<?> modelComponentType = parent == null ? currentModelHandler.getModelClass()
                    : parent.getActualType();
            while (true) {
                try {
                    final Field field = modelComponentType.getDeclaredField(fieldName);
                    final ParameterMetaData datum = new ParameterMetaData();
                    for (final Annotation element : field.getAnnotations()) {
                        if (element.annotationType().getName() != Layout.class.getName()) // Proxies
                            continue;
                        final Class<? extends Annotation> type = element.annotationType();
                        datum.verboseDescription = (String) type.getMethod("VerboseDescription").invoke(element);
                        datum.banner = (String) type.getMethod("Title").invoke(element);
                        datum.fieldName = (String) " " + type.getMethod("FieldName").invoke(element);
                        datum.imageFileName = (String) type.getMethod("Image").invoke(element);
                        datum.layoutOrder = (Double) type.getMethod("Order").invoke(element);
                    }
                    datum.parameter = record;
                    if (datum.fieldName.trim().isEmpty())
                        datum.fieldName = parameterName.replaceAll("([A-Z])", " $1");
                    metadata.add(datum);
                    break;
                } catch (final SecurityException e) {
                } catch (final NoSuchFieldException e) {
                } catch (final IllegalArgumentException e) {
                } catch (final IllegalAccessException e) {
                } catch (final InvocationTargetException e) {
                } catch (final NoSuchMethodException e) {
                }
                modelComponentType = modelComponentType.getSuperclass();
                if (modelComponentType == null) {
                    ParameterMetaData.createAndRegisterUnknown(fieldName, record, unknownFields);
                    break;
                }
            }
        }
        Collections.sort(metadata);
        for (int i = unknownFields.size() - 1; i >= 0; --i)
            metadata.add(0, unknownFields.get(i));

        // initialize single run form
        final DefaultFormBuilder formBuilder = FormsUtils.build("p ~ p:g", "");
        appendMinimumWidthHintToPresentation(formBuilder, 550);

        if (parent == null) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    numberOfTurnsField.grabFocus();
                }
            });

            appendBannerToPresentation(formBuilder, "General Parameters");
            appendTextToPresentation(formBuilder, "Global parameters affecting the entire simulation");

            formBuilder.append(NUMBER_OF_TURNS_LABEL_TEXT, numberOfTurnsField);
            formBuilder.append(NUMBER_OF_TIMESTEPS_TO_IGNORE_LABEL_TEXT, numberTimestepsIgnored);

            appendCheckBoxFieldToPresentation(formBuilder, UPDATE_CHARTS_LABEL_TEXT, onLineChartsCheckBox);
            appendCheckBoxFieldToPresentation(formBuilder, DISPLAY_ADVANCED_CHARTS_LABEL_TEXT,
                    advancedChartsCheckBox);
        }

        appendBannerToPresentation(formBuilder, title);

        final DefaultMutableTreeNode parentNode = (parent == null) ? parameterValueComponentTree
                : findParameterInfoNode(parent, false);

        final List<ParameterInfo> info = new ArrayList<ParameterInfo>();

        // Search for a @ConfigurationComponent annotation
        {
            String headerText = "", imagePath = "";
            final Class<?> parentType = parent == null ? currentModelHandler.getModelClass()
                    : parent.getActualType();
            for (final Annotation element : parentType.getAnnotations()) { // Proxies
                if (element.annotationType().getName() != ConfigurationComponent.class.getName())
                    continue;
                boolean doBreak = false;
                try {
                    try {
                        headerText = (String) element.annotationType().getMethod("Description").invoke(element);
                        if (headerText.startsWith("#")) {
                            headerText = (String) parent.getActualType().getMethod(headerText.substring(1))
                                    .invoke(parent.getInstance());
                        }
                        doBreak = true;
                    } catch (IllegalArgumentException e) {
                    } catch (SecurityException e) {
                    } catch (IllegalAccessException e) {
                    } catch (InvocationTargetException e) {
                    } catch (NoSuchMethodException e) {
                    }
                } catch (final Exception e) {
                }
                try {
                    imagePath = (String) element.annotationType().getMethod("ImagePath").invoke(element);
                    doBreak = true;
                } catch (IllegalArgumentException e) {
                } catch (SecurityException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                } catch (NoSuchMethodException e) {
                }
                if (doBreak)
                    break;
            }
            if (!headerText.isEmpty())
                appendHeaderTextToPresentation(formBuilder, headerText);
            if (!imagePath.isEmpty())
                appendImageToPresentation(formBuilder, imagePath);
        }

        if (metadata.isEmpty()) {
            // No fields to display.
            appendTextToPresentation(formBuilder, "No configuration is required for this module.");
        } else {
            for (final ParameterMetaData record : metadata) {
                final ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> batchParameterInfo = record.parameter;

                if (!record.banner.isEmpty())
                    appendBannerToPresentation(formBuilder, record.banner);
                if (!record.imageFileName.isEmpty())
                    appendImageToPresentation(formBuilder, record.imageFileName);
                appendTextToPresentation(formBuilder, record.verboseDescription);

                final ParameterInfo parameterInfo = InfoConverter.parameterInfo2ParameterInfo(batchParameterInfo);
                if (parent != null && parameterInfo instanceof ISubmodelGUIInfo) {
                    //               sgi.setParentValue(parent.getActualType());
                }

                final JComponent field;
                final DefaultMutableTreeNode oldNode = findParameterInfoNode(parameterInfo, true);
                Pair<ParameterInfo, JComponent> userData = null;
                JComponent oldField = null;
                if (oldNode != null) {
                    userData = (Pair<ParameterInfo, JComponent>) oldNode.getUserObject();
                    oldField = userData.getSecond();
                }

                if (parameterInfo.isBoolean()) {
                    field = new JCheckBox();
                    boolean value = oldField != null ? ((JCheckBox) oldField).isSelected()
                            : ((Boolean) batchParameterInfo.getDefaultValue()).booleanValue();
                    ((JCheckBox) field).setSelected(value);
                } else if (parameterInfo.isEnum() || parameterInfo instanceof MasonChooserParameterInfo) {
                    Object[] elements = null;
                    if (parameterInfo.isEnum()) {
                        final Class<Enum<?>> type = (Class<Enum<?>>) parameterInfo.getJavaType();
                        elements = type.getEnumConstants();
                    } else {
                        final MasonChooserParameterInfo chooserInfo = (MasonChooserParameterInfo) parameterInfo;
                        elements = chooserInfo.getValidStrings();
                    }
                    final JComboBox list = new JComboBox(elements);

                    if (parameterInfo.isEnum()) {
                        final Object value = oldField != null ? ((JComboBox) oldField).getSelectedItem()
                                : parameterInfo.getValue();
                        list.setSelectedItem(value);
                    } else {
                        final int value = oldField != null ? ((JComboBox) oldField).getSelectedIndex()
                                : (Integer) parameterInfo.getValue();
                        list.setSelectedIndex(value);
                    }

                    field = list;
                } else if (parameterInfo instanceof SubmodelInfo) {
                    final SubmodelInfo submodelInfo = (SubmodelInfo) parameterInfo;
                    final Object[] elements = new Object[] { "Loading class information..." };
                    final JComboBox list = new JComboBox(elements);
                    //            field = list;

                    final Object value = oldField != null
                            ? ((JComboBox) ((JPanel) oldField).getComponent(0)).getSelectedItem()
                            : new ClassElement(submodelInfo.getActualType(), null);

                    new ClassCollector(this, list, submodelInfo, value, submodelSelectionWithoutNotify).execute();

                    final JButton rightButton = new JButton();
                    rightButton.setOpaque(false);
                    rightButton.setRolloverEnabled(true);
                    rightButton.setIcon(SHOW_SUBMODEL_ICON);
                    rightButton.setRolloverIcon(SHOW_SUBMODEL_ICON_RO);
                    rightButton.setDisabledIcon(SHOW_SUBMODEL_ICON_DIS);
                    rightButton.setBorder(null);
                    rightButton.setToolTipText("Display submodel parameters");
                    rightButton.setActionCommand(ACTIONCOMMAND_SHOW_SUBMODEL);
                    rightButton.addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                            if (parameterInfo instanceof SubmodelInfo) {
                                SubmodelInfo submodelInfo = (SubmodelInfo) parameterInfo;
                                int level = 0;

                                showHideSubparameters(list, submodelInfo);

                                List<String> components = new ArrayList<String>();
                                components.add(submodelInfo.getName());
                                while (submodelInfo.getParent() != null) {
                                    submodelInfo = submodelInfo.getParent();
                                    components.add(submodelInfo.getName());
                                    level++;
                                }
                                Collections.reverse(components);
                                final String[] breadcrumbText = components.toArray(new String[components.size()]);
                                for (int i = 0; i < breadcrumbText.length; ++i)
                                    breadcrumbText[i] = breadcrumbText[i].replaceAll("([A-Z])", " $1");
                                breadcrumb.setPath(
                                        currentModelHandler.getModelClassSimpleName().replaceAll("([A-Z])", " $1"),
                                        breadcrumbText);
                                Style.apply(breadcrumb, dashboard.getCssStyle());

                                // reset all buttons that are nested deeper than this to default color
                                for (int i = submodelButtons.size() - 1; i >= level; i--) {
                                    JButton button = submodelButtons.get(i);
                                    button.setIcon(SHOW_SUBMODEL_ICON);
                                    submodelButtons.remove(i);
                                }

                                rightButton.setIcon(SHOW_SUBMODEL_ICON_RO);
                                submodelButtons.add(rightButton);
                            }
                        }
                    });

                    field = new JPanel(new BorderLayout());
                    field.add(list, BorderLayout.CENTER);
                    field.add(rightButton, BorderLayout.EAST);
                } else if (File.class.isAssignableFrom(parameterInfo.getJavaType())) {
                    field = new JPanel(new BorderLayout());

                    String oldName = "";
                    String oldPath = "";
                    if (oldField != null) {
                        final JTextField oldTextField = (JTextField) oldField.getComponent(0);
                        oldName = oldTextField.getText();
                        oldPath = oldTextField.getToolTipText();
                    } else if (parameterInfo.getValue() != null) {
                        final File file = (File) parameterInfo.getValue();
                        oldName = file.getName();
                        oldPath = file.getAbsolutePath();
                    }

                    final JTextField textField = new JTextField(oldName);
                    textField.setToolTipText(oldPath);
                    textField.setInputVerifier(new InputVerifier() {

                        @Override
                        public boolean verify(final JComponent input) {
                            final JTextField inputField = (JTextField) input;
                            if (inputField.getText() == null || inputField.getText().isEmpty()) {
                                final File file = new File("");
                                inputField.setToolTipText(file.getAbsolutePath());
                                hideError();
                                return true;
                            }

                            final File oldFile = new File(inputField.getToolTipText());
                            if (oldFile.exists() && oldFile.getName().equals(inputField.getText().trim())) {
                                hideError();
                                return true;
                            }

                            inputField.setToolTipText("");
                            final File file = new File(inputField.getText().trim());
                            if (file.exists()) {
                                inputField.setToolTipText(file.getAbsolutePath());
                                inputField.setText(file.getName());
                                hideError();
                                return true;
                            } else {
                                final PopupFactory popupFactory = PopupFactory.getSharedInstance();
                                final Point locationOnScreen = inputField.getLocationOnScreen();
                                final JLabel message = new JLabel("Please specify an existing file!");
                                message.setBorder(new LineBorder(Color.RED, 2, true));
                                if (errorPopup != null)
                                    errorPopup.hide();
                                errorPopup = popupFactory.getPopup(inputField, message, locationOnScreen.x - 10,
                                        locationOnScreen.y - 30);
                                errorPopup.show();
                                return false;
                            }
                        }
                    });

                    final JButton browseButton = new JButton(BROWSE_BUTTON_TEXT);
                    browseButton.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            final JFileChooser fileDialog = new JFileChooser(
                                    !"".equals(textField.getToolTipText()) ? textField.getToolTipText()
                                            : currentDirectory);
                            if (!"".equals(textField.getToolTipText()))
                                fileDialog.setSelectedFile(new File(textField.getToolTipText()));
                            int dialogResult = fileDialog.showOpenDialog(dashboard);
                            if (dialogResult == JFileChooser.APPROVE_OPTION) {
                                final File selectedFile = fileDialog.getSelectedFile();
                                if (selectedFile != null) {
                                    currentDirectory = selectedFile.getAbsoluteFile().getParent();
                                    textField.setText(selectedFile.getName());
                                    textField.setToolTipText(selectedFile.getAbsolutePath());
                                }
                            }
                        }
                    });

                    field.add(textField, BorderLayout.CENTER);
                    field.add(browseButton, BorderLayout.EAST);
                } else if (parameterInfo instanceof MasonIntervalParameterInfo) {
                    final MasonIntervalParameterInfo intervalInfo = (MasonIntervalParameterInfo) parameterInfo;

                    field = new JPanel(new BorderLayout());

                    String oldValueStr = String.valueOf(parameterInfo.getValue());
                    if (oldField != null) {
                        final JTextField oldTextField = (JTextField) oldField.getComponent(0);
                        oldValueStr = oldTextField.getText();
                    }

                    final JTextField textField = new JTextField(oldValueStr);

                    PercentJSlider tempSlider = null;
                    if (intervalInfo.isDoubleInterval())
                        tempSlider = new PercentJSlider(intervalInfo.getIntervalMin().doubleValue(),
                                intervalInfo.getIntervalMax().doubleValue(), Double.parseDouble(oldValueStr));
                    else
                        tempSlider = new PercentJSlider(intervalInfo.getIntervalMin().longValue(),
                                intervalInfo.getIntervalMax().longValue(), Long.parseLong(oldValueStr));

                    final PercentJSlider slider = tempSlider;
                    slider.setMajorTickSpacing(100);
                    slider.setMinorTickSpacing(10);
                    slider.setPaintTicks(true);
                    slider.setPaintLabels(true);
                    slider.addChangeListener(new ChangeListener() {
                        public void stateChanged(final ChangeEvent _) {
                            if (slider.hasFocus()) {
                                final String value = intervalInfo.isDoubleInterval()
                                        ? String.valueOf(slider.getDoubleValue())
                                        : String.valueOf(slider.getLongValue());
                                textField.setText(value);
                                slider.setToolTipText(value);
                            }
                        }
                    });

                    textField.setInputVerifier(new InputVerifier() {
                        public boolean verify(JComponent input) {
                            final JTextField inputField = (JTextField) input;

                            try {
                                hideError();
                                final String valueStr = inputField.getText().trim();
                                if (intervalInfo.isDoubleInterval()) {
                                    final double value = Double.parseDouble(valueStr);
                                    if (intervalInfo.isValidValue(valueStr)) {
                                        slider.setValue(value);
                                        return true;
                                    } else
                                        showError(
                                                "Please specify a value between " + intervalInfo.getIntervalMin()
                                                        + " and " + intervalInfo.getIntervalMax() + ".",
                                                inputField);
                                    return false;
                                } else {
                                    final long value = Long.parseLong(valueStr);
                                    if (intervalInfo.isValidValue(valueStr)) {
                                        slider.setValue(value);
                                        return true;
                                    } else {
                                        showError("Please specify an integer value between "
                                                + intervalInfo.getIntervalMin() + " and "
                                                + intervalInfo.getIntervalMax() + ".", inputField);
                                        return false;
                                    }
                                }
                            } catch (final NumberFormatException _) {
                                final String message = "The specified value is not a"
                                        + (intervalInfo.isDoubleInterval() ? "" : "n integer") + " number.";
                                showError(message, inputField);
                                return false;
                            }

                        }
                    });

                    textField.getDocument().addDocumentListener(new DocumentListener() {
                        //               private Popup errorPopup;

                        public void removeUpdate(final DocumentEvent _) {
                            textFieldChanged();
                        }

                        public void insertUpdate(final DocumentEvent _) {
                            textFieldChanged();
                        }

                        public void changedUpdate(final DocumentEvent _) {
                            textFieldChanged();
                        }

                        private void textFieldChanged() {
                            if (!textField.hasFocus()) {
                                hideError();
                                return;
                            }

                            try {
                                hideError();
                                final String valueStr = textField.getText().trim();
                                if (intervalInfo.isDoubleInterval()) {
                                    final double value = Double.parseDouble(valueStr);
                                    if (intervalInfo.isValidValue(valueStr))
                                        slider.setValue(value);
                                    else
                                        showError("Please specify a value between " + intervalInfo.getIntervalMin()
                                                + " and " + intervalInfo.getIntervalMax() + ".", textField);
                                } else {
                                    final long value = Long.parseLong(valueStr);
                                    if (intervalInfo.isValidValue(valueStr))
                                        slider.setValue(value);
                                    else
                                        showError("Please specify an integer value between "
                                                + intervalInfo.getIntervalMin() + " and "
                                                + intervalInfo.getIntervalMax() + ".", textField);
                                }
                            } catch (final NumberFormatException _) {
                                final String message = "The specified value is not a"
                                        + (intervalInfo.isDoubleInterval() ? "" : "n integer") + " number.";
                                showError(message, textField);
                            }
                        }
                    });

                    field.add(textField, BorderLayout.CENTER);
                    field.add(slider, BorderLayout.SOUTH);
                } else {
                    final Object value = oldField != null ? ((JTextField) oldField).getText()
                            : parameterInfo.getValue();
                    field = new JTextField(value.toString());
                    ((JTextField) field).addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(final ActionEvent e) {
                            wizard.clickDefaultButton();
                        }
                    });
                }

                final JLabel parameterLabel = new JLabel(record.fieldName);

                final String description = parameterInfo.getDescription();
                if (description != null && !description.isEmpty()) {
                    parameterLabel.addMouseListener(new MouseAdapter() {

                        @Override
                        public void mouseEntered(final MouseEvent e) {
                            final DescriptionPopupFactory popupFactory = DescriptionPopupFactory.getInstance();

                            final Popup parameterDescriptionPopup = popupFactory.getPopup(parameterLabel,
                                    description, dashboard.getCssStyle());

                            parameterDescriptionPopup.show();
                        }

                    });
                }

                if (oldNode != null)
                    userData.setSecond(field);
                else {
                    final Pair<ParameterInfo, JComponent> pair = new Pair<ParameterInfo, JComponent>(parameterInfo,
                            field);
                    final DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(pair);
                    parentNode.add(newNode);
                }

                if (field instanceof JCheckBox) {
                    parameterLabel
                            .setText("<html><div style=\"margin-bottom: 4pt; margin-top: 6pt; margin-left: 4pt\">"
                                    + parameterLabel.getText() + "</div></html>");
                    formBuilder.append(parameterLabel, field);

                    //            appendCheckBoxFieldToPresentation(
                    //               formBuilder, parameterLabel.getText(), (JCheckBox) field);
                } else {
                    formBuilder.append(parameterLabel, field);
                    final CellConstraints constraints = formBuilder.getLayout().getConstraints(parameterLabel);
                    constraints.vAlign = CellConstraints.TOP;
                    constraints.insets = new Insets(5, 0, 0, 0);
                    formBuilder.getLayout().setConstraints(parameterLabel, constraints);
                }

                // prepare the parameterInfo for the param sweeps
                parameterInfo.setRuns(0);
                parameterInfo.setDefinitionType(ParameterInfo.CONST_DEF);
                parameterInfo.setValue(batchParameterInfo.getDefaultValue());
                info.add(parameterInfo);
            }
        }
        appendVerticalSpaceToPresentation(formBuilder);

        final JPanel panel = formBuilder.getPanel();
        singleRunParametersPanel.add(panel);

        if (singleRunParametersPanel.getComponentCount() > 1) {
            panel.setBorder(
                    BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.GRAY),
                            BorderFactory.createEmptyBorder(0, 5, 0, 5)));
        } else {
            panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
        }

        Style.apply(panel, dashboard.getCssStyle());

        return info;
    }

    //----------------------------------------------------------------------------------------------------
    private DefaultMutableTreeNode findParameterInfoNode(final ParameterInfo info, final boolean checkParentValue) {
        if (info == null)
            return null;

        @SuppressWarnings("rawtypes")
        final Enumeration treeValues = parameterValueComponentTree.breadthFirstEnumeration();
        treeValues.nextElement(); // root node

        while (treeValues.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeValues.nextElement();
            @SuppressWarnings("unchecked")
            final Pair<ParameterInfo, JComponent> userData = (Pair<ParameterInfo, JComponent>) node.getUserObject();
            final ParameterInfo parameterInfo = userData.getFirst();

            if (checkParentValue && info instanceof ISubmodelGUIInfo && parameterInfo instanceof ISubmodelGUIInfo) {
                final ISubmodelGUIInfo sgi = (ISubmodelGUIInfo) info;
                final ISubmodelGUIInfo otherSgi = (ISubmodelGUIInfo) parameterInfo;
                if (info.equals(parameterInfo) && classEquals(sgi.getParentValue(), otherSgi.getParentValue()))
                    return node;
            } else if (info.equals(parameterInfo))
                return node;
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    boolean classEquals(final Class<?> class1, final Class<?> class2) {
        if (class1 == class2)
            return true;

        if (class1 == null)
            return false;

        return class1.equals(class2);
    }

    //------------------------------------------------------------------------------
    /** Builds the parameter list on the gui from the <code>parameters</code> list. */
    private void createDefaultParameterList(final List<ParameterInfo> parameters) {
        final DefaultListModel model = new DefaultListModel();
        for (final ParameterInfo parameterInfo : parameters)
            model.addElement(new AvailableParameter(parameterInfo, currentModelHandler.getModelClass()));
        parameterList.setModel(model);
    }

    //------------------------------------------------------------------------------
    /** Edits the information object <code>info</code> so this method fills the appropriate
     *  components with the informations of <code>info</code>.
     */
    private void edit(final ParameterInfo info) {
        changeText(info.getName(), info.getType());
        if (info instanceof SubmodelInfo) {
            final SubmodelInfo sInfo = (SubmodelInfo) info;
            editSubmodelInfo(sInfo);
        } else {
            String view = null;
            switch (info.getDefinitionType()) {
            case ParameterInfo.CONST_DEF: {
                if (info.isEnum() || info instanceof MasonChooserParameterInfo) {
                    view = "ENUM";
                    constDef.setSelected(true);
                    incrDef.setEnabled(false);
                    listDef.setEnabled(false);
                    Object[] elements = null;
                    if (info.isEnum()) {
                        @SuppressWarnings("unchecked")
                        final Class<Enum<?>> type = (Class<Enum<?>>) info.getJavaType();
                        elements = type.getEnumConstants();
                    } else {
                        final MasonChooserParameterInfo chooserInfo = (MasonChooserParameterInfo) info;
                        elements = chooserInfo.getValidStrings();
                    }
                    final DefaultComboBoxModel model = (DefaultComboBoxModel) enumDefBox.getModel();
                    model.removeAllElements();
                    for (final Object object : elements) {
                        model.addElement(object);
                    }
                    if (info.isEnum())
                        enumDefBox.setSelectedItem(info.getValue());
                    else
                        enumDefBox.setSelectedIndex((Integer) info.getValue());
                } else if (info.isFile()) {
                    view = "FILE";
                    constDef.setSelected(true);
                    final File file = (File) info.getValue();
                    if (file != null) {
                        fileTextField.setText(file.getName());
                        fileTextField.setToolTipText(file.getAbsolutePath());
                    }
                } else {
                    view = "CONST";
                    constDef.setSelected(true);
                    constDefField.setText(info.valuesToString());
                }
                break;
            }
            case ParameterInfo.LIST_DEF:
                view = "LIST";
                listDef.setSelected(true);
                listDefArea.setText(info.valuesToString());
                break;
            case ParameterInfo.INCR_DEF:
                view = "INCREMENT";
                incrDef.setSelected(true);
                incrStartValueField.setText(info.startToString());
                incrEndValueField.setText(info.endToString());
                incrStepField.setText(info.stepToString());
            }

            final CardLayout cl = (CardLayout) rightMiddle.getLayout();
            cl.show(rightMiddle, view);
            enableDisableSettings(true);
            if (!info.isNumeric())
                incrDef.setEnabled(false);
            if (info.isEnum() || info instanceof MasonChooserParameterInfo || info.isFile()) {
                incrDef.setEnabled(false);
                listDef.setEnabled(false);
            }
            modifyButton.setEnabled(true);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void editSubmodelInfo(final SubmodelInfo sInfo) {
        constDef.setSelected(true);
        incrDef.setEnabled(false);
        listDef.setEnabled(false);
        cancelButton.setEnabled(true);
        final DefaultComboBoxModel model = (DefaultComboBoxModel) submodelTypeBox.getModel();
        model.removeAllElements();
        model.addElement("Loading class information...");
        final CardLayout cl = (CardLayout) rightMiddle.getLayout();
        cl.show(rightMiddle, "SUBMODEL");

        try {
            final ClassElement[] elements = fetchPossibleTypes(sInfo);
            model.removeAllElements();
            for (final ClassElement classElement : elements)
                model.addElement(classElement);

            if (sInfo.getActualType() != null)
                submodelTypeBox.setSelectedItem(new ClassElement(sInfo.getActualType(), sInfo.getInstance()));
            submodelTypeBox.setEnabled(true);
            modifyButton.setEnabled(true);
        } catch (final ComboBoxIsTooFullException e) {
            String errorMsg = "Too much possibilities for " + sInfo.getName()
                    + ". Please narrow down the domain by "
                    + "defining the possible classes in the @Submodel annotation.";
            JOptionPane.showMessageDialog(wizard, new JLabel(errorMsg), "Error while analyizing model",
                    JOptionPane.ERROR_MESSAGE);
            cancelButton.doClick();
        }
    }

    //------------------------------------------------------------------------------
    /** Changes the text on the right top corner of the page. The text can be the initial
     *  commentary text ("Select a parameter to modify its settings") or
     *  the name and type of the edited parameter.
     * @param name name of the edited parameter (null if there is no editing parameter)
     * @param type name of type of the edited parameter
     */
    private void changeText(final String name, final String type) {
        if (name == null) {
            editedParameterText.setText(ORIGINAL_TEXT);
        } else {
            final String humanName = name.replaceAll("([A-Z])", " $1");
            editedParameterText.setText("<html><b>" + humanName + "</b>: " + type + "</html>");
        }
    }

    //----------------------------------------------------------------------------------------------------
    private boolean checkNumberOfTurnsField(final boolean singleRun) {
        try {
            final String value = singleRun ? numberOfTurnsField.getText() : numberOfTurnsFieldPSW.getText();
            Double.parseDouble(value);
            return true;
        } catch (final NumberFormatException _) {
            return false;
        }
    }

    //----------------------------------------------------------------------------------------------------
    private boolean checkNumberTimestepsIgnored(final boolean singleRun) {
        try {
            final String value = singleRun ? numberTimestepsIgnored.getText() : numberTimestepsIgnoredPSW.getText();
            Double.parseDouble(value);
            return true;
        } catch (final NumberFormatException _) {
            return false;
        }
    }

    //----------------------------------------------------------------------------------------------------
    private boolean modify() {
        final ParameterInATree userObj = (ParameterInATree) editedNode.getUserObject();

        final String[] errors = checkInput(userObj.info);
        if (errors != null && errors.length != 0) {
            Utilities.userAlert(sweepPanel, (Object) errors);
            return false;
        } else {
            modifyParameterInfo(userObj.info);
            resetSettings();
            modifyButton.setEnabled(false);

            if (!(userObj.info instanceof SubmodelInfo)) {
                final DefaultTreeModel model = (DefaultTreeModel) editedTree.getModel();
                model.nodeStructureChanged(editedNode);
            }

            editedNode = null;
            editedTree = null;

            updateNumberOfRuns();
            enableDisableSettings(false);
            return true;
        }
    }

    //------------------------------------------------------------------------------
    /** Checks the content of the editing components. 
     * @param info the info object that belongs to the edited parameter
     * @return the error messages in an array (or null if there is no error)
     */
    private String[] checkInput(final ParameterInfo info) {
        final ArrayList<String> errors = new ArrayList<String>();
        if (constDef.isSelected()) {
            if (info.isEnum() || info instanceof MasonChooserParameterInfo) {
                // well, the combo box must contain a valid value
            } else if (info instanceof SubmodelInfo) {
                final Object selectedObject = submodelTypeBox.getSelectedItem();
                if (!(selectedObject instanceof ClassElement))
                    errors.add("Invalid type is selected for parameter " + info.getName());
                else {
                    final ClassElement selectedElement = (ClassElement) selectedObject;
                    if (selectedElement.clazz == null)
                        errors.add("'Constant value' cannot be empty. Please select a type.");
                }
            } else if (info.isFile()) {
                if (fileTextField.getText().trim().isEmpty())
                    log.warn("Empty string was specified as file parameter "
                            + info.getName().replaceAll("([A-Z])", " $1"));

                final File file = new File(fileTextField.getToolTipText());
                if (!file.exists())
                    errors.add("File " + fileTextField.getToolTipText() + " does not exist.");
            } else if (constDefField.getText().trim().equals(""))
                errors.add("'Constant value' cannot be empty.");
            else {
                final boolean valid = ParameterInfo.isValid(constDefField.getText().trim(), info.getType());
                if (!valid)
                    errors.add("'Constant value' must be a valid " + getTypeText(info.getType()));
                errors.addAll(PlatformSettings.additionalParameterCheck(info,
                        new String[] { constDefField.getText().trim() }, ParameterInfo.CONST_DEF));
            }
        } else if (listDef.isSelected()) {
            String text = listDefArea.getText().trim();
            if (text.equals(""))
                errors.add("'List of values' cannot be empty.");
            else {
                text = text.replaceAll("[\\s]+", " ");
                final String[] elements = text.split(" ");
                boolean goodList = true;
                for (final String element : elements)
                    goodList = goodList && ParameterInfo.isValid(element.trim(), info.getType());
                if (!goodList)
                    errors.add("All elements of the list must be a valid " + getTypeText(info.getType()));
                //            else {
                //               final Set<String> previous = new HashSet<String>(elements.length);
                //               for (final String element : elements) {
                //                  if (previous.contains(element)) {
                //                     goodList = false;
                //                     break;
                //                  }
                //                  previous.add(element);
                //               }
                //               if (!goodList) {
                //                  final int result = Utilities.askUser(wizard,false,"Warning", "The list contains repetitive element(s).\nAre you sure?");
                //                  if (result == 0 && errors.size() == 0) // this doesn't work
                //                     return new String[0];
                //               }
                //            }
                errors.addAll(PlatformSettings.additionalParameterCheck(info, elements, ParameterInfo.LIST_DEF));
            }
        } else {
            boolean s = false, e = false, st = false;
            if (incrStartValueField.getText().trim().equals("")) {
                errors.add("'Start value' cannot be empty.");
                s = true;
            } else {
                final boolean valid = ParameterInfo.isValid(incrStartValueField.getText().trim(), info.getType());
                if (!valid)
                    errors.add("'Start value' must be a valid " + getTypeText(info.getType()));
            }
            if (incrEndValueField.getText().trim().equals("")) {
                errors.add("'End value' cannot be empty.");
                e = true;
            } else {
                final boolean valid = ParameterInfo.isValid(incrEndValueField.getText().trim(), info.getType());
                if (!valid)
                    errors.add("'End value' must be a valid " + getTypeText(info.getType()));
            }
            if (incrStepField.getText().trim().equals("")) {
                errors.add("'Step' cannot be empty.");
                st = true;
            } else {
                final double d = Double.valueOf(incrStepField.getText().trim());
                if (d == 0)
                    errors.add("'Step' cannot be zero.");
                else {
                    final boolean valid = ParameterInfo.isValid(incrStepField.getText().trim(), info.getType());
                    if (!valid)
                        errors.add("'Step' must be a valid " + getTypeText(info.getType()));
                }
            }
            if (!(s || e || st))
                errors.addAll(PlatformSettings.additionalParameterCheck(
                        info, new String[] { incrStartValueField.getText().trim(),
                                incrEndValueField.getText().trim(), incrStepField.getText().trim() },
                        ParameterInfo.INCR_DEF));
        }
        return errors.size() == 0 ? null : errors.toArray(new String[0]);
    }

    //------------------------------------------------------------------------------
    /** Returns the appropriate error message part according to the value of <code>type</code>. */
    String getTypeText(final String type) {
        if ("int".equals(type) || "Integer".equals(type))
            return "integer value.";
        if ("float".equals(type) || "Float".equals(type) || "double".equals(type) || "Double".equals(type))
            return "real value.";
        if ("boolean".equals(type) || "Boolean".equals(type))
            return "boolean value (\"true\" or \"false\").";
        if ("String".equals(type))
            return "string that not contains any white space.";
        return type + ".";
    }

    //----------------------------------------------------------------------------------------------------
    private void updateNumberOfRuns() {
        final List<Integer> runNumbers = new ArrayList<Integer>(parameterTreeBranches.size());
        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            final int run = Page_Parameters.calculateNumberOfRuns(pGUI.combinationRoot);
            pGUI.updateRunDisplay(run);
            runNumbers.add(run);
        }

        int validMin = Integer.MAX_VALUE;
        for (final int runNumber : runNumbers) {
            if (runNumber > 1 && runNumber < validMin)
                validMin = runNumber;
        }

        for (int i = 0; i < parameterTreeBranches.size(); ++i) {
            final int runNumber = runNumbers.get(i);
            parameterTreeBranches.get(i).setWarning(runNumber > 1 && runNumber != validMin);
        }
    }

    //----------------------------------------------------------------------------------------------------
    public boolean needWarning() {
        if (parameterTreeBranches.isEmpty())
            return false;

        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            if (pGUI.warningDisplay.getIcon() != null)
                return true;
        }

        return false;
    }

    //------------------------------------------------------------------------------
    /** Enables/disables the parameter editing components of the page according to
     *  the value of <code>enabled</code>.
     */
    private void enableDisableSettings(final boolean enabled) {
        constDef.setEnabled(enabled);
        listDef.setEnabled(enabled);
        incrDef.setEnabled(enabled);
        constDefField.setEnabled(enabled);
        listDefArea.setEnabled(enabled);
        incrStartValueField.setEnabled(enabled);
        incrEndValueField.setEnabled(enabled);
        incrStepField.setEnabled(enabled);
        enumDefBox.setEnabled(enabled);
        submodelTypeBox.setEnabled(enabled);
        fileTextField.setEnabled(enabled);
        fileBrowseButton.setEnabled(enabled);
        cancelButton.setEnabled(enabled);
    }

    //------------------------------------------------------------------------------
    /** Resets the parameter editing related components. */
    private void resetSettings() {
        changeText(null, null);
        constDefField.setText("");
        listDefArea.setText("");
        incrStartValueField.setText("");
        incrEndValueField.setText("");
        incrStepField.setText("");
        fileTextField.setText("");
        fileTextField.setToolTipText("");

        constDef.setSelected(true);
        final CardLayout cl = (CardLayout) rightMiddle.getLayout();
        cl.show(rightMiddle, "CONST");
    }

    //------------------------------------------------------------------------------
    // Pre-condition : all input are valid
    /** Modifies the information object from the contents of the editing components of the page.<br>
     *  Pre-condition: all input values are valid.
     */
    private void modifyParameterInfo(final ParameterInfo info) {
        info.clear();
        int defType = ParameterInfo.CONST_DEF;
        if (listDef.isSelected())
            defType = ParameterInfo.LIST_DEF;
        else if (incrDef.isSelected())
            defType = ParameterInfo.INCR_DEF;
        info.setDefinitionType(defType);
        switch (defType) {
        case ParameterInfo.CONST_DEF: {
            if (info.isEnum()) {
                info.setValue(enumDefBox.getSelectedItem());
            } else if (info instanceof MasonChooserParameterInfo) {
                info.setValue(enumDefBox.getSelectedIndex());
            } else if (info instanceof SubmodelInfo) {
                final SubmodelInfo sInfo = (SubmodelInfo) info;
                modifySubmodelParameterInfo(sInfo);
            } else if (info.isFile()) {
                info.setValue(ParameterInfo.getValue(fileTextField.getToolTipText(), info.getType()));
            } else {
                info.setValue(ParameterInfo.getValue(constDefField.getText().trim(), info.getType()));
            }

            break;
        }
        case ParameterInfo.LIST_DEF:
            String text = listDefArea.getText().trim();
            text = text.replaceAll("[\\s]+", " ");
            final String[] elements = text.split(" ");
            final List<Object> list = new ArrayList<Object>(elements.length);
            for (final String element : elements)
                list.add(ParameterInfo.getValue(element, info.getType()));
            info.setValues(list);
            break;
        case ParameterInfo.INCR_DEF:
            info.setStartValue(
                    (Number) ParameterInfo.getValue(incrStartValueField.getText().trim(), info.getType()));
            info.setEndValue((Number) ParameterInfo.getValue(incrEndValueField.getText().trim(), info.getType()));
            info.setStep((Number) ParameterInfo.getValue(incrStepField.getText().trim(), info.getType()));
            break;
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void modifySubmodelParameterInfo(final SubmodelInfo sInfo) {
        ClassElement aClassElement = (ClassElement) submodelTypeBox.getSelectedItem();
        final Class<?> newActualType = aClassElement.clazz;

        if (!newActualType.equals(sInfo.getActualType())) {
            sInfo.setActualType(newActualType, aClassElement.instance);
            addSubParametersToTree(sInfo, editedTree, editedNode);
            editedTree
                    .expandPath(new TreePath(((DefaultTreeModel) editedTree.getModel()).getPathToRoot(editedNode)));
        } // else do nothing

    }

    //----------------------------------------------------------------------------------------------------
    private void addSubParametersToTree(final SubmodelInfo sInfo, final JTree tree,
            final DefaultMutableTreeNode node) {
        try {
            final List<ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>> subparameters = ParameterTreeUtils
                    .fetchSubparameters(currentModelHandler, sInfo);

            final List<ParameterInfo> convertedSubparameters = new ArrayList<ParameterInfo>(subparameters.size());
            for (ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> parameterInfo : subparameters) {
                final ParameterInfo converted = InfoConverter.parameterInfo2ParameterInfo(parameterInfo);
                converted.setRuns(0);
                convertedSubparameters.add(converted);
            }
            Collections.sort(convertedSubparameters);

            final DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();

            if (node.getChildCount() > 0) {
                node.removeAllChildren();
                treeModel.nodeStructureChanged(node);
            }

            for (final ParameterInfo pInfo : convertedSubparameters) {
                final DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
                        new ParameterInATree(pInfo, currentModelHandler.getModelClass()));
                treeModel.insertNodeInto(newNode, node, node.getChildCount());

                if (pInfo instanceof SubmodelInfo) {
                    final SubmodelInfo ssInfo = (SubmodelInfo) pInfo;
                    if (ssInfo.getActualType() != null)
                        addSubParametersToTree(ssInfo, tree, newNode);
                }
            }

            //tree.expandPath(new TreePath(treeModel.getPathToRoot(node)));
        } catch (final ModelInformationException e) {
            sInfo.setActualType(null, null);
            JOptionPane.showMessageDialog(wizard, new JLabel(e.getMessage()), "Error while analyizing model",
                    JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
            submodelTypeBox.setSelectedIndex(0);
        }
    }

    //----------------------------------------------------------------------------------------------------
    /**
     * @return the numberOfTurnsField
     */
    public double getNumberOfRequestedTurns() {
        if (tabbedPane.getSelectedIndex() == SINGLE_RUN_GUI_TABINDEX)
            return Double.parseDouble(numberOfTurnsField.getText());
        else if (tabbedPane.getSelectedIndex() == PARAMSWEEP_GUI_TABINDEX)
            return Double.parseDouble(numberOfTurnsFieldPSW.getText());
        else
            return gaSearchPanel.getNumberOfRequestedTurns();
    }

    //----------------------------------------------------------------------------------------------------
    public double getNumberTimestepsToIgnore() {
        if (tabbedPane.getSelectedIndex() == SINGLE_RUN_GUI_TABINDEX) {
            return Double.parseDouble(numberTimestepsIgnored.getText());
        } else if (tabbedPane.getSelectedIndex() == PARAMSWEEP_GUI_TABINDEX) {
            return Double.parseDouble(numberTimestepsIgnoredPSW.getText());
        } else
            return 0.;
    }

    //----------------------------------------------------------------------------------------------------
    @Override
    public void actionPerformed(final ActionEvent e) {
        final String command = e.getActionCommand();

        if (ACTIONCOMMAND_EDIT.equals(command)) {
            if (editedNode != null)
                cancelAllSelectionBut(null);
        } else if (command.equals("CONST") || command.equals("LIST") || command.equals("INCREMENT")) {
            final CardLayout cl = (CardLayout) rightMiddle.getLayout();
            cl.show(rightMiddle, command);
        } else if (command.equals("CANCEL")) {
            resetSettings();
            enableDisableSettings(false);
            modifyButton.setEnabled(false);
            editedNode = null;
            editedTree = null;
            cancelAllSelectionBut(null);
            enableDisableParameterCombinationButtons();
        } else if (command.equals("RUNS_FIELD")
                && PlatformSettings.getGUIControllerForPlatform().getRunOption() == RunOption.LOCAL)
            constDef.grabFocus();
        else if (command.equals("CONST_FIELD") || command.equals("STEP_FIELD"))
            modifyButton.doClick();
        else if (command.equals("START_FIELD"))
            incrEndValueField.grabFocus();
        else if (command.equals("END_FIELD"))
            incrStepField.grabFocus();
        else if (ACTIONCOMMAND_ADD_BOX.equals(command))
            addBox();
        else if (ACTIONCOMMAND_BROWSE.equals(command))
            chooseFile();
    }

    //----------------------------------------------------------------------------------------------------
    private void addBox() {
        final JPanel panel = createAParameterBox(false);
        combinationsPanel.add(panel);
        combinationsPanel.revalidate();

        combinationsScrPane.invalidate();
        combinationsScrPane.validate();
        final JScrollBar verticalScrollBar = combinationsScrPane.getVerticalScrollBar();
        verticalScrollBar.setValue(verticalScrollBar.getMaximum());
    }

    //----------------------------------------------------------------------------------------------------
    private void chooseFile() {
        final JFileChooser fileDialog = new JFileChooser(
                !"".equals(fileTextField.getToolTipText()) ? fileTextField.getToolTipText() : currentDirectory);
        if (!"".equals(fileTextField.getToolTipText()))
            fileDialog.setSelectedFile(new File(fileTextField.getToolTipText()));
        int dialogResult = fileDialog.showOpenDialog(dashboard);
        if (dialogResult == JFileChooser.APPROVE_OPTION) {
            final File selectedFile = fileDialog.getSelectedFile();
            if (selectedFile != null) {
                currentDirectory = selectedFile.getAbsoluteFile().getParent();
                fileTextField.setText(selectedFile.getName());
                fileTextField.setToolTipText(selectedFile.getAbsolutePath());
            }
        }
    }

    //----------------------------------------------------------------------------------------------------
    String getCurrentDirectory() {
        return currentDirectory;
    }

    void setCurrentDirectory(final String currentDirectory) {
        this.currentDirectory = currentDirectory;
    }

    //----------------------------------------------------------------------------------------------------
    private void cancelAllSelectionBut(JComponent exception) {
        if (exception != parameterList)
            parameterList.clearSelection();

        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            if (exception != pGUI.tree)
                pGUI.tree.setSelectionPath(null);
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void updateDescriptionField(final Object... selectedValues) {
        if (selectedValues.length == 0)
            parameterDescriptionLabel.setText("");
        else if (selectedValues.length == 1) {
            parameterDescriptionLabel.setText(
                    selectedValues[0] != null ? ((AvailableParameter) selectedValues[0]).info.getDescription()
                            : "");
        } else {
            String text = "";
            for (final Object selectedValue : selectedValues) {
                final AvailableParameter selectedParameter = (AvailableParameter) selectedValue;
                if (selectedParameter.info.getDescription() != null
                        && !selectedParameter.info.getDescription().trim().isEmpty()) {
                    final String humanName = selectedParameter.info.getName().replaceAll("([A-Z])", " $1");
                    text += humanName + " -- " + selectedParameter.info.getDescription() + "\n\n";
                }
            }
            parameterDescriptionLabel.setText(text);
        }

        parameterDescriptionLabel.revalidate();
    }

    //----------------------------------------------------------------------------------------------------
    void showHideSubparameters(final JComboBox combobox, final SubmodelInfo info) {
        if (!combobox.isDisplayable()) {
            return;
        }
        final ClassElement classElement = (ClassElement) combobox.getSelectedItem();

        info.setActualType(classElement.clazz, classElement.instance);
        final int level = calculateParameterLevel(info);
        for (int i = singleRunParametersPanel.getComponentCount() - 1; i >= level + 1; --i)
            singleRunParametersPanel.remove(i);

        if (classElement.clazz != null) {
            try {
                final List<ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?>> subparameters = ParameterTreeUtils
                        .fetchSubparameters(currentModelHandler, info);
                String title = "Configure " + info.getName().replaceAll("([A-Z])", " $1").trim();
                createAndDisplayAParameterPanel(subparameters, title, info, true, currentModelHandler);
            } catch (final ModelInformationException e) {
                info.setActualType(null, null);
                JOptionPane.showMessageDialog(wizard, new JLabel(e.getMessage()), "Error while analyizing model",
                        JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
                combobox.setSelectedIndex(0);
            }
        }

        parametersScrollPane.invalidate();
        parametersScrollPane.validate();
        final JScrollBar horizontalScrollBar = parametersScrollPane.getHorizontalScrollBar();
        horizontalScrollBar.setValue(horizontalScrollBar.getMaximum());
    }

    //----------------------------------------------------------------------------------------------------
    private int calculateParameterLevel(final SubmodelInfo info) {
        SubmodelInfo _info = info;
        int level = 0;
        while (_info.getParent() != null) {
            level++;
            _info = _info.getParent();
        }

        return level;
    }

    //----------------------------------------------------------------------------------------------------
    private ParameterInfo findOriginalInfo(final ParameterInfo info) {
        for (final ai.aitia.meme.paramsweep.batch.param.ParameterInfo<?> pInfo : batchParameters) {
            final ParameterInfo converted = InfoConverter.parameterInfo2ParameterInfo(pInfo);
            if (info.equals(converted)) {
                converted.setRuns(0);
                return converted;
            }
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    private void enableDisableParameterCombinationButtons() {
        final boolean selectionInTheList = parameterList.getSelectedIndex() >= 0;

        for (ParameterCombinationGUI pGUI : parameterTreeBranches) {
            final boolean selectionInTheTree = pGUI.tree.getSelectionPath() != null;
            final boolean topLevelSelectionInTheTree = selectionInTheTree && pGUI.combinationRoot
                    .isNodeChild((DefaultMutableTreeNode) pGUI.tree.getSelectionPath().getLastPathComponent());

            pGUI.addButton.setEnabled(selectionInTheList);
            pGUI.removeButton.setEnabled(topLevelSelectionInTheTree);
            pGUI.upButton.setEnabled(selectionInTheTree);
            pGUI.downButton.setEnabled(selectionInTheTree);
        }
    }

    //----------------------------------------------------------------------------------------------------
    DWizard getWizard() {
        return wizard;
    }

    IModelHandler getCurrentModelHandler() {
        return currentModelHandler;
    }

    Dashboard getDashboard() {
        return dashboard;
    }

    //----------------------------------------------------------------------------------------------------
    ClassElement[] fetchPossibleTypes(final SubmodelInfo parameterInfo) throws ComboBoxIsTooFullException {
        List<Class<?>> possibleTypes = possibleTypesCache.get(parameterInfo.getName());

        if (possibleTypes == null)
            possibleTypes = parameterInfo.getPossibleTypes();
        if (possibleTypes == null || possibleTypes.isEmpty()) {
            possibleTypes = new ArrayList<Class<?>>();
            possibleTypes.add(parameterInfo.getJavaType());

            possibleTypes.addAll(getSubtypes(parameterInfo.getJavaType()));

            // delete all interfaces and abstract classes
            for (final Iterator<Class<?>> iter = possibleTypes.iterator(); iter.hasNext();) {
                final Class<?> clazz = iter.next();
                if (Modifier.isAbstract(clazz.getModifiers()) || Modifier.isInterface(clazz.getModifiers()))
                    iter.remove();
            }
        }

        possibleTypesCache.put(parameterInfo.getName(), possibleTypes);
        Collections.sort(possibleTypes, new Comparator<Class<?>>() {
            public int compare(final Class<?> class1, final Class<?> class2) {
                return class1.getName().compareTo(class2.getName());
            }

        });

        final ClassElement[] result = new ClassElement[possibleTypes.size() + 1];
        result[0] = new ClassElement(null, null);

        for (int i = 0; i < possibleTypes.size(); ++i) {
            if (possibleTypes.get(i).equals(parameterInfo.getActualType())) {
                result[i + 1] = new ClassElement(possibleTypes.get(i), parameterInfo.getInstance());
            } else {
                result[i + 1] = new ClassElement(possibleTypes.get(i), null);
            }
        }

        return result;
    }

    //----------------------------------------------------------------------------------------------------
    private Set<Class<?>> getSubtypes(final Class<?> type) throws ComboBoxIsTooFullException {
        final ClassLoader[] classloaders = new ClassLoader[] { currentModelHandler.getCustomClassLoader(),
                currentModelHandler.getCustomClassLoader().getParent() };
        final ConfigurationBuilder builder = new ConfigurationBuilder()
                .addUrls(ClasspathHelper.forClassLoader(currentModelHandler.getCustomClassLoader()))
                .addClassLoaders(classloaders).setScanners(new SubTypesScanner(false));
        final Reflections ref = new Reflections(builder);
        final Set<Class<?>> result = new HashSet<Class<?>>();
        final Set<String> subTypesStr = ref.getStore().getSubTypesOf(type.getName());
        if (subTypesStr.size() > MAX_SIZE_OF_SUBPARAMETER_COMBOBOX)
            throw new ComboBoxIsTooFullException();

        for (final String clsName : subTypesStr) {
            try {
                result.add(ReflectionUtils.forName(clsName, classloaders));
            } catch (final ReflectionsException e) {
                // intentionally blank
            }
        }

        return result;
    }

    //----------------------------------------------------------------------------------------------------
    private String checkInfos(final boolean submodel) {
        final DefaultListModel listModel = (DefaultListModel) parameterList.getModel();
        for (int i = 0; i < listModel.getSize(); ++i) {
            final AvailableParameter param = (AvailableParameter) listModel.get(i);
            final String invalid = submodel ? checkSubmodelInfo(param.info) : checkFileInfo(param);
            if (invalid != null)
                return invalid;
        }

        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            final DefaultMutableTreeNode root = pGUI.combinationRoot;
            @SuppressWarnings("rawtypes")
            final Enumeration nodes = root.breadthFirstEnumeration();
            nodes.nextElement(); // root
            while (nodes.hasMoreElements()) {
                final DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
                final ParameterInATree userObj = (ParameterInATree) node.getUserObject();
                final String invalid = submodel ? checkSubmodelInfo(userObj.info) : checkFileInfo(userObj);
                if (invalid != null)
                    return invalid;
            }
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    private String checkSubmodelInfo(final ParameterInfo info) {
        if (info instanceof SubmodelInfo) {
            final SubmodelInfo sInfo = (SubmodelInfo) info;
            if (sInfo.getActualType() == null)
                return sInfo.getName().replaceAll("([A-Z])", " $1");
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    private String checkFileInfo(final AvailableParameter parameter) {
        if (parameter.info.isFile()) {
            if (parameter.info.getValue() == null)
                return parameter.info.getName().replaceAll("([A-Z])", " $1");
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    private String checkInfosInGeneTree() {
        final DefaultTreeModel treeModel = gaSearchHandler.getChromosomeTree();
        final DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
        @SuppressWarnings("rawtypes")
        final Enumeration nodes = root.breadthFirstEnumeration();
        nodes.nextElement(); // root
        while (nodes.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
            final ParameterOrGene userObj = (ParameterOrGene) node.getUserObject();
            final String invalid = checkSubmodelInfo(userObj.getInfo());
            if (invalid != null)
                return invalid;
        }

        return null;
    }

    //----------------------------------------------------------------------------------------------------
    private ParameterTree createParameterTreeFromParamSweepGUI() throws ModelInformationException {
        final ParameterTree result = new ParameterTree();

        final DefaultListModel listModel = (DefaultListModel) parameterList.getModel();
        for (int i = 0; i < listModel.getSize(); ++i) {
            final AvailableParameter param = (AvailableParameter) listModel.get(i);
            final AbstractParameterInfo<?> batchParameter = InfoConverter.parameterInfo2ParameterInfo(param.info);
            ParameterTreeUtils.addConstantParameterToParameterTree(batchParameter, result, currentModelHandler);
        }

        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            final DefaultMutableTreeNode root = pGUI.combinationRoot;
            @SuppressWarnings("rawtypes")
            final Enumeration nodes = root.breadthFirstEnumeration();
            nodes.nextElement(); // root;
            while (nodes.hasMoreElements()) {
                final DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
                final ParameterInATree userObj = (ParameterInATree) node.getUserObject();
                ParameterTreeUtils.filterConstants(userObj, result, currentModelHandler);
            }
        }

        for (final ParameterCombinationGUI pGUI : parameterTreeBranches) {
            final DefaultMutableTreeNode root = pGUI.combinationRoot;
            @SuppressWarnings("rawtypes")
            final Enumeration nodes = root.preorderEnumeration();
            nodes.nextElement(); // root
            ParameterNode parent = result.getRoot();
            while (nodes.hasMoreElements()) {
                final DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
                final ParameterInATree userObj = (ParameterInATree) node.getUserObject();
                if (ParameterTreeUtils.isMutableParameter(userObj)) {
                    final AbstractParameterInfo<?> batchParameter = InfoConverter
                            .parameterInfo2ParameterInfo(userObj.info);
                    batchParameter.setRunNumber(1);
                    final ParameterNode parameterNode = new ParameterNode(batchParameter);
                    parent.add(parameterNode);
                    parent = parameterNode;
                }
            }
        }

        return result;
    }

    //----------------------------------------------------------------------------------------------------
    private void hideError() {
        if (errorPopup != null) {
            errorPopup.hide();
            errorPopup = null;
        }
    }

    //----------------------------------------------------------------------------------------------------
    private void showError(final String message, final JTextField textField) {
        PopupFactory popupFactory = PopupFactory.getSharedInstance();
        Point locationOnScreen = textField.getLocationOnScreen();
        JLabel messageLabel = new JLabel(message);
        messageLabel.setBorder(new LineBorder(Color.RED, 2, true));
        errorPopup = popupFactory.getPopup(textField, messageLabel, locationOnScreen.x - 10,
                locationOnScreen.y - 30);
        errorPopup.show();
    }

    private static int calculateNumberOfRuns(DefaultMutableTreeNode combinationRoot) {
        int result = 1;
        @SuppressWarnings("rawtypes")
        final Enumeration combinationElements = combinationRoot.children();

        while (combinationElements.hasMoreElements()) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) combinationElements.nextElement();
            final ParameterInfo info = ((ParameterInATree) node.getUserObject()).info;

            if (info instanceof SubmodelInfo)
                result *= calculateNumberOfRuns(node);
            else
                result *= info.getMultiplicity();
        }

        return result;
    }

    //====================================================================================================
    // nested classes

    //----------------------------------------------------------------------------------------------------
    @SuppressWarnings("serial")
    static class ComboBoxIsTooFullException extends Exception {
    }
}