/*******************************************************************************
 * Copyright (c) 2000, 2010 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.debug.internal.core;

 
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ibm.icu.text.MessageFormat;
 
/**
 * The information associated with a launch configuration handle.
 */
public class LaunchConfigurationInfo {
	
	/**
	 * Constants for XML element names and attributes
	 */
	private static final String KEY = "key"; //$NON-NLS-1$
	private static final String VALUE = "value"; //$NON-NLS-1$
	private static final String SET_ENTRY = "setEntry"; //$NON-NLS-1$
	private static final String LAUNCH_CONFIGURATION = "launchConfiguration"; //$NON-NLS-1$
	private static final String MAP_ENTRY = "mapEntry"; //$NON-NLS-1$
	private static final String LIST_ENTRY = "listEntry"; //$NON-NLS-1$
	private static final String SET_ATTRIBUTE = "setAttribute"; //$NON-NLS-1$
	private static final String MAP_ATTRIBUTE = "mapAttribute"; //$NON-NLS-1$
	private static final String LIST_ATTRIBUTE = "listAttribute"; //$NON-NLS-1$
	private static final String BOOLEAN_ATTRIBUTE = "booleanAttribute"; //$NON-NLS-1$
	private static final String INT_ATTRIBUTE = "intAttribute"; //$NON-NLS-1$
	private static final String STRING_ATTRIBUTE = "stringAttribute"; //$NON-NLS-1$
	private static final String TYPE = "type"; //$NON-NLS-1$
	
	/**
	 * This configurations attribute table. Keys are <code>String</code>s and
	 * values are one of <code>String</code>, <code>Integer</code>, or
	 * <code>Boolean</code>.
	 */
	private TreeMap fAttributes;
	
	/**
	 * This launch configuration's type
	 */
	private ILaunchConfigurationType fType;
	
	/**
	 * Whether running on Sun 1.4 VM - see bug 110215
	 */
	private static boolean fgIsSun14x = false;
	
	static {
		String vendor = System.getProperty("java.vm.vendor"); //$NON-NLS-1$
		if (vendor.startsWith("Sun Microsystems")) { //$NON-NLS-1$
			String version = System.getProperty("java.vm.version"); //$NON-NLS-1$
			if (version.startsWith("1.4")) { //$NON-NLS-1$
				fgIsSun14x = true;
			}
		}
	}
	
	/**
	 * Constructs a new empty info
	 */
	protected LaunchConfigurationInfo() {
		setAttributeTable(new TreeMap());
	}
	
	/**
	 * Returns this configuration's attribute table.
	 * 
	 * @return attribute table
	 */
	private TreeMap getAttributeTable() {
		return fAttributes;
	}

	/**
	 * Sets this configuration's attribute table.
	 * 
	 * @param table
	 *            attribute table
	 */	
	private void setAttributeTable(TreeMap table) {
		fAttributes = table;
	}
	
	/**
	 * Sets the attributes in this info to those in the given map.
	 * 
	 * @param map
	 */
	protected void setAttributes(Map map) {
		if (map == null) {
			setAttributeTable(new TreeMap());
			return;
		}
		setAttributeTable(new TreeMap(map));
	}
	
	/**
	 * Returns the <code>String</code> attribute with the given key or the
	 * given default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not a
	 *             <code>String</code>
	 */
	protected String getStringAttribute(String key, String defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof String) {
				return (String)attr;
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_Attribute__0__is_not_of_type_java_lang_String__1, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Returns the <code>int</code> attribute with the given key or the given
	 * default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not an
	 *             <code>int</code>
	 */
	protected int getIntAttribute(String key, int defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof Integer) {
				return ((Integer)attr).intValue();
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_Attribute__0__is_not_of_type_int__2, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Returns the <code>boolean</code> attribute with the given key or the
	 * given default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not a
	 *             <code>boolean</code>
	 */
	protected boolean getBooleanAttribute(String key, boolean defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof Boolean) {
				return ((Boolean)attr).booleanValue();
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_Attribute__0__is_not_of_type_boolean__3, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Returns the <code>java.util.List</code> attribute with the given key or
	 * the given default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not a
	 *             <code>java.util.List</code>
	 */
	protected List getListAttribute(String key, List defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof List) {
				return (List)attr;
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_Attribute__0__is_not_of_type_java_util_List__1, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Returns the <code>java.util.Set</code> attribute with the given key or
	 * the given default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not a
	 *             <code>java.util.Set</code>
	 * 
	 * @since 3.3
	 */
	protected Set getSetAttribute(String key, Set defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof Set) {
				return (Set)attr;
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_35, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Returns the <code>java.util.Map</code> attribute with the given key or
	 * the given default value if undefined.
	 * 
	 * @return attribute specified by given key or the defaultValue if undefined
	 * @throws CoreException
	 *             if the attribute with the given key exists but is not a
	 *             <code>java.util.Map</code>
	 */
	protected Map getMapAttribute(String key, Map defaultValue) throws CoreException {
		Object attr = getAttributeTable().get(key);
		if (attr != null) {
			if (attr instanceof Map) {
				return (Map)attr;
			} 
			throw new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_Attribute__0__is_not_of_type_java_util_Map__1, new String[] {key}), null 
				)
			);
		}
		return defaultValue;
	}
	
	/**
	 * Sets this configuration's type.
	 * 
	 * @param type
	 *            launch configuration type
	 */
	protected void setType(ILaunchConfigurationType type) {
		fType = type;
	}
	
	/**
	 * Returns this configuration's type.
	 * 
	 * @return launch configuration type
	 */
	protected ILaunchConfigurationType getType() {
		return fType;
	}	
	
	
	/**
	 * Returns a copy of this info object
	 * 
	 * @return copy of this info
	 */
	protected LaunchConfigurationInfo getCopy() {
		LaunchConfigurationInfo copy = new LaunchConfigurationInfo();
		copy.setType(getType());
		copy.setAttributeTable(getAttributes());
		return copy;
	}
	
	/**
	 * Returns a copy of this info's attribute map.
	 * 
	 * @return a copy of this info's attribute map
	 */
	protected TreeMap getAttributes() {
		return (TreeMap)getAttributeTable().clone();
	}
	
	/**
	 * Sets the given attribute to the given value. Only working copy's should
	 * use this API.
	 * 
	 * @param key
	 *            attribute key
	 * @param value
	 *            attribute value
	 */
	protected void setAttribute(String key, Object value) {
		if (value == null) {
			getAttributeTable().remove(key);
		} else {
			getAttributeTable().put(key, value);
		}
	}
	
	/**
	 * Returns the content of this info as XML
	 * 
	 * @return the content of this info as XML
	 * @throws CoreException
	 *             if a attribute has been set with a null key
	 * @throws IOException
	 *             if an exception occurs creating the XML
	 * @throws ParserConfigurationException
	 *             if an exception occurs creating the XML
	 * @throws TransformerException
	 *             if an exception occurs creating the XML
	 */
	protected String getAsXML() throws CoreException, IOException, ParserConfigurationException, TransformerException {

		Document doc = LaunchManager.getDocument();
		Element configRootElement = doc.createElement(LAUNCH_CONFIGURATION); 
		doc.appendChild(configRootElement);
		
		configRootElement.setAttribute(TYPE, getType().getIdentifier()); 
		
		Iterator keys = getAttributeTable().keySet().iterator();
		while (keys.hasNext()) {
			String key = (String)keys.next();
			if (key == null) {
				throw new DebugException(
					new Status(
						IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
						DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfigurationInfo_36, null 
					)
				);
			}
			Object value = getAttributeTable().get(key);
			if (value == null) {
				continue;
			}
			Element element = null;
			String valueString = null;
			if (value instanceof String) {
				valueString = (String)value;
				element = createKeyValueElement(doc, STRING_ATTRIBUTE, key, valueString); 
			} else if (value instanceof Integer) {
				valueString = ((Integer)value).toString();
				element = createKeyValueElement(doc, INT_ATTRIBUTE, key, valueString); 
			} else if (value instanceof Boolean) {
				valueString = ((Boolean)value).toString();
				element = createKeyValueElement(doc, BOOLEAN_ATTRIBUTE, key, valueString); 
			} else if (value instanceof List) {				
				element = createListElement(doc, LIST_ATTRIBUTE, key, (List)value); 
			} else if (value instanceof Map) {				
				element = createMapElement(doc, MAP_ATTRIBUTE, key, (Map)value); 
			} else if(value instanceof Set) {
				element = createSetElement(doc, SET_ATTRIBUTE, key, (Set)value); 
			}
			configRootElement.appendChild(element);
		}

		return LaunchManager.serializeDocument(doc);
	}
	
	/**
	 * Helper method that creates a 'key value' element of the specified type
	 * with the specified attribute values.
	 */
	protected Element createKeyValueElement(Document doc, String elementType, String key, String value) {
		Element element = doc.createElement(elementType);
		element.setAttribute(KEY, key); 
		element.setAttribute(VALUE, value);
		return element;
	}
	
	/**
	 * Creates a new <code>Element</code> for the specified
	 * <code>java.util.List</code>
	 * 
	 * @param doc the doc to add the element to
	 * @param elementType the type of the element
	 * @param setKey the key for the element
	 * @param list the list to fill the new element with
	 * @return the new element
	 */
	protected Element createListElement(Document doc, String elementType, String listKey, List list) {
		Element listElement = doc.createElement(elementType);
		listElement.setAttribute(KEY, listKey); 
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			String value = (String) iterator.next();
			Element element = doc.createElement(LIST_ENTRY); 
			element.setAttribute(VALUE, value);
			listElement.appendChild(element);
		}		
		return listElement;
	}
	
	/**
	 * Creates a new <code>Element</code> for the specified
	 * <code>java.util.Set</code>
	 * 
	 * @param doc the doc to add the element to
	 * @param elementType the type of the element
	 * @param setKey the key for the element
	 * @param set the set to fill the new element with
	 * @return the new element
	 * 
	 * @since 3.3
	 */
	protected Element createSetElement(Document doc, String elementType, String setKey, Set set) {
		Element setElement = doc.createElement(elementType);
		setElement.setAttribute(KEY, setKey);
		// persist in sorted order
		List list = new ArrayList(set);
		Collections.sort(list);
		Element element = null;
		for(Iterator iter = list.iterator(); iter.hasNext();) {
			element = doc.createElement(SET_ENTRY);
			element.setAttribute(VALUE, (String) iter.next());
			setElement.appendChild(element);
		}
		return setElement;
	}
	
	/**
	 * Creates a new <code>Element</code> for the specified
	 * <code>java.util.Map</code>
	 * 
	 * @param doc the doc to add the element to
	 * @param elementType the type of the element
	 * @param setKey the key for the element
	 * @param map the map to fill the new element with
	 * @return the new element
	 * 
	 */
	protected Element createMapElement(Document doc, String elementType, String mapKey, Map map) {
		Element mapElement = doc.createElement(elementType);
		mapElement.setAttribute(KEY, mapKey);
		// persist in sorted order based on keys
		List keys = new ArrayList(map.keySet());
		Collections.sort(keys);
		Iterator iterator = keys.iterator();
		while (iterator.hasNext()) {
			String key = (String) iterator.next();
			String value = (String) map.get(key);
			Element element = doc.createElement(MAP_ENTRY); 
			element.setAttribute(KEY, key); 
			element.setAttribute(VALUE, value); 
			mapElement.appendChild(element);
		}		
		return mapElement;		
	}
	
	/**
	 * Initializes the mapping of attributes from the XML file
	 * @param root the root node from the XML document
	 * @throws CoreException 
	 */
	protected void initializeFromXML(Element root) throws CoreException {
		if (!root.getNodeName().equalsIgnoreCase(LAUNCH_CONFIGURATION)) { 
			throw getInvalidFormatDebugException();
		}
		
		// read type
		String id = root.getAttribute(TYPE); 
		if (id == null) {
			throw getInvalidFormatDebugException();
		} 
		
		ILaunchConfigurationType type = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(id);
		if (type == null) {
			String message= MessageFormat.format(DebugCoreMessages.LaunchConfigurationInfo_missing_type, new Object[]{id}); 
			throw new DebugException(
					new Status(
					 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
					 DebugException.MISSING_LAUNCH_CONFIGURATION_TYPE, message, null)
				);
		}
		setType(type);
		
		NodeList list = root.getChildNodes();
		Node node = null;
		Element element = null;
		String nodeName = null;
		for (int i = 0; i < list.getLength(); ++i) {
			node = list.item(i);
			short nodeType = node.getNodeType();
			if (nodeType == Node.ELEMENT_NODE) {
				element = (Element) node;
				nodeName = element.getNodeName();
				if (nodeName.equalsIgnoreCase(STRING_ATTRIBUTE)) { 
					setStringAttribute(element);
				} else if (nodeName.equalsIgnoreCase(INT_ATTRIBUTE)) { 
					setIntegerAttribute(element);
				} else if (nodeName.equalsIgnoreCase(BOOLEAN_ATTRIBUTE))  { 
					setBooleanAttribute(element);
				} else if (nodeName.equalsIgnoreCase(LIST_ATTRIBUTE)) {   
					setListAttribute(element);					
				} else if (nodeName.equalsIgnoreCase(MAP_ATTRIBUTE)) {    
					setMapAttribute(element);										
				} else if(nodeName.equalsIgnoreCase(SET_ATTRIBUTE)) { 
					setSetAttribute(element);
				}
			}
		}
	}	
	
	/**
	 * Loads a <code>String</code> from the specified element into the local attribute mapping
	 * @param element the element to load from
	 * @throws CoreException
	 */
	protected void setStringAttribute(Element element) throws CoreException {
		setAttribute(getKeyAttribute(element), getValueAttribute(element));
	}
	
	/**
	 * Loads an <code>Integer</code> from the specified element into the local attribute mapping
	 * @param element the element to load from
	 * @throws CoreException
	 */
	protected void setIntegerAttribute(Element element) throws CoreException {
		setAttribute(getKeyAttribute(element), new Integer(getValueAttribute(element)));
	}
	
	/**
	 * Loads a <code>Boolean</code> from the specified element into the local attribute mapping
	 * @param element the element to load from
	 * @throws CoreException
	 */
	protected void setBooleanAttribute(Element element) throws CoreException {
		setAttribute(getKeyAttribute(element), Boolean.valueOf(getValueAttribute(element)));
	}
	
	/**
	 * Reads a <code>List</code> attribute from the specified XML node and
	 * loads it into the mapping of attributes
	 * 
	 * @param element the element to read the list attribute from
	 * @throws CoreException if the element has an invalid format
	 */
	protected void setListAttribute(Element element) throws CoreException {
		String listKey = element.getAttribute(KEY);  
		NodeList nodeList = element.getChildNodes();
		int entryCount = nodeList.getLength();
		List list = new ArrayList(entryCount);
		Node node = null;
		Element selement = null;
		for (int i = 0; i < entryCount; i++) {
			node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				selement = (Element) node;		
				if (!selement.getNodeName().equalsIgnoreCase(LIST_ENTRY)) { 
					throw getInvalidFormatDebugException();
				}
				list.add(getValueAttribute(selement));
			}
		}
		setAttribute(listKey, list);
	}
		
	/**
	 * Reads a <code>Set</code> attribute from the specified XML node and
	 * loads it into the mapping of attributes
	 * 
	 * @param element the element to read the set attribute from
	 * @throws CoreException if the element has an invalid format
	 * 
	 * @since 3.3
	 */
	protected void setSetAttribute(Element element) throws CoreException {
		String setKey = element.getAttribute(KEY);
		NodeList nodeList = element.getChildNodes();
		int entryCount = nodeList.getLength();
		Set set = new HashSet(entryCount);
		Node node = null;
		Element selement = null;
		for(int i = 0; i < entryCount; i++) {
			node = nodeList.item(i);
			if(node.getNodeType() == Node.ELEMENT_NODE) {
				selement = (Element)node;
				if(!selement.getNodeName().equalsIgnoreCase(SET_ENTRY)) { 
					throw getInvalidFormatDebugException();
				}
				set.add(getValueAttribute(selement));
			}
		}
		setAttribute(setKey, set);
	}
	
	/**
	 * Reads a <code>Map</code> attribute from the specified XML node and
	 * loads it into the mapping of attributes
	 * 
	 * @param element the element to read the map attribute from
	 * @throws CoreException if the element has an invalid format
	 */
	protected void setMapAttribute(Element element) throws CoreException {
		String mapKey = element.getAttribute(KEY);  
		NodeList nodeList = element.getChildNodes();
		int entryCount = nodeList.getLength();
		Map map = new HashMap(entryCount);
		Node node = null;
		Element selement = null;
		for (int i = 0; i < entryCount; i++) {
			node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				selement = (Element) node;		
				if (!selement.getNodeName().equalsIgnoreCase(MAP_ENTRY)) { 
					throw getInvalidFormatDebugException();
				}
				map.put(getKeyAttribute(selement), getValueAttribute(selement));
			}
		}
		setAttribute(mapKey, map);
	}
		
	/**
	 * Returns the <code>String</code> representation of the 'key' attribute from the specified element
	 * @param element the element to read from
	 * @return the value
	 * @throws CoreException
	 */
	protected String getKeyAttribute(Element element) throws CoreException {
		String key = element.getAttribute(KEY);
		if (key == null) {
			throw getInvalidFormatDebugException();
		}
		return key;
	}
	
	/**
	 * Returns the <code>String</code> representation of the 'value' attribute from the specified element
	 * @param element the element to read from
	 * @return the value
	 * @throws CoreException
	 */
	protected String getValueAttribute(Element element) throws CoreException {
		String value = element.getAttribute(VALUE);   
		if (value == null) {
			throw getInvalidFormatDebugException();
		}
		return value;
	}
	
	/**
	 * Returns an invalid format exception for reuse
	 * @return an invalid format exception
	 */
	protected DebugException getInvalidFormatDebugException() {
		return 
			new DebugException(
				new Status(
				 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
				 DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfigurationInfo_Invalid_launch_configuration_XML__10, null 
				)
			);
	}
	
	/**
	 * Two <code>LaunchConfigurationInfo</code> objects are equal if and only
	 * if they have the same type and they have the same set of attributes with
	 * the same values.
	 * 
	 * @see Object#equals(Object)
	 */
	public boolean equals(Object obj) {
		
		// Make sure it's a LaunchConfigurationInfo object
		if (!(obj instanceof LaunchConfigurationInfo)) {
			return false;
		}
		
		// Make sure the types are the same
		LaunchConfigurationInfo other = (LaunchConfigurationInfo) obj;
		if (!fType.getIdentifier().equals(other.getType().getIdentifier())) {
			return false;
		}
		
		// Make sure the attributes are the same
		return compareAttributes(fAttributes, other.getAttributeTable());
	}
	
	/**
	 * Returns whether the two attribute maps are equal, consulting registered
	 * comparator extensions.
	 * 
	 * @param map1  attribute map
	 * @param map2 attribute map
	 * @return whether the two attribute maps are equal
	 */
	protected boolean compareAttributes(TreeMap map1, TreeMap map2) {
		LaunchManager manager = (LaunchManager)DebugPlugin.getDefault().getLaunchManager();
		if (map1.size() == map2.size()) {
			Iterator attributes = map1.keySet().iterator();
			while (attributes.hasNext()) {
				String key = (String)attributes.next();
				Object attr1 = map1.get(key);
				Object attr2 = map2.get(key);
				if (attr2 == null) {
					return false;
				}
				Comparator comp = manager.getComparator(key);
				if (comp == null) {
					if (fgIsSun14x) {
						if(attr2 instanceof String & attr1 instanceof String) {
							// this is a hack for bug 110215, on SUN 1.4.x, \r
							// is stripped off when the stream is written to the
							// DOM
							// this is not the case for 1.5.x, so to be safe we
							// are stripping \r off all strings before we
							// compare for equality
							attr1 = ((String)attr1).replaceAll("\\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
							attr2 = ((String)attr2).replaceAll("\\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
						}
					}
					if (!attr1.equals(attr2)) {
						return false;
					}
				} else {
					if (comp.compare(attr1, attr2) != 0) {
						return false;
					}
				}
			}
			return true;	
		}
		return false;
	}
	
	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return fType.hashCode() + fAttributes.size();
	}

	/**
	 * Returns if the attribute map contains the specified key
	 * @param attributeName
	 * @return true if the attribute map contains the specified key, false otherwise
	 * 
	 * @since 3.4.0
	 */
	protected boolean hasAttribute(String attributeName) {
		return fAttributes.containsKey(attributeName);
	}
	
	/**
	 * Removes the specified attribute from the mapping and returns
	 * its value, or <code>null</code> if none. Does nothing
	 * if the attribute name is <code>null</code>
	 * @param attributeName
	 * @return attribute value or <code>null</code>
	 * 
	 * @since 3.4.0
	 */
	protected Object removeAttribute(String attributeName) {
		if(attributeName != null) {
			return fAttributes.remove(attributeName);
		}
		return null;
	}
}

