/*******************************************************************************
 * Copyright (c) 2001, 2011 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.internal.properties;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetEntry;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySource2;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.ui.views.properties.IPropertySourceExtension;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * An IPropertySource implementation for a JFace viewer used to display
 * properties of DOM nodes.
 */
public class XMLPropertySource implements IPropertySource, IPropertySourceExtension, IPropertySource2 {
	protected final static String CATEGORY_ATTRIBUTES = XMLUIMessages.XMLPropertySourceAdapter_0;

	/**
	 * Controls whether optional attributes are marked as for "experts"
	 */
	private static final boolean fSetExpertFilter = false;

	/**
	 * Controls whether to derive categories from CMDataTypes; disabled by
	 * default until display strings can be planned
	 */
	private boolean fShouldDeriveCategories = false;

	private final static boolean fSortEnumeratedValues = true;

	/**
	 * Note: we want the default fCaseSensitive to be true, but, to avoid
	 * meaningless double initialization, we leave default here, and set in
	 * constructor only.
	 */
	private boolean fCaseSensitive;
	private IPropertyDescriptor[] fDescriptors = null;
	private Node fNode = null;

	private Stack fValuesBeingSet = new Stack();

	public XMLPropertySource(INodeNotifier target) {
		super();
		fNode = initNode(target);
		fCaseSensitive = initCaseSensitive(fNode);
	}

	public XMLPropertySource(Node target, boolean useCategories) {
		super();
		initNode(target);
		fNode = target;
		fCaseSensitive = initCaseSensitive(fNode);
		fShouldDeriveCategories = useCategories;
	}

	/** Separate method just to isolate error processing */
	private static INodeNotifier initNode(Node target) {
		if (target instanceof INodeNotifier) {
			return (INodeNotifier) target;
		}
		throw new IllegalArgumentException("XMLPropertySource is only for INodeNotifiers"); //$NON-NLS-1$
	}

	/** Separate method just to isolate error processing */
	private static Node initNode(INodeNotifier target) {
		if (target instanceof Node) {
			return (Node) target;
		}
		throw new IllegalArgumentException("XMLPropertySource is only for W3C DOM Nodes"); //$NON-NLS-1$
	}

	private boolean initCaseSensitive(Node node) {
		// almost all tags are case sensitive, except that old HTML
		boolean caseSensitive = true;
		if (node instanceof IDOMNode) {
			DocumentTypeAdapter adapter = getDocTypeFromDOMNode(node);
			if (adapter != null) {
				caseSensitive = (adapter.getTagNameCase() == DocumentTypeAdapter.STRICT_CASE);
			}
		}
		return caseSensitive;
	}

	/**
	 * by "internal spec" the DOCTYPE adapter is only available from Document
	 * Node
	 * 
	 * @return {@link DocumentTypeAdapter}
	 */
	private DocumentTypeAdapter getDocTypeFromDOMNode(Node node) {
		DocumentTypeAdapter adapter = null;
		Document ownerDocument = node.getOwnerDocument();
		if (ownerDocument == null) {
			// if ownerDocument is null, then fNode must be the Document Node
			// [old, old comment]
			// hmmmm, guess not. See
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=130233
			// guess this is used for many INodeNotifiers, not just XML.
			// (and DTD's use IDOMNode? ... that doesn't sound quite right
			// ... but, maybe a separate issue).
			if (node instanceof Document) {
				ownerDocument = (Document) node;
			}
		}
		if (ownerDocument != null) {
			adapter = (DocumentTypeAdapter) ((INodeNotifier) ownerDocument).getAdapterFor(DocumentTypeAdapter.class);
		}

		return adapter;
	}

	private String[] _getValidFixedStrings(CMAttributeDeclaration attrDecl, CMDataType helper) {
		String attributeName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
		List values = new ArrayList(1);
		String impliedValue = helper.getImpliedValue();
		if (impliedValue != null) {
			values.add(impliedValue);
		}
		boolean checkIfCurrentValueIsIncluded = ((fNode.getAttributes() != null) && (fNode.getAttributes().getNamedItem(attributeName) != null) && (fNode.getAttributes().getNamedItem(attributeName).getNodeValue() != null));
		if (checkIfCurrentValueIsIncluded) {
			String currentValue = null;
			currentValue = fNode.getAttributes().getNamedItem(attributeName).getNodeValue();
			if (!currentValue.equals(impliedValue)) {
				values.add(currentValue);
			}
		}
		String[] validStrings = new String[values.size()];
		validStrings = (String[]) values.toArray(validStrings);
		return validStrings;
	}

	private String[] _getValidStrings(CMAttributeDeclaration attrDecl, CMDataType valuesHelper) {
		String attributeName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
		List values = new ArrayList(1);
		boolean currentValueKnown = false;
		boolean checkIfCurrentValueIsKnown = ((fNode.getAttributes() != null) && (fNode.getAttributes().getNamedItem(attributeName) != null) && (fNode.getAttributes().getNamedItem(attributeName).getNodeValue() != null));
		String currentValue = null;
		if (checkIfCurrentValueIsKnown) {
			currentValue = fNode.getAttributes().getNamedItem(attributeName).getNodeValue();
		}

		if ((valuesHelper.getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED) && (valuesHelper.getImpliedValue() != null)) {
			// FIXED value
			currentValueKnown = (currentValue != null) && valuesHelper.getImpliedValue().equals(currentValue);
			values.add(valuesHelper.getImpliedValue());
		}
		else {
			// ENUMERATED values
			String[] valueStrings = null;
			// valueStrings = valuesHelper.getEnumeratedValues();
			ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument());
			if ((modelQuery != null) && (fNode.getNodeType() == Node.ELEMENT_NODE)) {
				valueStrings = modelQuery.getPossibleDataTypeValues((Element) fNode, attrDecl);
			}
			else {
				valueStrings = attrDecl.getAttrType().getEnumeratedValues();
			}
			if (valueStrings != null) {
				for (int i = 0; i < valueStrings.length; i++) {
					if (checkIfCurrentValueIsKnown && valueStrings[i].equals(currentValue)) {
						currentValueKnown = true;
					}
					values.add(valueStrings[i]);
				}
			}
		}
		if ((valuesHelper.getImpliedValueKind() != CMDataType.IMPLIED_VALUE_NONE) && (valuesHelper.getImpliedValue() != null)) {
			if (!values.contains(valuesHelper.getImpliedValue())) {
				values.add(valuesHelper.getImpliedValue());
			}
		}

		if (checkIfCurrentValueIsKnown && !currentValueKnown && (currentValue != null) && (currentValue.length() > 0)) {
			values.add(currentValue);
		}
		String[] validStrings = new String[values.size()];
		validStrings = (String[]) values.toArray(validStrings);
		return validStrings;
	}

	private IPropertyDescriptor createDefaultPropertyDescriptor(String attributeName) {
		return createDefaultPropertyDescriptor(attributeName, false);
	}

	private IPropertyDescriptor createDefaultPropertyDescriptor(String attributeName, boolean hideOnFilter) {
		// The descriptor class used here is also used in
		// updatePropertyDescriptors()
		TextPropertyDescriptor descriptor = new TextPropertyDescriptor(attributeName, attributeName);
		descriptor.setCategory(getCategory(null, null));
		descriptor.setDescription(attributeName);
		if (hideOnFilter && fSetExpertFilter) {
			descriptor.setFilterFlags(new String[]{IPropertySheetEntry.FILTER_ID_EXPERT});
		}
		return descriptor;
	}

	/**
	 * Creates a property descriptor for an attribute with ENUMERATED values -
	 * if the value does not exist, an editable combo box is returned - if the
	 * value exists but is not one in the enumerated list of value, a combo
	 * box featuring the current and correct values is returned - if the value
	 * exists and it is a valid value, a combo box featuring the correct
	 * values with the current one visible is returned
	 */
	private IPropertyDescriptor createEnumeratedPropertyDescriptor(CMAttributeDeclaration attrDecl, CMDataType valuesHelper, Attr attr) {
		// the displayName MUST be set
		String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
		EnumeratedStringPropertyDescriptor descriptor = new EnumeratedStringPropertyDescriptor(attrName, attrName, _getValidStrings(attrDecl, valuesHelper));
		descriptor.setCategory(getCategory(attrDecl, attr));
		descriptor.setDescription(attrName);
		if ((attrDecl.getUsage() != CMAttributeDeclaration.REQUIRED) && fSetExpertFilter) {
			descriptor.setFilterFlags(new String[]{IPropertySheetEntry.FILTER_ID_EXPERT});
		}
		return descriptor;
	}

	/**
	 * Creates a property descriptor for an attribute with a FIXED value - if
	 * the value does not exist, an editable combo box is returned - if the
	 * value exists but is not the fixed/default value, a combo box featuring
	 * the current and correct value is returned - if the value exists and it
	 * is the fixed/default value, no cell editor is provided "locking" the
	 * value in
	 */
	private IPropertyDescriptor createFixedPropertyDescriptor(CMAttributeDeclaration attrDecl, CMDataType helper, Attr attr) {
		// the displayName MUST be set
		String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
		EnumeratedStringPropertyDescriptor descriptor = new EnumeratedStringPropertyDescriptor(attrName, attrName, _getValidFixedStrings(attrDecl, helper));
		descriptor.setCategory(getCategory(attrDecl, attr));
		descriptor.setDescription(DOMNamespaceHelper.computeName(attrDecl, fNode, null));
		return descriptor;
	}

	protected IPropertyDescriptor createPropertyDescriptor(CMAttributeDeclaration attrDecl, Attr attr) {
		IPropertyDescriptor descriptor = null;
		CMDataType attrType = attrDecl.getAttrType();

		if (attrType != null) {
			// handle declarations that provide FIXED/ENUMERATED values
			if ((attrType.getEnumeratedValues() != null) && (attrType.getEnumeratedValues().length > 0)) {
				descriptor = createEnumeratedPropertyDescriptor(attrDecl, attrType, attr);
			}
			else if (((attrDecl.getUsage() == CMAttributeDeclaration.FIXED) || (attrType.getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)) && (attrType.getImpliedValue() != null)) {
				descriptor = createFixedPropertyDescriptor(attrDecl, attrType, attr);
			}
			else {
				// plain text
				descriptor = createTextPropertyDescriptor(attrDecl, attr);
			}
		}
		else {
			// no extra information given
			descriptor = createTextPropertyDescriptor(attrDecl, attr);
		}
		return descriptor;
	}

	/**
	 * Returns the current collection of property descriptors.
	 * 
	 * @return all valid descriptors.
	 */
	private IPropertyDescriptor[] createPropertyDescriptors() {
		CMNamedNodeMap attrMap = null;
		CMElementDeclaration ed = getDeclaration();
		if (ed != null) {
			attrMap = ed.getAttributes();
			CMNamedNodeMapImpl allAttributes = new CMNamedNodeMapImpl(attrMap);
			List nodes = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument()).getAvailableContent((Element) fNode, ed, ModelQuery.INCLUDE_ATTRIBUTES);
			for (int k = 0; k < nodes.size(); k++) {
				CMNode cmnode = (CMNode) nodes.get(k);
				if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
					allAttributes.put(cmnode);
				}
			}
			attrMap = allAttributes;
		}

		List descriptorList = new ArrayList();
		List names = new ArrayList();
		IPropertyDescriptor descriptor;

		CMAttributeDeclaration attrDecl = null;

		// add descriptors for existing attributes
		NamedNodeMap attributes = fNode.getAttributes();
		if (attributes != null) {
			for (int i = 0; i < attributes.getLength(); i++) {
				Attr attr = (Attr) attributes.item(i);
				// if metainfo is present for this attribute, use the
				// CMAttributeDeclaration to derive a descriptor
				if (attrMap != null) {
					String attrName = attr.getName();
					if (fCaseSensitive) {
						attrDecl = (CMAttributeDeclaration) attrMap.getNamedItem(attrName);
					}
					else {
						attrDecl = null;
						for (int j = 0; j < attrMap.getLength(); j++) {
							if (!fCaseSensitive && attrMap.item(j).getNodeName().equalsIgnoreCase(attrName)) {
								attrDecl = (CMAttributeDeclaration) attrMap.item(j);
								break;
							}
						}
					}
				}
				// be consistent: if there's metainfo, use *that* as the
				// descriptor ID
				descriptor = null;
				if (attrDecl != null) {
					String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
					if (!names.contains(attrName)) {
						descriptor = createPropertyDescriptor(attrDecl, attr);
						if (descriptor != null)
							names.add(attrName);
					}
				}
				else {
					if (!names.contains(attr.getName())) {
						descriptor = createDefaultPropertyDescriptor(attr.getName());
						if (descriptor != null)
							names.add(attr.getName());
					}
				}
				if (descriptor != null) {
					descriptorList.add(descriptor);
				}
			}
		}

		// add descriptors from the metainfo that are not yet listed
		if (attrMap != null) {
			for (int i = 0; i < attrMap.getLength(); i++) {
				attrDecl = (CMAttributeDeclaration) attrMap.item(i);
				String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
				if (!names.contains(attrName)) {
					IPropertyDescriptor holdDescriptor = createPropertyDescriptor(attrDecl, null);
					if (holdDescriptor != null) {
						names.add(attrName);
						descriptorList.add(holdDescriptor);
					}
				}
			}
		}

		// add MQE-based descriptors
		if (ed != null && fNode.getNodeType() == Node.ELEMENT_NODE) {
			List nodes = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument()).getAvailableContent((Element) fNode, ed, ModelQuery.INCLUDE_ATTRIBUTES);
			for (int i = 0; i < nodes.size(); i++) {
				CMNode node = (CMNode) nodes.get(i);
				if (node.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
					attrDecl = (CMAttributeDeclaration) node;
					String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
					if (!names.contains(attrName)) {
						IPropertyDescriptor holdDescriptor = createPropertyDescriptor(attrDecl, null);
						if (holdDescriptor != null) {
							names.add(attrName);
							descriptorList.add(holdDescriptor);
						}
					}
				}
			}
		}


		IPropertyDescriptor[] descriptors = new IPropertyDescriptor[descriptorList.size()];
		for (int i = 0; i < descriptors.length; i++) {
			descriptors[i] = (IPropertyDescriptor) descriptorList.get(i);
		}
		return descriptors;
	}

	private IPropertyDescriptor createTextPropertyDescriptor(CMAttributeDeclaration attrDecl, Attr attr) {
		String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
		TextPropertyDescriptor descriptor = new TextPropertyDescriptor(attrName, attrName);
		descriptor.setCategory(getCategory(attrDecl, attr));
		descriptor.setDescription(attrName);
		if ((attrDecl.getUsage() != CMAttributeDeclaration.REQUIRED) && fSetExpertFilter) {
			descriptor.setFilterFlags(new String[]{IPropertySheetEntry.FILTER_ID_EXPERT});
		}
		return descriptor;
	}

	private String getCategory(CMAttributeDeclaration attrDecl, Attr attr) {
		if (attr != null) {
			String namespaceURI = attr.getNamespaceURI();
			if (namespaceURI == null)
				namespaceURI = attr.getOwnerElement().getNamespaceURI();
			if (namespaceURI != null)
				return namespaceURI;
		}
		if (attrDecl != null) {
			if (attrDecl.supports("category")) { //$NON-NLS-1$
				return (String) attrDecl.getProperty("category"); //$NON-NLS-1$
			}
			if (fShouldDeriveCategories && (attrDecl.getAttrType() != null) && (attrDecl.getAttrType().getDataTypeName() != null) && (attrDecl.getAttrType().getDataTypeName().length() > 0)) {
				return attrDecl.getAttrType().getDataTypeName();
			}
		}
		return CATEGORY_ATTRIBUTES;
	}

	private CMElementDeclaration getDeclaration() {
		if ((fNode == null) || (fNode.getNodeType() != Node.ELEMENT_NODE)) {
			return null;
		}
		ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument());
		if (modelQuery != null) {
			return modelQuery.getCMElementDeclaration((Element) fNode);
		}
		return null;
	}

	private Display getDisplay() {

		return PlatformUI.getWorkbench().getDisplay();
	}

	/**
	 * Returns a value for this Node that can be editted in a property sheet.
	 * 
	 * @return a value that can be editted
	 */
	public Object getEditableValue() {
		return null;
	}

	/**
	 * Returns the current collection of property descriptors.
	 * 
	 * @return all valid descriptors.
	 */
	public final IPropertyDescriptor[] getPropertyDescriptors() {
		if ((fDescriptors == null) || (fDescriptors.length == 0)) {
			fDescriptors = createPropertyDescriptors();
		}
		else {
			updatePropertyDescriptors();
		}
		return fDescriptors;
	}

	/**
	 * Returns the current value for the named property.
	 * 
	 */
	public Object getPropertyValue(Object nameObject) {
		String name = nameObject.toString();
		String returnedValue = null;
		NamedNodeMap attrMap = fNode.getAttributes();
		if (attrMap != null) {
			Node attribute = attrMap.getNamedItem(name);
			if (attribute != null) {
				if (attribute instanceof IDOMNode) {
					returnedValue = ((IDOMNode) attribute).getValueSource();
				}
				else {
					returnedValue = attribute.getNodeValue();
				}
			}
		}
		if (returnedValue == null) {
			returnedValue = ""; //$NON-NLS-1$
		}
		return returnedValue;
	}

	private String[] getValidValues(CMAttributeDeclaration attrDecl) {
		if (attrDecl == null) {
			return new String[0];
		}

		String[] validValues = null;
		CMDataType attrType = attrDecl.getAttrType();
		if (attrType != null) {
			validValues = _getValidStrings(attrDecl, attrType);
			if (fSortEnumeratedValues) {
				Arrays.sort(validValues);
			}
		}
		if (validValues == null) {
			validValues = new String[0];
		}
		return validValues;
	}

	public boolean isPropertyRemovable(Object id) {
		return true;
	}

	public boolean isPropertyResettable(Object id) {
		return fNode != null && fNode.getNodeType() == Node.ELEMENT_NODE;
	}

	/**
	 * Returns whether the property value has changed from the default.
	 * 
	 * @return <code>true</code> if the value of the specified property has
	 *         changed from its original default value; <code>false</code>
	 *         otherwise.
	 */
	public boolean isPropertySet(Object propertyObject) {
		String property = propertyObject.toString();

		NamedNodeMap attrMap = fNode.getAttributes();
		if (attrMap != null) {
			Node attr = attrMap.getNamedItem(property);
			return attr != null && (attr instanceof Attr ? ((Attr) attr).getSpecified() : true);
		}
		return false;
	}

	/**
	 * Remove the given attribute from the Node
	 * 
	 * @param propertyObject
	 */
	public void removeProperty(Object propertyObject) {
		NamedNodeMap attrMap = fNode.getAttributes();
		if (attrMap != null) {
			Node attribute = attrMap.getNamedItem(propertyObject.toString());
			if (attribute != null) {
				try {
					attrMap.removeNamedItem(propertyObject.toString());
				}
				catch (DOMException e) {
					if (e.code != DOMException.INVALID_MODIFICATION_ERR) {
						Logger.logException(e);
					}
				}
			}
		}
	}

	/**
	 * Resets the specified property's value to its default value.
	 */
	public void resetPropertyValue(Object propertyObject) {
		String property = propertyObject.toString();
		CMNamedNodeMap attrDecls = null;

		CMElementDeclaration ed = getDeclaration();
		if (ed != null) {
			attrDecls = ed.getAttributes();
			CMNamedNodeMapImpl allAttributes = new CMNamedNodeMapImpl(attrDecls);
			List nodes = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument()).getAvailableContent((Element) fNode, ed, ModelQuery.INCLUDE_ATTRIBUTES);
			for (int k = 0; k < nodes.size(); k++) {
				CMNode cmnode = (CMNode) nodes.get(k);
				if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
					allAttributes.put(cmnode);
				}
			}
			attrDecls = allAttributes;
		}

		NamedNodeMap attrMap = fNode.getAttributes();
		if (attrDecls != null) {
			CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) attrDecls.getNamedItem(property);
			String defValue = null;
			if (attrDecl != null) {
				if (attrDecl.getAttrType() != null) {
					CMDataType helper = attrDecl.getAttrType();
					if ((helper.getImpliedValueKind() != CMDataType.IMPLIED_VALUE_NONE) && (helper.getImpliedValue() != null)) {
						defValue = helper.getImpliedValue();
					}
				}
			}
			if ((defValue != null) && (defValue.length() > 0)) {
				// implied values will be in the DOM, but not the source
				attrMap.removeNamedItem(property);
			}
			else {
				((Attr) attrMap.getNamedItem(property)).setValue(""); //$NON-NLS-1$
			}
		}
		else {
			// remember, this method is for reset, not remove
			((Attr) attrMap.getNamedItem(property)).setValue(""); //$NON-NLS-1$
		}
	}

	/**
	 * Sets the named property to the given value.
	 * 
	 */
	public void setPropertyValue(Object nameObject, Object value) {
		// Avoid cycling - can happen if a closing cell editor causes a
		// refresh
		// on the PropertySheet page and the setInput again asks the editor to
		// close; besides, why apply the same value twice?
		if (!fValuesBeingSet.isEmpty() && (fValuesBeingSet.peek() == nameObject)) {
			return;
		}
		fValuesBeingSet.push(nameObject);
		String name = nameObject.toString();
		String valueString = ""; //$NON-NLS-1$
		if (value != null) {
			valueString = value.toString();
		}
		NamedNodeMap attrMap = fNode.getAttributes();
		try {
			if (attrMap != null) {
				Attr attr = (Attr) attrMap.getNamedItem(name);
				if (attr != null && attr.getSpecified()) {
					// EXISTING VALUE
					// potential out of control loop if updating the value
					// triggers a viewer update, forcing the
					// active cell editor to save its value and causing the
					// loop to continue
					if ((attr.getValue() == null) || !attr.getValue().equals(valueString)) {
						if (attr instanceof IDOMNode) {
							((IDOMNode) attr).setValueSource(valueString);
						}
						else {
							attr.setValue(valueString);
						}
					}
				}
				else {
					// NEW(?) value
					Attr newAttr = fNode.getOwnerDocument().createAttribute(name);
					if (newAttr instanceof IDOMNode) {
						((IDOMNode) newAttr).setValueSource(valueString);
					}
					else {
						newAttr.setValue(valueString);
					}
					attrMap.setNamedItem(newAttr);
				}
			}
			else {
				if (fNode instanceof Element) {
					((Element) fNode).setAttribute(name, valueString);
				}
			}
		}
		catch (DOMException e) {
			Display d = getDisplay();
			if (d != null) {
				d.beep();
			}
		}
		fValuesBeingSet.pop();
	}

	protected void updatePropertyDescriptors() {
		if ((fDescriptors == null) || (fDescriptors.length == 0)) {
			// Nothing to update
			return;
		}

		// List of all names encountered in the tag and defined by the element
		List declaredNames = new ArrayList();
		// New descriptor list that will become fDescriptors after all
		// processing is done
		List descriptors = new ArrayList();
		// Names of the descriptors in the above List
		List descriptorNames = new ArrayList();

		// Update any descriptors derived from the metainfo
		CMElementDeclaration ed = getDeclaration();
		CMNamedNodeMap attrMap = null;
		if (ed != null) {
			attrMap = ed.getAttributes();
			CMNamedNodeMapImpl allAttributes = new CMNamedNodeMapImpl(attrMap);
			ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode.getOwnerDocument());
			if(modelQuery != null) {
			List nodes = modelQuery.getAvailableContent((Element) fNode, ed, ModelQuery.INCLUDE_ATTRIBUTES);
				for (int k = 0; k < nodes.size(); k++) {
					CMNode cmnode = (CMNode) nodes.get(k);
					if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
						allAttributes.put(cmnode);
					}
				}
			}
			attrMap = allAttributes;
		}
		// Update exiting descriptors; not added to the final list here
		if (attrMap != null) {
			// Update existing descriptor types based on metainfo
			CMAttributeDeclaration attrDecl = null;
			for (int i = 0; i < attrMap.getLength(); i++) {
				attrDecl = (CMAttributeDeclaration) attrMap.item(i);
				String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
				if (!declaredNames.contains(attrName)) {
					declaredNames.add(attrName);
				}
				for (int j = 0; j < fDescriptors.length; j++) {
					boolean sameName = (fCaseSensitive && fDescriptors[j].getId().equals(attrDecl.getNodeName())) || (!fCaseSensitive && attrDecl.getNodeName().equals(fDescriptors[j].getId().toString()));
					if (sameName) {
						String[] validValues = getValidValues(attrDecl);
						// Update the descriptor for this
						// CMAttributeDeclaration (only enumerated values get
						// updated for now)
						if (fDescriptors[j] instanceof EnumeratedStringPropertyDescriptor) {
							((EnumeratedStringPropertyDescriptor) fDescriptors[j]).updateValues(validValues);
						}
						// Replace with better descriptor
						else if ((validValues != null) && (validValues.length > 0)) {
							fDescriptors[j] = createPropertyDescriptor(attrDecl, null);
						}
					}
				}
			}
		}
		else {
			// Update existing descriptors based on not having any metainfo
			for (int j = 0; j < fDescriptors.length; j++) {
				// Replace with basic descriptor
				if (!(fDescriptors[j] instanceof TextPropertyDescriptor)) {
					fDescriptors[j] = createDefaultPropertyDescriptor((String) fDescriptors[j].getId());
				}
			}
		}

		NamedNodeMap attributes = fNode.getAttributes();

		// Remove descriptors for attributes that aren't present AND aren't
		// known through metainfo,
		// do this by only reusing existing descriptors for attributes that
		// are present or declared
		for (int i = 0; i < fDescriptors.length; i++) {
			if (fDescriptors[i] != null) {
				String descriptorName = fDescriptors[i].getId().toString();
				if ((declaredNames.contains(descriptorName) || (attributes.getNamedItem(descriptorName) != null)) && !descriptorNames.contains(descriptorName)) {
					descriptorNames.add(descriptorName);
					descriptors.add(fDescriptors[i]);
				}
			}
		}

		// Add descriptors for declared attributes that don't already have one
		if (attrMap != null) {
			// Update existing descriptor types based on metainfo
			CMAttributeDeclaration attrDecl = null;
			for (int i = 0; i < attrMap.getLength(); i++) {
				attrDecl = (CMAttributeDeclaration) attrMap.item(i);
				String attrName = DOMNamespaceHelper.computeName(attrDecl, fNode, null);
				if (fCaseSensitive) {
					if (!descriptorNames.contains(attrName)) {
						IPropertyDescriptor descriptor = createPropertyDescriptor(attrDecl, null);
						if (descriptor != null) {
							descriptorNames.add(attrName);
							descriptors.add(descriptor);
						}
					}
				}
				else {
					boolean exists = false;
					for (int j = 0; j < descriptorNames.size(); j++) {
						exists = (descriptorNames.get(j).toString().equalsIgnoreCase(attrName)) || exists;
					}
					if (!exists) {
						descriptorNames.add(attrName);
						IPropertyDescriptor descriptor = createPropertyDescriptor(attrDecl, null);
						if (descriptor != null) {
							descriptorNames.add(attrName);
							descriptors.add(descriptor);
						}
					}
				}
			}
		}

		// Add descriptors for existing attributes that don't already have one
		if (attributes != null) {
			for (int i = 0; i < attributes.getLength(); i++) {
				Attr attr = (Attr) attributes.item(i);
				String attrName = attr.getName();
				if (fCaseSensitive) {
					if (!descriptorNames.contains(attrName)) {
						descriptorNames.add(attrName);
						descriptors.add(createDefaultPropertyDescriptor(attrName));
					}
				}
				else {
					boolean exists = false;
					for (int j = 0; j < descriptorNames.size(); j++) {
						exists = (descriptorNames.get(j).toString().equalsIgnoreCase(attrName)) || exists;
					}
					if (!exists) {
						descriptorNames.add(attrName);
						descriptors.add(createDefaultPropertyDescriptor(attrName));
					}
				}
			}
		}

		// Update fDescriptors
		IPropertyDescriptor[] newDescriptors = new IPropertyDescriptor[descriptors.size()];
		for (int i = 0; i < newDescriptors.length; i++) {
			newDescriptors[i] = (IPropertyDescriptor) descriptors.get(i);
		}
		fDescriptors = newDescriptors;
	}
}
