/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jesper S Møller - Bug 529432 - Allow JDT UI to target Java 10
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.preferences;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.osgi.service.prefs.Preferences;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.preferences.BundleDefaultsScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;

import org.eclipse.jface.dialogs.ControlEnableState;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.resource.JFaceResources;

import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;

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

import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;


/**
 * Configuration block for the 'Java Compiler' page.
 */
public class ComplianceConfigurationBlock extends OptionsConfigurationBlock {

	/**
	 * Key for the "Compiler compliance follows EE" setting.
	 * <br>Only applicable if <code>fProject != null</code>.
	 * <p>Values are { {@link #DEFAULT_CONF}, {@link #USER_CONF}, or {@link #DISABLED} }.
	 */
	private static final Key INTR_COMPLIANCE_FOLLOWS_EE= getLocalKey("internal.compliance.follows.ee"); //$NON-NLS-1$

	/**
	 * Key for the "Use default compliance" setting.
	 * <p>Values are { {@link #DEFAULT_CONF}, {@link #USER_CONF} }.
	 */
	private static final Key INTR_DEFAULT_COMPLIANCE= getLocalKey("internal.default.compliance"); //$NON-NLS-1$

	// Preference store keys, see JavaCore.getOptions
	private static final Key PREF_PB_ASSERT_AS_IDENTIFIER= getJDTCoreKey(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER);
	private static final Key PREF_PB_ENUM_AS_IDENTIFIER= getJDTCoreKey(JavaCore.COMPILER_PB_ENUM_IDENTIFIER);
	private static final Key PREF_SOURCE_COMPATIBILITY= getJDTCoreKey(JavaCore.COMPILER_SOURCE);
	private static final Key PREF_CODEGEN_TARGET_PLATFORM= getJDTCoreKey(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
	private static final Key PREF_COMPLIANCE= getJDTCoreKey(JavaCore.COMPILER_COMPLIANCE);
	private static final Key PREF_RELEASE= getJDTCoreKey(JavaCore.COMPILER_RELEASE);
	private static final Key PREF_ENABLE_PREVIEW= getJDTCoreKey(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES);
	private static final Key PREF_PB_REPORT_PREVIEW= getJDTCoreKey(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES);

	/* see also BuildPathSupport#PREFS_COMPLIANCE */
	private static final Key[] PREFS_COMPLIANCE= new Key[] { PREF_COMPLIANCE,
		PREF_PB_ASSERT_AS_IDENTIFIER, PREF_PB_ENUM_AS_IDENTIFIER,
		PREF_SOURCE_COMPATIBILITY, PREF_CODEGEN_TARGET_PLATFORM};
	private static final Key[] PREFS_COMPLIANCE_11_OR_HIGHER= new Key[] { PREF_COMPLIANCE,
		PREF_PB_ASSERT_AS_IDENTIFIER, PREF_PB_ENUM_AS_IDENTIFIER,
		PREF_SOURCE_COMPATIBILITY, PREF_CODEGEN_TARGET_PLATFORM,
		PREF_ENABLE_PREVIEW, PREF_PB_REPORT_PREVIEW};

	private static final Key PREF_CODEGEN_INLINE_JSR_BYTECODE= getJDTCoreKey(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE);

	private static final Key PREF_LOCAL_VARIABLE_ATTR=  getJDTCoreKey(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR);
	private static final Key PREF_LINE_NUMBER_ATTR= getJDTCoreKey(JavaCore.COMPILER_LINE_NUMBER_ATTR);
	private static final Key PREF_SOURCE_FILE_ATTR= getJDTCoreKey(JavaCore.COMPILER_SOURCE_FILE_ATTR);
	private static final Key PREF_CODEGEN_UNUSED_LOCAL= getJDTCoreKey(JavaCore.COMPILER_CODEGEN_UNUSED_LOCAL);
	private static final Key PREF_CODEGEN_METHOD_PARAMETERS_ATTR= getJDTCoreKey(JavaCore.COMPILER_CODEGEN_METHOD_PARAMETERS_ATTR);

	// values
	private static final String GENERATE= JavaCore.GENERATE;
	private static final String DO_NOT_GENERATE= JavaCore.DO_NOT_GENERATE;

	private static final String PRESERVE= JavaCore.PRESERVE;
	private static final String OPTIMIZE_OUT= JavaCore.OPTIMIZE_OUT;

	private static final String VERSION_CLDC_1_1= JavaCore.VERSION_CLDC_1_1;
	private static final String VERSION_1_1= JavaCore.VERSION_1_1;
	private static final String VERSION_1_2= JavaCore.VERSION_1_2;
	private static final String VERSION_1_3= JavaCore.VERSION_1_3;

	private static final String VERSION_1_4= JavaCore.VERSION_1_4;
	private static final String VERSION_1_5= JavaCore.VERSION_1_5;
	private static final String VERSION_1_6= JavaCore.VERSION_1_6;
	private static final String VERSION_1_7= JavaCore.VERSION_1_7;
	private static final String VERSION_1_8= JavaCore.VERSION_1_8;
	private static final String VERSION_9= JavaCore.VERSION_9;
	private static final String VERSION_10= JavaCore.VERSION_10;
	private static final String VERSION_11= JavaCore.VERSION_11;
	private static final String VERSION_12 = JavaCore.VERSION_12;
	private static final String VERSION_13 = JavaCore.VERSION_13;
	private static final String VERSION_14 = JavaCore.VERSION_14;
	private static final String VERSION_15 = JavaCore.VERSION_15;
	private static final String VERSION_16 = JavaCore.VERSION_16;
	private static final String VERSION_17 = JavaCore.VERSION_17;
	private static final String VERSION_LATEST = JavaCore.latestSupportedJavaVersion();
	private static final String VERSION_JSR14= "jsr14"; //$NON-NLS-1$

	private static final String ERROR= JavaCore.ERROR;
	private static final String WARNING= JavaCore.WARNING;
	private static final String INFO= JavaCore.INFO;
	private static final String IGNORE= JavaCore.IGNORE;

	private static final String ENABLED= JavaCore.ENABLED;
	private static final String DISABLED= JavaCore.DISABLED;

	private static final String DEFAULT_CONF= "default"; //$NON-NLS-1$
	private static final String USER_CONF= "user";	 //$NON-NLS-1$

	private ArrayList<Control> fComplianceFollowsEEControls;
	private ArrayList<Control> fComplianceControls;
	private ArrayList<Control> fComplianceChildControls;
	private PixelConverter fPixelConverter;

	/**
	 * Remembered user compliance (stored when {@link #INTR_DEFAULT_COMPLIANCE} is switched to
	 * {@link #DEFAULT_CONF}). Elements are identified by <code>IDX_*</code> constants.
	 *
	 * @see #IDX_ASSERT_AS_IDENTIFIER
	 * @see #IDX_ENUM_AS_IDENTIFIER
	 * @see #IDX_SOURCE_COMPATIBILITY
	 * @see #IDX_CODEGEN_TARGET_PLATFORM
	 * @see #IDX_COMPLIANCE
	 * @see #IDX_INLINE_JSR_BYTECODE
	 * @see #IDX_METHOD_PARAMETERS_ATTR
	 * @see #IDX_RELEASE
	 * @see #IDX_ENABLE_PREVIEW
	 * @see #IDX_REPORT_PREVIEW
	 */
	private String[] fRememberedUserCompliance;

	/**
	 * Stored compliance settings that were active when the page was first shown. May be
	 * <code>null</code>. Elements are identified by <code>IDX_*</code> constants.
	 *
	 * @see #IDX_ASSERT_AS_IDENTIFIER
	 * @see #IDX_ENUM_AS_IDENTIFIER
	 * @see #IDX_SOURCE_COMPATIBILITY
	 * @see #IDX_CODEGEN_TARGET_PLATFORM
	 * @see #IDX_COMPLIANCE
	 * @see #IDX_INLINE_JSR_BYTECODE
	 * @see #IDX_METHOD_PARAMETERS_ATTR
	 * @see #IDX_RELEASE
	 * @see #IDX_ENABLE_PREVIEW
	 * @see #IDX_REPORT_PREVIEW
	 */
	private String[] fOriginalStoredCompliance;

	private static final int IDX_ASSERT_AS_IDENTIFIER= 0;
	private static final int IDX_ENUM_AS_IDENTIFIER= 1;
	private static final int IDX_SOURCE_COMPATIBILITY= 2;
	private static final int IDX_CODEGEN_TARGET_PLATFORM= 3;
	private static final int IDX_COMPLIANCE= 4;
	private static final int IDX_INLINE_JSR_BYTECODE= 5;
	private static final int IDX_METHOD_PARAMETERS_ATTR= 6;
	private static final int IDX_RELEASE= 7;
	private static final int IDX_ENABLE_PREVIEW= 8;
	private static final int IDX_REPORT_PREVIEW= 9;

	private IStatus fComplianceStatus;

	private Link fJRE50InfoText;
	private Label fJRE50InfoImage;
	private Composite fControlsComposite;
	private ControlEnableState fBlockEnableState;
	private Button fCompilerReleaseCheck;
	private Button fEnablePreviewCheck;
	private Combo fReportPreviewCombo;

	public ComplianceConfigurationBlock(IStatusChangeListener context, IProject project, IWorkbenchPreferenceContainer container) {
		super(context, project, getKeys(project != null), container);
		setDefaultCompilerComplianceValues();

		fBlockEnableState= null;
		fComplianceFollowsEEControls= new ArrayList<>();
		fComplianceControls= new ArrayList<>();
		fComplianceChildControls= new ArrayList<>();

		fComplianceStatus= new StatusInfo();

		fRememberedUserCompliance= new String[] { // caution: order depends on IDX_* constants
			getValue(PREF_PB_ASSERT_AS_IDENTIFIER),
			getValue(PREF_PB_ENUM_AS_IDENTIFIER),
			getValue(PREF_SOURCE_COMPATIBILITY),
			getValue(PREF_CODEGEN_TARGET_PLATFORM),
			getValue(PREF_COMPLIANCE),
			getValue(PREF_CODEGEN_INLINE_JSR_BYTECODE),
			getValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR),
			getValue(PREF_RELEASE),
			getValue(PREF_ENABLE_PREVIEW),
			getValue(PREF_PB_REPORT_PREVIEW)
		};
	}

	public static Key[] getKeys(boolean projectSpecific) {
		Key[] keys= new Key[] {
				PREF_LOCAL_VARIABLE_ATTR, PREF_LINE_NUMBER_ATTR, PREF_SOURCE_FILE_ATTR, PREF_CODEGEN_UNUSED_LOCAL, PREF_CODEGEN_INLINE_JSR_BYTECODE, INTR_DEFAULT_COMPLIANCE,
				PREF_COMPLIANCE, PREF_SOURCE_COMPATIBILITY,
				PREF_CODEGEN_TARGET_PLATFORM, PREF_PB_ASSERT_AS_IDENTIFIER, PREF_PB_ENUM_AS_IDENTIFIER, PREF_CODEGEN_METHOD_PARAMETERS_ATTR, PREF_RELEASE,
				PREF_ENABLE_PREVIEW, PREF_PB_REPORT_PREVIEW
			};

		if (projectSpecific) {
			Key[] allKeys = new Key[keys.length + 1];
			System.arraycopy(keys, 0, allKeys, 0, keys.length);
			allKeys[keys.length]= INTR_COMPLIANCE_FOLLOWS_EE;
			return allKeys;
		}

		return keys;
	}

	@Override
	protected void settingsUpdated() {
		setValue(INTR_DEFAULT_COMPLIANCE, getCurrentCompliance());
		updateComplianceFollowsEE();
		super.settingsUpdated();
	}

	/*
	 * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite)
	 */
	@Override
	protected Control createContents(Composite parent) {
		fPixelConverter= new PixelConverter(parent);
		setShell(parent.getShell());

		Composite complianceComposite= createComplianceTabContent(parent);

		validateSettings(null, null, null);

		return complianceComposite;
	}

	public void enablePreferenceContent(boolean enable) {
		if (fControlsComposite != null && !fControlsComposite.isDisposed()) {
			if (enable) {
				if (fBlockEnableState != null) {
					fBlockEnableState.restore();
					fBlockEnableState= null;
				}
			} else {
				if (fBlockEnableState == null) {
					fBlockEnableState= ControlEnableState.disable(fControlsComposite);
				}
			}
		}
	}

	private Composite createComplianceTabContent(Composite folder) {

		final String[] complianceVersions= new String[] { VERSION_1_3, VERSION_1_4,
				VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12, VERSION_13, VERSION_14, VERSION_15, VERSION_16, VERSION_17 };
		final String[] complianceLabels= new String[] {
			PreferencesMessages.ComplianceConfigurationBlock_version13,
			PreferencesMessages.ComplianceConfigurationBlock_version14,
			PreferencesMessages.ComplianceConfigurationBlock_version15,
			PreferencesMessages.ComplianceConfigurationBlock_version16,
			PreferencesMessages.ComplianceConfigurationBlock_version17,
			PreferencesMessages.ComplianceConfigurationBlock_version18,
			PreferencesMessages.ComplianceConfigurationBlock_version9,
			PreferencesMessages.ComplianceConfigurationBlock_version10,
			PreferencesMessages.ComplianceConfigurationBlock_version_11,
			PreferencesMessages.ComplianceConfigurationBlock_version_12,
			PreferencesMessages.ComplianceConfigurationBlock_version_13,
			PreferencesMessages.ComplianceConfigurationBlock_version_14,
			PreferencesMessages.ComplianceConfigurationBlock_version_15,
			PreferencesMessages.ComplianceConfigurationBlock_version_16,
			PreferencesMessages.ComplianceConfigurationBlock_version_17,
		};

		String[] targetVersions= new String[] { VERSION_CLDC_1_1, VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4,
				VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12, VERSION_13, VERSION_14, VERSION_15, VERSION_16, VERSION_17 };
		String[] targetLabels= new String[] {
				PreferencesMessages.ComplianceConfigurationBlock_versionCLDC11,
				PreferencesMessages.ComplianceConfigurationBlock_version11,
				PreferencesMessages.ComplianceConfigurationBlock_version12,
				PreferencesMessages.ComplianceConfigurationBlock_version13,
				PreferencesMessages.ComplianceConfigurationBlock_version14,
				PreferencesMessages.ComplianceConfigurationBlock_version15,
				PreferencesMessages.ComplianceConfigurationBlock_version16,
				PreferencesMessages.ComplianceConfigurationBlock_version17,
				PreferencesMessages.ComplianceConfigurationBlock_version18,
				PreferencesMessages.ComplianceConfigurationBlock_version9,
				PreferencesMessages.ComplianceConfigurationBlock_version10,
				PreferencesMessages.ComplianceConfigurationBlock_version_11,
				PreferencesMessages.ComplianceConfigurationBlock_version_12,
				PreferencesMessages.ComplianceConfigurationBlock_version_13,
				PreferencesMessages.ComplianceConfigurationBlock_version_14,
				PreferencesMessages.ComplianceConfigurationBlock_version_15,
				PreferencesMessages.ComplianceConfigurationBlock_version_16,
				PreferencesMessages.ComplianceConfigurationBlock_version_17,
		};
		if (ComplianceConfigurationBlock.VERSION_JSR14.equals(getValue(PREF_CODEGEN_TARGET_PLATFORM))) {
			targetVersions= append(targetVersions, ComplianceConfigurationBlock.VERSION_JSR14);
			targetLabels= append(targetLabels, ComplianceConfigurationBlock.VERSION_JSR14);
		}

		String[] sourceVersions= new String[] { VERSION_1_3, VERSION_1_4,
				VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12, VERSION_13, VERSION_14, VERSION_15, VERSION_16, VERSION_17 };
		String[] sourceLabels= new String[] {
				PreferencesMessages.ComplianceConfigurationBlock_version13,
				PreferencesMessages.ComplianceConfigurationBlock_version14,
				PreferencesMessages.ComplianceConfigurationBlock_version15,
				PreferencesMessages.ComplianceConfigurationBlock_version16,
				PreferencesMessages.ComplianceConfigurationBlock_version17,
				PreferencesMessages.ComplianceConfigurationBlock_version18,
				PreferencesMessages.ComplianceConfigurationBlock_version9,
				PreferencesMessages.ComplianceConfigurationBlock_version10,
				PreferencesMessages.ComplianceConfigurationBlock_version_11,
				PreferencesMessages.ComplianceConfigurationBlock_version_12,
				PreferencesMessages.ComplianceConfigurationBlock_version_13,
				PreferencesMessages.ComplianceConfigurationBlock_version_14,
				PreferencesMessages.ComplianceConfigurationBlock_version_15,
				PreferencesMessages.ComplianceConfigurationBlock_version_16,
				PreferencesMessages.ComplianceConfigurationBlock_version_17,
		};

		final ScrolledPageContent sc1 = new ScrolledPageContent(folder);
		Composite composite= sc1.getBody();
		GridLayout layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		composite.setLayout(layout);

		fControlsComposite= new Composite(composite, SWT.NONE);
		fControlsComposite.setFont(composite.getFont());
		fControlsComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));

		layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.numColumns= 1;
		fControlsComposite.setLayout(layout);

		int nColumns= 3;

		layout= new GridLayout();
		layout.numColumns= nColumns;

		Group group= new Group(fControlsComposite, SWT.NONE);
		group.setFont(fControlsComposite.getFont());
		group.setText(PreferencesMessages.ComplianceConfigurationBlock_compliance_group_label);
		group.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
		group.setLayout(layout);

		String[] defaultUserValues= new String[] { DEFAULT_CONF, USER_CONF };

		Control[] otherChildren= group.getChildren();
		if (fProject != null) {
			String label= PreferencesMessages.ComplianceConfigurationBlock_compliance_follows_EE_label;
			int widthHint= fPixelConverter.convertWidthInCharsToPixels(40);
			addCheckBoxWithLink(group, label, INTR_COMPLIANCE_FOLLOWS_EE, defaultUserValues, 0, widthHint, new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					openBuildPathPropertyPage();
				}
			});
		}

		Control[] allChildren= group.getChildren();
		fComplianceFollowsEEControls.addAll(Arrays.asList(allChildren));
		fComplianceFollowsEEControls.removeAll(Arrays.asList(otherChildren));
		otherChildren= allChildren;


		String label= PreferencesMessages.ComplianceConfigurationBlock_compiler_compliance_label;
		addComboBox(group, label, PREF_COMPLIANCE, complianceVersions, complianceLabels, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_backwardcompatibility_label;
		fCompilerReleaseCheck= addCheckBox(group, label, PREF_RELEASE, new String[] { DISABLED, ENABLED }, 0, false);

		label= PreferencesMessages.ComplianceConfigurationBlock_default_settings_label;
		addCheckBox(group, label, INTR_DEFAULT_COMPLIANCE, defaultUserValues, 0);

		allChildren= group.getChildren();
		fComplianceControls.addAll(Arrays.asList(allChildren));
		fComplianceControls.removeAll(Arrays.asList(otherChildren));
		otherChildren= allChildren;


		int indent= LayoutUtil.getIndent();

		String[] warningInfoIgnore= new String[] { WARNING, INFO, IGNORE };
		String[] warningInfoIgnoreLabels= new String[] {
				PreferencesMessages.ComplianceConfigurationBlock_warning,
				PreferencesMessages.ComplianceConfigurationBlock_info,
				PreferencesMessages.ComplianceConfigurationBlock_ignore
		};

		label= Messages.format(PreferencesMessages.ComplianceConfigurationBlock_enable_preview_label, new String[] { getVersionLabel(VERSION_LATEST) });
		fEnablePreviewCheck= addCheckBox(group, label, PREF_ENABLE_PREVIEW, new String[] { ENABLED, DISABLED }, indent);
		label= PreferencesMessages.ComplianceConfigurationBlock_enable_preview_severity_label;
		fReportPreviewCombo= addComboBox(group, label, PREF_PB_REPORT_PREVIEW, warningInfoIgnore, warningInfoIgnoreLabels, indent * 2);
		fReportPreviewCombo.setEnabled(fEnablePreviewCheck.isEnabled() && fEnablePreviewCheck.getSelection());

		label= PreferencesMessages.ComplianceConfigurationBlock_codegen_targetplatform_label;
		addComboBox(group, label, PREF_CODEGEN_TARGET_PLATFORM, targetVersions, targetLabels, indent);

		label= PreferencesMessages.ComplianceConfigurationBlock_source_compatibility_label;
		addComboBox(group, label, PREF_SOURCE_COMPATIBILITY, sourceVersions, sourceLabels, indent);

		String[] errorWarningInfoIgnore= new String[] { ERROR, WARNING, INFO, IGNORE };

		String[] errorWarningInfoIgnoreLabels= new String[] {
			PreferencesMessages.ComplianceConfigurationBlock_error,
			PreferencesMessages.ComplianceConfigurationBlock_warning,
			PreferencesMessages.ComplianceConfigurationBlock_info,
			PreferencesMessages.ComplianceConfigurationBlock_ignore
		};

		label= PreferencesMessages.ComplianceConfigurationBlock_pb_assert_as_identifier_label;
		addComboBox(group, label, PREF_PB_ASSERT_AS_IDENTIFIER, errorWarningInfoIgnore, errorWarningInfoIgnoreLabels, indent);

		label= PreferencesMessages.ComplianceConfigurationBlock_pb_enum_as_identifier_label;
		addComboBox(group, label, PREF_PB_ENUM_AS_IDENTIFIER, errorWarningInfoIgnore, errorWarningInfoIgnoreLabels, indent);

		allChildren= group.getChildren();
		fComplianceChildControls.addAll(Arrays.asList(allChildren));
		fComplianceChildControls.removeAll(Arrays.asList(otherChildren));


		layout= new GridLayout();
		layout.numColumns= nColumns;

		group= new Group(fControlsComposite, SWT.NONE);
		group.setFont(fControlsComposite.getFont());
		group.setText(PreferencesMessages.ComplianceConfigurationBlock_classfiles_group_label);
		group.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
		group.setLayout(layout);

		String[] generateValues= new String[] { GENERATE, DO_NOT_GENERATE };
		String[] enableDisableValues= new String[] { ENABLED, DISABLED };

		label= PreferencesMessages.ComplianceConfigurationBlock_variable_attr_label;
		addCheckBox(group, label, PREF_LOCAL_VARIABLE_ATTR, generateValues, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_line_number_attr_label;
		addCheckBox(group, label, PREF_LINE_NUMBER_ATTR, generateValues, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_source_file_attr_label;
		addCheckBox(group, label, PREF_SOURCE_FILE_ATTR, generateValues, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_codegen_unused_local_label;
		addCheckBox(group, label, PREF_CODEGEN_UNUSED_LOCAL, new String[] { PRESERVE, OPTIMIZE_OUT }, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_codegen_inline_jsr_bytecode_label;
		addCheckBox(group, label, PREF_CODEGEN_INLINE_JSR_BYTECODE, enableDisableValues, 0);

		label= PreferencesMessages.ComplianceConfigurationBlock_codegen_method_parameters_attr;
		addCheckBox(group, label, PREF_CODEGEN_METHOD_PARAMETERS_ATTR, generateValues, 0);

		Composite infoComposite= new Composite(fControlsComposite, SWT.NONE);
		infoComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		infoComposite.setLayout(new GridLayout(2, false));

		fJRE50InfoImage= new Label(infoComposite, SWT.NONE);
		fJRE50InfoImage.setImage(JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING));
		GridData gd= new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false);
		fJRE50InfoImage.setLayoutData(gd);

		fJRE50InfoText= new Link(infoComposite, SWT.WRAP);
		fJRE50InfoText.setFont(composite.getFont());
		// set a text: not the real one, just for layouting
		fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info_project, new String[] { getVersionLabel(VERSION_1_3), getVersionLabel(VERSION_1_3) }));
		fJRE50InfoText.setVisible(false);
		fJRE50InfoText.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				if ("1".equals(e.text)) { //$NON-NLS-1$
					openJREInstallPreferencePage(false);
				} else if ("2".equals(e.text)) { //$NON-NLS-1$
					openJREInstallPreferencePage(true);
				} else {
					openBuildPathPropertyPage();
				}
			}
			@Override
			public void widgetSelected(SelectionEvent e) {
				widgetDefaultSelected(e);
			}
		});
		gd= new GridData(GridData.FILL, GridData.FILL, true, true);
		gd.widthHint= fPixelConverter.convertWidthInCharsToPixels(50);
		fJRE50InfoText.setLayoutData(gd);
		initializeReleaseCheckBox(false);
		updateReleaseOptionStatus();
		validateComplianceStatus();
		return sc1;
	}

	private void initializeReleaseCheckBox(boolean useProjectSpecificSettings) {
		if (fProject != null && !useProjectSpecificSettings) {
			String value= PREF_RELEASE.getStoredValue(new IScopeContext[] { new ProjectScope(fProject) }, false, null);
			if (value != null) {
				setValue(PREF_RELEASE, value);
				fCompilerReleaseCheck.setSelection(DISABLED.equals(value) ? false : true);
			} else {
				setValue(PREF_RELEASE, DISABLED);
				fCompilerReleaseCheck.setSelection(false);
			}
		} else {
			String value= PREF_RELEASE.getStoredValue(new IScopeContext[] { InstanceScope.INSTANCE }, false, null);
			if (value != null) {
				setValue(PREF_RELEASE, value);
				fCompilerReleaseCheck.setSelection(DISABLED.equals(value) ? false : true);
			} else {
				setValue(PREF_RELEASE, DISABLED);
				fCompilerReleaseCheck.setSelection(false);
			}
		}
	}

	private static String[] append(String[] versions, String version) {
		String[] result= new String[versions.length + 1];
		System.arraycopy(versions, 0, result, 0, versions.length);
		result[versions.length]= version;
		return result;
	}

	protected final void openBuildPathPropertyPage() {
		if (getPreferenceContainer() != null) {
			Map<Object, IClasspathEntry> data= new HashMap<>();
			data.put(BuildPathsPropertyPage.DATA_REVEAL_ENTRY, JavaRuntime.getDefaultJREContainerEntry());
			getPreferenceContainer().openPage(BuildPathsPropertyPage.PROP_ID, data);
		}
		updateReleaseOptionStatus();
		validateComplianceStatus();
	}

	protected final void openJREInstallPreferencePage(boolean openEE) {
		String jreID= BuildPathSupport.JRE_PREF_PAGE_ID;
		String eeID= BuildPathSupport.EE_PREF_PAGE_ID;
		String pageId= openEE ? eeID : jreID;
		if (fProject == null && getPreferenceContainer() != null) {
			getPreferenceContainer().openPage(pageId, null);
		} else {
			PreferencesUtil.createPreferenceDialogOn(getShell(), pageId, new String[] { jreID, eeID }, null).open();
		}
		updateReleaseOptionStatus();
		validateComplianceStatus();
	}

	@Override
	protected void validateSettings(Key changedKey, String oldValue, String newValue) {
		if (!areSettingsEnabled()) {
			return;
		}
		if (changedKey != null) {
			if (INTR_DEFAULT_COMPLIANCE.equals(changedKey)) {
				updateComplianceEnableState();
				updateComplianceDefaultSettings(true, null);
				fComplianceStatus= validateCompliance();
			} else if (INTR_COMPLIANCE_FOLLOWS_EE.equals(changedKey)) {
				setValue(INTR_DEFAULT_COMPLIANCE, DEFAULT_CONF);
				updateReleaseOptionStatus();
				updateComplianceEnableState();
				updateComplianceDefaultSettings(true, null);
				updateControls();
				fComplianceStatus= validateCompliance();
				validateComplianceStatus();
			} else if (PREF_COMPLIANCE.equals(changedKey)) {
				updateReleaseOptionStatus();
			    // set compliance settings to default
			    Object oldDefault= getValue(INTR_DEFAULT_COMPLIANCE);
				boolean rememberOld= USER_CONF.equals(oldDefault);
				updateComplianceDefaultSettings(rememberOld, oldValue);
				fComplianceStatus= validateCompliance();
				validateComplianceStatus();
			} else if (PREF_RELEASE.equals(changedKey)) {
				setValue(PREF_RELEASE, DISABLED.equals(newValue) ? ENABLED : DISABLED);
				updateReleaseOptionStatus();
				updateComplianceDefaultSettings(true, null);
				fComplianceStatus= validateCompliance();
				validateComplianceStatus();
			} else if (PREF_SOURCE_COMPATIBILITY.equals(changedKey)) {
				updatePreviewFeaturesState();
				updateAssertEnumAsIdentifierEnableState();
				fComplianceStatus= validateCompliance();
			} else if (PREF_CODEGEN_TARGET_PLATFORM.equals(changedKey)) {
				if (VERSION_CLDC_1_1.equals(newValue) && !oldValue.equals(newValue)) {
					String compliance= getValue(PREF_COMPLIANCE);
					String source= getValue(PREF_SOURCE_COMPATIBILITY);
					if (!JavaModelUtil.isVersionLessThan(compliance, VERSION_1_5)) {
						setValue(PREF_COMPLIANCE, VERSION_1_4);
					}
					if (!VERSION_1_3.equals(source)) {
						setValue(PREF_SOURCE_COMPATIBILITY, VERSION_1_3);
					}
				}
				updateControls();
				updateInlineJSREnableState();
				updateStoreMethodParamNamesEnableState();
				updatePreviewFeaturesState();
				updateAssertEnumAsIdentifierEnableState();
				fComplianceStatus= validateCompliance();
			} else if (PREF_PB_ENUM_AS_IDENTIFIER.equals(changedKey) ||
					PREF_PB_ASSERT_AS_IDENTIFIER.equals(changedKey)) {
				fComplianceStatus= validateCompliance();
			} else if (PREF_ENABLE_PREVIEW.equals(changedKey)) {
				fComplianceStatus= validateCompliance();
				updatePreviewFeaturesState();
			} else if (PREF_PB_REPORT_PREVIEW.equals(changedKey)) {
				fComplianceStatus= validateCompliance();
			} else {
				return;
			}
		} else {
			updateComplianceFollowsEE();
			updateControls();
			updateComplianceEnableState();
			updatePreviewFeaturesState();
			updatePreviewControls();
			updateAssertEnumAsIdentifierEnableState();
			updateInlineJSREnableState();
			updateStoreMethodParamNamesEnableState();
			fComplianceStatus= validateCompliance();
			updateComplianceReleaseSettings();
			updateReleaseOptionStatus();
			validateComplianceStatus();
		}
		fContext.statusChanged(fComplianceStatus);
	}

	public void refreshComplianceSettings() {
		if (fOriginalStoredCompliance == null) {
			fOriginalStoredCompliance= new String[] { // caution: order depends on IDX_* constants
					getOriginalStoredValue(PREF_PB_ASSERT_AS_IDENTIFIER),
					getOriginalStoredValue(PREF_PB_ENUM_AS_IDENTIFIER),
					getOriginalStoredValue(PREF_SOURCE_COMPATIBILITY),
					getOriginalStoredValue(PREF_CODEGEN_TARGET_PLATFORM),
					getOriginalStoredValue(PREF_COMPLIANCE),
					getOriginalStoredValue(PREF_CODEGEN_INLINE_JSR_BYTECODE),
					getOriginalStoredValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR),
					getOriginalStoredValue(PREF_RELEASE),
					getOriginalStoredValue(PREF_ENABLE_PREVIEW),
					getOriginalStoredValue(PREF_PB_REPORT_PREVIEW)
				};

		} else {
			String[] storedCompliance= new String[] {
					getOriginalStoredValue(PREF_PB_ASSERT_AS_IDENTIFIER),
					getOriginalStoredValue(PREF_PB_ENUM_AS_IDENTIFIER),
					getOriginalStoredValue(PREF_SOURCE_COMPATIBILITY),
					getOriginalStoredValue(PREF_CODEGEN_TARGET_PLATFORM),
					getOriginalStoredValue(PREF_COMPLIANCE),
					getOriginalStoredValue(PREF_CODEGEN_INLINE_JSR_BYTECODE),
					getOriginalStoredValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR),
					getOriginalStoredValue(PREF_RELEASE),
					getOriginalStoredValue(PREF_ENABLE_PREVIEW),
					getOriginalStoredValue(PREF_PB_REPORT_PREVIEW)
				};
			if (!Arrays.equals(fOriginalStoredCompliance, storedCompliance)) {
				// compliance changed on disk -> override user modifications

				fOriginalStoredCompliance= storedCompliance;

				setValue(PREF_PB_ASSERT_AS_IDENTIFIER, storedCompliance[IDX_ASSERT_AS_IDENTIFIER]);
				setValue(PREF_PB_ENUM_AS_IDENTIFIER, storedCompliance[IDX_ENUM_AS_IDENTIFIER]);
				setValue(PREF_SOURCE_COMPATIBILITY, storedCompliance[IDX_SOURCE_COMPATIBILITY]);
				setValue(PREF_CODEGEN_TARGET_PLATFORM, storedCompliance[IDX_CODEGEN_TARGET_PLATFORM]);
				setValue(PREF_COMPLIANCE, storedCompliance[IDX_COMPLIANCE]);
				setValue(PREF_CODEGEN_INLINE_JSR_BYTECODE, storedCompliance[IDX_INLINE_JSR_BYTECODE]);
				setValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR, storedCompliance[IDX_METHOD_PARAMETERS_ATTR]);
				setValue(PREF_RELEASE, storedCompliance[IDX_RELEASE]);
				setValue(PREF_ENABLE_PREVIEW, storedCompliance[IDX_ENABLE_PREVIEW]);
				setValue(PREF_PB_REPORT_PREVIEW, storedCompliance[IDX_REPORT_PREVIEW]);
			}

			updateComplianceFollowsEE();
			updateControls();
			updateComplianceEnableState();
			validateComplianceStatus();
			updateInlineJSREnableState();
			updateAssertEnumAsIdentifierEnableState();
			updatePreviewFeaturesState();
			updateStoreMethodParamNamesEnableState();
		}
	}

	@Override
	public void performDefaults() {
		super.performDefaults();
		performReleasePreferenceDefault();
	}

	private void performReleasePreferenceDefault() {
		String defValue= getDefaultValue(PREF_RELEASE);
		if (defValue == null) {
			defValue= DISABLED;
		}
		fCompilerReleaseCheck.setSelection(DISABLED.equals(defValue) ? false : true);
		setValue(PREF_RELEASE, defValue);
		updateReleaseOptionStatus();
	}

	private void validateComplianceStatus() {
		if (fJRE50InfoText != null && !fJRE50InfoText.isDisposed()) {
			boolean isVisible= false;
			Image image= JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING);
			String compliance= getStoredValue(PREF_COMPLIANCE); // get actual value
			IVMInstall install= null;
			if (fProject != null) { // project specific settings: only test if a 50 JRE is installed
				try {
					install= JavaRuntime.getVMInstall(JavaCore.create(fProject));
				} catch (CoreException e) {
					JavaPlugin.log(e);
				}
			} else {
				install= JavaRuntime.getDefaultVMInstall();
			}
			boolean isJREUnsupportedAndGreater= false;
			if (install instanceof IVMInstall2) {
				String version= ((IVMInstall2) install).getJavaVersion();
				String compilerCompliance= JavaModelUtil.getCompilerCompliance((IVMInstall2) install, compliance);
				isJREUnsupportedAndGreater= isJREVersionUnsupportedAndGreater(version, compilerCompliance);
				if (isJREUnsupportedAndGreater) {
					version= getJREVersionString(version);
				}
				if (!compilerCompliance.equals(compliance)) { // Discourage using compiler with version other than compliance
					String[] args= { getVersionLabel(compliance), getVersionLabel(compilerCompliance) };
					if (isJREUnsupportedAndGreater) {
						args[1]= getVersionLabel(version);
					}
					if (JavaModelUtil.is9OrHigher(compilerCompliance)) {
						if (!JavaModelUtil.is1d6OrHigher(compliance) || !fCompilerReleaseCheck.getSelection()) {
							if (fProject == null) {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info, args));
							} else {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info_project, args));
							}
						} else {
							if (JavaModelUtil.is10OrHigher(compilerCompliance) && !JavaModelUtil.is12OrHigher(compilerCompliance)) {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_backwardcompatibility_warning, args));
							}
							else {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_backwardcompatibility_info, args));
								image= JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO);							}
						}
					} else {
						if (fProject == null) {
							fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info, args));
						} else {
							fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info_project, args));
						}
					}
					isVisible= true;
				} else {
					if (isJREUnsupportedAndGreater) {
						String[] args= { getVersionLabel(compilerCompliance), getVersionLabel(version) };
						if (fCompilerReleaseCheck.getSelection()) {
							fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_backwardcompatibility_info, args));
							image= JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO);
						} else {
							if (fProject == null) {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info, args));
							} else {
								fJRE50InfoText.setText(Messages.format(PreferencesMessages.ComplianceConfigurationBlock_jrecompliance_info_project, args));
							}
						}
						isVisible= true;
					}
				}
			}

			//TODO: Comment once Java SE 17 has been shipped:
//			String selectedCompliance= getValue(PREF_COMPLIANCE);
//			if (VERSION_17.equals(selectedCompliance)) {
//				fJRE50InfoText.setText(
//						"This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and is made available for testing and evaluation purposes only. The code is not compatible with any specification of the JCP."); //$NON-NLS-1$
//				isVisible= true;
//			}

			fJRE50InfoText.setVisible(isVisible);
			fJRE50InfoImage.setImage(isVisible ? image : null);
			fJRE50InfoImage.getParent().layout();
		}
	}

	private void updateReleaseOptionStatus() {
		if (fCompilerReleaseCheck != null && !fCompilerReleaseCheck.isDisposed()) {
			String compliance= getStoredValue(PREF_COMPLIANCE); // get actual value
			IVMInstall install= null;
			if (fProject != null) { // project specific settings: only test if a 50 JRE is installed
				try {
					install= JavaRuntime.getVMInstall(JavaCore.create(fProject));
				} catch (CoreException e) {
					JavaPlugin.log(e);
				}
			} else {
				install= JavaRuntime.getDefaultVMInstall();
			}
			if (install instanceof IVMInstall2) {
				String compilerCompliance= JavaModelUtil.getCompilerCompliance((IVMInstall2) install, compliance);
				String version= ((IVMInstall2) install).getJavaVersion();
				boolean isJREUnsupportedAndGreater= isJREVersionUnsupportedAndGreater(version, compilerCompliance);
				if (!compilerCompliance.equals(compliance)) { // Discourage using compiler with version other than compliance
					if (JavaModelUtil.is9OrHigher(compilerCompliance)) {
						if (!JavaModelUtil.isVersionLessThan(compliance, compilerCompliance)
								|| !JavaModelUtil.is1d6OrHigher(compliance)
								|| ( JavaModelUtil.is12OrHigher(compilerCompliance))
								&& !JavaModelUtil.is1d7OrHigher(compliance)) {
							fCompilerReleaseCheck.setEnabled(false);
							fCompilerReleaseCheck.setSelection(false);
							setValue(PREF_RELEASE, DISABLED);
						} else {
							if (fProject != null) {
								fCompilerReleaseCheck.setEnabled(checkValue(INTR_COMPLIANCE_FOLLOWS_EE, USER_CONF) || checkValue(INTR_COMPLIANCE_FOLLOWS_EE, DISABLED));
							} else {
								fCompilerReleaseCheck.setEnabled(true);
							}
						}
						updateComplianceEnableSourceTargetState();
					} else {
						fCompilerReleaseCheck.setEnabled(false);
						fCompilerReleaseCheck.setSelection(false);
						setValue(PREF_RELEASE, DISABLED);
					}
				} else if (!JavaModelUtil.is9OrHigher(compilerCompliance)) {
					fCompilerReleaseCheck.setEnabled(false);
					fCompilerReleaseCheck.setSelection(false);
					setValue(PREF_RELEASE, JavaCore.DISABLED);
				} else {
					if (fProject == null
							|| (isJREUnsupportedAndGreater && JavaModelUtil.is1d6OrHigher(compliance))
							|| JavaModelUtil.is9OrHigher(compliance)) {
						fCompilerReleaseCheck.setEnabled(true);
					}
					updateComplianceEnableSourceTargetState();
				}
			}
		}
	}

	private boolean isJREVersionUnsupportedAndGreater(String version, String compilerCompliance) {
		boolean isJREUnsupportedAndGreater= false;
		String versionStr= version;
		if (!JavaCore.isSupportedJavaVersion(versionStr)) {
			try {
				versionStr= getJREVersionString(versionStr);
				int jreVersion= Integer.parseInt(versionStr);
				int supportedVersion= Integer.parseInt(compilerCompliance);
				if (jreVersion > supportedVersion) {
					isJREUnsupportedAndGreater= true;
				}
			} catch (NumberFormatException e) {
				//do nothing
			}
		}
		return isJREUnsupportedAndGreater;
	}

	private String getJREVersionString(String version) {
		String newVersion= version;
		int index= newVersion.indexOf('.');
		if (index != -1) {
			newVersion= newVersion.substring(0, index);
		} else {
			index= newVersion.indexOf('-');
			if (index != -1)
				newVersion= newVersion.substring(0, index);
		}
		return newVersion;
	}

	private String getVersionLabel(String version) {
		return BasicElementLabels.getVersionName(version);
	}


	private IStatus validateCompliance() {
		StatusInfo status= new StatusInfo();
		String compliance= getValue(PREF_COMPLIANCE);
		String source= getValue(PREF_SOURCE_COMPATIBILITY);
		String target= getValue(PREF_CODEGEN_TARGET_PLATFORM);

		if (ComplianceConfigurationBlock.VERSION_JSR14.equals(target)) {
			target= source;
		}

		// compliance must not be smaller than source or target
		if (JavaModelUtil.isVersionLessThan(compliance, source)) {
			status.setError(PreferencesMessages.ComplianceConfigurationBlock_src_greater_compliance);
			return status;
		}

		if (JavaModelUtil.isVersionLessThan(compliance, target)) {
			status.setError(PreferencesMessages.ComplianceConfigurationBlock_classfile_greater_compliance);
			return status;
		}

		if (VERSION_CLDC_1_1.equals(target)) {
			if (!VERSION_1_3.equals(source) || !JavaModelUtil.isVersionLessThan(compliance, VERSION_1_5)) {
				status.setError(PreferencesMessages.ComplianceConfigurationBlock_cldc11_requires_source13_compliance_se14);
				return status;
			}
		}

		// target must not be smaller than source
		if (!VERSION_1_3.equals(source) && JavaModelUtil.isVersionLessThan(target, source)) {
			status.setError(PreferencesMessages.ComplianceConfigurationBlock_classfile_greater_source);
			return status;
		}

		return status;
	}


	@Override
	public void useProjectSpecificSettings(boolean enable) {
		super.useProjectSpecificSettings(enable);
		if (!enable) {
			initializeReleaseCheckBox(!enable);
		}
		updateReleaseOptionStatus();
		validateComplianceStatus();
	}

	private void updateComplianceFollowsEE() {
		if (fProject != null) {
			String complianceFollowsEE= DISABLED;
			IExecutionEnvironment ee= getEE();
			String label;
			if (ee != null) {
				complianceFollowsEE= getComplianceFollowsEE(ee);
				label= Messages.format(PreferencesMessages.ComplianceConfigurationBlock_compliance_follows_EE_with_EE_label, ee.getId());
			} else {
				label= PreferencesMessages.ComplianceConfigurationBlock_compliance_follows_EE_label;
			}
			Link checkBoxLink= getCheckBoxLink(INTR_COMPLIANCE_FOLLOWS_EE);
			if (checkBoxLink != null) {
				checkBoxLink.setText(label);
			}
			setValue(INTR_COMPLIANCE_FOLLOWS_EE, complianceFollowsEE);
		}
	}

	private void updateComplianceEnableState() {
		boolean enableComplianceControls= true;
		if (fProject != null) {
			boolean hasProjectSpecificOptions= hasProjectSpecificOptions(fProject);
			String complianceFollowsEE= getValue(INTR_COMPLIANCE_FOLLOWS_EE);
			updateCheckBox(getCheckBox(INTR_COMPLIANCE_FOLLOWS_EE));
			boolean enableComplianceFollowsEE= hasProjectSpecificOptions && ! DISABLED.equals(complianceFollowsEE); // is default or user
			updateControlsEnableState(fComplianceFollowsEEControls, enableComplianceFollowsEE);

			enableComplianceControls= hasProjectSpecificOptions && ! DEFAULT_CONF.equals(complianceFollowsEE); // is disabled or user
			updateControlsEnableState(fComplianceControls, enableComplianceControls);
		}

		boolean enableComplianceChildren= enableComplianceControls && checkValue(INTR_DEFAULT_COMPLIANCE, USER_CONF);
		updateControlsEnableState(fComplianceChildControls, enableComplianceChildren);
		updateReleaseOptionStatus();
	}

	private void updateComplianceEnableSourceTargetState() {
		boolean enableComplianceControls= true;
		if (fProject != null) {
			boolean hasProjectSpecificOptions= hasProjectSpecificOptions(fProject);
			String complianceFollowsEE= getValue(INTR_COMPLIANCE_FOLLOWS_EE);
			enableComplianceControls= hasProjectSpecificOptions && !DEFAULT_CONF.equals(complianceFollowsEE); // is disabled or user
		}
		boolean enableBasedOnRelease= !fCompilerReleaseCheck.getSelection() || !JavaModelUtil.is1d6OrHigher(getValue(PREF_COMPLIANCE));
		boolean enableComplianceChildren= enableComplianceControls && checkValue(INTR_DEFAULT_COMPLIANCE, USER_CONF) && enableBasedOnRelease;
		for (int i= fComplianceChildControls.size() - 1; i >= 0; i--) {
			Control curr= fComplianceChildControls.get(i);
			ControlData data= (ControlData) curr.getData();
			if (data != null) {
				if (PREF_SOURCE_COMPATIBILITY.equals(data.getKey())
						|| PREF_CODEGEN_TARGET_PLATFORM.equals(data.getKey())) {
					Combo combo= getComboBox(data.getKey());
					combo.setEnabled(enableComplianceChildren);
				}
			}
		}
	}

	private void updateControlsEnableState(List<Control> controls, boolean enable) {
		for (int i= controls.size() - 1; i >= 0; i--) {
			Control curr= controls.get(i);
			if (curr instanceof Composite) {
				updateControlsEnableState(Arrays.asList(((Composite)curr).getChildren()), enable);
			}
			curr.setEnabled(enable);
		}
		if (controls.contains(fReportPreviewCombo)) {
			fReportPreviewCombo.setEnabled(fEnablePreviewCheck.isEnabled() && fEnablePreviewCheck.getSelection());
		}
	}

	private void updatePreviewFeaturesState() {
		if (checkValue(INTR_DEFAULT_COMPLIANCE, USER_CONF)) {
			String compatibility= getValue(PREF_SOURCE_COMPATIBILITY);

			boolean isLessThanLatest= JavaModelUtil.isVersionLessThan(compatibility, VERSION_LATEST);
			updateRememberedComplianceOption(PREF_ENABLE_PREVIEW, IDX_ENABLE_PREVIEW, !isLessThanLatest, null);
			updateRememberedComplianceOption(PREF_PB_REPORT_PREVIEW, IDX_REPORT_PREVIEW, fEnablePreviewCheck.isEnabled() && fEnablePreviewCheck.getSelection(), WARNING);
		}
	}

	private void updatePreviewControls() {
		String compliance= getValue(PREF_COMPLIANCE);
		if (JavaCore.compareJavaVersions(compliance, VERSION_LATEST) < 0) {
			fEnablePreviewCheck.setSelection(false);
			fReportPreviewCombo.select(0);
		}
	}

	private void updateAssertEnumAsIdentifierEnableState() {
		if (checkValue(INTR_DEFAULT_COMPLIANCE, USER_CONF)) {
			String compatibility= getValue(PREF_SOURCE_COMPATIBILITY);

			boolean isLessThan14= VERSION_1_3.equals(compatibility);
			updateRememberedComplianceOption(PREF_PB_ASSERT_AS_IDENTIFIER, IDX_ASSERT_AS_IDENTIFIER, isLessThan14, ERROR);

			boolean isLessThan15= isLessThan14 || VERSION_1_4.equals(compatibility);
			updateRememberedComplianceOption(PREF_PB_ENUM_AS_IDENTIFIER, IDX_ENUM_AS_IDENTIFIER, isLessThan15, ERROR);
		}
	}

	private void updateRememberedComplianceOption(Key prefKey, int idx, boolean enabled, String defaultComboValue) {
		if (prefKey.getName().equals(PREF_ENABLE_PREVIEW.getName())) {
			Button checkBox= getCheckBox(prefKey);
			boolean wasCheckBoxEnabled= checkBox.isEnabled();
			checkBox.setEnabled(enabled);

			if (enabled) {
				if (!wasCheckBoxEnabled) {
					String val= fRememberedUserCompliance[idx];
					if (ENABLED.equals(val)) {
						setValue(PREF_ENABLE_PREVIEW, val);
						updateCheckBox(checkBox);
					}
				}
			} else {
				String val= getValue(PREF_ENABLE_PREVIEW);
				if (wasCheckBoxEnabled) {
					fRememberedUserCompliance[idx]= val;
				}

				if (ENABLED.equals(val)) {
					setValue(PREF_ENABLE_PREVIEW, DISABLED);
					updateCheckBox(checkBox);
				}
			}

		} else {
			Combo combo= getComboBox(prefKey);
			combo.setEnabled(enabled);

			if (!enabled) {
				String val= getValue(prefKey);
				if (!defaultComboValue.equals(val)) {
					setValue(prefKey, defaultComboValue);
					updateCombo(combo);
					fRememberedUserCompliance[idx]= val;
				}
			} else {
				String val= fRememberedUserCompliance[idx];
				if (!defaultComboValue.equals(val)) {
					setValue(prefKey, val);
					updateCombo(combo);
				}
			}
		}

	}

	private void updateInlineJSREnableState() {
		String target= getValue(PREF_CODEGEN_TARGET_PLATFORM);

		boolean enabled= JavaModelUtil.isVersionLessThan(target, VERSION_1_5);
		Button checkBox= getCheckBox(PREF_CODEGEN_INLINE_JSR_BYTECODE);
		boolean wasCheckBoxEnabled= checkBox.isEnabled();
		checkBox.setEnabled(enabled);

		if (!enabled) {
			String val= getValue(PREF_CODEGEN_INLINE_JSR_BYTECODE);
			if (wasCheckBoxEnabled)
				fRememberedUserCompliance[IDX_INLINE_JSR_BYTECODE]= val;

			if (!ENABLED.equals(val)) {
				setValue(PREF_CODEGEN_INLINE_JSR_BYTECODE, ENABLED);
				updateCheckBox(checkBox);
			}
		} else {
			if (!wasCheckBoxEnabled) {
				String val= fRememberedUserCompliance[IDX_INLINE_JSR_BYTECODE];
				if (!ENABLED.equals(val)) {
					setValue(PREF_CODEGEN_INLINE_JSR_BYTECODE, val);
					updateCheckBox(checkBox);
				}
			}
		}
	}

	private void updateStoreMethodParamNamesEnableState() {
		String target= getValue(PREF_CODEGEN_TARGET_PLATFORM);
		boolean enabled= JavaModelUtil.is1d8OrHigher(target);
		Button checkBox= getCheckBox(PREF_CODEGEN_METHOD_PARAMETERS_ATTR);
		boolean wasCheckBoxEnabled= checkBox.isEnabled();
		checkBox.setEnabled(enabled);

		if (enabled) {
			if (!wasCheckBoxEnabled) {
				String val= fRememberedUserCompliance[IDX_METHOD_PARAMETERS_ATTR];
				if (GENERATE.equals(val)) {
					setValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR, val);
					updateCheckBox(checkBox);
				}
			}
		} else {
			String val= getValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR);
			if (wasCheckBoxEnabled)
				fRememberedUserCompliance[IDX_METHOD_PARAMETERS_ATTR]= val;

			if (GENERATE.equals(val)) {
				setValue(PREF_CODEGEN_METHOD_PARAMETERS_ATTR, DO_NOT_GENERATE);
				updateCheckBox(checkBox);
			}
		}
	}

	/**
	 * Sets the default compliance values derived from the chosen level or restores the user
	 * compliance settings.
	 *
	 * @param rememberOld if <code>true</code>, the current compliance settings are remembered as
	 *            user settings. If <code>false</code>, overwrite the current settings.
	 * @param oldComplianceLevel the previous compliance level
	 */
	private void updateComplianceDefaultSettings(boolean rememberOld, String oldComplianceLevel) {
		String enablePreview, reportPreview, assertAsId, enumAsId, source, target;
		boolean isDefault= checkValue(INTR_DEFAULT_COMPLIANCE, DEFAULT_CONF);
		boolean isFollowEE= checkValue(INTR_COMPLIANCE_FOLLOWS_EE, DEFAULT_CONF);
		String complianceLevel= getValue(PREF_COMPLIANCE);
		boolean isRelease= checkValue(PREF_RELEASE, JavaCore.ENABLED) && JavaModelUtil.is1d6OrHigher(complianceLevel) && !isDefault;

		if (isDefault || isFollowEE || isRelease) {
			if (rememberOld) {
				if (oldComplianceLevel == null) {
					oldComplianceLevel= complianceLevel;
				}

				fRememberedUserCompliance[IDX_ENABLE_PREVIEW]= getValue(PREF_ENABLE_PREVIEW);
				fRememberedUserCompliance[IDX_REPORT_PREVIEW]= getValue(PREF_PB_REPORT_PREVIEW);
				fRememberedUserCompliance[IDX_ASSERT_AS_IDENTIFIER]= getValue(PREF_PB_ASSERT_AS_IDENTIFIER);
				fRememberedUserCompliance[IDX_ENUM_AS_IDENTIFIER]= getValue(PREF_PB_ENUM_AS_IDENTIFIER);
				fRememberedUserCompliance[IDX_SOURCE_COMPATIBILITY]= getValue(PREF_SOURCE_COMPATIBILITY);
				fRememberedUserCompliance[IDX_CODEGEN_TARGET_PLATFORM]= getValue(PREF_CODEGEN_TARGET_PLATFORM);
				fRememberedUserCompliance[IDX_RELEASE]= getValue(PREF_RELEASE);
				fRememberedUserCompliance[IDX_COMPLIANCE]= oldComplianceLevel;
			}

			if (isFollowEE) {
				IExecutionEnvironment ee= getEE();
				Map<String, String> eeOptions= BuildPathSupport.getEEOptions(ee);
				if (eeOptions == null)
					return;

				enablePreview= eeOptions.get(PREF_ENABLE_PREVIEW.getName());
				reportPreview= eeOptions.get(PREF_PB_REPORT_PREVIEW.getName());
				assertAsId= eeOptions.get(PREF_PB_ASSERT_AS_IDENTIFIER.getName());
				enumAsId= eeOptions.get(PREF_PB_ENUM_AS_IDENTIFIER.getName());
				source= eeOptions.get(PREF_SOURCE_COMPATIBILITY.getName());
				target= eeOptions.get(PREF_CODEGEN_TARGET_PLATFORM.getName());

				setValue(PREF_COMPLIANCE, eeOptions.get(PREF_COMPLIANCE.getName()));
				String inlineJSR= eeOptions.get(PREF_CODEGEN_INLINE_JSR_BYTECODE.getName());
				if (inlineJSR != null) {
					setValue(PREF_CODEGEN_INLINE_JSR_BYTECODE, inlineJSR);
				}
				String release= eeOptions.get(PREF_RELEASE.getName());
				if (release == null) {
					setValue(PREF_RELEASE, DISABLED);
					fCompilerReleaseCheck.setSelection(false);
				}

			} else if (isRelease) {
				enablePreview= getValue(PREF_ENABLE_PREVIEW);
				reportPreview= getValue(PREF_PB_REPORT_PREVIEW);
				source= getValue(PREF_COMPLIANCE);
				target= getValue(PREF_COMPLIANCE);
				assertAsId= getValue(PREF_PB_ASSERT_AS_IDENTIFIER);
				enumAsId= getValue(PREF_PB_ENUM_AS_IDENTIFIER);
			} else {
				HashMap<String, String> options= new HashMap<>();
				JavaModelUtil.setComplianceOptions(options, complianceLevel);
				if (complianceLevel.equals(options.get(JavaCore.COMPILER_COMPLIANCE))) {
					enablePreview= options.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES);
					reportPreview= options.get(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES);
					source= options.get(JavaCore.COMPILER_SOURCE);
					target= options.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
					assertAsId= options.get(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER);
					enumAsId= options.get(JavaCore.COMPILER_PB_ENUM_IDENTIFIER);
				} else {
					enablePreview= DISABLED;
					reportPreview= WARNING;
					assertAsId= IGNORE;
					enumAsId= IGNORE;
					source= VERSION_1_3;
					target= VERSION_1_1;
				}
			}
		} else {
			if (rememberOld && complianceLevel.equals(fRememberedUserCompliance[IDX_COMPLIANCE])) {
				enablePreview= fRememberedUserCompliance[IDX_ENABLE_PREVIEW];
				reportPreview= fRememberedUserCompliance[IDX_REPORT_PREVIEW];
				assertAsId= fRememberedUserCompliance[IDX_ASSERT_AS_IDENTIFIER];
				enumAsId= fRememberedUserCompliance[IDX_ENUM_AS_IDENTIFIER];
				source= fRememberedUserCompliance[IDX_SOURCE_COMPATIBILITY];
				target= fRememberedUserCompliance[IDX_CODEGEN_TARGET_PLATFORM];
			} else {
				updateInlineJSREnableState();
				updatePreviewFeaturesState();
				updateAssertEnumAsIdentifierEnableState();
				updateStoreMethodParamNamesEnableState();
				return;
			}
		}
		if (enablePreview == null) {
			enablePreview= DISABLED;
		}
		if (reportPreview == null) {
			reportPreview= WARNING;
		}
		setValue(PREF_ENABLE_PREVIEW, enablePreview);
		setValue(PREF_PB_REPORT_PREVIEW, reportPreview);
		setValue(PREF_PB_ASSERT_AS_IDENTIFIER, assertAsId);
		setValue(PREF_PB_ENUM_AS_IDENTIFIER, enumAsId);
		setValue(PREF_SOURCE_COMPATIBILITY, source);
		setValue(PREF_CODEGEN_TARGET_PLATFORM, target);
		updateControls();
		updateInlineJSREnableState();
		updatePreviewFeaturesState();
		updateAssertEnumAsIdentifierEnableState();
		updateStoreMethodParamNamesEnableState();
	}

	private void updateComplianceReleaseSettings() {
		String compliance= getValue(PREF_COMPLIANCE);
		boolean isRelease= checkValue(PREF_RELEASE, JavaCore.ENABLED) && JavaModelUtil.is1d6OrHigher(compliance);
		if (isRelease) {
			setValue(PREF_SOURCE_COMPATIBILITY, compliance);
			setValue(PREF_CODEGEN_TARGET_PLATFORM, compliance);
		}
	}

	/**
	 * Evaluate if the current compliance setting correspond to a default setting.
	 *
	 * @return {@link #DEFAULT_CONF} or {@link #USER_CONF}
	 */
	private String getCurrentCompliance() {
		String complianceLevel= getValue(PREF_COMPLIANCE);

		HashMap<String, String> defaultOptions= new HashMap<>();
		JavaModelUtil.setComplianceOptions(defaultOptions, complianceLevel);

		boolean isDefault= complianceLevel.equals(defaultOptions.get(JavaCore.COMPILER_COMPLIANCE))
				&& getValue(PREF_SOURCE_COMPATIBILITY).equals(defaultOptions.get(JavaCore.COMPILER_SOURCE))
				&& getValue(PREF_CODEGEN_TARGET_PLATFORM).equals(defaultOptions.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))
				&& getValue(PREF_PB_ASSERT_AS_IDENTIFIER).equals(defaultOptions.get(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER))
				&& getValue(PREF_PB_ENUM_AS_IDENTIFIER).equals(defaultOptions.get(JavaCore.COMPILER_PB_ENUM_IDENTIFIER));
		if (JavaCore.compareJavaVersions(complianceLevel, JavaCore.VERSION_10) > 0) {
			isDefault= isDefault
					&& getValue(PREF_ENABLE_PREVIEW).equals(defaultOptions.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES))
					&& getValue(PREF_PB_REPORT_PREVIEW).equals(defaultOptions.get(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES));
		}
		return isDefault ? DEFAULT_CONF : USER_CONF;
	}

	private IExecutionEnvironment getEE() {
		if (fProject == null)
			return null;

		try {
			for (IClasspathEntry entry : JavaCore.create(fProject).getRawClasspath()) {
				if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
					String eeId= JavaRuntime.getExecutionEnvironmentId(entry.getPath());
					if (eeId != null) {
						return JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(eeId);
					}
				}
			}
		} catch (CoreException e) {
			JavaPlugin.log(e);
		}
		return null;
	}

	/**
	 * Evaluate if the builds path contains an execution environment and the current compliance
	 * settings follow the EE options.
	 *
	 * @param ee the EE, or <code>null</code> if none available
	 * @return {@link #DEFAULT_CONF} if the compliance follows the EE, or {@link #USER_CONF} if the
	 *         settings differ, or {@link #DISABLED} if there's no EE at all
	 */
	private String getComplianceFollowsEE(IExecutionEnvironment ee) {
		Map<String, String> options= BuildPathSupport.getEEOptions(ee);
		if (options == null)
			return DISABLED;
		String complianceOption= options.get(JavaCore.COMPILER_COMPLIANCE);
		if (JavaCore.compareJavaVersions(complianceOption, JavaCore.VERSION_10) > 0) {
			return checkDefaults(PREFS_COMPLIANCE_11_OR_HIGHER, options);
		} else {
			return checkDefaults(PREFS_COMPLIANCE, options);
		}
	}

	private String checkDefaults(Key[] keys, Map<String, String> options) {
		for (Key key : keys) {
			Object option= options.get(key.getName());
			if (!checkValue(key, (String)option))
				return USER_CONF;
		}
		return DEFAULT_CONF;
	}

	@Override
	protected String[] getFullBuildDialogStrings(boolean workspaceSettings) {
		String title= PreferencesMessages.ComplianceConfigurationBlock_needsbuild_title;
		String message;
		if (workspaceSettings) {
			message= PreferencesMessages.ComplianceConfigurationBlock_needsfullbuild_message;
		} else {
			message= PreferencesMessages.ComplianceConfigurationBlock_needsprojectbuild_message;
		}
		return new String[] { title, message };
	}

	/**
	 * Sets the default compiler compliance options based on the current default JRE in the
	 * workspace.
	 *
	 * @since 3.5
	 */
	private void setDefaultCompilerComplianceValues() {
		IVMInstall defaultVMInstall= JavaRuntime.getDefaultVMInstall();
		if (defaultVMInstall instanceof IVMInstall2) {
			String complianceLevel= JavaModelUtil.getCompilerCompliance((IVMInstall2)defaultVMInstall, JavaCore.VERSION_1_4);
			if (isOriginalDefaultCompliance(complianceLevel)) {
				Map<String, String> complianceOptions= new HashMap<>();
				JavaModelUtil.setComplianceOptions(complianceOptions, complianceLevel);
				String releaseVal= complianceOptions.get(PREF_RELEASE.getName());
				setDefaultValue(PREF_COMPLIANCE, complianceOptions.get(PREF_COMPLIANCE.getName()));
				setDefaultValue(PREF_PB_ASSERT_AS_IDENTIFIER, complianceOptions.get(PREF_PB_ASSERT_AS_IDENTIFIER.getName()));
				setDefaultValue(PREF_PB_ENUM_AS_IDENTIFIER, complianceOptions.get(PREF_PB_ENUM_AS_IDENTIFIER.getName()));
				setDefaultValue(PREF_SOURCE_COMPATIBILITY, complianceOptions.get(PREF_SOURCE_COMPATIBILITY.getName()));
				setDefaultValue(PREF_CODEGEN_TARGET_PLATFORM, complianceOptions.get(PREF_CODEGEN_TARGET_PLATFORM.getName()));
				setDefaultValue(PREF_RELEASE, releaseVal != null ? releaseVal : DISABLED);
				if (JavaCore.compareJavaVersions(complianceLevel, JavaCore.VERSION_10) > 0) {
					setDefaultValue(PREF_ENABLE_PREVIEW, complianceOptions.get(PREF_ENABLE_PREVIEW.getName()));
					setDefaultValue(PREF_PB_REPORT_PREVIEW, complianceOptions.get(PREF_PB_REPORT_PREVIEW.getName()));
				} else {
					setDefaultValue(PREF_ENABLE_PREVIEW, DISABLED);
					setDefaultValue(PREF_PB_REPORT_PREVIEW, WARNING);
				}
			}
		}
	}

	/**
	 * Tells whether the compliance option is the same as the original default.
	 * @param complianceLevel the compliance level
	 *
	 * @return <code>true</code> if the compliance is the same as the original default
	 * @since 3.6
	 */
	private static final boolean isOriginalDefaultCompliance(String complianceLevel) {
		Hashtable<String, String> options= JavaCore.getDefaultOptions();
		Preferences bundleDefaults= BundleDefaultsScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);

		boolean isDefault= equals(JavaCore.COMPILER_COMPLIANCE, bundleDefaults, options)
				&& equals(JavaCore.COMPILER_SOURCE, bundleDefaults, options)
				&& equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, bundleDefaults, options)
				&& equals(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, bundleDefaults, options)
				&& equals(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, bundleDefaults, options)
				&& equals(JavaCore.COMPILER_RELEASE, bundleDefaults, options);
		if (JavaCore.compareJavaVersions(complianceLevel, JavaCore.VERSION_10) > 0) {
			isDefault= isDefault
					&& equals(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, bundleDefaults, options)
					&& equals(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, bundleDefaults, options);
		}
		return isDefault;
	}

	/**
	 * Returns whether the option for the given key is the same in the map and the preferences.
	 *
	 * @param key the key of option to test
	 * @param preferences the preferences
	 * @param map the map
	 * @return <code>true</code> if the options are the same in both maps
	 * @since 3.6
	 */
	private static boolean equals(String key, Preferences preferences, Map<String, String> map) {
		String dummy= ""; //$NON-NLS-1$
		String defaultValue= preferences.get(key, dummy);
		return defaultValue != null && defaultValue != dummy
				? map.containsKey(key) && equals(defaultValue, map.get(key))
				: !map.containsKey(key);
	}

	/**
	 * Returns whether the objects are equal.
	 *
	 * @param o1 an object
	 * @param o2 an object
	 * @return <code>true</code> if the two objects are equal
	 * @since 3.6
	 */
	private static boolean equals(Object o1, Object o2) {
		return o1 == null ? o2 == null : o1.equals(o2);
	}

}
