Switch from propertySourceAdapters to using property sheet configuration
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/registry/AdapterFactoryProviderForJSP.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/registry/AdapterFactoryProviderForJSP.java
index 6416985..28ab5dc 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/registry/AdapterFactoryProviderForJSP.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/registry/AdapterFactoryProviderForJSP.java
@@ -17,7 +17,6 @@
 import org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapterFactory;
 import org.eclipse.jst.jsp.core.internal.modelhandler.ModelHandlerForJSP;
 import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
-import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.wst.html.ui.internal.contentoutline.JFaceNodeAdapterFactoryForHTML;
 import org.eclipse.wst.sse.core.internal.PropagatingAdapter;
 import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IDocumentTypeHandler;
@@ -31,7 +30,6 @@
 import org.eclipse.wst.sse.ui.internal.util.Assert;
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySourceAdapterFactory;
 
 public class AdapterFactoryProviderForJSP implements AdapterFactoryProvider {
 
@@ -54,11 +52,6 @@
 		FactoryRegistry factoryRegistry = structuredModel.getFactoryRegistry();
 		Assert.isNotNull(factoryRegistry, "Program Error: client caller must ensure model has factory registry"); //$NON-NLS-1$
 		INodeAdapterFactory factory = null;
-		factory = factoryRegistry.getFactoryFor(IPropertySource.class);
-		if (factory == null) {
-			factory = new XMLPropertySourceAdapterFactory();
-			factoryRegistry.addFactory(factory);
-		}
 		factory = factoryRegistry.getFactoryFor(IJFaceNodeAdapter.class);
 		if (factory == null) {
 			factory = new JFaceNodeAdapterFactoryForHTML(IJFaceNodeAdapter.class, true);
diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySource.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySource.java
index dee33b8..54cafb0 100644
--- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySource.java
+++ b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySource.java
@@ -33,20 +33,19 @@
 import org.eclipse.wst.css.core.internal.provisional.document.ICSSNodeList;
 import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclItem;
 import org.eclipse.wst.css.ui.internal.CSSUIMessages;
-import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
 import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
 import org.w3c.dom.css.CSSStyleDeclaration;
 
 /**
  * A IPropertySource implementation for a JFace viewer used to display
- * propreties of DOM nodes. This takes an adapter factory to create JFace
- * adapters for the nodes in the tree.
+ * properties of CSS nodes.
  */
-public class CSSPropertySource implements INodeAdapter, IPropertySource {
+public class CSSPropertySource implements IPropertySource {
 	protected ICSSNode fNode = null;
 	// for performance...
 	final static Class ADAPTER_KEY = IPropertySource.class;
-
+	final boolean PERF_GETDESCRIPTORS = true;
+	private long time0;
 	/**
 	 * DOMPropertySource constructor comment.
 	 */
@@ -58,7 +57,7 @@
 	protected IPropertyDescriptor createDefaultPropertyDescriptor(String attributeName) {
 		// the displayName MUST be set
 		IPropertyDescriptor descriptor = new CSSTextPropertyDescriptor(attributeName, attributeName, fNode);
-		//	IPropertyDescriptor descriptor = new
+		// IPropertyDescriptor descriptor = new
 		// TextPropertyDescriptor(attributeName, attributeName);
 		return descriptor;
 	}
@@ -75,12 +74,12 @@
 				category = CSSUIMessages.INFO_Not_Categorized_1; //$NON-NLS-1$
 			}
 			descriptor = new CSSTextPropertyDescriptor(name, name, fNode, category);
-			//			if (category == null) {
-			//				descriptor = new CSSTextPropertyDescriptor(name, name, fNode);
-			//			} else {
-			//				descriptor = new CSSTextPropertyDescriptor(name, name, fNode,
+			// if (category == null) {
+			// descriptor = new CSSTextPropertyDescriptor(name, name, fNode);
+			// } else {
+			// descriptor = new CSSTextPropertyDescriptor(name, name, fNode,
 			// category);
-			//			}
+			// }
 		}
 		return descriptor;
 	}
@@ -101,6 +100,8 @@
 	 * @return a vector containing all descriptors.
 	 */
 	public IPropertyDescriptor[] getPropertyDescriptors() {
+		time0 = System.currentTimeMillis();
+
 		CSSMetaModel metamodel = CSSMetaModelFinder.getInstance().findMetaModelFor(fNode);
 		Iterator iProperties = Collections.EMPTY_LIST.iterator();
 		switch (fNode.getNodeType()) {
@@ -178,6 +179,9 @@
 		}
 
 		IPropertyDescriptor[] resultArray = new IPropertyDescriptor[descriptors.size()];
+		if (PERF_GETDESCRIPTORS) {
+			System.out.println(getClass().getName() + ".getPropertyDescriptors: " + (System.currentTimeMillis() - time0) + "ms");
+		}
 		return (IPropertyDescriptor[]) descriptors.toArray(resultArray);
 	}
 
@@ -234,14 +238,6 @@
 	}
 
 	/**
-	 * Allowing the INodeAdapter to compare itself against the type allows it
-	 * to return true in more than one case.
-	 */
-	public boolean isAdapterForType(java.lang.Object type) {
-		return type.equals(ADAPTER_KEY);
-	}
-
-	/**
 	 * Returns whether the property value has changed from the default.
 	 * 
 	 * @return <code>true</code> if the value of the specified property has
@@ -264,11 +260,6 @@
 	}
 
 	/**
-	 */
-	public void notifyChanged(INodeNotifier notifier, int eventType, java.lang.Object changedFeature, java.lang.Object oldValue, java.lang.Object newValue, int pos) {
-	}
-
-	/**
 	 * Resets the specified property's value to its default value.
 	 * 
 	 * @param property
@@ -303,10 +294,12 @@
 			try {
 				if (valueString == null || valueString.length() <= 0) {
 					declaration.removeProperty(nameString);
-				} else {
+				}
+				else {
 					declaration.setProperty(nameString, valueString, ""); //$NON-NLS-1$
 				}
-			} catch (Exception e) {
+			}
+			catch (Exception e) {
 				IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
 				String title = CSSUIMessages.Title_InvalidValue; //$NON-NLS-1$
 				String message = CSSUIMessages.Message_InvalidValue; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySourceAdapterFactory.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySourceAdapterFactory.java
deleted file mode 100644
index 240b33c..0000000
--- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/properties/CSSPropertySourceAdapterFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2004 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.css.ui.internal.properties;
-
-import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory;
-import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
-import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
-
-
-
-public class CSSPropertySourceAdapterFactory extends AbstractAdapterFactory {
-	/**
-	 * PropertySourceAdapterFactory constructor comment.
-	 */
-	public CSSPropertySourceAdapterFactory() {
-		super();
-	}
-
-	/**
-	 * PropertySourceAdapterFactory constructor comment.
-	 * 
-	 * @param adapterKey
-	 *            java.lang.Object
-	 * @param registerAdapters
-	 *            boolean
-	 */
-	public CSSPropertySourceAdapterFactory(Object newAdapterKey, boolean newRegisterAdapters) {
-		super(newAdapterKey, newRegisterAdapters);
-	}
-
-	/**
-	 * createAdapter method comment.
-	 */
-	protected INodeAdapter createAdapter(INodeNotifier target) {
-		// at the moment, only one implementation exists
-		return new CSSPropertySource(target);
-	}
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/registry/AdapterFactoryProviderCSS.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/registry/AdapterFactoryProviderCSS.java
index 8eecc2e..2d108bf 100644
--- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/registry/AdapterFactoryProviderCSS.java
+++ b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/registry/AdapterFactoryProviderCSS.java
@@ -8,10 +8,8 @@
  ****************************************************************************/
 package org.eclipse.wst.css.ui.internal.registry;
 
-import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.wst.css.core.internal.modelhandler.ModelHandlerForCSS;
 import org.eclipse.wst.css.ui.internal.contentoutline.JFaceNodeAdapterFactoryCSS;
-import org.eclipse.wst.css.ui.internal.properties.CSSPropertySourceAdapterFactory;
 import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IDocumentTypeHandler;
 import org.eclipse.wst.sse.core.internal.model.FactoryRegistry;
 import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
@@ -35,12 +33,6 @@
 		Assert.isNotNull(factoryRegistry, "Program Error: client caller must ensure model has factory registry"); //$NON-NLS-1$
 		INodeAdapterFactory factory = null;
 
-		factory = factoryRegistry.getFactoryFor(IPropertySource.class);
-		if (factory == null) {
-			factory = new CSSPropertySourceAdapterFactory(IPropertySource.class, true);
-			factoryRegistry.addFactory(factory);
-		}
-
 		factory = factoryRegistry.getFactoryFor(IJFaceNodeAdapter.class);
 		if (factory == null) {
 			factory = new JFaceNodeAdapterFactoryCSS(IJFaceNodeAdapter.class, true);
diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/properties/CSSPropertySheetConfiguration.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/properties/CSSPropertySheetConfiguration.java
index 0469698..e369534 100644
--- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/properties/CSSPropertySheetConfiguration.java
+++ b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/properties/CSSPropertySheetConfiguration.java
@@ -6,42 +6,178 @@
  * 
  * Contributors: IBM Corporation - initial API and implementation
  ****************************************************************************/
-/*
- * Created on Jan 23, 2004
- * 
- * To change the template for this generated file go to Window - Preferences -
- * Java - Code Generation - Code and Comments
- */
+
 package org.eclipse.wst.css.ui.views.properties;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.IPropertySourceProvider;
+import org.eclipse.ui.views.properties.PropertySheetPage;
 import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
-import org.eclipse.wst.sse.ui.views.properties.StructuredPropertySheetConfiguration;
+import org.eclipse.wst.css.ui.internal.properties.CSSPropertySource;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
+import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
 
-public class CSSPropertySheetConfiguration extends StructuredPropertySheetConfiguration {
+public class CSSPropertySheetConfiguration extends PropertySheetConfiguration {
+	private class CSSPropertySheetRefreshAdapter implements INodeAdapter {
+		public boolean isAdapterForType(Object type) {
+			return false;
+		}
+
+		public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
+			if (fPropertySheetPage != null) {
+				getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
+			}
+		}
+	}
+
+	private class CSSPropertySourceProvider implements IPropertySourceProvider {
+		private IPropertySource fPropertySource = null;
+		private INodeNotifier fSource = null;
+
+		public IPropertySource getPropertySource(Object object) {
+			if (fSource != null && object.equals(fSource)) {
+				return fPropertySource;
+			}
+
+			if (object instanceof INodeNotifier) {
+				fSource = (INodeNotifier) object;
+				fPropertySource = new CSSPropertySource((INodeNotifier) object);
+			}
+			else {
+				fSource = null;
+				fPropertySource = null;
+			}
+			return fPropertySource;
+		}
+	}
+
+	private class PropertiesRefreshJob extends UIJob {
+		public static final int UPDATE_DELAY = 200;
+
+		private Set propertySheetPages = null;
+
+		public PropertiesRefreshJob() {
+			super(XMLUIMessages.JFaceNodeAdapter_1);
+			setSystem(true);
+			setPriority(Job.SHORT);
+			propertySheetPages = new HashSet(1);
+		}
+
+		void addPropertySheetPage(IPropertySheetPage page) {
+			propertySheetPages.add(page);
+			schedule(UPDATE_DELAY);
+		}
+
+		public IStatus runInUIThread(IProgressMonitor monitor) {
+			Object[] pages = propertySheetPages.toArray();
+			propertySheetPages.clear();
+
+			for (int i = 0; i < pages.length; i++) {
+				PropertySheetPage page = (PropertySheetPage) pages[i];
+				if (page.getControl() != null && !page.getControl().isDisposed()) {
+					page.refresh();
+				}
+			}
+
+			return Status.OK_STATUS;
+		}
+	}
+
+	private PropertiesRefreshJob fPropertiesRefreshJob = null;
+
+	IPropertySheetPage fPropertySheetPage;
+
+	private IPropertySourceProvider fPropertySourceProvider = null;
+
+	private INodeAdapter fRefreshAdapter = new CSSPropertySheetRefreshAdapter();
+
+	private INodeNotifier[] fSelectedNotifiers;
+
 	public CSSPropertySheetConfiguration() {
 		super();
 	}
 
-	public ISelection getSelection(IWorkbenchPart selectingPart, ISelection selection) {
-		ISelection preferredSelection = super.getSelection(selectingPart, selection);
+	public ISelection getInputSelection(IWorkbenchPart selectingPart, ISelection selection) {
+		// remove UI refresh adapters
+		if (fSelectedNotifiers != null) {
+			for (int i = 0; i < fSelectedNotifiers.length; i++) {
+				fSelectedNotifiers[i].removeAdapter(fRefreshAdapter);
+			}
+			fSelectedNotifiers = null;
+		}
+
+		ISelection preferredSelection = super.getInputSelection(selectingPart, selection);
 		if (preferredSelection instanceof IStructuredSelection) {
-			Object[] objects = ((IStructuredSelection) preferredSelection).toArray();
-			for (int i = 0; i < objects.length; i++) {
-				if (objects[i] instanceof ICSSNode) {
-					ICSSNode node = (ICSSNode) objects[i];
+			Object[] selectedObjects = new Object[((IStructuredSelection) selection).size()];
+			System.arraycopy(((IStructuredSelection) selection).toArray(), 0, selectedObjects, 0, selectedObjects.length);
+			for (int i = 0; i < selectedObjects.length; i++) {
+				if (selectedObjects[i] instanceof ICSSNode) {
+					ICSSNode node = (ICSSNode) selectedObjects[i];
 					while (node.getNodeType() == ICSSNode.PRIMITIVEVALUE_NODE || node.getNodeType() == ICSSNode.STYLEDECLITEM_NODE) {
 						node = node.getParentNode();
-						objects[i] = node;
-
+						selectedObjects[i] = node;
 					}
 				}
 			}
-			preferredSelection = new StructuredSelection(objects);
+
+			/*
+			 * Add UI refresh adapters and remember notifiers for later
+			 * removal
+			 */
+			if (selectedObjects.length > 0) {
+				List selectedNotifiers = new ArrayList(1);
+				for (int i = 0; i < selectedObjects.length; i++) {
+					if (selectedObjects[i] instanceof INodeNotifier) {
+						selectedNotifiers.add(selectedObjects[i]);
+						((INodeNotifier) selectedObjects[i]).addAdapter(fRefreshAdapter);
+					}
+				}
+				fSelectedNotifiers = (INodeNotifier[]) selectedNotifiers.toArray(new INodeNotifier[selectedNotifiers.size()]);
+			}
+			preferredSelection = new StructuredSelection(selectedObjects);
 		}
 		return preferredSelection;
 	}
+
+	PropertiesRefreshJob getPropertiesRefreshJob() {
+		if (fPropertiesRefreshJob == null) {
+			fPropertiesRefreshJob = new PropertiesRefreshJob();
+		}
+		return fPropertiesRefreshJob;
+	}
+
+	public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
+		if (fPropertySourceProvider == null) {
+			fPropertySourceProvider = new CSSPropertySourceProvider();
+			fPropertySheetPage = page;
+		}
+		return fPropertySourceProvider;
+	}
+
+	public void unconfigure() {
+		super.unconfigure();
+		if (fSelectedNotifiers != null) {
+			for (int i = 0; i < fSelectedNotifiers.length; i++) {
+				fSelectedNotifiers[i].removeAdapter(fRefreshAdapter);
+			}
+			fSelectedNotifiers = null;
+		}
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/registry/AdapterFactoryProviderForHTML.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/registry/AdapterFactoryProviderForHTML.java
index 36a9b9e..58bb496 100644
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/registry/AdapterFactoryProviderForHTML.java
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/registry/AdapterFactoryProviderForHTML.java
@@ -10,7 +10,6 @@
  *******************************************************************************/
 package org.eclipse.wst.html.ui.internal.registry;
 
-import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.wst.html.core.internal.modelhandler.ModelHandlerForHTML;
 import org.eclipse.wst.html.ui.internal.contentoutline.JFaceNodeAdapterFactoryForHTML;
 import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IDocumentTypeHandler;
@@ -21,7 +20,6 @@
 import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryProvider;
 import org.eclipse.wst.sse.ui.internal.util.Assert;
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySourceAdapterFactory;
 
 
 public class AdapterFactoryProviderForHTML implements AdapterFactoryProvider {
@@ -43,11 +41,6 @@
 		Assert.isNotNull(factoryRegistry, "Program Error: client caller must ensure model has factory registry"); //$NON-NLS-1$
 		INodeAdapterFactory factory = null;
 
-		factory = factoryRegistry.getFactoryFor(IPropertySource.class);
-		if (factory == null) {
-			factory = new XMLPropertySourceAdapterFactory();
-			factoryRegistry.addFactory(factory);
-		}
 		factory = factoryRegistry.getFactoryFor(IJFaceNodeAdapter.class);
 		if (factory == null) {
 			factory = new JFaceNodeAdapterFactoryForHTML();
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/AdapterPropertySourceProvider.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/AdapterPropertySourceProvider.java
deleted file mode 100644
index 9053fba..0000000
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/AdapterPropertySourceProvider.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 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.sse.ui.internal.properties;
-
-
-
-import org.eclipse.ui.views.properties.IPropertySource;
-import org.eclipse.ui.views.properties.IPropertySourceProvider;
-import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
-
-
-public class AdapterPropertySourceProvider implements IPropertySourceProvider {
-
-	public AdapterPropertySourceProvider() {
-		super();
-	}
-
-	public IPropertySource getPropertySource(Object object) {
-		if (object instanceof INodeNotifier) {
-			return (IPropertySource) ((INodeNotifier) object).getAdapterFor(IPropertySource.class);
-		}
-		return null;
-	}
-}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/ConfigurablePropertySheetPage.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/ConfigurablePropertySheetPage.java
index 3722eaf..0786476 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/ConfigurablePropertySheetPage.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/properties/ConfigurablePropertySheetPage.java
@@ -15,6 +15,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.action.IToolBarManager;
@@ -27,7 +28,9 @@
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.part.IPageSite;
 import org.eclipse.ui.views.properties.IPropertySheetEntry;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
 import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.IPropertySourceProvider;
 import org.eclipse.ui.views.properties.PropertySheetPage;
 import org.eclipse.wst.sse.ui.views.properties.IPropertySourceExtension;
 import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
@@ -39,21 +42,27 @@
  */
 
 public class ConfigurablePropertySheetPage extends PropertySheetPage {
-	private static final boolean _DEBUG_ENTRY_SELECTION = false;
-	private static final boolean _DEBUG_SELECTION = false;
+	private class NullPropertySheetConfiguration extends PropertySheetConfiguration {
+		public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
+			return null;
+		}
+	}
+
+	private static final boolean _DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/propertySheet")); //$NON-NLS-1$  //$NON-NLS-2$;;
+
 	private long _DEBUG_TIME = 0;
 
 	private PropertySheetConfiguration fConfiguration;
-
+	private ISelection fInput = null;
 	private IMenuManager fMenuManager;
+
 	private RemoveAction fRemoveAction;
+
 	private IStatusLineManager fStatusLineManager;
 
 	private IToolBarManager fToolBarManager;
 
-	private final PropertySheetConfiguration NULL_CONFIGURATION = new PropertySheetConfiguration();
-
-	private Object selectedEntry = null;
+	private final PropertySheetConfiguration NULL_CONFIGURATION = new NullPropertySheetConfiguration();
 
 	public ConfigurablePropertySheetPage() {
 		super();
@@ -77,10 +86,6 @@
 	}
 
 	public void handleEntrySelection(ISelection selection) {
-		if (_DEBUG_ENTRY_SELECTION) {
-			System.out.println("(P:entry " + selection);
-		}
-		selectedEntry = selection;
 		if (getControl() != null && !getControl().isDisposed() && selection != null) {
 			super.handleEntrySelection(selection);
 			fRemoveAction.setEnabled(!selection.isEmpty());
@@ -114,7 +119,7 @@
 				Object data = items[0].getData();
 				if (data instanceof IPropertySheetEntry) {
 					IPropertySheetEntry entry = (IPropertySheetEntry) data;
-					ISelection selection = getConfiguration().getSelection(null, new StructuredSelection(selectedNodes));
+					ISelection selection = getConfiguration().getInputSelection(null, new StructuredSelection(selectedNodes));
 					if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) {
 						IPropertySource source = getConfiguration().getPropertySourceProvider(this).getPropertySource(((IStructuredSelection) selection).getFirstElement());
 						if (source != null && source instanceof IPropertySourceExtension) {
@@ -136,13 +141,29 @@
 	 */
 	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
 		_DEBUG_TIME = System.currentTimeMillis();
-		if (getControl() != null && getControl().isVisible() && selection != selectedEntry && !getControl().isFocusControl()) {
-			super.selectionChanged(part, getConfiguration().getSelection(part, selection));
-			if (_DEBUG_SELECTION) {
-				System.out.println("(P:service " + (System.currentTimeMillis() - _DEBUG_TIME) + "ms) " + part + " : " + selection);
+		if (getControl() != null && getControl().isVisible() && !getControl().isFocusControl()) {
+			ISelection preferredSelection = getConfiguration().getInputSelection(part, selection);
+			/*
+			 * Do some minor caching of the selection.
+			 * 
+			 * As a PropertySheetPage, we've always notified of selection
+			 * changes, but we've also subscribed to post selection
+			 * notification so we can track caret movements in source viewers.
+			 * When selecting a block of text, we're thus notified of the new
+			 * selection twice. Remembering what our last *effective*
+			 * selection was allows us to cut out most of the
+			 * double-notification penalty.
+			 */
+			if (!preferredSelection.equals(fInput)) {
+				fInput = preferredSelection;
+				super.selectionChanged(part, preferredSelection);
+			}
+
+			if (_DEBUG) {
+				System.out.println("(P:service " + (System.currentTimeMillis() - _DEBUG_TIME) + "ms) " + part + " : " + ((IStructuredSelection) preferredSelection).getFirstElement());
 			}
 		}
-		else if (_DEBUG_SELECTION) {
+		else if (_DEBUG) {
 			System.out.println("[skipped] (P:" + (System.currentTimeMillis() - _DEBUG_TIME) + "ms) " + part + " : " + selection);
 		}
 	}
@@ -163,5 +184,6 @@
 			setPropertySourceProvider(fConfiguration.getPropertySourceProvider(this));
 			fConfiguration.addContributions(fMenuManager, fToolBarManager, fStatusLineManager);
 		}
+
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/PropertySheetConfiguration.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/PropertySheetConfiguration.java
index 001df68..2da912b 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/PropertySheetConfiguration.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/PropertySheetConfiguration.java
@@ -12,18 +12,14 @@
  *******************************************************************************/
 package org.eclipse.wst.sse.ui.views.properties;
 
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExecutableExtension;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IEditorPart;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.views.properties.IPropertyDescriptor;
 import org.eclipse.ui.views.properties.IPropertySheetPage;
-import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.ui.views.properties.IPropertySourceProvider;
 
 
@@ -32,85 +28,7 @@
  * 
  * @plannedfor 1.0
  */
-public class PropertySheetConfiguration implements IExecutableExtension {
-
-	private class NullPropertySource implements IPropertySource {
-		private final IPropertyDescriptor[] descriptors = new IPropertyDescriptor[0];
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
-		 */
-		public Object getEditableValue() {
-			return null;
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
-		 */
-		public IPropertyDescriptor[] getPropertyDescriptors() {
-			return descriptors;
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
-		 */
-		public Object getPropertyValue(Object id) {
-			return ""; //$NON-NLS-1$
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
-		 */
-		public boolean isPropertySet(Object id) {
-			return false;
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
-		 */
-		public void resetPropertyValue(Object id) {
-			// do nothing
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object,
-		 *      java.lang.Object)
-		 */
-		public void setPropertyValue(Object id, Object value) {
-			// do nothing
-		}
-	}
-
-	private class NullPropertySourceProvider implements IPropertySourceProvider {
-		private IPropertySource fNullPropertySource = null;
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.ui.views.properties.IPropertySourceProvider#getPropertySource(java.lang.Object)
-		 */
-		public IPropertySource getPropertySource(Object object) {
-			if (fNullPropertySource == null)
-				fNullPropertySource = new NullPropertySource();
-			return fNullPropertySource;
-		}
-	}
-
-	private IEditorPart fEditor;
-	protected IPropertySourceProvider fPropertySourceProvider = null;
-
+public abstract class PropertySheetConfiguration {
 	public PropertySheetConfiguration() {
 		super();
 	}
@@ -120,29 +38,6 @@
 	}
 
 	/**
-	 * @return
-	 */
-	protected IPropertySourceProvider createPropertySourceProvider(IPropertySheetPage page) {
-		return new NullPropertySourceProvider();
-	}
-
-	/**
-	 * @return Returns the editor.
-	 */
-	public IEditorPart getEditor() {
-		return fEditor;
-	}
-
-	/**
-	 * Returns the correct IPropertySourceProvider
-	 */
-	public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
-		if (fPropertySourceProvider == null)
-			fPropertySourceProvider = createPropertySourceProvider(page);
-		return fPropertySourceProvider;
-	}
-
-	/**
 	 * Allows for filteration of selection before being sent to the viewer
 	 * 
 	 * @param selectingPart -
@@ -150,31 +45,25 @@
 	 * @param selection
 	 * @return
 	 */
-	public ISelection getSelection(IWorkbenchPart selectingPart, ISelection selection) {
-		return selection;
+	public ISelection getInputSelection(IWorkbenchPart selectingPart, ISelection selection) {
+		ISelection preferredSelection = selection;
+		if (selection instanceof IStructuredSelection) {
+			// don't support more than one selected node
+			if (((IStructuredSelection) selection).size() > 1)
+				preferredSelection = StructuredSelection.EMPTY;
+		}
+		return preferredSelection;
 	}
 
+	/**
+	 * Returns the correct IPropertySourceProvider
+	 */
+	public abstract IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page);
+
 	public void removeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
 		// do nothing
 	}
 
-	/**
-	 * @param editor
-	 *            The editor to set.
-	 */
-	public void setEditor(IEditorPart editor) {
-		fEditor = editor;
-	}
-
-	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
-		/*
-		 * Currently no need for initialization data but is good practice to
-		 * implement IExecutableExtension since is a class that can be created
-		 * by executable extension
-		 */
-	}
-
 	public void unconfigure() {
-		// do nothing
 	}
 }
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/StructuredPropertySheetConfiguration.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/StructuredPropertySheetConfiguration.java
deleted file mode 100644
index e6f3496..0000000
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/properties/StructuredPropertySheetConfiguration.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 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.sse.ui.views.properties;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.views.properties.IPropertySheetPage;
-import org.eclipse.ui.views.properties.IPropertySourceProvider;
-import org.eclipse.wst.sse.ui.internal.properties.AdapterPropertySourceProvider;
-
-
-/**
- * A PropertySheetConfiguration appropriate for StructuredTextEditors and
- * StructuredModels
- * 
- * @plannedfor 1.0
- */
-public class StructuredPropertySheetConfiguration extends PropertySheetConfiguration {
-	public StructuredPropertySheetConfiguration() {
-		super();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration#getSelection(org.eclipse.jface.viewers.ISelection,
-	 *      org.eclipse.ui.IWorkbenchPart)
-	 */
-	public ISelection getSelection(IWorkbenchPart selectingPart, ISelection selection) {
-		ISelection preferredSelection = selection;
-		if (selection instanceof IStructuredSelection) {
-			// don't support more than one selected node
-			if (((IStructuredSelection) selection).size() > 1)
-				preferredSelection = StructuredSelection.EMPTY;
-		}
-		return preferredSelection;
-	}
-
-	protected IPropertySourceProvider createPropertySourceProvider(IPropertySheetPage page) {
-		return new AdapterPropertySourceProvider();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration#unconfigure()
-	 */
-	public void unconfigure() {
-		super.unconfigure();
-		setEditor(null);
-	}
-}
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapter.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySource.java
similarity index 96%
rename from bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapter.java
rename to bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySource.java
index a9cc508..4e1325f 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapter.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySource.java
@@ -24,7 +24,6 @@
 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.INodeAdapter;
 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;
@@ -46,10 +45,9 @@
 
 /**
  * An IPropertySource implementation for a JFace viewer used to display
- * properties of DOM nodes. Requires an adapter factory to create JFace
- * adapters for the nodes in the tree.
+ * properties of DOM nodes.
  */
-public class XMLPropertySourceAdapter implements INodeAdapter, IPropertySource, IPropertySourceExtension, IPropertySource2 {
+public class XMLPropertySource implements IPropertySource, IPropertySourceExtension, IPropertySource2 {
 	protected final static String CATEGORY_ATTRIBUTES = XMLUIMessages.XMLPropertySourceAdapter_0; //$NON-NLS-1$
 
 	private static final boolean fSetExpertFilter = false;
@@ -65,7 +63,7 @@
 
 	private Stack fValuesBeingSet = new Stack();
 
-	public XMLPropertySourceAdapter(INodeNotifier target) {
+	public XMLPropertySource(INodeNotifier target) {
 		super();
 		fNode = (Node) target;
 		if (fNode instanceof IDOMNode) {
@@ -341,7 +339,7 @@
 	 * 
 	 * @return all valid descriptors.
 	 */
-	public IPropertyDescriptor[] getPropertyDescriptors() {
+	public final IPropertyDescriptor[] getPropertyDescriptors() {
 		if (fDescriptors == null || fDescriptors.length == 0) {
 			fDescriptors = createPropertyDescriptors();
 		}
@@ -389,14 +387,6 @@
 		return validValues;
 	}
 
-	/**
-	 * Allowing the INodeAdapter to compare itself against the type allows it
-	 * to return true in more than one case.
-	 */
-	public boolean isAdapterForType(Object type) {
-		return type == IPropertySource.class;
-	}
-
 	public boolean isPropertyRemovable(Object id) {
 		return true;
 	}
@@ -441,9 +431,6 @@
 		return false;
 	}
 
-	public void notifyChanged(INodeNotifier notifier, int eventType, java.lang.Object changedFeature, java.lang.Object oldValue, java.lang.Object newValue, int pos) {
-	}
-
 	/**
 	 * Remove the given attribute from the Node
 	 * 
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapterFactory.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapterFactory.java
deleted file mode 100644
index 040f622..0000000
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/properties/XMLPropertySourceAdapterFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 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 org.eclipse.ui.views.properties.IPropertySource;
-import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory;
-import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
-import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
-import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
-
-public class XMLPropertySourceAdapterFactory extends AbstractAdapterFactory {
-
-	public XMLPropertySourceAdapterFactory() {
-		super(IPropertySource.class, true);
-	}
-
-	public XMLPropertySourceAdapterFactory(Object adapterType, boolean registerAdapters) {
-		super(adapterType, registerAdapters);
-	}
-
-	public INodeAdapterFactory copy() {
-		return new XMLPropertySourceAdapterFactory(this.adapterKey, this.shouldRegisterAdapter);
-	}
-
-	protected INodeAdapter createAdapter(INodeNotifier target) {
-		// at the moment, only one implementation exists
-		return new XMLPropertySourceAdapter(target);
-	}
-}
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/registry/AdapterFactoryProviderForXML.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/registry/AdapterFactoryProviderForXML.java
index 8fa695b..76f45cd 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/registry/AdapterFactoryProviderForXML.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/registry/AdapterFactoryProviderForXML.java
@@ -13,7 +13,6 @@
 package org.eclipse.wst.xml.ui.internal.registry;
 
 import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IDocumentTypeHandler;
 import org.eclipse.wst.sse.core.internal.model.FactoryRegistry;
 import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
@@ -29,7 +28,6 @@
 import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
 import org.eclipse.wst.xml.ui.internal.contentoutline.JFaceNodeAdapterFactory;
 import org.eclipse.wst.xml.ui.internal.preferences.XMLUIPreferenceNames;
-import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySourceAdapterFactory;
 
 /**
  *  
@@ -50,11 +48,6 @@
 		Assert.isNotNull(factoryRegistry, "Program Error: client caller must ensure model has factory registry"); //$NON-NLS-1$
 		INodeAdapterFactory factory = null;
 
-		factory = factoryRegistry.getFactoryFor(IPropertySource.class);
-		if (factory == null) {
-			factory = new XMLPropertySourceAdapterFactory();
-			factoryRegistry.addFactory(factory);
-		}
 		factory = factoryRegistry.getFactoryFor(IJFaceNodeAdapter.class);
 		if (factory == null) {
 			factory = new JFaceNodeAdapterFactory();
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/properties/XMLPropertySheetConfiguration.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/properties/XMLPropertySheetConfiguration.java
index e6da1a8..88f17ab 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/properties/XMLPropertySheetConfiguration.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/properties/XMLPropertySheetConfiguration.java
@@ -12,9 +12,7 @@
  *******************************************************************************/
 package org.eclipse.wst.xml.ui.views.properties;
 
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -27,9 +25,12 @@
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.progress.UIJob;
 import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.IPropertySource;
 import org.eclipse.ui.views.properties.IPropertySourceProvider;
 import org.eclipse.ui.views.properties.PropertySheetPage;
-import org.eclipse.wst.sse.ui.views.properties.StructuredPropertySheetConfiguration;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
 import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
 import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
 import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManagerListener;
@@ -37,10 +38,12 @@
 import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
 import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
 import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
+import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySource;
 import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-public class XMLPropertySheetConfiguration extends StructuredPropertySheetConfiguration {
+public class XMLPropertySheetConfiguration extends PropertySheetConfiguration {
 	public class CMDocumentManagerListenerImpl implements CMDocumentManagerListener {
 		public void cacheCleared(CMDocumentCache cache) {
 			// nothing to do
@@ -59,36 +62,35 @@
 		}
 
 		private void refreshPages() {
-			PropertySheetPage[] pages = getPages();
-			for (int i = 0; i < pages.length; i++) {
-				getPropertiesRefreshJob().addPropertySheetPage(pages[i]);
-				getPropertiesRefreshJob().schedule(PropertiesRefreshJob.UPDATE_DELAY);
-			}
+			getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
+			getPropertiesRefreshJob().schedule(PropertiesRefreshJob.UPDATE_DELAY);
+
 		}
 	}
 
 	private class PropertiesRefreshJob extends UIJob {
 		public static final int UPDATE_DELAY = 200;
 
-		private List propertySheetPages = null;
+		private Set propertySheetPages = null;
 
 		public PropertiesRefreshJob() {
 			super(XMLUIMessages.JFaceNodeAdapter_1);
 			setSystem(true);
 			setPriority(Job.SHORT);
-			propertySheetPages = new ArrayList(1);
+			propertySheetPages = new HashSet(1);
 		}
 
-		void addPropertySheetPage(PropertySheetPage page) {
+		void addPropertySheetPage(IPropertySheetPage page) {
 			propertySheetPages.add(page);
+			schedule(UPDATE_DELAY);
 		}
 
 		public IStatus runInUIThread(IProgressMonitor monitor) {
-			List pages = propertySheetPages;
-			propertySheetPages = new ArrayList(1);
+			Object[] pages = propertySheetPages.toArray();
+			propertySheetPages.clear();
 
-			for (int i = 0; i < propertySheetPages.size(); i++) {
-				PropertySheetPage page = (PropertySheetPage) propertySheetPages.get(i);
+			for (int i = 0; i < pages.length; i++) {
+				PropertySheetPage page = (PropertySheetPage) pages[i];
 				if (page.getControl() != null && !page.getControl().isDisposed()) {
 					page.refresh();
 				}
@@ -98,93 +100,144 @@
 		}
 	}
 
-	private CMDocumentManagerListenerImpl fCMDocumentManagerListener = null;
+	private class XMLPropertySheetRefreshAdapter implements INodeAdapter {
+		public boolean isAdapterForType(Object type) {
+			return false;
+		}
+
+		public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
+			if (fPropertySheetPage != null) {
+				getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
+			}
+		}
+	}
+
+	private class XMLPropertySourceProvider implements IPropertySourceProvider {
+		private IPropertySource fPropertySource = null;
+		private INodeNotifier fSource = null;
+
+		public IPropertySource getPropertySource(Object object) {
+			if (fSource != null && object.equals(fSource)) {
+				return fPropertySource;
+			}
+
+			if (object instanceof INodeNotifier) {
+				fSource = (INodeNotifier) object;
+				fPropertySource = new XMLPropertySource((INodeNotifier) object);
+			}
+			else {
+				fSource = null;
+				fPropertySource = null;
+			}
+			return fPropertySource;
+		}
+	}
+
+	private CMDocumentManagerListenerImpl fCMDocumentManagerListener = new CMDocumentManagerListenerImpl();
 	private PropertiesRefreshJob fPropertiesRefreshJob = null;
-	private Set fPropertySheetPages = null;
-	private CMDocumentManager[] fSelectedCMDocumentManagers;
+	IPropertySheetPage fPropertySheetPage = null;
+	private IPropertySourceProvider fPropertySourceProvider = null;
+	private INodeAdapter fRefreshAdapter = new XMLPropertySheetRefreshAdapter();
+	private CMDocumentManager[] fSelectedCMDocumentManagers = new CMDocumentManager[0];
+	private INodeNotifier[] fSelectedNotifiers = new INodeNotifier[0];;
 
 	public XMLPropertySheetConfiguration() {
 		super();
-		fPropertySheetPages = new HashSet(2);
-		fSelectedCMDocumentManagers = new CMDocumentManager[0];
-		// register for CMDocumentManager events
-		fCMDocumentManagerListener = new CMDocumentManagerListenerImpl();
 	}
 
-	protected IPropertySourceProvider createPropertySourceProvider(IPropertySheetPage page) {
-		fPropertySheetPages.add(page);
-		return super.createPropertySourceProvider(page);
+	public ISelection getInputSelection(IWorkbenchPart selectingPart, ISelection selection) {
+		if (fSelectedNotifiers != null) {
+			for (int i = 0; i < fSelectedNotifiers.length; i++) {
+				fSelectedNotifiers[i].removeAdapter(fRefreshAdapter);
+			}
+			fSelectedNotifiers = null;
+		}
+		for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
+			fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
+		}
+
+		ISelection preferredSelection = selection;
+		if (selection instanceof IStructuredSelection) {
+			IStructuredSelection structuredSel = (IStructuredSelection) selection;
+
+			/*
+			 * On Attr nodes, select the owner Element. On Text nodes, select
+			 * the parent Element.
+			 */
+			Object[] selectedObjects = new Object[structuredSel.size()];
+			System.arraycopy(structuredSel.toArray(), 0, selectedObjects, 0, selectedObjects.length);
+			for (int i = 0; i < selectedObjects.length; i++) {
+				Object inode = selectedObjects[i];
+				if (inode instanceof Node) {
+					Node node = (Node) inode;
+					// replace Attribute Node with its owner
+					Node parentNode = node.getParentNode();
+					if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+						Element ownerElement = ((Attr) node).getOwnerElement();
+						selectedObjects[i] = ownerElement;
+					}
+					// replace Text Node with its parent
+					else if ((node.getNodeType() == Node.TEXT_NODE || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && parentNode != null) {
+						selectedObjects[i] = parentNode;
+					}
+				}
+			}
+
+			if (selectedObjects.length > 0) {
+				Set managers = new HashSet(1);
+				Set selectedNotifiers = new HashSet(1);
+
+				for (int i = 0; i < selectedObjects.length; i++) {
+					if (selectedObjects[i] instanceof Node) {
+						ModelQuery query = ModelQueryUtil.getModelQuery(((Node) selectedObjects[i]).getOwnerDocument());
+						if (query != null) {
+							CMDocumentManager mgr = query.getCMDocumentManager();
+							if (mgr != null) {
+								managers.add(mgr);
+								mgr.addListener(fCMDocumentManagerListener);
+							}
+						}
+					}
+					/*
+					 * Add UI refresh adapters and remember notifiers for
+					 * later removal
+					 */
+					if (selectedObjects[i] instanceof INodeNotifier) {
+						selectedNotifiers.add(selectedObjects[i]);
+						((INodeNotifier) selectedObjects[i]).addAdapter(fRefreshAdapter);
+					}
+				}
+				fSelectedCMDocumentManagers = (CMDocumentManager[]) managers.toArray(new CMDocumentManager[managers.size()]);
+				fSelectedNotifiers = (INodeNotifier[]) selectedNotifiers.toArray(new INodeNotifier[selectedNotifiers.size()]);
+			}
+
+
+			preferredSelection = new StructuredSelection(selectedObjects);
+		}
+		return preferredSelection;
 	}
 
-	public PropertySheetPage[] getPages() {
-		PropertySheetPage[] pages = (PropertySheetPage[]) fPropertySheetPages.toArray(new PropertySheetPage[fPropertySheetPages.size()]);
-		return pages;
-	}
-
-	public PropertiesRefreshJob getPropertiesRefreshJob() {
-		if (fPropertiesRefreshJob != null) {
+	PropertiesRefreshJob getPropertiesRefreshJob() {
+		if (fPropertiesRefreshJob == null) {
 			fPropertiesRefreshJob = new PropertiesRefreshJob();
 		}
 		return fPropertiesRefreshJob;
 	}
 
-	public ISelection getSelection(IWorkbenchPart selectingPart, ISelection selection) {
-		// On Attr nodes, select the owner Element. On Text nodes, select the
-		// parent Element.
-		ISelection preferredSelection = selection;
-		if (selection instanceof IStructuredSelection) {
-			for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
-				fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
-			}
-			Set managers = new HashSet(1);
-
-			IStructuredSelection structuredSel = (IStructuredSelection) selection;
-
-			List inputList = new ArrayList(structuredSel.toList());
-			for (int i = 0; i < inputList.size(); i++) {
-				Object inode = inputList.get(i);
-				if (inode instanceof Node) {
-					Node node = (Node) inputList.get(i);
-					// replace Attribute Node with its owner
-					if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
-						inputList.set(i, ((Attr) node).getOwnerElement());
-						ModelQuery query = ModelQueryUtil.getModelQuery(((Attr) node).getOwnerElement().getOwnerDocument());
-						if (query != null) {
-							Object o = query.getCMDocumentManager();
-							if (o != null) {
-								managers.add(o);
-							}
-						}
-					}
-					// replace Text Node with its parent
-					else if ((node.getNodeType() == Node.TEXT_NODE || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && node.getParentNode() != null) {
-						inputList.set(i, node.getParentNode());
-						ModelQuery query = ModelQueryUtil.getModelQuery(node.getParentNode().getOwnerDocument());
-						if (query != null) {
-							Object o = query.getCMDocumentManager();
-							if (o != null) {
-								managers.add(o);
-							}
-						}
-					}
-				}
-			}
-
-			fSelectedCMDocumentManagers = (CMDocumentManager[]) managers.toArray(new CMDocumentManager[managers.size()]);
-			for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
-				fSelectedCMDocumentManagers[i].addListener(fCMDocumentManagerListener);
-			}
-
-			preferredSelection = new StructuredSelection(inputList);
+	public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
+		if (fPropertySourceProvider == null) {
+			fPropertySheetPage = page;
+			fPropertySourceProvider = new XMLPropertySourceProvider();
 		}
-		return preferredSelection;
+		return fPropertySourceProvider;
 	}
 
+
 	public void unconfigure() {
 		super.unconfigure();
 		for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
 			fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
 		}
-		fPropertySheetPages.clear();
+		fPropertySheetPage = null;
 	}
 }