com.motorolamobility.preflighting.ui.tabs.CheckersTabComposite.java Source code

Java tutorial

Introduction

Here is the source code for com.motorolamobility.preflighting.ui.tabs.CheckersTabComposite.java

Source

/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorolamobility.preflighting.ui.tabs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import com.motorolamobility.preflighting.core.checker.CheckerDescription;
import com.motorolamobility.preflighting.core.checker.condition.Condition;
import com.motorolamobility.preflighting.core.validation.ValidationManager;
import com.motorolamobility.preflighting.ui.PreflightingUIPlugin;
import com.motorolamobility.preflighting.ui.i18n.PreflightingUiNLS;

/**
 * This class represents the Checkers Tab on the App Validador preference page.
 */
public class CheckersTabComposite extends AbstractAppValidatorTabComposite {

    private final class CheckersColumnSelectionAdapter extends SelectionAdapter {
        private int columnIndex;

        public CheckersColumnSelectionAdapter(int columnIndex) {
            this.columnIndex = columnIndex;
        }

        @Override
        public void widgetSelected(SelectionEvent e) {
            checkersTableComparator.setColumn(columnIndex);
            checkersTableViewer.getTable().setSortColumn((TableColumn) e.getSource());
            checkersTableViewer.getTable().setSortDirection(checkersTableComparator.getSwtDirection());
            checkersTableViewer.refresh();
            super.widgetSelected(e);
        }
    }

    private final class ConditionsColumnSelectionAdapter extends SelectionAdapter {
        private int columnIndex;

        public ConditionsColumnSelectionAdapter(int columnIndex) {
            this.columnIndex = columnIndex;
        }

        @Override
        public void widgetSelected(SelectionEvent e) {
            conditionsTableComparator.setColumn(columnIndex);
            conditionsTableViewer.getTable().setSortColumn((TableColumn) e.getSource());
            conditionsTableViewer.getTable().setSortDirection(conditionsTableComparator.getSwtDirection());
            conditionsTableViewer.refresh();
            super.widgetSelected(e);
        }
    }

    private static final String NO_CHECKERS_SELECTED = "none"; //$NON-NLS-1$

    /**
     * Checkers table label provider, provides Cell Text and Tooltip 
     */
    public class CheckersLabelProvider extends CellLabelProvider {

        /*
         * Display time in seconds
         */
        private static final int TOOLTIP_DISPLAYTIME = 10;

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#update(org.eclipse.jface.viewers.ViewerCell)
         */
        @Override
        public void update(ViewerCell cell) {
            String text = "";
            int columnIndex = cell.getColumnIndex();
            CheckerDescription checkerDescription = (CheckerDescription) cell.getElement();
            switch (columnIndex) {
            case NAME_COLUMN_INDEX:
                text = checkerDescription.getName();
                break;
            case ID_COLUMN_INDEX:
                text = checkerDescription.getId();
                break;
            case CHECKER_PARAMS_COLUMN_INDEX:
                String checkerId = checkerDescription.getId();
                text = checkerParams.containsKey(checkerId) ? checkerParams.get(checkerId) : "";
                break;
            case CHECKER_CHANGE_WARNING_LEVEL_COLUMN_INDEX:
                text = getWarningLevelText(customCheckersWarningLevels.get(checkerDescription.getId()));
                break;
            default:
                break;
            }
            cell.setText(text);
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipDisplayDelayTime(java.lang.Object)
         */
        @Override
        public int getToolTipDisplayDelayTime(Object object) {
            return 200;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipTimeDisplayed(java.lang.Object)
         */
        @Override
        public int getToolTipTimeDisplayed(Object object) {
            return TOOLTIP_DISPLAYTIME * 1000;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
         */
        @Override
        public String getToolTipText(Object element) {
            CheckerDescription checkerDescription = (CheckerDescription) element;
            return checkerDescription.getDescription();
        }

    }

    /**
     * Conditions table label provider, provides Cell Text and Tooltip 
     */
    public class ConditionsLabelProvider extends CellLabelProvider {

        /*
         * Display time in seconds
         */
        private static final int TOOLTIP_DISPLAYTIME = 10;

        @Override
        public void update(ViewerCell cell) {
            String text = "";
            int columnIndex = cell.getColumnIndex();
            Condition condition = (Condition) cell.getElement();
            switch (columnIndex) {
            case NAME_COLUMN_INDEX:
                text = condition.getName();
                break;
            case ID_COLUMN_INDEX:
                text = condition.getId();
                break;
            case CONDITION_WARNING_LEVEL_COLUMN_INDEX:
                text = condition.getSeverityLevel().toString();
                break;
            case CONDITION_CHANGE_WARNING_LEVEL_COLUMN_INDEX:
                text = getWarningLevelText(customConditionsWarningLevels.get(condition.getId()));
                break;
            default:
                break;
            }
            cell.setText(text);
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipDisplayDelayTime(java.lang.Object)
         */
        @Override
        public int getToolTipDisplayDelayTime(Object object) {
            return 200;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipTimeDisplayed(java.lang.Object)
         */
        @Override
        public int getToolTipTimeDisplayed(Object object) {
            return TOOLTIP_DISPLAYTIME * 1000;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
         */
        @Override
        public String getToolTipText(Object element) {
            Condition condition = (Condition) element;
            return condition.getDescription();
        }

    }

    /**
     *  Checkers Table content provider
     */
    public class CheckersContentProvider implements IStructuredContentProvider {

        @SuppressWarnings("unchecked")
        public Object[] getElements(Object inputElement) {
            List<CheckerDescription> checkersDescription = (List<CheckerDescription>) inputElement;
            return checkersDescription.toArray();
        }

        public void dispose() {
            //do nothing
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            //do nothing
        }
    }

    /**
     *  Conditions Table content provider
     */
    public class ConditionsContentProvider implements IStructuredContentProvider {

        @SuppressWarnings("unchecked")
        public Object[] getElements(Object inputElement) {
            List<Condition> conditions = (List<Condition>) inputElement;
            return conditions.toArray();
        }

        public void dispose() {
            //do nothing
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            //do nothing
        }
    }

    /**
     * Table comparator
     * Add sort functionality for checkers
     */
    private class CheckersTableComparator extends ViewerComparator {
        private final int ORDER_ASC = 1;

        private final int ORDER_DESC = -1;

        /**
         * Column that must be used to sort elements
         */
        private int column = -1;

        private int direction = ORDER_ASC;

        public void setColumn(int column) {
            if (this.column == column) {
                direction = direction == ORDER_ASC ? ORDER_DESC : ORDER_ASC;
            } else {
                this.column = column;
                direction = ORDER_ASC;
            }
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
         */
        @Override
        public int compare(Viewer viewer, Object e1, Object e2) {
            CheckerDescription checkerLeft = (CheckerDescription) e1;
            CheckerDescription checkerRight = (CheckerDescription) e2;

            String left = ""; //$NON-NLS-1$
            String right = ""; //$NON-NLS-1$
            switch (column) {
            case NAME_COLUMN_INDEX:
                left = checkerLeft.getName();
                right = checkerRight.getName();
                break;
            case ID_COLUMN_INDEX:
                left = checkerLeft.getId();
                right = checkerRight.getId();
                break;
            case CHECKER_PARAMS_COLUMN_INDEX:
                String leftParams = checkerParams.get(checkerLeft.getId());
                String rightParams = checkerParams.get(checkerRight.getId());
                left = ((leftParams != null) ? leftParams : "");
                right = ((rightParams != null) ? rightParams : "");
                break;
            case CHECKER_CHANGE_WARNING_LEVEL_COLUMN_INDEX:
                Boolean leftWarningLevel = customCheckersWarningLevels.get(checkerLeft.getId());
                Boolean rightWarningLevel = customCheckersWarningLevels.get(checkerRight.getId());
                left = ((leftWarningLevel != null) ? leftWarningLevel.toString() : "");
                right = ((rightWarningLevel != null) ? rightWarningLevel.toString() : "");
                break;
            default:
                break;
            }

            return left.compareTo(right) * direction;
        }

        /**
         * Returns the SWT constant which represents the direction
         * @return
         */
        public int getSwtDirection() {
            return direction == ORDER_ASC ? SWT.UP : SWT.DOWN;
        }
    }

    /**
     * Conditions comparator
     * Add sort functionality for checkers
     */
    private class ConditionsTableComparator extends ViewerComparator {
        private final int ORDER_ASC = 1;

        private final int ORDER_DESC = -1;

        /**
         * Column that must be used to sort elements
         */
        private int column = -1;

        private int direction = ORDER_ASC;

        public void setColumn(int column) {
            if (this.column == column) {
                direction = direction == ORDER_ASC ? ORDER_DESC : ORDER_ASC;
            } else {
                this.column = column;
                direction = ORDER_ASC;
            }
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
         */
        @Override
        public int compare(Viewer viewer, Object e1, Object e2) {
            Condition conditionLeft = (Condition) e1;
            Condition conditionRight = (Condition) e2;

            String left = ""; //$NON-NLS-1$
            String right = ""; //$NON-NLS-1$
            switch (column) {
            case NAME_COLUMN_INDEX:
                left = conditionLeft.getName();
                right = conditionRight.getName();
                break;
            case ID_COLUMN_INDEX:
                left = conditionLeft.getId();
                right = conditionRight.getId();
                break;
            case CHECKER_PARAMS_COLUMN_INDEX:
                left = conditionLeft.getSeverityLevel().toString();
                right = conditionRight.getSeverityLevel().toString();
                break;
            case CHECKER_CHANGE_WARNING_LEVEL_COLUMN_INDEX:
                Boolean leftWarningLevel = customConditionsWarningLevels.get(conditionLeft.getId());
                Boolean rightWarningLevel = customConditionsWarningLevels.get(conditionRight.getId());
                left = ((leftWarningLevel != null) ? leftWarningLevel.toString() : "");
                right = ((rightWarningLevel != null) ? rightWarningLevel.toString() : "");
                break;
            default:
                break;
            }

            return left.compareTo(right) * direction;
        }

        /**
         * Returns the SWT constant which represents the direction
         * @return
         */
        public int getSwtDirection() {
            return direction == ORDER_ASC ? SWT.UP : SWT.DOWN;
        }
    }

    /*
     * Table columns
     */
    private static final int NAME_COLUMN_INDEX = 0;

    private static final int ID_COLUMN_INDEX = 1;

    private static final int CONDITION_WARNING_LEVEL_COLUMN_INDEX = 2;

    private static final int CONDITION_CHANGE_WARNING_LEVEL_COLUMN_INDEX = 3;

    private static final int CHECKER_PARAMS_COLUMN_INDEX = 2;

    private static final int CHECKER_CHANGE_WARNING_LEVEL_COLUMN_INDEX = 3;

    /**
     * The Checkers TableViewer
     */
    private CheckboxTableViewer checkersTableViewer;

    /**
     * The Conditions TableViewer
     */
    private CheckboxTableViewer conditionsTableViewer;

    /**
     * The Select All checkbox for checkers
     */
    private Button selectAllCheckersCheck;

    /**
     * The Select All checkbox for conditions
     */
    private Button selectAllConditionsCheck;

    /**
     * A list with all CheckerDescription
     */
    private List<CheckerDescription> checkersDescriptions;

    /**
     * The model which keeps checker params, Key is checkerId and value is the Parameters String
     */
    private Map<String, String> checkerParams;

    /**
     * The model which keeps the custom warning levels, Key is checkerId and value is a Boolean that indicates:
     * true -> increases warning level
     * false -> decreases warning level
     * null and/or inexistent -> no change
     */
    private Map<String, Boolean> customCheckersWarningLevels = new HashMap<String, Boolean>();

    private Map<String, Boolean> customConditionsWarningLevels = new HashMap<String, Boolean>();

    /**
     * The model which keeps all conditions, Key is checkerId and value is a list of its conditions
     */
    private Map<String, List<Condition>> allConditionsMap = new HashMap<String, List<Condition>>();

    /**
     * The model which keeps only the selected conditions, Key is checkerId and value is a list of its selected conditions
     */
    private Map<String, List<Condition>> selectedConditionsMap = new HashMap<String, List<Condition>>();

    /**
     * Warning Level Operations (increase, keep, decrease)
     * Currently, it's not possible to set the warning level, you can only increase or decrease it
     */
    private String[] WarningLevelOperations = {
            PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Increase,
            PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Kepp,
            PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Decrease };

    /**
     * Checkers table comparator, used for sort functionality
     */
    private CheckersTableComparator checkersTableComparator;

    /**
     * Conditions table comparator, used for sort functionality
     */
    private ConditionsTableComparator conditionsTableComparator;

    /**
     * Return the text that represents the warning level change, which is
     * saved as a boolean
     * 
     * true -> increases warning level
     * false -> decreases warning level
     * null -> no change
     * 
     * @param action the value stored
     * @return the corresponding warning level operation
     */
    public String getWarningLevelText(Boolean action) {
        String result = PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Kepp;

        if (action != null) {
            if (action) {
                result = PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Increase;
            } else {
                result = PreflightingUiNLS.CheckersTabComposite_WarningLevel_Operation_Decrease;
            }
        }

        return result;
    }

    /**
     * Initialize all UI items
     * 
     * @param parent the parent composite
     * @param style the SWT styles
     * @param preferenceStore the preference store
     */
    public CheckersTabComposite(Composite parent, int style, IPreferenceStore preferenceStore) {
        super(parent, style);

        Layout layout = new GridLayout(1, false);
        this.setLayout(layout);

        createCheckersComposite();

        init(preferenceStore);
    }

    /**
     * Creates the composite which will have the checkers and also
     * the conditions selection
     */
    private void createCheckersComposite() {
        Layout layout;
        Composite composite = new Composite(this, SWT.NONE);
        layout = new GridLayout(1, true);
        composite.setLayout(layout);

        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(gd);

        /*
         * Create checkers group
         */
        createCheckersGroup(composite);

        /*
         * Include the conditions area in the checker group.
         * This are is updated according to the checker selection
         */
        createConditionsGroup(composite);

    }

    /**
     * Create and return the Checkers group. 
     * It contains the table with all checkers listed. When a checker is
     * selected, the corresponding conditions are updated in the conditions
     * table.
     * 
     * @param topComposite the parent composite
     */
    private void createCheckersGroup(Composite topComposite) {

        Group checkersGroup = new Group(topComposite, SWT.NONE);
        checkersGroup.setLayout(new GridLayout(1, false));
        checkersGroup.setText(PreflightingUiNLS.CheckersTabComposite_Checkers_Group);
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        checkersGroup.setLayoutData(gd);

        checkersTableViewer = CheckboxTableViewer.newCheckList(checkersGroup,
                SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
        Control checkersTableControl = checkersTableViewer.getTable();
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        checkersTableControl.setLayoutData(gd);

        checkersTableComparator = new CheckersTableComparator();
        checkersTableViewer.setComparator(checkersTableComparator);

        /*
         * Create Columns
         */
        TableViewerColumn column = new TableViewerColumn(checkersTableViewer, SWT.NONE); // Name
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_Name_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(230);
        column.setLabelProvider(new CheckersLabelProvider());
        column.getColumn().addSelectionListener(new CheckersColumnSelectionAdapter(NAME_COLUMN_INDEX));

        column = new TableViewerColumn(checkersTableViewer, SWT.NONE); // ID
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_Id_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new CheckersLabelProvider());
        column.getColumn().addSelectionListener(new CheckersColumnSelectionAdapter(ID_COLUMN_INDEX));

        column = new TableViewerColumn(checkersTableViewer, SWT.NONE); // Parameters
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_Checker_Params_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new CheckersLabelProvider());
        column.getColumn().addSelectionListener(new CheckersColumnSelectionAdapter(CHECKER_PARAMS_COLUMN_INDEX));
        // set a custom editor for this column
        column.setEditingSupport(new ParameterEditingSupport(checkersTableViewer));

        column = new TableViewerColumn(checkersTableViewer, SWT.NONE); // Change Warning Level
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_ChangeWarningLevel_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new CheckersLabelProvider());
        column.getColumn().addSelectionListener(
                new CheckersColumnSelectionAdapter(CHECKER_CHANGE_WARNING_LEVEL_COLUMN_INDEX));
        // set a custom editor for this column
        column.setEditingSupport(new WarningLevelEditingSupport(checkersTableViewer));

        checkersTableViewer.getTable().setHeaderVisible(true);

        checkersTableViewer.setContentProvider(new CheckersContentProvider());
        ColumnViewerToolTipSupport.enableFor(checkersTableViewer);
        // Selection Change Listener handles needed UI updates on the paramsText according to checkers selected
        // It also updates the conditions table
        checkersTableViewer.getTable().addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                CheckerDescription checkerDescription = (CheckerDescription) e.item.getData();
                TableItem tableItem = (TableItem) e.item;
                updateConditionTableBasedOnChecker(tableItem.getChecked());
                populateConditionsTable(checkerDescription.getId());
            }
        });

        // CheckStateListener handles the selectAll check box behavior and also selects the clicked item on the table.
        checkersTableViewer.addCheckStateListener(new ICheckStateListener() {

            public void checkStateChanged(CheckStateChangedEvent event) {
                boolean isAllSelected = areAllItemsChecked(checkersTableViewer);
                selectAllCheckersCheck.setSelection(isAllSelected);
                checkersTableViewer.setSelection(new StructuredSelection(event.getElement()), true);
                updateConditionTableBasedOnChecker(event.getChecked());
                notifyListener();
            }
        });

        ValidationManager validationManager = new ValidationManager();
        checkersDescriptions = validationManager.getCheckersDescription();
        checkerParams = new HashMap<String, String>(checkersDescriptions.size());
        checkersTableViewer.setInput(checkersDescriptions);

        selectAllCheckersCheck = new Button(checkersGroup, SWT.CHECK);
        selectAllCheckersCheck.setText(PreflightingUiNLS.CheckersTabComposite_Checkers_SelectAll_Check);
        gd = new GridData(SWT.LEFT, SWT.BOTTOM, false, false);
        selectAllCheckersCheck.setLayoutData(gd);
        selectAllCheckersCheck.setSelection(true);
        selectAllCheckersCheck.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                checkersTableViewer.setAllChecked(selectAllCheckersCheck.getSelection());
                updateConditionTableBasedOnChecker(selectAllCheckersCheck.getSelection());
                super.widgetSelected(e);
                notifyListener();
            }
        });

        checkersTableComparator.setColumn(0);

    }

    /**
     * @param event
     */
    public void updateConditionTableBasedOnChecker(boolean checkerEnabled) {
        if (!checkerEnabled) {
            //disabling checker => disable all conditions as well (and disable the table)
            conditionsTableViewer.getTable().setEnabled(false);
            selectAllConditionsCheck.setEnabled(false);
        } else {
            //enabling checker => enables all conditions as well (and enable the table)
            conditionsTableViewer.getTable().setEnabled(true);
            selectAllConditionsCheck.setEnabled(true);
        }
    }

    /**
     * Create the conditions are, which contains a table with all
     * conditions of the selected checker. Its content is updated
     * dynamically based on the checker selection
     * 
     * @param topComposite the parent composite
     */
    /**
     * @param topComposite
     */
    private void createConditionsGroup(Composite topComposite) {

        Group conditionsGroup = new Group(topComposite, SWT.NONE);
        conditionsGroup.setLayout(new GridLayout(1, false));
        conditionsGroup.setText(PreflightingUiNLS.CheckersTabComposite_Conditions_Group);
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        gd.heightHint = 200;
        conditionsGroup.setLayoutData(gd);

        conditionsTableViewer = CheckboxTableViewer.newCheckList(conditionsGroup,
                SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        Control conditionsTableControl = conditionsTableViewer.getTable();
        gd.heightHint = 200;
        conditionsTableControl.setLayoutData(gd);

        conditionsTableViewer.setContentProvider(new ConditionsContentProvider());
        ColumnViewerToolTipSupport.enableFor(conditionsTableViewer);

        conditionsTableComparator = new ConditionsTableComparator();
        conditionsTableViewer.setComparator(conditionsTableComparator);

        // Create Columns
        TableViewerColumn column = new TableViewerColumn(conditionsTableViewer, SWT.NONE); // Name
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_Name_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(230);
        column.setLabelProvider(new ConditionsLabelProvider());
        column.getColumn().addSelectionListener(new ConditionsColumnSelectionAdapter(NAME_COLUMN_INDEX));

        column = new TableViewerColumn(conditionsTableViewer, SWT.NONE); // ID
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_Id_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new ConditionsLabelProvider());
        column.getColumn().addSelectionListener(new ConditionsColumnSelectionAdapter(ID_COLUMN_INDEX));

        column = new TableViewerColumn(conditionsTableViewer, SWT.NONE); // Warning Level
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_WarningLevel_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new ConditionsLabelProvider());
        column.getColumn()
                .addSelectionListener(new ConditionsColumnSelectionAdapter(CONDITION_WARNING_LEVEL_COLUMN_INDEX));

        column = new TableViewerColumn(conditionsTableViewer, SWT.NONE); // Change Warning Level
        column.getColumn().setText(PreflightingUiNLS.CheckersTabComposite_ChangeWarningLevel_Column);
        column.getColumn().setResizable(true);
        column.getColumn().setWidth(100);
        column.setLabelProvider(new ConditionsLabelProvider());
        column.getColumn().addSelectionListener(
                new ConditionsColumnSelectionAdapter(CONDITION_CHANGE_WARNING_LEVEL_COLUMN_INDEX));
        // set a custom editor for this column
        column.setEditingSupport(new WarningLevelEditingSupport(conditionsTableViewer));

        conditionsTableViewer.getTable().setHeaderVisible(true);

        conditionsTableViewer.addCheckStateListener(new ICheckStateListener() {

            public void checkStateChanged(CheckStateChangedEvent event) {
                // update "select all" control
                boolean isAllSelected = areAllItemsChecked(conditionsTableViewer);
                selectAllConditionsCheck.setSelection(isAllSelected);
                // move the selection to the checked item
                conditionsTableViewer.setSelection(new StructuredSelection(event.getElement()), true);

                // get the condition and the checker that are selected
                Condition condition = (Condition) event.getElement();
                CheckerDescription selectedChecker = (CheckerDescription) ((StructuredSelection) checkersTableViewer
                        .getSelection()).getFirstElement();
                // update the selected conditions maps accordingly, adding the specified condition
                // if the checkbox is checked or removing it otherwise
                List<Condition> conditions = selectedConditionsMap.get(selectedChecker.getId());
                if (event.getChecked()) {
                    conditions.add(condition);
                } else {
                    conditions.remove(condition);
                }
                notifyListener();
            }
        });

        selectAllConditionsCheck = new Button(conditionsGroup, SWT.CHECK);
        selectAllConditionsCheck.setText(PreflightingUiNLS.CheckersTabComposite_Checkers_SelectAll_Check);
        gd = new GridData(SWT.LEFT, SWT.BOTTOM, false, false);
        selectAllConditionsCheck.setLayoutData(gd);
        selectAllConditionsCheck.setSelection(true);
        selectAllConditionsCheck.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                // update UI
                conditionsTableViewer.setAllChecked(selectAllConditionsCheck.getSelection());

                // update model
                CheckerDescription selectedChecker = (CheckerDescription) ((StructuredSelection) checkersTableViewer
                        .getSelection()).getFirstElement();
                // get all conditions of the selected checker and add them to the selected conditions list
                if (selectAllConditionsCheck.getSelection()) {
                    selectAllConditions(selectedChecker.getId());
                }
                // clear the selected conditions list
                else {
                    selectedConditionsMap.put(selectedChecker.getId(), new ArrayList<Condition>());
                }
                super.widgetSelected(e);
                notifyListener();
            }
        });

        selectAllConditionsCheck.setEnabled(conditionsTableViewer.getTable().isEnabled());

        conditionsTableComparator.setColumn(0);
    }

    /**
     * Select all conditions in the model, by copying the list with all conditions
     * 
     * @param checkerId the checker id to have all its conditions selected
     */
    private void selectAllConditions(String checkerId) {
        List<Condition> selectedConditions = new ArrayList<Condition>();
        for (Condition condition : allConditionsMap.get(checkerId)) {
            selectedConditions.add(condition);
        }
        selectedConditionsMap.put(checkerId, selectedConditions);
    }

    /**
     * Create a custom cell editor which will contain a text editor so that
     * users can modify the parameters for a particular checker
     */
    public class ParameterEditingSupport extends EditingSupport {

        public ParameterEditingSupport(ColumnViewer viewer) {
            super(viewer);
        }

        @Override
        protected void setValue(Object element, Object value) {
            checkerParams.put(((CheckerDescription) element).getId(), (String) value);
            getViewer().update(element, null);
            notifyListener();
        }

        @Override
        protected Object getValue(Object element) {
            CheckerDescription checkerDescription = (CheckerDescription) element;
            String params = ""; //$NON-NLS-1$
            if (checkerParams.containsKey(checkerDescription.getId())) {
                params = checkerParams.get(checkerDescription.getId());
            }
            return params;
        }

        @Override
        protected CellEditor getCellEditor(Object element) {
            return new TextCellEditor(((TableViewer) getViewer()).getTable(), SWT.NONE);
        }

        @Override
        protected boolean canEdit(Object element) {
            return true;
        }

    }

    /**
     * Create a custom cell editor which will contain a combobox so that
     * users can modify (increase / decrease) the warning level for a particular 
     * condition or checker
     */
    public class WarningLevelEditingSupport extends EditingSupport {

        public WarningLevelEditingSupport(TableViewer viewer) {
            super(viewer);
        }

        @Override
        protected CellEditor getCellEditor(Object element) {
            CellEditor comboEditor = new ComboBoxCellEditor(((TableViewer) getViewer()).getTable(),
                    WarningLevelOperations, SWT.READ_ONLY | SWT.FULL_SELECTION | SWT.DROP_DOWN);
            return comboEditor;

        }

        @Override
        protected boolean canEdit(Object element) {
            return true;
        }

        @Override
        protected Object getValue(Object element) {
            // Get value from model
            Boolean customWarningLevel = null;
            if (element instanceof Condition) {
                customWarningLevel = customConditionsWarningLevels.get(((Condition) element).getId());
            } else {
                customWarningLevel = customCheckersWarningLevels.get(((CheckerDescription) element).getId());
            }

            // select the appropriate item in the combobox 
            int value = 1; // keep 
            if (customWarningLevel != null) {
                value = ((customWarningLevel) ? 0 : 2); // increase, decrease
            }
            return new Integer(value);
        }

        @Override
        protected void setValue(Object element, Object value) {
            int intValue = ((Integer) value).intValue();
            Boolean booleanValue = null; // 1 = default (keep warning level)
            if (intValue != 1) {
                booleanValue = ((intValue == 0) ? new Boolean(true) : new Boolean(false));
            }

            // Set value in the model
            if (element instanceof Condition) {
                customConditionsWarningLevels.put(((Condition) element).getId(), booleanValue);
            } else {
                customCheckersWarningLevels.put(((CheckerDescription) element).getId(), booleanValue);
            }

            // Update the UI. This generate a call to the label provider
            getViewer().update(element, null);
            getViewer().refresh();
        }
    }

    /**
     * Update the conditions table based on the checker that is selected
     * 
     * @param checkerId the checker selected in the UI
     */
    private void populateConditionsTable(String checkerId) {

        // display appropriate elements
        if (checkerId != null) {
            conditionsTableViewer.setInput(allConditionsMap.get(checkerId));
        } else {
            conditionsTableViewer.setInput(new ArrayList<Condition>());
        }

        // update selection in the table and also the "select all" button state
        conditionsTableViewer.setCheckedElements(selectedConditionsMap.get(checkerId).toArray());
        selectAllConditionsCheck.setEnabled(conditionsTableViewer.getTable().isEnabled());
        selectAllConditionsCheck.setSelection(areAllItemsChecked(conditionsTableViewer));

    }

    /*
     * Verifies if all items on a given CheckboxTableViewer are selected
     */
    private boolean areAllItemsChecked(CheckboxTableViewer tableViewer) {
        Table table = tableViewer.getTable();
        TableItem[] items = table.getItems();
        boolean allChecked = true;
        int i = 0;
        while ((i < items.length) && allChecked) {
            TableItem tableItem = items[i];
            if (!tableItem.getChecked()) {
                allChecked = false;
            }
            i++;
        }
        return allChecked;
    }

    /*
     * Load data from the preference store and configure the UI accordingly.
     */
    private void init(IPreferenceStore preferenceStore) {
        /*
         * Populate condition maps
         */
        ValidationManager validationManager = new ValidationManager();
        for (CheckerDescription checkerDescription : checkersDescriptions) {
            allConditionsMap.put(checkerDescription.getId(),
                    validationManager.getCheckerConditions(checkerDescription.getId()));
        }

        String checkersPreference = preferenceStore.getString(PreflightingUIPlugin.CHECKERS_PREFERENCE_KEY);
        // Preference is empty means first time. Perform defaults
        if (checkersPreference.length() == 0) {
            performDefaults();
        } else {
            /*
             * Checkers information
             */
            if (!checkersPreference.equals(NO_CHECKERS_SELECTED)) //There's checkers to load and check on the table
            {
                StringTokenizer tokenizer = new StringTokenizer(checkersPreference, ","); //$NON-NLS-1$
                List<CheckerDescription> selectedCheckerDescriptions = new ArrayList<CheckerDescription>(
                        tokenizer.countTokens());
                while (tokenizer.hasMoreTokens()) {
                    String checkerId = tokenizer.nextToken();
                    CheckerDescription checkerDescription = getCheckerDescription(checkerId);
                    if (checkerDescription != null) {
                        selectedCheckerDescriptions.add(checkerDescription);
                    }
                }
                checkersTableViewer.setCheckedElements(selectedCheckerDescriptions.toArray());
            }
            selectAllCheckersCheck.setSelection(areAllItemsChecked(checkersTableViewer));

            String checkersConditionsPreference = preferenceStore
                    .getString(PreflightingUIPlugin.CHECKERS_CONDITIONS_PREFERENCE_KEY);
            if (checkersConditionsPreference.length() > 0) {
                StringTokenizer tokenizer = new StringTokenizer(checkersConditionsPreference, ";");
                while (tokenizer.hasMoreElements()) {
                    String checkerConditionStr = tokenizer.nextToken();
                    String[] split = checkerConditionStr.split(":");
                    if (split.length == 2) {
                        String checkerId = split[0];
                        String[] selectedConditionsIds = split[1].split(",");

                        // define which are the selected conditions
                        Set<String> selectedConditionsIdsSet = new HashSet<String>();
                        for (String selectedConditionId : selectedConditionsIds) {
                            selectedConditionsIdsSet.add(selectedConditionId);
                        }
                        // get the Condition objects and add them to the selected conditions map
                        List<Condition> allConditionsList = allConditionsMap.get(checkerId);
                        List<Condition> selectedConditionsList = new ArrayList<Condition>();
                        if (allConditionsList != null) {
                            for (Condition condition : allConditionsList) {
                                if (selectedConditionsIdsSet.contains(condition.getId())) {
                                    selectedConditionsList.add(condition);
                                }
                            }
                        }
                        selectedConditionsMap.put(checkerId, selectedConditionsList);
                    }
                }
            }
            // create an empty list for the checkers that had no preferences set (new checkers, for example)
            for (CheckerDescription checkerDescription : checkersDescriptions) {
                if (selectedConditionsMap.get(checkerDescription.getId()) == null) {
                    selectedConditionsMap.put(checkerDescription.getId(), new ArrayList<Condition>());
                }
            }

            /*
             * Get Extended Properties
             */
            // Checker parameters
            loadExtendedProperty(checkerParams, preferenceStore,
                    PreflightingUIPlugin.CHECKERS_PARAMS_PREFERENCE_KEY, String.class);

            // Custom checker warning levels
            loadExtendedProperty(customCheckersWarningLevels, preferenceStore,
                    PreflightingUIPlugin.CHECKERS_WARNING_LEVELS_PREFERENCE_KEY, Boolean.class);

            // Custom conditions warning levels
            loadExtendedProperty(customConditionsWarningLevels, preferenceStore,
                    PreflightingUIPlugin.CHECKERS_CONDITIONS_WARNING_LEVELS_PREFERENCE_KEY, Boolean.class);

            checkersTableViewer.refresh();

        }
    }

    /**
     * Load saved extend property. The extended properties are related to
     * a checker or condition, and are saved in the form:
     * <id>,<extended_property>;<id>,<extended_property>...
     * 
     * These properties are loaded in a map <id> -> <extended_property>
     * 
     * @param map the map where the information will be loaded
     * @param preferenceStore the preference store
     * @param preferenceName the preference key used to store
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void loadExtendedProperty(Map map, IPreferenceStore preferenceStore, String preferenceName,
            Class valueType) {

        String preference = preferenceStore.getString(preferenceName);
        if (preference.length() > 0) {
            StringTokenizer tokenizer = new StringTokenizer(preference, ";");
            while (tokenizer.hasMoreElements()) {
                String extendedProperty = tokenizer.nextToken();
                String[] split = extendedProperty.split(",");
                if (split.length == 2) {
                    String id = split[0];
                    String params = split[1];
                    // string (checker param)
                    if (valueType.getName().equals("java.lang.String")) {
                        map.put(id, params);
                    }
                    // boolean (warning levels)
                    else {
                        map.put(id, new Boolean(params));
                    }
                }
            }
        }
    }

    /**
     * Saved extended properties. The extended properties are related to
     * a checker or condition, and are saved in the form:
     * <id>,<extended_property>;<id>,<extended_property>...
     * 
     * The properties come from a map <id> -> <extended_property>
     * 
     * @param map a map with the extended properties
     * @param preferenceStore the preference store
     * @param preferenceName the preference key used to store
     */
    private void saveExtendedProperty(Map<String, ?> map, IPreferenceStore preferenceStore, String preferenceName) {
        StringBuilder stringBuilder = new StringBuilder();
        if (!map.isEmpty()) {
            for (String id : map.keySet()) {
                String params = ((map.get(id) != null) ? map.get(id).toString() : null);
                if ((params != null) && (params.length() > 0)) {
                    stringBuilder.append(id);
                    stringBuilder.append(","); //$NON-NLS-1$
                    stringBuilder.append(params);
                    stringBuilder.append(";"); //$NON-NLS-1$
                }
            }
            deleteLastChar(stringBuilder);
        }
        preferenceStore.setValue(preferenceName, stringBuilder.toString());
    }

    /**
     * Get the CheckerDescription object for a fiven checkerId passed as parameter
     * 
     * @param checkerId the checker id of the object to be retrieved
     * @return the CheckerDescription object that represents the checker with the id passed as parameter
     */
    private CheckerDescription getCheckerDescription(String checkerId) {
        CheckerDescription checkerDescriptionFound = null;
        Iterator<CheckerDescription> it = checkersDescriptions.iterator();
        while ((checkerDescriptionFound == null) && it.hasNext()) {
            CheckerDescription checkerDescription = it.next();
            if (checkerDescription.getId().equals(checkerId)) {
                checkerDescriptionFound = checkerDescription;
            }
        }
        return checkerDescriptionFound;
    }

    /* (non-Javadoc)
     * @see com.motorolamobility.preflighting.ui.tabs.AbstractAppValidatorTabComposite#isValid()
     */
    @Override
    public IStatus isValid() {
        IStatus status = Status.OK_STATUS;
        boolean isValid = true;
        boolean hasWarning = false;
        String msg = "";

        // check if no checker is selected
        if (checkersTableViewer.getCheckedElements().length == 0) {
            isValid = false;
            msg = PreflightingUiNLS.CheckersTabComposite_Validation_Error_No_Checker;
        }

        // check if there are parameters for checkers that have custom conditions selection
        Object[] checkerDescriptions = checkersTableViewer.getCheckedElements();
        if (checkerDescriptions.length > 0) {
            for (Object checkerDescObj : checkerDescriptions) {
                String checkerId = ((CheckerDescription) checkerDescObj).getId();
                if (((checkerParams.get(checkerId) != null) && !checkerParams.get(checkerId).equals(""))) {
                    if (hasCustomConditionsSelection(checkerId)) {
                        hasWarning = true;
                        msg = PreflightingUiNLS.CheckersTabComposite_Validation_Warning_Param_Problem;
                    }
                }
            }
        }

        if (!isValid) {
            status = new Status(IStatus.ERROR, PreflightingUIPlugin.PREFLIGHTING_UI_PLUGIN_ID, msg);
        } else if (hasWarning) {
            status = new Status(IStatus.WARNING, PreflightingUIPlugin.PREFLIGHTING_UI_PLUGIN_ID, msg);
        }

        return status;
    }

    /**
     * Check if there are unselected conditions for the checker passed as parameter
     * 
     * @param checkerId the checker to have the conditions selection analysed
     * @return true if there is custom selection for the conditions (i.e. unselected conditions), false otherwise
     */
    private boolean hasCustomConditionsSelection(String checkerId) {
        boolean result = false;
        List<Condition> selectedConditions = selectedConditionsMap.get(checkerId);

        if ((selectedConditions != null)
                && (selectedConditionsMap.get(checkerId).size() != allConditionsMap.get(checkerId).size())) {
            result = true;
        }

        return result;
    }

    /* (non-Javadoc)
     * @see com.motorolamobility.preflighting.ui.tabs.AbstractAppValidatorTabComposite#performDefaults()
     */
    @Override
    public void performDefaults() {

        /*
         * Checkers - select all
         */
        // model / UI
        checkersTableViewer.setAllChecked(true);
        selectAllCheckersCheck.setSelection(true);

        // model
        for (CheckerDescription checkerDescription : checkersDescriptions) {
            selectAllConditions(checkerDescription.getId());
        }
        // UI
        conditionsTableViewer.setAllChecked(true);
        selectAllConditionsCheck.setSelection(true);

        /*
         * Extended Properties
         */
        // model
        checkerParams.clear();
        customCheckersWarningLevels.clear();
        customConditionsWarningLevels.clear();

        /*
         * Update UIs
         */
        checkersTableViewer.refresh();
        conditionsTableViewer.refresh();

    }

    /* (non-Javadoc)
     * @see com.motorolamobility.preflighting.ui.tabs.AbstractAppValidatorTabComposite#performOk(org.eclipse.jface.preference.IPreferenceStore)
     */
    @Override
    public void performOk(IPreferenceStore preferenceStore) {
        StringBuilder stringBuilder;

        /*
         * Checkers information
         */
        Object[] checkerDescriptions = checkersTableViewer.getCheckedElements();

        stringBuilder = new StringBuilder();
        if (checkerDescriptions.length > 0) {
            for (Object checkerDescObj : checkerDescriptions) {
                CheckerDescription checkerDescription = (CheckerDescription) checkerDescObj;
                stringBuilder.append(checkerDescription.getId());
                stringBuilder.append(","); //$NON-NLS-1$
            }
            deleteLastChar(stringBuilder);
            preferenceStore.putValue(PreflightingUIPlugin.CHECKERS_PREFERENCE_KEY, stringBuilder.toString());
        } else {
            preferenceStore.putValue(PreflightingUIPlugin.CHECKERS_PREFERENCE_KEY, NO_CHECKERS_SELECTED);
        }

        stringBuilder = new StringBuilder();
        if (!selectedConditionsMap.isEmpty()) {
            for (String checkerId : selectedConditionsMap.keySet()) {
                stringBuilder.append(checkerId);
                stringBuilder.append(":");
                for (Condition condition : selectedConditionsMap.get(checkerId)) {
                    stringBuilder.append(condition.getId());
                    stringBuilder.append(","); //$NON-NLS-1$
                }
                deleteLastChar(stringBuilder);
                stringBuilder.append(";");
            }
            deleteLastChar(stringBuilder);
        }
        preferenceStore.setValue(PreflightingUIPlugin.CHECKERS_CONDITIONS_PREFERENCE_KEY, stringBuilder.toString());

        /*
         * Extended Properties
         */
        // Checker parameters
        saveExtendedProperty(checkerParams, preferenceStore, PreflightingUIPlugin.CHECKERS_PARAMS_PREFERENCE_KEY);
        // Custom checker warning levels
        saveExtendedProperty(customCheckersWarningLevels, preferenceStore,
                PreflightingUIPlugin.CHECKERS_WARNING_LEVELS_PREFERENCE_KEY);
        // Custom conditions warning levels
        saveExtendedProperty(customConditionsWarningLevels, preferenceStore,
                PreflightingUIPlugin.CHECKERS_CONDITIONS_WARNING_LEVELS_PREFERENCE_KEY);

    }

    /**
     * Delete the last char of a string builder
     * 
     * @param stringBuilder the string builder to have the last char deleted
     */
    private void deleteLastChar(StringBuilder stringBuilder) {
        if (stringBuilder.length() > 0) {
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
    }

    /* (non-Javadoc)
     * @see com.motorolamobility.preflighting.ui.tabs.AbstractAppValidatorTabComposite#commandLineBuilder()
     */
    @Override
    public String commandLineBuilder() {
        String commandline = "";

        boolean hasCustomCheckers = !areAllItemsChecked(checkersTableViewer);
        boolean hasCustomParameters = hasParameters();
        boolean hasCustomConditions = hasCustomConditions();
        boolean hasCustomWarningLevels = hasCustomWarningLevels();

        // check if there are custom configurations
        if (hasCustomCheckers || hasCustomParameters || hasCustomConditions || hasCustomWarningLevels) {
            Object[] checkedElements = checkersTableViewer.getCheckedElements();
            StringBuilder stringBuilder = new StringBuilder();

            Boolean customWarningLevel = null;
            List<String> elementsToIncreaseWarningLevel = new ArrayList<String>();
            List<String> elementsToDecreaseWarningLevel = new ArrayList<String>();

            /*
             * Iterate in the selected checkers
             */
            for (Object checkedObj : checkedElements) {
                CheckerDescription checkerDescription = (CheckerDescription) checkedObj;
                String checkerId = checkerDescription.getId();
                List<Condition> selectedConditions = ((selectedConditionsMap.get(checkerId) != null)
                        ? selectedConditionsMap.get(checkerId)
                        : new ArrayList<Condition>());

                // Have custom parameters or there are checkers disabled
                // just create the command line block to 
                // select the checker and to pass the appropriate parameters, if any
                if (hasCustomParameters
                        || (checkedElements.length < checkersTableViewer.getTable().getItems().length)) {
                    stringBuilder.append("-c ");
                    stringBuilder.append(checkerId);
                    stringBuilder.append(" ");

                    // params only apply if there are no unselected/custom conditions
                    String parameters = checkerParams.get(checkerId);
                    if ((parameters != null) && (parameters.length() > 0)) {
                        stringBuilder.append(parameters);
                        stringBuilder.append(" ");
                    }
                }
                // Given that there are conditions disabled, create the command line block
                // to enable only the selected ones. Additionally, define the custom warning level
                // for that condition, if any
                List<Condition> allConditions = allConditionsMap.get(checkerId);
                if (allConditions != null) {
                    for (Condition condition : allConditions) {
                        if ((selectedConditions != null) && !selectedConditions.contains(condition)) {
                            //Condition is NOT selected => add it to -dc (disable condition) command
                            stringBuilder.append("-dc ");
                            stringBuilder.append(checkerId);
                            stringBuilder.append(".");
                            stringBuilder.append(condition.getId());
                            stringBuilder.append(" ");
                        }
                    }
                }

                /*
                 * Build the list of items that must have their warning levels changed
                 */
                // checker
                customWarningLevel = customCheckersWarningLevels.get(checkerId);
                if (customWarningLevel != null) {
                    if (customWarningLevel) {
                        elementsToIncreaseWarningLevel.add(checkerId);
                    } else {
                        elementsToDecreaseWarningLevel.add(checkerId);
                    }
                }
                // conditions
                for (Condition condition : ((selectedConditions != null) ? selectedConditions
                        : allConditionsMap.get(checkerId))) {
                    customWarningLevel = customConditionsWarningLevels.get(condition.getId());
                    if (customWarningLevel != null) {
                        if (customWarningLevel) {
                            elementsToIncreaseWarningLevel.add(checkerId + "." + condition.getId());
                        } else {
                            elementsToDecreaseWarningLevel.add(checkerId + "." + condition.getId());
                        }
                    }

                }

            }

            /*
             * Custom warning levels
             */
            stringBuilder.append(createCustomWarningLevelCommandLine(true, elementsToIncreaseWarningLevel));
            stringBuilder.append(createCustomWarningLevelCommandLine(false, elementsToDecreaseWarningLevel));

            commandline = stringBuilder.toString().trim();

        }

        return commandline;

    }

    /**
     * Create the command line piece which increases or decreases the warning level
     * for certain element (checker or condition)
     * 
     * @param increase true if the warning level must be increased, false if it must be decreased, null if the warning level must not change
     * @param element the element to have its warning level changed
     * @return the command line piece
     */
    public String createCustomWarningLevelCommandLine(Boolean increase, List<String> elements) {
        StringBuilder result = new StringBuilder();

        if ((increase != null) && (elements.size() > 0)) {
            if (increase) {
                result.append("-wx"); // increase
            } else {
                result.append("-xw"); // decrease
            }
            result.append(" ");
            for (String element : elements) {
                result.append(element);
                result.append(" ");
            }
        }

        return result.toString();
    }

    /**
     * Check if there are parameters set for any checker
     * 
     * @return true if there are parameters set, false otherwise
     */
    private boolean hasParameters() {
        boolean paramsFound = false;

        Iterator<String> it = checkerParams.values().iterator();
        while (it.hasNext() && !paramsFound) {
            String checkerParam = it.next();
            if (checkerParam.length() > 0) {
                paramsFound = true;
            }
        }

        return paramsFound;
    }

    /**
     * Check if there are unselected/custom conditions.
     * This is used to decide if the App Validator command line must be created or not
     * 
     * @return true if there are custom unselected/custom conditions, false otherwise
     */
    private boolean hasCustomConditions() {
        boolean result = false;

        for (String checkerId : allConditionsMap.keySet()) {
            List<Condition> selectedConditions = ((selectedConditionsMap.get(checkerId) != null)
                    ? selectedConditionsMap.get(checkerId)
                    : new ArrayList<Condition>());
            if (allConditionsMap.get(checkerId).size() != selectedConditions.size()) {
                result = true;
                break;
            }
        }

        return result;
    }

    /**
     * Check if there are custom warning levels
     * This is used to decide if the App Validator command line must be created or not
     * 
     * @return true if there are custom warning levels, false otherwise
     */
    private boolean hasCustomWarningLevels() {

        boolean result = false;

        List<Map<String, Boolean>> maps = new ArrayList<Map<String, Boolean>>();
        maps.add(customCheckersWarningLevels);
        maps.add(customConditionsWarningLevels);

        for (Map<String, Boolean> map : maps) {
            for (Boolean customWarningLevel : map.values()) {
                if (customWarningLevel != null) {
                    result = true;
                    break;
                }
            }
        }

        return result;
    }
}