content: /*******************************************************************************
   * Copyright (c) 2000, 2008 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.wst.jsdt.internal.ui.preferences.formatter;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Observable;
  
  import org.eclipse.core.resources.IProject;
  import org.eclipse.core.resources.ProjectScope;
  import org.eclipse.core.resources.ResourcesPlugin;
  import org.eclipse.core.runtime.preferences.DefaultScope;
  import org.eclipse.core.runtime.preferences.IEclipsePreferences;
  import org.eclipse.core.runtime.preferences.IScopeContext;
  import org.eclipse.core.runtime.preferences.InstanceScope;
  import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
  import org.eclipse.wst.jsdt.internal.corext.util.Messages;
  import org.eclipse.wst.jsdt.internal.ui.preferences.PreferencesAccess;
  import org.eclipse.wst.jsdt.ui.JavaScriptUI;
  import org.osgi.service.prefs.BackingStoreException;
  
  /**
   * The model for the set of profiles which are available in the workbench.
   */
  public abstract class ProfileManager extends Observable {
  	
      public static final class KeySet {
  
  		private final List fKeys;
  		private final String fNodeName;
  
  		public KeySet(String nodeName, List keys) {
  			fNodeName= nodeName;
  			fKeys= keys;
          }
  
          public String getNodeName() {
  	        return fNodeName;
          }
  
          public List getKeys() {
  	        return fKeys;
          }
      }
  
  	/**
       * A prefix which is prepended to every ID of a user-defined profile, in order
       * to differentiate it from a built-in profile.
       */
  	public final static String ID_PREFIX= "_"; //$NON-NLS-1$
  	
  	/**
  	 * Represents a profile with a unique ID, a name and a map 
  	 * containing the code formatter settings.
  	 */
  	public static abstract class Profile implements Comparable {
  		
  		public abstract String getName();
  		public abstract Profile rename(String name, ProfileManager manager);
  		
  		public abstract Map getSettings();
  		public abstract void setSettings(Map settings);
  		
  		public abstract int getVersion();
  		
  		public boolean hasEqualSettings(Map otherMap, List allKeys) {
  			Map settings= getSettings();
  			for (Iterator iter= allKeys.iterator(); iter.hasNext(); ){
  				String key= (String) iter.next();
  				Object other= otherMap.get(key);
  				Object curr= settings.get(key);
  				if (other == null) {
  					if (curr != null) {
  						return false;
  					}
  				} else if (!other.equals(curr)) {
  					return false;
  				}
  			}
  			return true;
  		}
  		
  		public abstract boolean isProfileToSave();
  		
  		public abstract String getID();
  		
  		public boolean isSharedProfile() {
  			return false;
  		}
  		
  		public boolean isBuiltInProfile() {
  			return false;
  		}
  	}
  	
  	/**
  	 * Represents a built-in profile. The state of a built-in profile 
  	 * cannot be changed after instantiation.
  	 */
  	public static final class BuiltInProfile extends Profile {
  		private final String fName;
  		private final String fID;
  		private final Map fSettings;
  		private final int fOrder;
  		private final int fCurrentVersion;
  		private final String fProfileKind;
  		
  		public BuiltInProfile(String ID, String name, Map settings, int order, int currentVersion, String profileKind) {
  			fName= name;
  			fID= ID;
  			fSettings= settings;
  			fOrder= order;
  			fCurrentVersion= currentVersion;
  			fProfileKind= profileKind;
  		}
  		
  		public String getName() { 
  			return fName;	
  		}
  		
  		public Profile rename(String name, ProfileManager manager) {
  			final String trimmed= name.trim();
  		 	CustomProfile newProfile= new CustomProfile(trimmed, fSettings, fCurrentVersion, fProfileKind);
  		 	manager.addProfile(newProfile);
  			return newProfile;
  		}
  		
  		public Map getSettings() {
  			return fSettings;
  		}
  	
  		public void setSettings(Map settings) {
  		}
  	
  		public String getID() { 
  			return fID; 
  		}
  		
  		public final int compareTo(Object o) {
  			if (o instanceof BuiltInProfile) {
  				return fOrder - ((BuiltInProfile)o).fOrder;
  			}
  			return -1;
  		}
  
  		public boolean isProfileToSave() {
  			return false;
  		}
  		
  		public boolean isBuiltInProfile() {
  			return true;
  		}
  
          public int getVersion() {
  	        return fCurrentVersion;
          }
  	
  	}
  
  	/**
  	 * Represents a user-defined profile. A custom profile can be modified after instantiation.
  	 */
  	public static class CustomProfile extends Profile {
  		private String fName;
  		private Map fSettings;
  		protected ProfileManager fManager;
  		private int fVersion;
  		private final String fKind;
  
  		public CustomProfile(String name, Map settings, int version, String kind) {
  			fName= name;
  			fSettings= settings;
  			fVersion= version;
  			fKind= kind;
  		}
  		
  		public String getName() {
  			return fName;
  		}
  		
  		public Profile rename(String name, ProfileManager manager) {
  			final String trimmed= name.trim();
  			if (trimmed.equals(getName())) 
  				return this;
  			
  			String oldID= getID(); // remember old id before changing name
  			fName= trimmed;
  			
  			manager.profileRenamed(this, oldID);
  			return this;
  		}
  
  		public Map getSettings() { 
  			return fSettings;
  		}
  		
  		public void setSettings(Map settings) {
  			if (settings == null)
  				throw new IllegalArgumentException();
  			fSettings= settings;
  			if (fManager != null) {
  				fManager.profileChanged(this);
  			}
  		}
  		
  		public String getID() { 
  			return ID_PREFIX + fName;
  		}
  		
  		public void setManager(ProfileManager profileManager) {
  			fManager= profileManager;
  		}
  		
  		public ProfileManager getManager() {
  			return fManager;
  		}
  
  		public int getVersion() {
  			return fVersion;
  		}
  		
  		public void setVersion(int version)	{
  			fVersion= version;
  		}
  		
  		public int compareTo(Object o) {
  			if (o instanceof SharedProfile) {
  				return -1;
  			}
  			if (o instanceof CustomProfile) {
  				return getName().compareToIgnoreCase(((Profile)o).getName());
  			}
  			return 1;
  		}
  		
  		public boolean isProfileToSave() {
  			return true;
  		}
  
          public String getKind() {
  	        return fKind;
          }
  
  	}
  	
  	public final class SharedProfile extends CustomProfile {
  		
  		public SharedProfile(String oldName, Map options, int version, String profileKind) {
  			super(oldName, options, version, profileKind);
  		}
  		
  		public Profile rename(String name, ProfileManager manager) {
  			CustomProfile profile= new CustomProfile(name.trim(), getSettings(), getVersion(), getKind());
  
  			manager.profileReplaced(this, profile);
  			return profile;
  		}
  				
  		public String getID() { 
  			return SHARED_PROFILE;
  		}
  		
  		public final int compareTo(Object o) {
  			return 1;
  		}
  		
  		public boolean isProfileToSave() {
  			return false;
  		}
  		
  		public boolean isSharedProfile() {
  			return true;
  		}
  	}
  	
  
  	/**
  	 * The possible events for observers listening to this class.
  	 */
  	public final static int SELECTION_CHANGED_EVENT= 1;
  	public final static int PROFILE_DELETED_EVENT= 2;
  	public final static int PROFILE_RENAMED_EVENT= 3;
  	public final static int PROFILE_CREATED_EVENT= 4;
  	public final static int SETTINGS_CHANGED_EVENT= 5;
  	
  	
  	/**
  	 * The key of the preference where the selected profile is stored.
  	 */
  	private final String fProfileKey;
  	
  	/**
  	 * The key of the preference where the version of the current settings is stored
  	 */
  	private final String fProfileVersionKey;
  
  	
  	private final static String SHARED_PROFILE= "org.eclipse.wst.jsdt.ui.default.shared"; //$NON-NLS-1$
  	
  	
  	/**
  	 * A map containing the available profiles, using the IDs as keys.
  	 */
  	private final Map fProfiles;
  	
  	/**
  	 * The available profiles, sorted by name.
  	 */
  	private final List fProfilesByName;
  	
  
  	/**
  	 * The currently selected profile. 
  	 */
  	private Profile fSelected;
  	
  
  	/**
  	 * The keys of the options to be saved with each profile
  	 */
  	private final KeySet[] fKeySets;
  
  	private final PreferencesAccess fPreferencesAccess;
  	private final IProfileVersioner fProfileVersioner;
  
  	/**
  	 * Create and initialize a new profile manager.
  	 * @param profiles Initial custom profiles (List of type <code>CustomProfile</code>)
  	 * @param profileVersioner 
  	 */
  	public ProfileManager(
  			List profiles, 
  			IScopeContext context, 
  			PreferencesAccess preferencesAccess, 
  			IProfileVersioner profileVersioner,
  			KeySet[] keySets,
  			String profileKey,
  			String profileVersionKey) {
  		
  		fPreferencesAccess= preferencesAccess;
  		fProfileVersioner= profileVersioner;
  		fKeySets= keySets;
  		fProfileKey= profileKey;
  		fProfileVersionKey= profileVersionKey;
  		
  		fProfiles= new HashMap();
  		fProfilesByName= new ArrayList();
  	
  		for (final Iterator iter = profiles.iterator(); iter.hasNext();) {
  			final Profile profile= (Profile) iter.next();
  			if (profile instanceof CustomProfile) {
  				((CustomProfile)profile).setManager(this);
  			}
  			fProfiles.put(profile.getID(), profile);
  			fProfilesByName.add(profile);
  		}
  		
  		Collections.sort(fProfilesByName);
  		
  		String profileId= getSelectedProfileId(fPreferencesAccess.getInstanceScope());
  		
  		Profile profile= (Profile) fProfiles.get(profileId);
  		if (profile == null) {
  			profile= getDefaultProfile();
  		}
  		fSelected= profile;
  		
  		if (context.getName() == ProjectScope.SCOPE && hasProjectSpecificSettings(context)) {
  			Map map= readFromPreferenceStore(context, profile);
  			if (map != null) {
  				
  				List allKeys= new ArrayList();
  				for (int i= 0; i < fKeySets.length; i++) {
  			        allKeys.addAll(fKeySets[i].getKeys());
  		        }
  		        Collections.sort(allKeys);
  				
  				Profile matching= null;
  			
  				String projProfileId= context.getNode(JavaScriptUI.ID_PLUGIN).get(fProfileKey, null);
  				if (projProfileId != null) {
  					Profile curr= (Profile) fProfiles.get(projProfileId);
  					if (curr != null && (curr.isBuiltInProfile() || curr.hasEqualSettings(map, allKeys))) {
  						matching= curr;
  					}
  				} else {
  					// old version: look for similar
  					for (final Iterator iter = fProfilesByName.iterator(); iter.hasNext();) {
  						Profile curr= (Profile) iter.next();
  						if (curr.hasEqualSettings(map, allKeys)) {
  							matching= curr;
  							break;
  						}
  					}
  				}
  				if (matching == null) {
  					String name;
  					if (projProfileId != null && !fProfiles.containsKey(projProfileId)) {
  						name= Messages.format(FormatterMessages.ProfileManager_unmanaged_profile_with_name, projProfileId.substring(ID_PREFIX.length()));
  					} else {
  						name= FormatterMessages.ProfileManager_unmanaged_profile;
  					}
  					// current settings do not correspond to any profile -> create a 'team' profile
  					SharedProfile shared= new SharedProfile(name, map, fProfileVersioner.getCurrentVersion(), fProfileVersioner.getProfileKind());
  					shared.setManager(this);
  					fProfiles.put(shared.getID(), shared);
  					fProfilesByName.add(shared); // add last
  					matching= shared;
  				}
  				fSelected= matching;
  			}
  		}
  	}
  
  	protected String getSelectedProfileId(IScopeContext instanceScope) {
  		String profileId= instanceScope.getNode(JavaScriptUI.ID_PLUGIN).get(fProfileKey, null);
  		if (profileId == null) {
  			// request from bug 129427
  			profileId= new DefaultScope().getNode(JavaScriptUI.ID_PLUGIN).get(fProfileKey, null);
  		}
  	    return profileId;
      }
  
  	/**
  	 * Notify observers with a message. The message must be one of the following:
  	 * @param message Message to send out
  	 * 
  	 * @see #SELECTION_CHANGED_EVENT
  	 * @see #PROFILE_DELETED_EVENT
  	 * @see #PROFILE_RENAMED_EVENT
  	 * @see #PROFILE_CREATED_EVENT
  	 * @see #SETTINGS_CHANGED_EVENT
  	 */
  	protected void notifyObservers(int message) {
  		setChanged();
  		notifyObservers(Integer.valueOf(message));
  	}
  	
  	public static boolean hasProjectSpecificSettings(IScopeContext context, KeySet[] keySets) {
  		for (int i= 0; i < keySets.length; i++) {
  	        KeySet keySet= keySets[i];
  	        IEclipsePreferences preferences= context.getNode(keySet.getNodeName());
  	        for (final Iterator keyIter= keySet.getKeys().iterator(); keyIter.hasNext();) {
  	            final String key= (String)keyIter.next();
  	            Object val= preferences.get(key, null);
  	            if (val != null) {
  	            	return true;
  	            }
              }
          }
  		return false;
  	}
  	
  	public boolean hasProjectSpecificSettings(IScopeContext context) {
  		return hasProjectSpecificSettings(context, fKeySets);
  	}
  
  	/**
  	 * Only to read project specific settings to find out to what profile it matches.
  	 * @param context The project context
  	 */
  	private Map readFromPreferenceStore(IScopeContext context, Profile workspaceProfile) {
  		final Map profileOptions= new HashMap();
  		IEclipsePreferences uiPrefs= context.getNode(JavaScriptUI.ID_PLUGIN);
  				
  		int version= uiPrefs.getInt(fProfileVersionKey, fProfileVersioner.getFirstVersion());
  		if (version != fProfileVersioner.getCurrentVersion()) {
  			Map allOptions= new HashMap();
  			for (int i= 0; i < fKeySets.length; i++) {
  	            addAll(context.getNode(fKeySets[i].getNodeName()), allOptions);
              }
  			CustomProfile profile= new CustomProfile("tmp", allOptions, version, fProfileVersioner.getProfileKind()); //$NON-NLS-1$
  			fProfileVersioner.update(profile);
  			return profile.getSettings();
  		}
  		
  		boolean hasValues= false;
  		for (int i= 0; i < fKeySets.length; i++) {
  	        KeySet keySet= fKeySets[i];
  	        IEclipsePreferences preferences= context.getNode(keySet.getNodeName());
  	        for (final Iterator keyIter = keySet.getKeys().iterator(); keyIter.hasNext(); ) {
  				final String key= (String) keyIter.next();
  				Object val= preferences.get(key, null);
  				if (val != null) {
  					hasValues= true;
  				} else {
  					val= workspaceProfile.getSettings().get(key);
  				}
  				profileOptions.put(key, val);
  			}
          }
  		
  		if (!hasValues) {
  			return null;
  		}
  
  		setLatestCompliance(profileOptions);
  		return profileOptions;
  	}
  	
  	
  	/**
  	 * @param uiPrefs
  	 * @param allOptions
  	 */
  	private void addAll(IEclipsePreferences uiPrefs, Map allOptions) {
  		try {
  			String[] keys= uiPrefs.keys();
  			for (int i= 0; i < keys.length; i++) {
  				String key= keys[i];
  				String val= uiPrefs.get(key, null);
  				if (val != null) {
  					allOptions.put(key, val);
  				}
  			}
  		} catch (BackingStoreException e) {
  			// ignore
  		}
  		
  	}
  
  	private boolean updatePreferences(IEclipsePreferences prefs, List keys, Map profileOptions) {
  		boolean hasChanges= false;
  		for (final Iterator keyIter = keys.iterator(); keyIter.hasNext(); ) {
  			final String key= (String) keyIter.next();
  			final String oldVal= prefs.get(key, null);
  			final String val= (String) profileOptions.get(key);
  			if (val == null) {
  				if (oldVal != null) {
  					prefs.remove(key);
  					hasChanges= true;
  				}
  			} else if (!val.equals(oldVal)) {
  				prefs.put(key, val);
  				hasChanges= true;
  			}
  		}
  		return hasChanges;
  	}
  	
  	
  	/**
  	 * Update all formatter settings with the settings of the specified profile. 
  	 * @param profile The profile to write to the preference store
  	 */
  	private void writeToPreferenceStore(Profile profile, IScopeContext context) {
  		final Map profileOptions= profile.getSettings();
  		
  		for (int i= 0; i < fKeySets.length; i++) {
  	        updatePreferences(context.getNode(fKeySets[i].getNodeName()), fKeySets[i].getKeys(), profileOptions);
          }
  		
  		final IEclipsePreferences uiPrefs= context.getNode(JavaScriptUI.ID_PLUGIN);
  		if (uiPrefs.getInt(fProfileVersionKey, 0) != fProfileVersioner.getCurrentVersion()) {
  			uiPrefs.putInt(fProfileVersionKey, fProfileVersioner.getCurrentVersion());
  		}
  		
  		if (context.getName() == InstanceScope.SCOPE) {
  			uiPrefs.put(fProfileKey, profile.getID());
  		} else if (context.getName() == ProjectScope.SCOPE && !profile.isSharedProfile()) {
  			uiPrefs.put(fProfileKey, profile.getID());
  		}
  	}
  	
  		
  	/** 
  	 * Get an immutable list as view on all profiles, sorted alphabetically. Unless the set 
  	 * of profiles has been modified between the two calls, the sequence is guaranteed to 
  	 * correspond to the one returned by <code>getSortedNames</code>.
  	 * @return a list of elements of type <code>Profile</code>
  	 * 
  	 * @see #getSortedDisplayNames()
  	 */
  	public List getSortedProfiles() {
  		return Collections.unmodifiableList(fProfilesByName);
  	}
  
  	/**
  	 * Get the names of all profiles stored in this profile manager, sorted alphabetically. Unless the set of 
  	 * profiles has been modified between the two calls, the sequence is guaranteed to correspond to the one 
  	 * returned by <code>getSortedProfiles</code>.
  	 * @return All names, sorted alphabetically
  	 * @see #getSortedProfiles()  
  	 */	
  	public String[] getSortedDisplayNames() {
  		final String[] sortedNames= new String[fProfilesByName.size()];
  		int i= 0;
  		for (final Iterator iter = fProfilesByName.iterator(); iter.hasNext();) {
  			Profile curr= (Profile) iter.next();
  			sortedNames[i++]= curr.getName();
  		}
  		return sortedNames;
  	}
  	
  	/**
  	 * Get the profile for this profile id.
  	 * @param ID The profile ID
  	 * @return The profile with the given ID or <code>null</code> 
  	 */
  	public Profile getProfile(String ID) {
  		return (Profile)fProfiles.get(ID);
  	}
  	
  	/**
  	 * Activate the selected profile, update all necessary options in
  	 * preferences and save profiles to disk.
  	 */
  	public void commitChanges(IScopeContext scopeContext) {
  		if (fSelected != null) {
  			writeToPreferenceStore(fSelected, scopeContext);
  		}
  	}
  	
  	public void clearAllSettings(IScopeContext context) {
  		for (int i= 0; i < fKeySets.length; i++) {
  	        updatePreferences(context.getNode(fKeySets[i].getNodeName()), fKeySets[i].getKeys(), Collections.EMPTY_MAP);
          }
  		
  		final IEclipsePreferences uiPrefs= context.getNode(JavaScriptUI.ID_PLUGIN);
  		uiPrefs.remove(fProfileKey);
  	}
  	
  	/**
  	 * Get the currently selected profile.
  	 * @return The currently selected profile.
  	 */
  	public Profile getSelected() {
  		return fSelected;
  	}
  
  	/**
  	 * Set the selected profile. The profile must already be contained in this profile manager.
  	 * @param profile The profile to select
  	 */
  	public void setSelected(Profile profile) {
  		final Profile newSelected= (Profile)fProfiles.get(profile.getID());
  		if (newSelected != null && !newSelected.equals(fSelected)) {
  			fSelected= newSelected;
  			notifyObservers(SELECTION_CHANGED_EVENT);
  		}
  	}
  
  	/**
  	 * Check whether a user-defined profile in this profile manager
  	 * already has this name.
  	 * @param name The name to test for
  	 * @return Returns <code>true</code> if a profile with the given name exists
  	 */
  	public boolean containsName(String name) {
  		for (final Iterator iter = fProfilesByName.iterator(); iter.hasNext();) {
  			Profile curr= (Profile) iter.next();
  			if (name.equals(curr.getName())) {
  				return true;
  			}
  		}
  		return false;
  	}
  	
  	/**
  	 * Add a new custom profile to this profile manager.
  	 * @param profile The profile to add
  	 */	
  	public void addProfile(CustomProfile profile) {
  		profile.setManager(this);
  		final CustomProfile oldProfile= (CustomProfile)fProfiles.get(profile.getID());
  		if (oldProfile != null) {
  			fProfiles.remove(oldProfile.getID());
  			fProfilesByName.remove(oldProfile);
  			oldProfile.setManager(null);
  		}
  		fProfiles.put(profile.getID(), profile);
  		fProfilesByName.add(profile);
  		Collections.sort(fProfilesByName);
  		fSelected= profile;
  		notifyObservers(PROFILE_CREATED_EVENT);
  	}
  	
  	/**
  	 * Delete the currently selected profile from this profile manager. The next profile
  	 * in the list is selected.
  	 * @return true if the profile has been successfully removed, false otherwise.
  	 */
  	public boolean deleteSelected() {
  		if (!(fSelected instanceof CustomProfile)) 
  			return false;
  		
  		return deleteProfile((CustomProfile)fSelected);
  	}
  
  	public boolean deleteProfile(CustomProfile profile) {
  	    int index= fProfilesByName.indexOf(profile);
  		
  		fProfiles.remove(profile.getID());
  		fProfilesByName.remove(profile);
  		
  		profile.setManager(null);
  		
  		if (index >= fProfilesByName.size())
  			index--;
  		fSelected= (Profile) fProfilesByName.get(index);
  
  		if (!profile.isSharedProfile()) {
  			updateProfilesWithName(profile.getID(), null, false);
  		}
  		
  		notifyObservers(PROFILE_DELETED_EVENT);
  		return true;
      }
  
  	
  	public void profileRenamed(CustomProfile profile, String oldID) {
  		fProfiles.remove(oldID);
  		fProfiles.put(profile.getID(), profile);
  
  		if (!profile.isSharedProfile()) {
  			updateProfilesWithName(oldID, profile, false);
  		}
  		
  		Collections.sort(fProfilesByName);
  		notifyObservers(PROFILE_RENAMED_EVENT);
  	}
  	
  	public void profileReplaced(CustomProfile oldProfile, CustomProfile newProfile) {
  		fProfiles.remove(oldProfile.getID());
  		fProfiles.put(newProfile.getID(), newProfile);
  		fProfilesByName.remove(oldProfile);
  		fProfilesByName.add(newProfile);
  		Collections.sort(fProfilesByName);
  		
  		if (!oldProfile.isSharedProfile()) {
  			updateProfilesWithName(oldProfile.getID(), null, false);
  		}
  		
  		setSelected(newProfile);
  		notifyObservers(PROFILE_CREATED_EVENT);
  		notifyObservers(SELECTION_CHANGED_EVENT);
  	}
  	
  	public void profileChanged(CustomProfile profile) {
  		if (!profile.isSharedProfile()) {
  			updateProfilesWithName(profile.getID(), profile, true);
  		}
  		
  		notifyObservers(SETTINGS_CHANGED_EVENT);
  	}
  	
  	
  	protected void updateProfilesWithName(String oldName, Profile newProfile, boolean applySettings) {
  		IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
  		for (int i= 0; i < projects.length; i++) {
  			IScopeContext projectScope= fPreferencesAccess.getProjectScope(projects[i]);
  			IEclipsePreferences node= projectScope.getNode(JavaScriptUI.ID_PLUGIN);
  			String profileId= node.get(fProfileKey, null);
  			if (oldName.equals(profileId)) {
  				if (newProfile == null) {
  					node.remove(fProfileKey);
  				} else {
  					if (applySettings) {
  						writeToPreferenceStore(newProfile, projectScope);
  					} else {
  						node.put(fProfileKey, newProfile.getID());
  					}
  				}
  			}
  		}
  		
  		IScopeContext instanceScope= fPreferencesAccess.getInstanceScope();
  		final IEclipsePreferences uiPrefs= instanceScope.getNode(JavaScriptUI.ID_PLUGIN);
  		if (newProfile != null && oldName.equals(uiPrefs.get(fProfileKey, null))) {
  			writeToPreferenceStore(newProfile, instanceScope);
  		}
  	}
  	
  	private static void setLatestCompliance(Map map) {
  		JavaModelUtil.set50CompilanceOptions(map);
  	}
  
      public abstract Profile getDefaultProfile();
  
  	public IProfileVersioner getProfileVersioner() {
      	return fProfileVersioner;
      }
  }
  