/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Cameron Bateman/Oracle - adapted for use in JSF validation tooling
 *******************************************************************************/
package org.eclipse.jst.jsf.ui.internal.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jst.jsf.core.internal.IJSFPreferenceModel;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.ui.internal.JSFUiPlugin;
import org.eclipse.jst.jsf.validation.internal.Severity;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.ui.preferences.IWorkingCopyManager;
import org.eclipse.ui.preferences.WorkingCopyManager;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Abstract options configuration block providing a general implementation for setting up
 * an options configuration page.
 * 
 * @since 2.1
 */
abstract class OptionsConfigurationBlock 
{
    /**
     * The preference model to be used
     */
    protected final IJSFPreferenceModel     _prefs;
    
    static final class Key 
    {
        private String fQualifier;
        private String fKey;
        
        Key(String qualifier, String key) {
            fQualifier= qualifier;
            fKey= key;
        }
        
        /**
         * @return the key name
         */
        public String getName() {
            return fKey;
        }
        
//        private IEclipsePreferences getNode(IScopeContext context, IWorkingCopyManager manager) {
//            IEclipsePreferences node= context.getNode(fQualifier);
//            if (manager != null) {
//                return manager.getWorkingCopy(node);
//            }
//            return node;
//            
//        }
        
        /**
         * @param prefModel
         * @param context
         * @param manager
         * @return the value stored for the key
         */
        public Object getStoredValue(IJSFPreferenceModel prefModel, IScopeContext context, IWorkingCopyManager manager)
        {
            return prefModel.getStoredValueByKey(context, fKey);
        }
        
        /**
         * @param prefModel
         * @param context
         * @param manager
         * @return the stored value in prefModel under context for
         * this key
         */
        public Object getCurValue(IJSFPreferenceModel prefModel, IScopeContext context, IWorkingCopyManager manager) {
            //return getNode(context, manager).get(fKey, null);
            return prefModel.getValueByKey(context, fKey);
        }
        
        /**
         * @param prefModel
         * @param lookupOrder
         * @param ignoreTopScope
         * @param manager
         * @return the stored value in the prefModelunder context
         * using the list of lookupOrder for precedence of scopes
         * in which to look.  Return first found based on order in lookupOrder
         */
        public Object getCurValue(IJSFPreferenceModel prefModel, IScopeContext[] lookupOrder, boolean ignoreTopScope, IWorkingCopyManager manager) {
            for (int i= ignoreTopScope ? 1 : 0; i < lookupOrder.length; i++) {
                Object value= getCurValue(prefModel, lookupOrder[i], manager);
                if (value != null) {
                    return value;
                }
            }
            return null;
        }
        
        /**
         * Set the stored value
         * @param prefModel 
         * @param context
         * @param value
         * @param manager
         * @return the old value or null if none
         */
        public Object setCurValue(IJSFPreferenceModel prefModel, IScopeContext context, Object value, IWorkingCopyManager manager) {
            return prefModel.setValueByKey(context, fKey, value);
//            if (value != null) {
//                getNode(context, manager).put(fKey, value);
//            } else {
//                getNode(context, manager).remove(fKey);
//            }
        }
            
        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        public String toString() {
            return fQualifier + '/' + fKey;
        }

        /**
         * @return the plugin qualifier
         */
        public String getQualifier() {
            return fQualifier;
        }

    }
    

    static class ControlData {
        private Key fKey;
        private String[] fValues;
        
        ControlData(Key key, String[] values) {
            fKey= key;
            fValues= values;
        }
        
        Key getKey() {
            return fKey;
        }
        
        String getValue(boolean selection) {
            int index= selection ? 0 : 1;
            return fValues[index];
        }
        
        String getValue(int index) {
            return fValues[index];
        }       
        
        int getSelection(String value) {
            if (value != null) {
                for (int i= 0; i < fValues.length; i++) {
                    if (value.equals(fValues[i])) {
                        return i;
                    }
                }
            }
            return fValues.length -1; // assume the last option is the least severe
        }
    }
    
    private static final String REBUILD_COUNT_KEY= "preferences_build_requested"; //$NON-NLS-1$
    
    private static final String SETTINGS_EXPANDED= "expanded"; //$NON-NLS-1$

    private final ArrayList fCheckBoxes;
    private final ArrayList fComboBoxes;
    private final ArrayList fTextBoxes;
    private final HashMap fLabels;
    private final ArrayList fExpandedComposites;
    
    private SelectionListener fSelectionListener;
    private ModifyListener fTextModifyListener;

    // TODO: protected IStatusChangeListener fContext;
    private final IProject fProject; // project or null
    private final Key[] fAllKeys;
    
    private IScopeContext[] fLookupOrder;
    
    private Shell fShell;

    private final IWorkingCopyManager fManager;
    private IWorkbenchPreferenceContainer fContainer;

    private Map fDisabledProjectSettings; // null when project specific settings are turned off
    
    private int fRebuildCount; /// used to prevent multiple dialogs that ask for a rebuild
    
    OptionsConfigurationBlock(/*IStatusChangeListener context,*/IJSFPreferenceModel prefs, IProject project, Key[] allKeys, IWorkbenchPreferenceContainer container) {
        //fContext= context;
        fProject= project;
        fAllKeys= allKeys;
        fContainer= container;
        _prefs = prefs;
        
        if (container == null) {
            fManager= new WorkingCopyManager();
        } else {
            fManager= container.getWorkingCopyManager();
        }
        
        if (fProject != null) {
            fLookupOrder= new IScopeContext[] {
                new ProjectScope(fProject),
                new InstanceScope(),
                new DefaultScope()
            };
        } else {
            fLookupOrder= new IScopeContext[] {
                new InstanceScope(),
                new DefaultScope()
            };
        }
        
        testIfOptionsComplete(allKeys);
        if (fProject == null || hasProjectSpecificOptions(fProject)) {
            fDisabledProjectSettings= null;
        } else {
            fDisabledProjectSettings= new IdentityHashMap();
            for (int i= 0; i < allKeys.length; i++) {
                Key curr= allKeys[i];
                fDisabledProjectSettings.put(curr, curr.getCurValue(_prefs, fLookupOrder, false, fManager));
            }
        }
        
        fCheckBoxes= new ArrayList();
        fComboBoxes= new ArrayList();
        fTextBoxes= new ArrayList(2);
        fLabels= new HashMap();
        fExpandedComposites= new ArrayList();
        
        fRebuildCount= getRebuildCount();
    }   
    
    /**
     * @return the preference container
     */
    protected final IWorkbenchPreferenceContainer getPreferenceContainer() {
        return fContainer;
    }
    
    /**
     * @param plugin
     * @param key
     * @return construct a new Key based on the on the plugin id and
     * preference key
     */
    protected static Key getKey(String plugin, String key) {
        return new Key(plugin, key);
    }
    
    /**
     * @param key
     * @return construct a new Key for a JSF core plugin preference
     */
    protected final static Key getJSFCoreKey(String key) {
        return getKey(JSFCorePlugin.PLUGIN_ID, key);
    }
    
    private void testIfOptionsComplete(Key[] allKeys) {
        for (int i= 0; i < allKeys.length; i++) {
            if (allKeys[i].getCurValue(_prefs, fLookupOrder, false, fManager) == null) {
                JSFUiPlugin.log(IStatus.ERROR, "preference option missing: " + allKeys[i] + " (" + this.getClass().getName() +')');  //$NON-NLS-1$//$NON-NLS-2$
            }
        }
    }
    
    private int getRebuildCount() {
        return fManager.getWorkingCopy(new DefaultScope().getNode(JavaUI.ID_PLUGIN)).getInt(REBUILD_COUNT_KEY, 0);
    }
    
    private void incrementRebuildCount() {
        fRebuildCount++;
        fManager.getWorkingCopy(new DefaultScope().getNode(JavaUI.ID_PLUGIN)).putInt(REBUILD_COUNT_KEY, fRebuildCount);
    }
    
//    public void selectOption(String key, String qualifier) {
//        for (int i= 0; i < fAllKeys.length; i++) {
//            Key curr= fAllKeys[i];
//            if (curr.getName().equals(key) && curr.getQualifier().equals(qualifier)) {
//                selectOption(curr);
//            }
//        }
//    }
//    
//    public void selectOption(Key key) {
//        Control control= findControl(key);
//        if (control != null) {
//            if (!fExpandedComposites.isEmpty()) {
//                ExpandableComposite expandable= getParentExpandableComposite(control);
//                if (expandable != null) {
//                    for (int i= 0; i < fExpandedComposites.size(); i++) {
//                        ExpandableComposite curr= (ExpandableComposite) fExpandedComposites.get(i);
//                        curr.setExpanded(curr == expandable);
//                    }
//                    expandedStateChanged(expandable);
//                }
//            }
//            control.setFocus();
//        }
//    }
    
    
    /**
     * @param project
     * @return true if there are project specific overrides in the 
     * preferences for 'project'
     */
    public final boolean hasProjectSpecificOptions(IProject project) {
        if (project != null) {
            IScopeContext projectContext= new ProjectScope(project);
            Key[] allKeys= fAllKeys;
            for (int i= 0; i < allKeys.length; i++) {
                if (allKeys[i].getCurValue(_prefs, projectContext, fManager) != null) {
                    return true;
                }
            }
        }
        return false;
    }   
            
    /**
     * @return the shell hosting the UI
     */
    protected Shell getShell() {
        return fShell;
    }
    
    /**
     * Set the shell hosting the UI.
     * @param shell
     */
    protected void setShell(Shell shell) {
        fShell= shell;
    }   
    
    /**
     * @param parent
     * @return the parent of the UI control to be created
     */
    protected abstract Control createContents(Composite parent);
    
//    protected Button addCheckBox(Composite parent, String label, Key key, String[] values, int indent) {
//        ControlData data= new ControlData(key, values);
//        
//        GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
//        gd.horizontalSpan= 3;
//        gd.horizontalIndent= indent;
//        
//        Button checkBox= new Button(parent, SWT.CHECK);
//        checkBox.setFont(JFaceResources.getDialogFont());
//        checkBox.setText(label);
//        checkBox.setData(data);
//        checkBox.setLayoutData(gd);
//        checkBox.addSelectionListener(getSelectionListener());
//        
//        makeScrollableCompositeAware(checkBox);
//        
//        String currValue= getValue(key);
//        checkBox.setSelection(data.getSelection(currValue) == 0);
//        
//        fCheckBoxes.add(checkBox);
//        
//        return checkBox;
//    }
    
    /**
     * @param parent
     * @param label
     * @param key
     * @param values
     * @param indent
     * @param widthHint
     * @param listener
     * @return a check box styled button with a related link
     */
    protected Button addCheckBoxWithLink(Composite parent, String label, Key key, String[] values, int indent, int widthHint, SelectionListener listener) {
        ControlData data= new ControlData(key, values);
        
        GridData gd= new GridData(GridData.FILL, GridData.FILL, true, false);
        gd.horizontalSpan= 3;
        gd.horizontalIndent= indent;
        
        Composite composite= new Composite(parent, SWT.NONE);
        GridLayout layout= new GridLayout();
        layout.marginHeight= 0;
        layout.marginWidth= 0;
        layout.numColumns= 2;
        composite.setLayout(layout);
        composite.setLayoutData(gd);
        
        Button checkBox= new Button(composite, SWT.CHECK);
        checkBox.setFont(JFaceResources.getDialogFont());
        checkBox.setData(data);
        checkBox.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false));
        checkBox.addSelectionListener(getSelectionListener());
        
        gd= new GridData(GridData.FILL, GridData.CENTER, true, false);
        gd.widthHint= widthHint;
        
        Link link= new Link(composite, SWT.NONE);
        link.setText(label);
        link.setLayoutData(gd);
        if (listener != null) {
            link.addSelectionListener(listener);
        }
        
        makeScrollableCompositeAware(link);
        makeScrollableCompositeAware(checkBox);
        
        String currValue= getValue(key);
        checkBox.setSelection(data.getSelection(currValue) == 0);
        
        fCheckBoxes.add(checkBox);
        
        return checkBox;
    }
    
    /**
     * @param parent
     * @param label
     * @param key
     * @param values
     * @param valueLabels
     * @param indent
     * @return a Combo box added to parent with the label and key
     */
    protected Combo addComboBox(Composite parent, String label, Key key, String[] values, String[] valueLabels, int indent) {
        GridData gd= new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1);
        gd.horizontalIndent= indent;
                
        Label labelControl= new Label(parent, SWT.LEFT);
        labelControl.setFont(JFaceResources.getDialogFont());
        
        labelControl.setText(label);
        labelControl.setLayoutData(gd);
                
        Combo comboBox= newComboControl(parent, key, values, valueLabels);
        comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

        fLabels.put(comboBox, labelControl);
        
        return comboBox;
    }
    
    Combo addInversedComboBox(Composite parent, String label, Key key, String[] values, String[] valueLabels, int indent) {
        GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gd.horizontalIndent= indent;
        gd.horizontalSpan= 3;
        
        Composite composite= new Composite(parent, SWT.NONE);
        GridLayout layout= new GridLayout();
        layout.marginHeight= 0;
        layout.marginWidth= 0;
        layout.numColumns= 2;
        composite.setLayout(layout);
        composite.setLayoutData(gd);
        
        Combo comboBox= newComboControl(composite, key, values, valueLabels);
        comboBox.setFont(JFaceResources.getDialogFont());
        comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
        
        Label labelControl= new Label(composite, SWT.LEFT | SWT.WRAP);
        labelControl.setText(label);
        labelControl.setLayoutData(new GridData());
        
        fLabels.put(comboBox, labelControl);
        return comboBox;
    }
    
    Combo newComboControl(Composite composite, Key key, String[] values, String[] valueLabels) {
        ControlData data= new ControlData(key, values);
        
        Combo comboBox= new Combo(composite, SWT.READ_ONLY);
        comboBox.setItems(valueLabels);
        comboBox.setData(data);
        comboBox.addSelectionListener(getSelectionListener());
        comboBox.setFont(JFaceResources.getDialogFont());
            
        makeScrollableCompositeAware(comboBox);
        
        String currValue= getValue(key);    
        comboBox.select(data.getSelection(currValue));
        
        fComboBoxes.add(comboBox);
        return comboBox;
    }

    Text addTextField(Composite parent, String label, Key key, int indent, int widthHint) {   
        Label labelControl= new Label(parent, SWT.WRAP);
        labelControl.setText(label);
        labelControl.setFont(JFaceResources.getDialogFont());
        labelControl.setLayoutData(new GridData());
                
        Text textBox= new Text(parent, SWT.BORDER | SWT.SINGLE);
        textBox.setData(key);
        textBox.setLayoutData(new GridData());
        
        makeScrollableCompositeAware(textBox);
        
        fLabels.put(textBox, labelControl);
        
        String currValue= getValue(key);    
        if (currValue != null) {
            textBox.setText(currValue);
        }
        textBox.addModifyListener(getTextModifyListener());

        GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        if (widthHint != 0) {
            data.widthHint= widthHint;
        }
        data.horizontalIndent= indent;
        data.horizontalSpan= 2;
        textBox.setLayoutData(data);

        fTextBoxes.add(textBox);
        return textBox;
    }
    
    ScrolledPageContent getParentScrolledComposite(Control control) {
        Control parent= control.getParent();
        while (!(parent instanceof ScrolledPageContent) && parent != null) {
            parent= parent.getParent();
        }
        if (parent instanceof ScrolledPageContent) {
            return (ScrolledPageContent) parent;
        }
        return null;
    }
    
    ExpandableComposite getParentExpandableComposite(Control control) {
        Control parent= control.getParent();
        while (!(parent instanceof ExpandableComposite) && parent != null) {
            parent= parent.getParent();
        }
        if (parent instanceof ExpandableComposite) {
            return (ExpandableComposite) parent;
        }
        return null;
    }
    
    private void makeScrollableCompositeAware(Control control) {
        ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(control);
        if (parentScrolledComposite != null) {
            parentScrolledComposite.adaptChild(control);
        }
    }
    
    ExpandableComposite createStyleSection(Composite parent, String label, int nColumns) {
        ExpandableComposite excomposite= new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
        excomposite.setText(label);
        excomposite.setExpanded(false);
        excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
        excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1));
        excomposite.addExpansionListener(new ExpansionAdapter() {
            public void expansionStateChanged(ExpansionEvent e) {
                expandedStateChanged((ExpandableComposite) e.getSource());
            }
        });
        fExpandedComposites.add(excomposite);
        makeScrollableCompositeAware(excomposite);
        return excomposite;
    }
    
    final void expandedStateChanged(ExpandableComposite expandable) {
        ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(expandable);
        if (parentScrolledComposite != null) {
            parentScrolledComposite.reflow(true);
        }
    }
    
    void restoreSectionExpansionStates(IDialogSettings settings) {
        for (int i= 0; i < fExpandedComposites.size(); i++) {
            ExpandableComposite excomposite= (ExpandableComposite) fExpandedComposites.get(i);
            if (settings == null) {
                excomposite.setExpanded(i == 0); // only expand the first node by default
            } else {
                excomposite.setExpanded(settings.getBoolean(SETTINGS_EXPANDED + String.valueOf(i)));
            }
        }
    }
    
    void storeSectionExpansionStates(IDialogSettings settings) {
        for (int i= 0; i < fExpandedComposites.size(); i++) {
            ExpandableComposite curr= (ExpandableComposite) fExpandedComposites.get(i);
            settings.put(SETTINGS_EXPANDED + String.valueOf(i), curr.isExpanded());
        }
    }
    
    SelectionListener getSelectionListener() {
        if (fSelectionListener == null) {
            fSelectionListener= new SelectionListener() {
                public void widgetDefaultSelected(SelectionEvent e) {/*do nothing*/}
    
                public void widgetSelected(SelectionEvent e) {
                    controlChanged(e.widget);
                }
            };
        }
        return fSelectionListener;
    }
    
    ModifyListener getTextModifyListener() {
        if (fTextModifyListener == null) {
            fTextModifyListener= new ModifyListener() {
                public void modifyText(ModifyEvent e) {
                    textChanged((Text) e.widget);
                }
            };
        }
        return fTextModifyListener;
    }       
    
    void controlChanged(Widget widget) {
        ControlData data= (ControlData) widget.getData();
        String newValue= null;
        if (widget instanceof Button) {
            newValue= data.getValue(((Button)widget).getSelection());           
        } else if (widget instanceof Combo) {
            newValue= data.getValue(((Combo)widget).getSelectionIndex());
        } else {
            return;
        }
        String oldValue= setValue(data.getKey(), newValue);
        validateSettings(data.getKey(), oldValue, newValue);
    }
    
    void textChanged(Text textControl) {
        Key key= (Key) textControl.getData();
        String number= textControl.getText();
        String oldValue= setValue(key, number);
        validateSettings(key, oldValue, number);
    }   

    boolean checkValue(Key key, String value) {
        return value.equals(getValue(key));
    }
    
    String getValue(Key key) {
        if (fDisabledProjectSettings != null) {
            return (String) fDisabledProjectSettings.get(key);
        }
        return key.getCurValue(_prefs, fLookupOrder, false, fManager).toString();
    }
    
    
    boolean getBooleanValue(Key key) {
        return Boolean.valueOf(getValue(key)).booleanValue();
    }
    
    String setValue(Key key, String value) {
        if (fDisabledProjectSettings != null) {
            return (String) fDisabledProjectSettings.put(key, value);
        }
        Object newValue =  key.setCurValue(_prefs, fLookupOrder[0], Severity.valueOfString(value), fManager);
        return newValue != null ? newValue.toString() : ""; //$NON-NLS-1$
    }
    
    String setValue(Key key, boolean value) {
        return setValue(key, String.valueOf(value));
    }

    /**
     * Returns the value as actually stored in the preference store.
     * @param key
     * @return the value as actually stored in the preference store.
     */
    Object getStoredValue(Key key) {
        return key.getCurValue(_prefs, fLookupOrder, false, fManager);
    }
    
    /**
     * Update fields and validate.
     * @param changedKey Key that changed, or null, if all changed.
     * @param oldValue 
     * @param newValue 
     */ 
    protected abstract void validateSettings(Key changedKey, String oldValue, String newValue);
    
    
    String[] getTokens(String text, String separator) {
        StringTokenizer tok= new StringTokenizer(text, separator); 
        int nTokens= tok.countTokens();
        String[] res= new String[nTokens];
        for (int i= 0; i < res.length; i++) {
            res[i]= tok.nextToken().trim();
        }
        return res;
    }

    private boolean getChanges(IScopeContext currContext, List changedSettings) {
        boolean needsBuild= false;
        for (int i= 0; i < fAllKeys.length; i++) {
            Key key= fAllKeys[i];
            Object oldVal= key.getStoredValue(_prefs, currContext, null);
            Object val= key.getCurValue(_prefs, currContext, fManager);
            if (val == null) {
                if (oldVal != null) {
                    changedSettings.add(key);
                    needsBuild |= !oldVal.equals(key.getCurValue(_prefs, fLookupOrder, true, fManager));
                }
            } else if (!val.equals(oldVal)) {
                changedSettings.add(key);
                needsBuild |= oldVal != null || !val.equals(key.getCurValue(_prefs, fLookupOrder, true, fManager));
            }
        }
        return needsBuild;
    }
    
    void useProjectSpecificSettings(boolean enable) {
        boolean hasProjectSpecificOption= fDisabledProjectSettings == null;
        if (enable != hasProjectSpecificOption && fProject != null) {
            if (enable) {
                for (int i= 0; i < fAllKeys.length; i++) {
                    Key curr= fAllKeys[i];
                    String val= (String) fDisabledProjectSettings.get(curr);
                    curr.setCurValue(_prefs, fLookupOrder[0], Severity.valueOfString(val), fManager);
                }
                fDisabledProjectSettings= null;
                updateControls();
                validateSettings(null, null, null);
            } else {
                fDisabledProjectSettings= new IdentityHashMap();
                for (int i= 0; i < fAllKeys.length; i++) {
                    Key curr= fAllKeys[i];
                    Object oldSetting= curr.getCurValue(_prefs, fLookupOrder, false, fManager);
                    fDisabledProjectSettings.put(curr, oldSetting);
                    curr.setCurValue(_prefs, fLookupOrder[0], null, fManager); // clear project settings
                }
            }
        }
    }
    
    boolean areSettingsEnabled() {
        return fDisabledProjectSettings == null || fProject == null;
    }
    
    
    boolean performOk() {
        return processChanges(fContainer);
    }
    
//    public boolean performApply() {
//        return processChanges(null); // apply directly
//    }
    
    boolean processChanges(IWorkbenchPreferenceContainer container) {
        IScopeContext currContext= fLookupOrder[0];
        
        List /* <Key>*/ changedOptions= new ArrayList();
        boolean needsBuild= getChanges(currContext, changedOptions);
        if (changedOptions.isEmpty()) {
            return true;
        }
        if (needsBuild) {
            int count= getRebuildCount();
            if (count > fRebuildCount) {
                needsBuild= false; // build already requested
                fRebuildCount= count;
            }
        }

        boolean doBuild= false;
        
        final String  showBuildWarningKey = JSFCorePlugin.PLUGIN_ID + "." + "buildwarning_dont_show_again"; //$NON-NLS-1$ //$NON-NLS-2$
        final IPreferenceStore prefStore = JSFCorePlugin.getDefault().getPreferenceStore();
        final boolean showDialog = !MessageDialogWithToggle.ALWAYS.equals(prefStore.getString(showBuildWarningKey));
        
        if (needsBuild && showDialog) {
            String[] strings= getFullBuildDialogStrings(fProject == null);
            if (strings != null) {
                MessageDialogWithToggle.openInformation
                	(getShell(), strings[0], strings[1], 
                			PreferencesMessages.ProblemSeveritiesConfigurationBlock_buildwarning_dont_show_again
                			, false, prefStore, showBuildWarningKey);
//                int res= dialog.open();
//                if (res == 0) {
//                    doBuild= true;
//                } else if (res != 1) {
//                    return false; // cancel pressed
//                }
            }
        }
        if (container != null) {
            // no need to apply the changes to the original store: will be done by the page container
            if (doBuild) { // post build
                incrementRebuildCount();
                // TODO: container.registerUpdateJob(CoreUtility.getBuildJob(fProject));
            }
        } else {
            // apply changes right away
            try {
                fManager.applyChanges();
            } catch (BackingStoreException e) {
                JSFUiPlugin.log(IStatus.ERROR, "Error applying changes", e); //$NON-NLS-1$
                return false;
            }
            if (doBuild) {
                //CoreUtility.getBuildJob(fProject).schedule();
            }
            
        }
        return true;
    }
    
    abstract String[] getFullBuildDialogStrings(boolean workspaceSettings);
            
    
//    public void performDefaults() {
//        for (int i= 0; i < fAllKeys.length; i++) {
//            Key curr= fAllKeys[i];
//            String defValue= curr.getStoredValue(fLookupOrder, true, fManager);
//            setValue(curr, defValue);
//        }
//        
//        settingsUpdated();
//        updateControls();
//        validateSettings(null, null, null);
//    }

    /**
     * @since 3.1
     */
    void performRevert() {
        for (int i= 0; i < fAllKeys.length; i++) {
            Key curr= fAllKeys[i];
            String origValue= curr.getCurValue(_prefs, fLookupOrder, false, null).toString();
            setValue(curr, origValue);
        }

        updateControls();
        validateSettings(null, null, null);
    }
    
    void dispose() {
        // do nothing; sub-class should override
    }
    
    void updateControls() {
        // update the UI
        for (int i= fCheckBoxes.size() - 1; i >= 0; i--) {
            updateCheckBox((Button) fCheckBoxes.get(i));
        }
        for (int i= fComboBoxes.size() - 1; i >= 0; i--) {
            updateCombo((Combo) fComboBoxes.get(i));
        }
        for (int i= fTextBoxes.size() - 1; i >= 0; i--) {
            updateText((Text) fTextBoxes.get(i));
        }
    }
    
    void updateCombo(Combo curr) {
        ControlData data= (ControlData) curr.getData();
        
        String currValue= getValue(data.getKey());  
        curr.select(data.getSelection(currValue));                  
    }
    
    void updateCheckBox(Button curr) {
        ControlData data= (ControlData) curr.getData();
        
        String currValue= getValue(data.getKey());  
        curr.setSelection(data.getSelection(currValue) == 0);                       
    }
    
    void updateText(Text curr) {
        Key key= (Key) curr.getData();
        
        String currValue= getValue(key);
        if (currValue != null) {
            curr.setText(currValue);
        }
    }
    
    Button getCheckBox(Key key) {
        for (int i= fCheckBoxes.size() - 1; i >= 0; i--) {
            Button curr= (Button) fCheckBoxes.get(i);
            ControlData data= (ControlData) curr.getData();
            if (key.equals(data.getKey())) {
                return curr;
            }
        }
        return null;        
    }
    
    Combo getComboBox(Key key) {
        for (int i= fComboBoxes.size() - 1; i >= 0; i--) {
            Combo curr= (Combo) fComboBoxes.get(i);
            ControlData data= (ControlData) curr.getData();
            if (key.equals(data.getKey())) {
                return curr;
            }
        }
        return null;        
    }
    
    Text getTextControl(Key key) {
        for (int i= fTextBoxes.size() - 1; i >= 0; i--) {
            Text curr= (Text) fTextBoxes.get(i);
            ControlData data= (ControlData) curr.getData();
            if (key.equals(data.getKey())) {
                return curr;
            }
        }
        return null;        
    }
    
    Control findControl(Key key) {
        Combo comboBox= getComboBox(key);
        if (comboBox != null) {
            return comboBox;
        }
        Button checkBox= getCheckBox(key);
        if (checkBox != null) {
            return checkBox;
        }
        Text text= getTextControl(key);
        if (text != null) {
            return text;
        }
        return null;
    }
    
    void setComboEnabled(Key key, boolean enabled) {
        Combo combo= getComboBox(key);
        Label label= (Label) fLabels.get(combo);
        combo.setEnabled(enabled);
        label.setEnabled(enabled);
    }
}
