/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.preferences.formatter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
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.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Twistie;

import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaUI;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.preferences.FilteredPreferenceTree;
import org.eclipse.jdt.internal.ui.preferences.FilteredPreferenceTree.HighlightHelper;
import org.eclipse.jdt.internal.ui.preferences.FilteredPreferenceTree.PreferenceTreeNode;
import org.eclipse.jdt.internal.ui.preferences.PreferencesMessages;
import org.eclipse.jdt.internal.ui.preferences.formatter.IModifyDialogTabPage.IModificationListener;
import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.CustomProfile;
import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.Profile;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.util.SWTUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;

public abstract class ModifyDialog extends StatusDialog implements IModificationListener {

	protected static class Section extends PreferenceTreeNode<ExpandableComposite> {
		protected final Composite fInnerComposite;

		private final String fPreviewKey;

		private final Control fToggle;

		public static Section create(Composite parentComposite, String label, String previewKey) {
			final ExpandableComposite excomposite= new ExpandableComposite(parentComposite, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT) {
				// don't expand/collapse when click on header label gives focus
				boolean fHasFocusBeforeClick= false;
				boolean fExpandLock= false;
				{
					textLabel.addListener(SWT.MouseEnter, e -> fHasFocusBeforeClick= toggle.isFocusControl());
					textLabel.addListener(SWT.MouseDown, e -> fExpandLock= !fHasFocusBeforeClick || e.button != 1);
				}

				@Override
				protected void internalSetExpanded(boolean expanded) {
					if (fExpandLock) {
						toggle.setExpanded(isExpanded());
						fHasFocusBeforeClick= true;
						fExpandLock= false;
					} else {
						super.internalSetExpanded(expanded);
					}
				}

				@Override
				public void setMenu(Menu menu) {
					// add only to header, not the rest of the composite
					textLabel.setMenu(menu);
				}
			};
			excomposite.clientVerticalSpacing= 0;
			excomposite.setText(label);
			excomposite.setExpanded(false);
			excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
			excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, GRID_COLUMNS, 1));

			Composite inner= new Composite(excomposite, SWT.NONE);
			inner.setFont(parentComposite.getFont());
			GridLayout layout= new GridLayout(GRID_COLUMNS, false);
			layout.marginWidth= 0;
			layout.marginLeft= 5;
			inner.setLayout(layout);
			excomposite.setClient(inner);
			return new Section(label, excomposite, inner, previewKey);
		}

		private Section(String label, ExpandableComposite control, Composite innerComposite, String previewKey) {
			super(label, control, false);
			fInnerComposite= innerComposite;
			fPreviewKey= previewKey;

			Control toggle= null;
			for (Control child : control.getChildren()) {
				if (child instanceof Twistie)
					toggle= child;
			}
			assert toggle != null;
			fToggle= toggle;

			// clicking inside section should bring it to focus
			final MouseAdapter mouseListener= new MouseAdapter() {
				@Override
				public void mouseDown(MouseEvent e) {
					if (e.getSource() == fControl && e.x < fControl.getClient().getLocation().x)
						return;
					if (e.getSource() == fControl.getClient() && e.x < getChildren().get(0).getControl().getLocation().x)
						return;
					fToggle.setFocus();
				}
			};
			control.addMouseListener(mouseListener);
			control.getClient().addMouseListener(mouseListener);

			// section with focus should be emphasized to show where current preview comes from
			fToggle.addFocusListener(new FocusListener() {
				@Override
				public void focusLost(FocusEvent e) {
					Display.getCurrent().asyncExec(() -> changeFont(false));
				}

				@Override
				public void focusGained(FocusEvent e) {
					Display.getCurrent().asyncExec(() -> changeFont(true));
				}

				private void changeFont(boolean italic) {
					FontData fontData= fControl.getFont().getFontData()[0];
					Font font= new Font(fControl.getDisplay(), new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD + (italic ? SWT.ITALIC : 0)));
					fControl.setFont(font);
					fControl.layout();
				}
			});
		}

		public String getKey() {
			return fPreviewKey;
		}

		public Control getToggle() {
			return fToggle;
		}
	}

	protected abstract static class ModifyAll<T extends Control> {
		private final Section fSection;

		private final Composite fModifyAllPanel;

		protected final T fControl;

		public ModifyAll(Section section, Images images) {
			fSection= section;

			final ExpandableComposite excomposite= section.getControl();
			Composite modifyAllParent= new Composite(excomposite, SWT.NONE);
			excomposite.setTextClient(modifyAllParent);
			RowLayout rowLayout= new RowLayout();
			rowLayout.marginTop= rowLayout.marginBottom= rowLayout.marginRight= 0;
			rowLayout.center= true;
			rowLayout.spacing= 1;
			modifyAllParent.setLayout(rowLayout);

			fModifyAllPanel= new Composite(modifyAllParent, SWT.NONE);
			fModifyAllPanel.setLayout(rowLayout);
			fModifyAllPanel.setVisible(false);
			fControl= createControl(fModifyAllPanel);

			ToolItem item= createToolItem(modifyAllParent, images);
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					fModifyAllPanel.setVisible(!fModifyAllPanel.isVisible());
					if (fModifyAllPanel.isVisible()) {
						excomposite.setFocus(); // force preview update
						prepareControl();
						fControl.requestLayout();
						fControl.setFocus();
					}
				}
			});
			fControl.addFocusListener(new FocusAdapter() {
				@Override
				public void focusLost(FocusEvent e) {
					fModifyAllPanel.setVisible(false);
				}
			});
		}

		protected abstract T createControl(Composite parent);

		protected abstract void prepareControl();

		protected <P extends Preference<T>> List<P> findPreferences(Class<P> prefClass) {
			List<P> result= new ArrayList<>();
			ArrayDeque<PreferenceTreeNode<?>> queue= new ArrayDeque<>();
			queue.add(fSection);
			while (!queue.isEmpty()) {
				PreferenceTreeNode<?> node= queue.removeFirst();
				if (!node.isVisible())
					continue;
				if (prefClass.isInstance(node))
					result.add(prefClass.cast(node));
				queue.addAll(node.getChildren());
			}
			return result;
		}

		static ToolItem createToolItem(Composite parent, Images images) {
			ToolBar toolBar= new ToolBar(parent, SWT.FLAT);
			ToolItem item= new ToolItem(toolBar, SWT.PUSH);
			item.setToolTipText(FormatterMessages.ModifyDialog_modifyAll_tooltip);
			item.setImage(images.get(JavaPluginImages.DESC_ELCL_MODIFYALL));
			return item;
		}
	}

	protected abstract static class Preference<T extends Control> extends PreferenceTreeNode<T> {

		private Map<String, String> fWorkingValues;

		private Predicate<String> fValueValidator;
		protected Runnable fValueChangeListener;

		private String fKey;

		private Map<PreferenceTreeNode<?>, Predicate<String>> fDependants= new HashMap<>();

		public Preference(T control, String label, String key, ValueMatcher<T> valueMatcher) {
			super(label, control, true, valueMatcher);
			assert key != null;
			fKey= key;
		}

		protected void init(Map<String, String> workingValues, Predicate<String> valueValidator, Runnable valueChangeListener) {
			fWorkingValues= workingValues;
			fValueValidator= valueValidator;
			fValueChangeListener= valueChangeListener;
			updateWidget();

			fControl.addFocusListener(new FocusAdapter() {
				@Override
				public void focusLost(FocusEvent e) {
					fValueValidator.test(null);
				}
			});
		}

		protected Map<String, String> getPreferences() {
			return fWorkingValues;
		}

		public void setValueValidator(Predicate<String> valueValidator) {
			fValueValidator = valueValidator;
		}

		/**
		 * Set the key which is used to store the value.
		 * 
		 * @param key New value
		 */
		public final void setKey(String key) {
			assert key != null;
			fKey= key;
			updateWidget();
		}

		/**
		 * @return Gets the currently used key which is used to store the value.
		 */
		public final String getKey() {
			return fKey;
		}

		public void addDependant(PreferenceTreeNode<?> dependentChild, Predicate<String> dependencyChecker) {
			fDependants.put(dependentChild, dependencyChecker);
			if (fWorkingValues != null)
				updateDependants();
		}

		/**
		 * To be implemented in subclasses. Update the SWT widgets when the state of this object has changed
		 * (enabled, key, ...).
		 */
		protected abstract void updateWidget();

		protected abstract String getValue();

		protected void updateValue() {
			String newValue= getValue();
			String oldValue= fWorkingValues.put(fKey, newValue);
			if (fValueValidator.test(newValue)) {
				updateDependants();
				fValueChangeListener.run();
			} else {
				fWorkingValues.put(fKey, oldValue);
			}
		}

		private void updateDependants() {
			for (Entry<PreferenceTreeNode<?>, Predicate<String>> entry : fDependants.entrySet()) {
				PreferenceTreeNode<?> dependant= entry.getKey();
				Predicate<String> dependencyChecker= entry.getValue();
				dependant.setEnabled(dependencyChecker.test(fWorkingValues.get(fKey)));
			}
		}

		@Override
		public void setEnabled(boolean enabled) {
			super.setEnabled(enabled);
			if (enabled)
				updateDependants();
		}

		protected void addLabel(String label, boolean highlight, int indent) {
			if (label == null)
				return;
			Label labelControl= createLabel(GRID_COLUMNS - 2, fControl.getParent(), label, indent);
			labelControl.moveAbove(fControl);
			if (highlight)
				HighlightHelper.addHighlight(labelControl, fControl);
			addChild(new PreferenceTreeNode<>(label, labelControl, true));
		}
	}

	/**
	 * Wrapper around a checkbox with a label.
	 */
	protected static final class CheckboxPreference extends Preference<Button> {
		/**
		 * Constant array for boolean false/true selection.
		 */
		public static final String[] FALSE_TRUE= { DefaultCodeFormatterConstants.FALSE, DefaultCodeFormatterConstants.TRUE };

		/**
		 * Constant array for boolean true/false selection.
		 */
		public static final String[] TRUE_FALSE= { DefaultCodeFormatterConstants.TRUE, DefaultCodeFormatterConstants.FALSE };

		/**
		 * Constant array for insert / not_insert.
		 */
		public static final String[] DO_NOT_INSERT_INSERT= { JavaCore.DO_NOT_INSERT, JavaCore.INSERT };

		private final String[] fValues;

		/**
		 * Create a new CheckboxPreference.
		 * 
		 * @param parentComposite The composite on which the SWT widgets are added.
		 * @param indent how many levels of indentation to apply.
		 * @param label The label text for this Preference.
		 * @param key The key to store the values.
		 * @param values An array of two elements indicating the values to store when unchecked/checked.
		 * @return a newly created CheckboxPreference.
		 */
		public static CheckboxPreference create(Composite parentComposite, int indent, String label, String key, String[] values) {
			Button checkbox= new Button(parentComposite, SWT.CHECK);
			checkbox.setText(label);
			checkbox.setLayoutData(createGridData(GRID_COLUMNS - 1, GridData.FILL_HORIZONTAL, SWT.DEFAULT, indent));
			checkbox.setFont(parentComposite.getFont());
			return new CheckboxPreference(checkbox, label, key, values);
		}

		private CheckboxPreference(Button button, String label, String key, String[] values) {
			super(button, label, key, FilteredPreferenceTree.CHECK_BOX_MATCHER);
			fValues= values;

			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					updateValue();
				}
			});
		}

		@Override
		protected String getValue() {
			boolean state= fControl.getSelection();
			return state ? fValues[1] : fValues[0];
		}

		@Override
		protected void updateWidget() {
			boolean checked= fValues[1].equals(getPreferences().get(getKey()));
			fControl.setSelection(checked);
		}

		public static ModifyAll<Button> addModifyAll(Section section, Images images) {
			return new ModifyAll<Button>(section, images) {
				@Override
				protected Button createControl(Composite parent) {
					Button checkBox= new Button(parent, SWT.CHECK);
					checkBox.setFont(parent.getFont());
					checkBox.addSelectionListener(new SelectionAdapter() {
						@Override
						public void widgetSelected(SelectionEvent e) {
							boolean selected= fControl.getSelection();
							for (CheckboxPreference pref : findPreferences(CheckboxPreference.class)) {
								pref.getControl().setSelection(selected);
								pref.updateValue();
							}
							prepareControl();
						}
					});
					return checkBox;
				}

				@Override
				protected void prepareControl() {
					List<CheckboxPreference> preferences= findPreferences(CheckboxPreference.class);
					int count= 0;
					for (CheckboxPreference pref : preferences) {
						if (pref.getControl().getSelection())
							count++;
					}
					fControl.setSelection(count == preferences.size());
					fControl.setText(Messages.format(FormatterMessages.ModifyDialog_modifyAll_checkBox, new Object[] { count, preferences.size() }));
					fControl.requestLayout();
				}
			};
		}
	}

	/**
	 * Wrapper around a combo box and a label.
	 */
	protected static final class ComboPreference extends Preference<Combo> {
		private final List<String> fValues;

		/**
		 * @param parentComposite The composite on which the SWT widgets are added.
		 * @param indent how many levels of indentation to apply.
		 * @param label The label text for this Preference or {@code null} if none.
		 * @param key The key to store the values.
		 * @param values An array of n elements indicating the values to store for each selection.
		 * @param items An array of n elements indicating the text to be written in the combo box.
		 * @param highlight whether highlight arrow should be added.
		 * @return a newly created ComboPreference.
		 */
		public static ComboPreference create(Composite parentComposite, int indent, String label, String key, String[] values, String[] items, boolean highlight) {
			Combo combo= new Combo(parentComposite, SWT.SINGLE | SWT.READ_ONLY);
			combo.setFont(parentComposite.getFont());
			SWTUtil.setDefaultVisibleItemCount(combo);
			combo.setItems(items);
			combo.setLayoutData(createGridData(1, GridData.HORIZONTAL_ALIGN_FILL, combo.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, 0));

			ComboPreference comboPreference= new ComboPreference(combo, label, key, values);
			comboPreference.addLabel(label, highlight, indent);

			return comboPreference;
		}

		private ComboPreference(Combo combo, String label, String key, String[] values) {
			super(combo, label, key, FilteredPreferenceTree.COMBO_VALUE_MATCHER);

			fValues= Arrays.asList(values);

			combo.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					updateValue();
				}
			});
		}

		@Override
		protected void updateWidget() {
			int valueIndex= fValues.indexOf(getPreferences().get(getKey()));
			if (valueIndex == -1) {
				final String message= Messages.format(FormatterMessages.ModifyDialog_ComboPreference_error_invalid_key, new Object[] { getKey(), getPreferences().get(getKey()) });
				JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, message, null));
				valueIndex= 0;
			}
			fControl.select(valueIndex);
		}

		@Override
		protected String getValue() {
			return fValues.get(fControl.getSelectionIndex());
		}

		public static ModifyAll<Combo> addModifyAll(Section section, Images images) {
			return new ModifyAll<Combo>(section, images) {
				ArrayList<String> fItems= new ArrayList<>();

				@Override
				protected Combo createControl(Composite parent) {
					Combo combo= new Combo(parent, SWT.SINGLE | SWT.READ_ONLY);
					combo.setFont(parent.getFont());
					SWTUtil.setDefaultVisibleItemCount(combo);
					combo.addSelectionListener(new SelectionAdapter() {
						@Override
						public void widgetSelected(SelectionEvent e) {
							String selected= fItems.get(fControl.getSelectionIndex());
							for (ComboPreference pref : findPreferences(ComboPreference.class)) {
								int index= pref.fControl.indexOf(selected);
								if (index >= 0)
									pref.fControl.select(index);
								pref.updateValue();
							}
							prepareControl();
						}
					});
					return combo;
				}

				@Override
				protected void prepareControl() {
					LinkedHashMap<String, Integer> itemCounts= new LinkedHashMap<>();
					List<ComboPreference> preferences= findPreferences(ComboPreference.class);
					for (ComboPreference pref : preferences) {
						String[] items= pref.getControl().getItems();
						for (String item : items) {
							if (!itemCounts.containsKey(item))
								itemCounts.put(item, 0);
						}
						String selected= items[pref.getControl().getSelectionIndex()];
						itemCounts.put(selected, itemCounts.get(selected) + 1);
					}

					String[] items= new String[itemCounts.size()];
					fItems.clear();
					int i= 0;
					int maxCount= 0;
					int maxCountIndex= 0;
					for (Entry<String, Integer> entry : itemCounts.entrySet()) {
						String item= entry.getKey();
						int count= entry.getValue();
						fItems.add(item);
						if (count > 0) {
							item+= Messages.format(FormatterMessages.ModifyDialog_modifyAll_summary, new Object[] { count, preferences.size() });
						}
						if (count > maxCount) {
							maxCount= count;
							maxCountIndex= i;
						}
						items[i++]= item;
					}
					fControl.setItems(items);
					fControl.select(maxCountIndex);
					fControl.requestLayout();
				}
			};
		}
	}

	/**
	 * Wrapper around a textfied which requests an integer input of a given range.
	 */
	protected static final class NumberPreference extends Preference<Spinner> {

		/**
		 * @param parentComposite The composite on which the SWT widgets are added.
		 * @param indent how many levels of indentation to apply.
		 * @param label The label text for this Preference or {@code null} if none.
		 * @param key The key to store the values.
		 * @param minValue The minimum value which is valid input.
		 * @param maxValue The maximum value which is valid input.
		 * @param highlight whether highlight arrow should be added.
		 * @return a newly created NumberPreference.
		 */
		public static NumberPreference create(Composite parentComposite, int indent, String label, String key, int minValue, int maxValue, boolean highlight) {
			Spinner spinner= createSpinner(parentComposite, minValue, maxValue);
			NumberPreference numberPreference= new NumberPreference(spinner, label, key);
			numberPreference.addLabel(label, highlight, indent);

			return numberPreference;
		}

		static Spinner createSpinner(Composite parentComposite, int minValue, int maxValue) {
			Spinner spinner= new Spinner(parentComposite, SWT.BORDER);
			spinner.setFont(parentComposite.getFont());
			spinner.setMinimum(minValue);
			spinner.setMaximum(maxValue);

			spinner.setLayoutData(createGridData(1, GridData.HORIZONTAL_ALIGN_END, SWT.DEFAULT, 0));
			return spinner;
		}

		private NumberPreference(Spinner spinner, String label, String key) {
			super(spinner, label, key, FilteredPreferenceTree.SPINNER_VALUE_MATCHER);

			spinner.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					updateValue();
				}
			});
		}

		@Override
		protected void updateWidget() {
			try {
				String s= getPreferences().get(getKey());
				int number= Integer.parseInt(s);
				number= Math.max(fControl.getMinimum(), Math.min(fControl.getMaximum(), number));
				fControl.setSelection(number);
			} catch (NumberFormatException x) {
				final String message= Messages.format(FormatterMessages.ModifyDialogTabPage_NumberPreference_error_invalid_key, getKey());
				JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, message, null));
				fControl.setSelection(fControl.getMinimum());
			}
		}

		@Override
		protected String getValue() {
			return Integer.toString(fControl.getSelection());
		}

		public static ModifyAll<Spinner> addModifyAll(final int minValue, final int maxValue, Section section, Images images) {
			return new ModifyAll<Spinner>(section, images) {
				private Label fLabel;

				@Override
				protected Spinner createControl(Composite parent) {
					GridLayout layout= new GridLayout(2, false);
					layout.marginWidth= layout.marginHeight= 0;
					parent.setLayout(layout);

					fLabel= createLabel(1, parent, "", 0); //$NON-NLS-1$
					Spinner spinner= createSpinner(parent, minValue, maxValue);
					spinner.addSelectionListener(new SelectionAdapter() {
						@Override
						public void widgetSelected(SelectionEvent e) {
							int selected= fControl.getSelection();
							for (NumberPreference pref : findPreferences(NumberPreference.class)) {
								pref.getControl().setSelection(selected);
								pref.updateValue();
							}
							prepareControl();
						}
					});
					return spinner;
				}

				@Override
				protected void prepareControl() {
					int modeValue= 0;
					int modeCount= -1;
					HashMap<Integer, Integer> counts= new HashMap<>();
					List<NumberPreference> preferences= findPreferences(NumberPreference.class);
					for (NumberPreference pref : preferences) {
						int value= pref.getControl().getSelection();
						Integer count= counts.get(value);
						count= count == null ? 1 : count + 1;
						counts.put(value, count);
						if (count > modeCount) {
							modeValue= value;
							modeCount= count;
						}
					}
					fControl.setSelection(modeValue);
					fLabel.setText(modeCount == preferences.size() ? "" : Messages.format(FormatterMessages.ModifyDialog_modifyAll_summary, new Object[] { modeCount, preferences.size() })); //$NON-NLS-1$
					fLabel.requestLayout();
				}
			};
		}
	}

	/**
	 * Wrapper around a text field which requests a string input.
	 */
	protected static final class StringPreference extends Preference<Text> {

		/**
		 * @param parentComposite The composite on which the SWT widgets are added.
		 * @param indent how many levels of indentation to apply.
		 * @param label the label text for this Preference.
		 * @param key the key to store the values.
		 * @param highlight whether highlight arrow should be added
		 * @return a newly created StringPreference
		 */
		public static StringPreference create(Composite parentComposite, int indent, String label, String key, boolean highlight) {
			Text text= new Text(parentComposite, SWT.SINGLE | SWT.BORDER);
			text.setFont(parentComposite.getFont());
			final int length= 30;
			PixelConverter pixelConverter= new PixelConverter(parentComposite);
			GridData gridData= createGridData(1, GridData.HORIZONTAL_ALIGN_BEGINNING, pixelConverter.convertWidthInCharsToPixels(length), 0);
			gridData.grabExcessHorizontalSpace= true;
			text.setLayoutData(gridData);

			StringPreference stringPreference= new StringPreference(text, label, key);
			stringPreference.addLabel(label, highlight, indent);

			return stringPreference;
		}

		private StringPreference(Text control, String label, String key) {
			super(control, label, key, FilteredPreferenceTree.TEXT_VALUE_MATCHER);
			
			fControl.addModifyListener(e -> updateValue());

			fControl.addFocusListener(new FocusAdapter() {
				@Override
				public void focusGained(FocusEvent e) {
					fControl.setSelection(0, fControl.getCharCount());
				}
			});
		}

		@Override
		protected void updateWidget() {
			String value= getPreferences().get(getKey());
			fControl.setText(value);
		}

		@Override
		protected String getValue() {
			return fControl.getText();
		}
	}

	@FunctionalInterface
	public interface PreferenceBuilder {
		Preference<?> buildPreference(Section parent, String label, String key);
	}

	protected class ProfilePreferenceTree extends FilteredPreferenceTree {

		/**
		 * Helper class for easy, call-chain based building of subtrees that contain only Sections and one
		 * type of preference.
		 * 
		 * @param <T> Type of preference or section built
		 */
		public abstract class SimpleTreeBuilder<T extends PreferenceTreeNode<?>> {
			protected final String fLabel, fKey;

			protected boolean fGap;

			protected Consumer<T> fCustomizer;

			protected SimpleTreeBuilder(String label, String key, Consumer<T> customizer) {
				fLabel= label;
				fKey= key;
				fCustomizer= customizer;
			}

			protected abstract T build(Section parent, PreferenceBuilder prefBuilder);
		}

		public class SectionBuilder extends SimpleTreeBuilder<Section> {
			private ArrayList<SimpleTreeBuilder<?>> fChildren= new ArrayList<>();

			SectionBuilder(String label, String key, Consumer<Section> customizer) {
				super(label, key, customizer);
			}

			public SectionBuilder node(SimpleTreeBuilder<?> child) {
				fChildren.add(child);
				return this;
			}

			public SectionBuilder pref(String label, String key) {
				return pref(label, key, null);
			}

			public SectionBuilder pref(String label, String key, Consumer<Preference<?>> customizer) {
				return node(new PrefBuilder(label, key, customizer));
			}

			public SectionBuilder gap() {
				fChildren.get(fChildren.size() - 1).fGap= true;
				return this;
			}

			@Override
			public Section build(Section parent, PreferenceBuilder prefBuilder) {
				String key= fKey;
				if (key != null) {
					Section ancestorWithKey= parent;
					while (ancestorWithKey != null && ancestorWithKey.getKey() == null)
						ancestorWithKey= (Section) ancestorWithKey.getParent();
					if (ancestorWithKey != null)
						key= ancestorWithKey.getKey() + key;
				}

				Section section= addSection(parent, fLabel, key);
				for (SimpleTreeBuilder<?> child : fChildren) {
					child.build(section, prefBuilder);
					if (child.fGap)
						addGap(section);
				}
				if (fCustomizer != null)
					fCustomizer.accept(section);
				return section;
			}
		}

		private class PrefBuilder extends SimpleTreeBuilder<Preference<?>> {
			public PrefBuilder(String label, String key, Consumer<Preference<?>> customizer) {
				super(label, key, customizer);
			}

			@Override
			protected Preference<?> build(Section parent, PreferenceBuilder prefBuilder) {
				Preference<?> pref= prefBuilder.buildPreference(parent, fLabel, fKey);
				if (fCustomizer != null)
					fCustomizer.accept(pref);
				return pref;
			}
		}

		private boolean fFilterEmpty;
		private int fRightMargin;

		public ProfilePreferenceTree(Composite parentComposite) {
			super(parentComposite, FormatterMessages.ModifyDialog_filter_label, FormatterMessages.ModifyDialog_filter_hint);

			// calculate rigth margin width
			ToolBar modifyAllToolbar= ModifyAll.createToolItem(parentComposite, fImages).getParent();
			fRightMargin= modifyAllToolbar.computeSize(SWT.DEFAULT, SWT.DEFAULT).x - 12;
			modifyAllToolbar.dispose();
		}

		public Section addSection(Section parent, String label, String previewKey) {
			Section section= Section.create(getParentComposite(parent), label, previewKey);

			ExpandableComposite excomposite= section.getControl();
			getScrolledPageContent().adaptChild(excomposite);

			Menu expandAllMenu= new Menu(excomposite);
			MenuItem expandAllItem= new MenuItem(expandAllMenu, SWT.NONE);
			expandAllItem.setText(PreferencesMessages.FilteredPreferencesTree_expandAll_tooltip);
			expandAllItem.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					setAllExpanded(section, true);
				}
			});
			excomposite.setMenu(expandAllMenu);

			return addChild(parent, section);
		}

		public CheckboxPreference addCheckbox(PreferenceTreeNode<?> parent, String label, String key, String[] values) {
			CheckboxPreference button= CheckboxPreference.create(getParentComposite(parent), getIndent(parent), label, key, values);
			return addChild(parent, button);
		}

		public ComboPreference addComboPref(PreferenceTreeNode<?> parent, String label, String key, String[] values, String[] items) {
			ComboPreference combo= ComboPreference.create(getParentComposite(parent), getIndent(parent), label, key, values, items, true);
			return addChild(parent, combo);
		}

		public NumberPreference addNumberPref(PreferenceTreeNode<?> parent, String label, String key, int minValue, int maxValue) {
			NumberPreference number= NumberPreference.create(getParentComposite(parent), getIndent(parent), label, key, minValue, maxValue, true);
			return addChild(parent, number);
		}

		public StringPreference addStringPreference(PreferenceTreeNode<?> parent, String label, String key) {
			StringPreference stringPreference= StringPreference.create(getParentComposite(parent), getIndent(parent), label, key, true);
			return addChild(parent, stringPreference);
		}

		@Override
		public <T extends PreferenceTreeNode<?>> T addChild(PreferenceTreeNode<?> parent, T node) {
			super.addChild(parent, node);
			fFocusManager.add(node);
			if (node instanceof Preference<?>) {
				Predicate<String> validator = v -> {
					doValidate();
					return true;
				};
				((Preference<?>) node).init(fWorkingValues, validator , () -> valuesModified());
			}

			if (!(node instanceof Section)) {
				Label margin= new Label(node.getControl().getParent(), SWT.NONE);
				margin.setLayoutData(new GridData(fRightMargin, SWT.DEFAULT));
				node.addChild(new PreferenceTreeNode<>("", margin, true)); //$NON-NLS-1$
			}
			return node;
		}

		public void addGap(PreferenceTreeNode<?> parent) {
			Composite gap= new Composite(getParentComposite(parent), SWT.NONE);
			GridData gd= new GridData(0, 4);
			gd.horizontalSpan= GRID_COLUMNS;
			gap.setLayoutData(gd);
			parent.addChild(new PreferenceTreeNode<>("", gap, true)); //$NON-NLS-1$
		}

		public SectionBuilder builder(String label, String key) {
			return builder(label, key, null);
		}

		public SectionBuilder builder(String label, String key, Consumer<Section> customizer) {
			return new SectionBuilder(label, key, customizer);
		}

		private Composite getParentComposite(PreferenceTreeNode<?> parent) {
			while (parent != null) {
				if (parent instanceof Section)
					return ((Section) parent).fInnerComposite;
				parent= parent.getParent();
			}
			return getScrolledPageContent().getBody();
		}

		private int getIndent(PreferenceTreeNode<?> parent) {
			int indent= 0;
			while (parent != null) {
				if (parent instanceof Section)
					return indent;
				indent++;
				parent= parent.getParent();
			}
			return indent;
		}

		protected void saveState() {
			try (ByteArrayOutputStream out= new ByteArrayOutputStream()) {
				writeExpansionState(fRoot, out);
				fDialogSettings.put(fKeyPreferenceTreeExpansion, out.toString("UTF-8")); //$NON-NLS-1$
			} catch (IOException e) {
				throw new AssertionError(e);
			}

			int scrollPosition= getScrolledPageContent().getOrigin().y;
			fDialogSettings.put(fKeyPreferenceScrollPosition, scrollPosition);
		}

		private void writeExpansionState(PreferenceTreeNode<?> node, OutputStream output) throws IOException {
			for (PreferenceTreeNode<?> child : node.getChildren()) {
				if (child instanceof Section) {
					output.write(((Section) child).getControl().isExpanded() ? '1' : '0');
					writeExpansionState(child, output);
				}
			}
			output.write('.');
		}

		protected void restoreExpansionState() {
			String treeState= fDialogSettings.get(fKeyPreferenceTreeExpansion);
			if (treeState == null)
				return;
			try (ByteArrayInputStream in= new ByteArrayInputStream(treeState.getBytes("UTF-8"))) { //$NON-NLS-1$
				fScrolledPageContent.setReflow(false);
				readExpansionState(fRoot, in);
				fScrolledPageContent.setReflow(true);
			} catch (IOException e) {
				throw new AssertionError(e);
			}
		}

		private void readExpansionState(PreferenceTreeNode<?> node, InputStream in) throws IOException {
			for (PreferenceTreeNode<?> child : node.getChildren()) {
				if (child instanceof Section) {
					int state= in.read();
					((Section) child).getControl().setExpanded(state == '1');
					readExpansionState(child, in);
					if (state == '.' || state == -1)
						return; // some nodes missing in stored tree
				}
			}
			int c= in.read();
			while (c != '.' && c != -1) { // some extra nodes in stored tree 
				readExpansionState(new PreferenceTreeNode<>(null, null, false), in);
				c= in.read();
			}
		}

		protected void restoreScrollPosition() {
			try {
				int scrollPosition= fDialogSettings.getInt(fKeyPreferenceScrollPosition);
				getScrolledPageContent().setOrigin(0, scrollPosition);
			} catch (NumberFormatException e) {
				// ignore invalid/undefined value
			}
		}

		@Override
		public void doFilter(String filterText) {
			fFilterEmpty= filterText.trim().isEmpty();
			super.doFilter(filterText);
		}

		@Override
		protected void updateUI(PreferenceTreeNode<?> node) {
			super.updateUI(node);
			if (node == fRoot && fFilterEmpty)
				restoreExpansionState();
		}

		public void unifySectionTitlesHeights(Section section) {
			List<PreferenceTreeNode<?>> children= section == null ? fRoot.getChildren() : section.getChildren();
			int maxHeightDiff= 0;
			for (PreferenceTreeNode<?> child : children) {
				if (child instanceof Section)
					maxHeightDiff= Math.max(maxHeightDiff, ((Section) child).getControl().getTextClientHeightDifference());
			}
			int nextChildIndent= 0;
			for (PreferenceTreeNode<?> child : children) {
				int indent= nextChildIndent;
				nextChildIndent= 0;
				if (child instanceof Section) {
					Section sectionChild= (Section) child;
					int diff= maxHeightDiff - sectionChild.getControl().getTextClientHeightDifference();
					nextChildIndent= diff / 2;
					indent+= diff - diff / 2;

					unifySectionTitlesHeights(sectionChild);
				}
				GridData gd= (GridData) child.getControl().getLayoutData();
				gd.verticalIndent+= indent;
			}
		}
	}

	public class Images {
		private Map<ImageDescriptor, Image> imagesMap= new HashMap<>();

		protected Images(Composite rootComposite) {
			rootComposite.addDisposeListener(e -> {
				for (Image image : imagesMap.values())
					image.dispose();
				imagesMap.clear();
			});
		}

		public Image get(ImageDescriptor descriptor) {
			return imagesMap.computeIfAbsent(descriptor, ImageDescriptor::createImage);
		}
	}

	/**
	 * The default focus manager. It knows all widgets which can have the focus and listens for
	 * focusGained events, on which it stores the index of the current focus holder. When the dialog
	 * is restarted, <code>restoreFocus()</code> sets the focus to the last control which had it.
	 * 
	 * Focus manager also makes sure that proper preview is displayed for currently focused
	 * preference.
	 * 
	 * The standard Preference objects are managed by this focus manager if they are created using
	 * the respective factory methods. Other SWT widgets can be added in subclasses when they are
	 * created.
	 */
	protected final class FocusManager implements FocusListener {
		private HashMap<Control, PreferenceTreeNode<?>> fControl2node= new HashMap<>();
		private final Map<Control, Integer> fItemMap= new HashMap<>();
		private final List<Control> fItemList= new ArrayList<>();
		private int fIndex= 0;
		private PreferenceTreeNode<?> fCurrentlyFocused;

		public void add(PreferenceTreeNode<?> node) {
			Control control= node.getControl();
			if (node instanceof Section) {
				// workaround: can't add focus listener directly to ExpadableComposite
				control= ((Section) node).getToggle();
			}
			fControl2node.put(control, node);
			add(control);
		}

		private void add(Control control) {
			control.addFocusListener(this);
			fItemList.add(fIndex, control);
			fItemMap.put(control, new Integer(fIndex++));
		}

		@Override
		public void focusGained(FocusEvent e) {
			PreferenceTreeNode<?> focusNode= fControl2node.get(e.getSource());
			if (focusNode != null && focusNode != fCurrentlyFocused) {
				fCurrentlyFocused= focusNode;
				updatePreviewCode();
			}

			fDialogSettings.put(fKeyLastFocusIndex, fItemMap.get(e.widget).intValue());
		}

		@Override
		public void focusLost(FocusEvent e) {
			doValidate();
		}

		public void restoreFocus() {
			try {
				int index= fDialogSettings.getInt(fKeyLastFocusIndex);
				if (index >= 0 && index < fItemList.size()) {
					fItemList.get(index).forceFocus();
				}
			} catch (NumberFormatException ex) {
				// this is the first time
				updatePreviewCode();
			}
		}
	}

	protected static final int GRID_COLUMNS= 4;

	/* The keys to retrieve the preferred area from the dialog settings */
	private static final String DS_KEY_PREFERRED_WIDTH= "modify_dialog.preferred_width"; //$NON-NLS-1$
	private static final String DS_KEY_PREFERRED_HEIGHT= "modify_dialog.preferred_height"; //$NON-NLS-1$
	private static final String DS_KEY_PREFERRED_X= "modify_dialog.preferred_x"; //$NON-NLS-1$
	private static final String DS_KEY_PREFERRED_Y= "modify_dialog.preferred_y"; //$NON-NLS-1$
	private static final String DS_KEY_SASH_FORM_LEFT_WIDTH= "modify_dialog.sash_form_left_width"; //$NON-NLS-1$
	private static final String DS_KEY_SASH_FORM_RIGHT_WIDTH= "modify_dialog.sash_form_rigth_width"; //$NON-NLS-1$

	private static final String DS_KEY_PREFERENCE_TREE_EXPANSION= ".preference_tree_expansion"; //$NON-NLS-1$
	private static final String DS_KEY_PREFERENCE_SCROLL_POSITION= ".preference_scroll_position"; //$NON-NLS-1$
	private static final String DS_KEY_LAST_FOCUS_INDEX= ".last_focus_index"; //$NON-NLS-1$

	private static final int APPLAY_BUTTON_ID= IDialogConstants.CLIENT_ID;
	private static final int SAVE_BUTTON_ID= IDialogConstants.CLIENT_ID + 1;

	protected final Map<String, String> fWorkingValues;
	protected final IDialogSettings fDialogSettings;
	protected final boolean fNewProfile;

	protected final String fKeyPreferredWidth;
	protected final String fKeyPreferredHight;
	private final String fKeyPreferredX;
	private final String fKeyPreferredY;
	private final String fKeySashFormLeftWidth;
	private final String fKeySashFormRightWidth;
	protected final String fKeyPreferenceTreeExpansion;
	protected final String fKeyPreferenceScrollPosition;
	protected final String fKeyLastFocusIndex;
	private final String fLastSaveLoadPathKey;
	private final ProfileStore fProfileStore;
	private Profile fProfile;
	private final ProfileManager fProfileManager;
	private Button fApplyButton;
	private Button fSaveButton;
	private StringDialogField fProfileNameField;

	private SashForm fSashForm;
	protected JavaPreview fPreview;
	protected ProfilePreferenceTree fTree;
	protected final Images fImages;
	protected final FocusManager fFocusManager= new FocusManager();
	private String fPreviewSources= ""; //$NON-NLS-1$
	private int fCurrentPreviewType;

	public ModifyDialog(Shell parentShell, Profile profile, ProfileManager profileManager, ProfileStore profileStore, boolean newProfile, String dialogPreferencesKey, String lastSavePathKey) {
		super(parentShell);

		fProfileStore= profileStore;
		fLastSaveLoadPathKey= lastSavePathKey;

		fKeyPreferredWidth= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERRED_WIDTH;
		fKeyPreferredHight= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERRED_HEIGHT;
		fKeyPreferredX= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERRED_X;
		fKeyPreferredY= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERRED_Y;
		fKeySashFormLeftWidth= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_SASH_FORM_LEFT_WIDTH;
		fKeySashFormRightWidth= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_SASH_FORM_RIGHT_WIDTH;
		fKeyPreferenceTreeExpansion= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERENCE_TREE_EXPANSION;
		fKeyPreferenceScrollPosition= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_PREFERENCE_SCROLL_POSITION;
		fKeyLastFocusIndex= JavaUI.ID_PLUGIN + dialogPreferencesKey + DS_KEY_LAST_FOCUS_INDEX;

		fProfileManager= profileManager;
		fNewProfile= newProfile;

		fProfile= profile;
		setTitle(Messages.format(FormatterMessages.ModifyDialog_dialog_title, profile.getName()));
		fWorkingValues= new HashMap<>(fProfile.getSettings());
		setStatusLineAboveButtons(false);
		fDialogSettings= JavaPlugin.getDefault().getDialogSettings();

		fImages= new Images(parentShell);
	}

	/*
	 * @see org.eclipse.jface.dialogs.Dialog#isResizable()
	 * @since 3.4
	 */
	@Override
	protected boolean isResizable() {
		return true;
	}

	@Override
	protected Control createDialogArea(Composite parent) {

		final Composite composite= (Composite) super.createDialogArea(parent);
		createNameArea(composite);
		createMainArea(composite);

		doValidate();

		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, getHelpContextId());

		fFocusManager.restoreFocus();

		return composite;
	}

	protected void createMainArea(Composite parent) {
		fSashForm= new SashForm(parent, SWT.HORIZONTAL);
		fSashForm.setFont(parent.getFont());
		fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		createPreferenceTree(fSashForm);
		fTree.unifySectionTitlesHeights(null);
		fTree.restoreExpansionState();
		createPreviewPane(fSashForm);

		try {
			fSashForm.setWeights(new int[] { fDialogSettings.getInt(fKeySashFormLeftWidth), fDialogSettings.getInt(fKeySashFormRightWidth) });
		} catch (NumberFormatException e) {
			Control[] children= fSashForm.getChildren();
			int treeWidth= children[0].computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
			int previewWidth= children[1].computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
			fSashForm.setWeights(new int[] { treeWidth, previewWidth });
		}
	}

	protected void createPreferenceTree(Composite parent) {
		Composite mainComp= new Composite(parent, SWT.NONE);
		mainComp.setFont(parent.getFont());
		mainComp.setLayout(new GridLayout(2, false));

		fTree= new ProfilePreferenceTree(mainComp);
		GridLayout layout= new GridLayout();
		layout.verticalSpacing= 0;
		layout.marginLeft= layout.marginWidth - 1;
		layout.marginWidth= 1;
		fTree.getScrolledPageContent().getBody().setLayout(layout);
		fTree.setConcatAncestorLabels(true);
		fTree.setExpectMultiWordValueMatch(true);

		// restoring scroll position must wait until layout is complete
		Display.getCurrent().asyncExec(fTree::restoreScrollPosition);
	}

	private void createNameArea(final Composite parent) {
		Composite nameComposite= new Composite(parent, SWT.NONE);
		nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		nameComposite.setLayout(new GridLayout(3, false));

		fProfileNameField= new StringDialogField();
		fProfileNameField.setLabelText(FormatterMessages.ModifyDialog_ProfileName_Label);
		fProfileNameField.setText(fProfile.getName());
		fProfileNameField.getLabelControl(nameComposite).setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
		fProfileNameField.getTextControl(nameComposite).setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		fProfileNameField.setDialogFieldListener(new IDialogFieldListener() {
			@Override
			public void dialogFieldChanged(DialogField field) {
				doValidate();
			}
		});

		fSaveButton= createButton(nameComposite, SAVE_BUTTON_ID, FormatterMessages.ModifyDialog_Export_Button, false);
	}

	/**
	 * Returns the context ID for the Help system
	 *
	 * @return the string used as ID for the Help context
	 * @since 3.5
	 */
	protected abstract String getHelpContextId();

	@Override
	public void updateStatus(IStatus status) {
		if (status == null) {
			doValidate();
		} else {
			super.updateStatus(status);
		}
	}

	@Override
	protected Point getInitialLocation(Point initialSize) {
		try {
			return new Point(fDialogSettings.getInt(fKeyPreferredX), fDialogSettings.getInt(fKeyPreferredY));
		} catch (NumberFormatException ex) {
			return super.getInitialLocation(initialSize);
		}
	}

	@Override
	public boolean close() {
		final Rectangle shell= getShell().getBounds();
		fDialogSettings.put(fKeyPreferredWidth, shell.width);
		fDialogSettings.put(fKeyPreferredHight, shell.height);
		fDialogSettings.put(fKeyPreferredX, shell.x);
		fDialogSettings.put(fKeyPreferredY, shell.y);
		if (fSashForm != null) {
			Control[] children= fSashForm.getChildren();
			fDialogSettings.put(fKeySashFormLeftWidth, children[0].getSize().x);
			fDialogSettings.put(fKeySashFormRightWidth, children[1].getSize().x);
		}

		if (fTree != null)
			fTree.saveState();

		return super.close();
	}

	@Override
	protected void okPressed() {
		applyPressed();
		super.okPressed();
	}

    @Override
	protected void buttonPressed(int buttonId) {
		if (buttonId == APPLAY_BUTTON_ID) {
			applyPressed();
			setTitle(Messages.format(FormatterMessages.ModifyDialog_dialog_title, fProfile.getName()));
		} else if (buttonId == SAVE_BUTTON_ID) {
			saveButtonPressed();
		} else {
			super.buttonPressed(buttonId);
		}
    }

	private void applyPressed() {
		if (!fProfile.getName().equals(fProfileNameField.getText())) {
			fProfile= fProfile.rename(fProfileNameField.getText(), fProfileManager);
		}
		fProfile.setSettings(new HashMap<>(fWorkingValues));
		fProfileManager.setSelected(fProfile);
		doValidate();
	}

	private void saveButtonPressed() {
		Profile selected= new CustomProfile(fProfileNameField.getText(), new HashMap<>(fWorkingValues), fProfile.getVersion(), fProfileManager.getProfileVersioner().getProfileKind());

		final FileDialog dialog= new FileDialog(getShell(), SWT.SAVE | SWT.SHEET);
		dialog.setText(FormatterMessages.CodingStyleConfigurationBlock_save_profile_dialog_title);
		dialog.setFilterExtensions(new String [] {"*.xml"}); //$NON-NLS-1$

		final String lastPath= JavaPlugin.getDefault().getDialogSettings().get(fLastSaveLoadPathKey + ".savepath"); //$NON-NLS-1$
		if (lastPath != null) {
			dialog.setFilterPath(lastPath);
		}
		final String path= dialog.open();
		if (path == null)
			return;

		JavaPlugin.getDefault().getDialogSettings().put(fLastSaveLoadPathKey + ".savepath", dialog.getFilterPath()); //$NON-NLS-1$

		final File file= new File(path);
		if (file.exists() && !MessageDialog.openQuestion(getShell(), FormatterMessages.CodingStyleConfigurationBlock_save_profile_overwrite_title, Messages.format(FormatterMessages.CodingStyleConfigurationBlock_save_profile_overwrite_message, BasicElementLabels.getPathLabel(file)))) {
			return;
		}
		String encoding= ProfileStore.ENCODING;
		final IContentType type= Platform.getContentTypeManager().getContentType("org.eclipse.core.runtime.xml"); //$NON-NLS-1$
		if (type != null)
			encoding= type.getDefaultCharset();
		final Collection<Profile> profiles= new ArrayList<>();
		profiles.add(selected);
		try {
			fProfileStore.writeProfilesToFile(profiles, file, encoding);
		} catch (CoreException e) {
			final String title= FormatterMessages.CodingStyleConfigurationBlock_save_profile_error_title;
			final String message= FormatterMessages.CodingStyleConfigurationBlock_save_profile_error_message;
			ExceptionHandler.handle(e, getShell(), title, message);
		}
	}

    @Override
	protected void createButtonsForButtonBar(Composite parent) {
	    fApplyButton= createButton(parent, APPLAY_BUTTON_ID, FormatterMessages.ModifyDialog_apply_button, false);
		fApplyButton.setEnabled(false);

		GridLayout layout= (GridLayout) parent.getLayout();
		layout.numColumns++;
		layout.makeColumnsEqualWidth= false;
		Label label= new Label(parent, SWT.NONE);
		GridData data= new GridData();
		data.widthHint= layout.horizontalSpacing;
		label.setLayoutData(data);
		super.createButtonsForButtonBar(parent);
	}

	@Override
	public void valuesModified() {
		doValidate();
		if (fPreview != null)
			fPreview.update();
	}

	@Override
	protected void updateButtonsEnableState(IStatus status) {
	    super.updateButtonsEnableState(status);
	    if (fApplyButton != null && !fApplyButton.isDisposed()) {
	    	fApplyButton.setEnabled(hasChanges() && !status.matches(IStatus.ERROR));
		}
	    if (fSaveButton != null && !fSaveButton.isDisposed()) {
	    	fSaveButton.setEnabled(!validateProfileName().matches(IStatus.ERROR));
	    }
	}

    private void doValidate() {
    	String name= fProfileNameField.getText().trim();
		if (name.equals(fProfile.getName()) && fProfile.hasEqualSettings(fWorkingValues, fWorkingValues.keySet())) {
			updateStatus(StatusInfo.OK_STATUS);
			return;
		}

    	IStatus status= validateProfileName();
    	if (status.matches(IStatus.ERROR)) {
    		updateStatus(status);
    		return;
    	}

		if (!name.equals(fProfile.getName()) && fProfileManager.containsName(name)) {
			updateStatus(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FormatterMessages.ModifyDialog_Duplicate_Status));
			return;
		}

		if (fProfile.isBuiltInProfile() || fProfile.isSharedProfile()) {
			updateStatus(new Status(IStatus.INFO, JavaUI.ID_PLUGIN, FormatterMessages.ModifyDialog_NewCreated_Status));
			return;
		}

	    updateStatus(StatusInfo.OK_STATUS);
    }

    private IStatus validateProfileName() {
    	final String name= fProfileNameField.getText().trim();

	    if (fProfile.isBuiltInProfile()) {
			if (fProfile.getName().equals(name)) {
				return new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FormatterMessages.ModifyDialog_BuiltIn_Status);
			}
    	}

    	if (fProfile.isSharedProfile()) {
			if (fProfile.getName().equals(name)) {
				return new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FormatterMessages.ModifyDialog_Shared_Status);
			}
    	}

		if (name.length() == 0) {
			return new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FormatterMessages.ModifyDialog_EmptyName_Status);
		}

		return StatusInfo.OK_STATUS;
    }

	private boolean hasChanges() {
		if (!fProfileNameField.getText().trim().equals(fProfile.getName()))
			return true;

		Iterator<Entry<String, String>> iter= fProfile.getSettings().entrySet().iterator();
		for (;iter.hasNext();) {
			Entry<String, String> curr= iter.next();
			if (!fWorkingValues.get(curr.getKey()).equals(curr.getValue())) {
				return true;
			}
		}
		return false;
	}

	protected Composite createPreviewPane(Composite parent) {
		final Composite previewPane= new Composite(parent, SWT.NONE);
		createGridLayout(previewPane, GRID_COLUMNS, true);
		previewPane.setFont(parent.getFont());

		createLabel(GRID_COLUMNS, previewPane, FormatterMessages.ModifyDialogTabPage_preview_label_text, 0);

		fPreview= new JavaPreview(fWorkingValues, previewPane);
		fPreview.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, GRID_COLUMNS, 1));

		return previewPane;
	}

	protected void updatePreviewCode() {
		if (fPreview != null) {
			String previewCode= getPreviewCode();
			if (previewCode == null || previewCode.trim().isEmpty())
				previewCode= "// " + FormatterMessages.ModifyDialog_previewMissing_comment; //$NON-NLS-1$
			fPreview.setPreviewText(previewCode, fCurrentPreviewType);
		}
	}

	private String getPreviewCode() {
		PreferenceTreeNode<?> currentNode= fFocusManager.fCurrentlyFocused;
		if (currentNode == null)
			return null;
		
		// try this node
		String previewCode= doGetPreviewCode(currentNode);
		if (previewCode != null)
			return previewCode;

		// combine previews from children, if any
		StringBuilder sb= new StringBuilder();
		List<PreferenceTreeNode<?>> currentLevel= new ArrayList<>(currentNode.getChildren());
		List<PreferenceTreeNode<?>> nextLevel= new ArrayList<>();
		while (!currentLevel.isEmpty()) {
			boolean onlyModuleInfos= true;
			for (PreferenceTreeNode<?> node : currentLevel) {
				previewCode= doGetPreviewCode(node);
				onlyModuleInfos= onlyModuleInfos && fCurrentPreviewType == CodeFormatter.K_MODULE_INFO;
				if (previewCode != null && sb.indexOf(previewCode) == -1)
					sb.append("\n\n").append(previewCode); //$NON-NLS-1$
				nextLevel.addAll(node.getChildren());
			}
			if (sb.length() > 0) {
				fCurrentPreviewType= onlyModuleInfos ? CodeFormatter.K_MODULE_INFO : CodeFormatter.K_UNKNOWN;
				return sb.toString();
			}

			currentLevel= nextLevel;
			nextLevel= new ArrayList<>();
		}

		// try its ancestors
		PreferenceTreeNode<?> node= currentNode.getParent();
		while (node != null) {
			previewCode= doGetPreviewCode(node);
			if (previewCode != null)
				return previewCode;
			node= node.getParent();
		}

		return null;
	}

	private String doGetPreviewCode(PreferenceTreeNode<?> node) {
		if (!(node instanceof Section || node instanceof Preference))
			return null;
		String key= node instanceof Section ? ((Section) node).getKey() : ((Preference<?>) node).getKey();
		final String START_PREFIX= "//--PREVIEW--START--"; //$NON-NLS-1$
		final String END_PREFIX= "//--PREVIEW--END--"; //$NON-NLS-1$
		int startIndex= fPreviewSources.indexOf(START_PREFIX + key);
		if (startIndex < 0)
			return null;

		fCurrentPreviewType= CodeFormatter.K_UNKNOWN;
		int nextPos= startIndex + START_PREFIX.length() + key.length();
		switch (fPreviewSources.charAt(nextPos)) {
			case '\n':
				break;
			case ':':
				if (fPreviewSources.indexOf("COMPILATION_UNIT\n", nextPos) == nextPos + 1) { //$NON-NLS-1$
					fCurrentPreviewType= CodeFormatter.K_COMPILATION_UNIT;
				} else if (fPreviewSources.indexOf("EXPRESSION\n", nextPos) == nextPos + 1) { //$NON-NLS-1$
					fCurrentPreviewType= CodeFormatter.K_EXPRESSION;
				} else if (fPreviewSources.indexOf("CLASS_BODY_DECLARATIONS\n", nextPos) == nextPos + 1) { //$NON-NLS-1$
					fCurrentPreviewType= CodeFormatter.K_CLASS_BODY_DECLARATIONS;
				} else if (fPreviewSources.indexOf("STATEMENTS\n", nextPos) == nextPos + 1) { //$NON-NLS-1$
					fCurrentPreviewType= CodeFormatter.K_STATEMENTS;
				} else if (fPreviewSources.indexOf("MODULE_INFO\n", nextPos) == nextPos + 1) { //$NON-NLS-1$
					fCurrentPreviewType= CodeFormatter.K_MODULE_INFO;
				}
				break;
			default:
				return null;
		}

		int endIndex= fPreviewSources.indexOf(END_PREFIX + key + '\n');
		String previewCode= fPreviewSources.substring(startIndex, endIndex);
		previewCode= previewCode.replaceAll(START_PREFIX + ".*\\R", ""); //$NON-NLS-1$ //$NON-NLS-2$
		previewCode= previewCode.replaceAll(END_PREFIX + ".*\\R", ""); //$NON-NLS-1$ //$NON-NLS-2$
		return previewCode;
	}

	protected void loadPreviews(String previewFile) {
		String resource= "/preview/" + previewFile; //$NON-NLS-1$
		try (Scanner s= new Scanner(getClass().getResourceAsStream(resource), "UTF-8")) { //$NON-NLS-1$
			fPreviewSources= s.useDelimiter("\\A").next(); //$NON-NLS-1$
		}
	}

	protected static Composite createGridComposite(Composite parent, int numColumns) {
		final Composite grid= new Composite(parent, SWT.NONE);
		createGridLayout(parent, numColumns, true);
		grid.setFont(parent.getFont());
		return grid;
	}

	/*
	 * Create a GridLayout with the default margin and spacing settings, as
	 * well as the specified number of columns.
	 */
	protected static void createGridLayout(Composite composite, int numColumns, boolean margins) {
		final GridLayout layout= new GridLayout(numColumns, false);
		PixelConverter pixelConverter= new PixelConverter(composite);
		layout.verticalSpacing= pixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
		layout.horizontalSpacing= pixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
		if (margins) {
			layout.marginHeight= pixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
			layout.marginWidth= pixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
		} else {
			layout.marginHeight= 0;
			layout.marginWidth= 0;
		}
		composite.setLayout(layout);
	}

	/*
	 * Convenience method to create a GridData.
	 */
	protected static GridData createGridData(int numColumns, int style, int widthHint, int indent) {
		final GridData gd= new GridData(style);
		gd.horizontalSpan= numColumns;
		gd.widthHint= widthHint;
		gd.horizontalIndent= indent * LayoutUtil.getIndent();
		return gd;
	}

	/*
	 * Convenience method to create a label
	 */
	protected static Label createLabel(int numColumns, Composite parent, String text, int indent) {
		final Label label= new Label(parent, SWT.WRAP);
		label.setFont(parent.getFont());
		label.setText(text);
		GridData gd= new GridData(GridData.BEGINNING, GridData.CENTER, true, false, numColumns, 1);
		gd.horizontalIndent= indent * LayoutUtil.getIndent();
		label.setLayoutData(gd);
		return label;
	}

	/*
	 * Helper to be used with Preference.addDependant(), dependency checker that accepts specific values.
	 */
	protected static Predicate<String> valueAcceptor(String... values) {
		final List<String> valuesList= Arrays.asList(values);
		return valuesList::contains;
	}
}
