bug 268250 [CommonNavigator] Project labels missing in Project Explorer when working sets are top level elements
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java
index 8e5290a..58a77e5 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java
@@ -613,15 +613,18 @@
 				disassociate(item);
 			}
 			item.setData(element);
+			mapElement(element, item);
+			if (associateListener != null)
+				associateListener.associate(element, item);
+		} else {
+			// Always map the element, even if data == element,
+			// since unmapAllElements() can leave the map inconsistent
+			// See bug 2741 for details.
+			mapElement(element, item);
 		}
-		// Always map the element, even if data == element,
-		// since unmapAllElements() can leave the map inconsistent
-		// See bug 2741 for details.
-		mapElement(element, item);
-		if (associateListener != null)
-			associateListener.associate(element, item);
 	}
 
+	
 	/**
 	 * Disassociates the given SWT item from its corresponding element. Sets the
 	 * item's data to <code>null</code> and removes the element from the
diff --git a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentService.java b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentService.java
index 6079f74..e307447 100644
--- a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentService.java
+++ b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentService.java
@@ -679,6 +679,8 @@
 		for (int i = 0; i < elements.length; i++) {
 			if (Policy.DEBUG_RESOLUTION)
 				System.out.println("rememberContribution: " + source + ": " + elements[i]);  //$NON-NLS-1$//$NON-NLS-2$
+			if (contributionMemory.containsValue(elements[i]))
+				continue;
 			contributionMemory.put(elements[i], source);
 		}
 	}
@@ -692,6 +694,8 @@
 	public void rememberContribution(NavigatorContentDescriptor source, Object element) {
 		if (Policy.DEBUG_RESOLUTION)
 			System.out.println("rememberContribution: " + source + ": " + element);  //$NON-NLS-1$//$NON-NLS-2$
+		if (contributionMemory.containsValue(element))
+			return;
 		contributionMemory.put(element, source);
 	}
 	
diff --git a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceContentProvider.java b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceContentProvider.java
index 73b35b4..9aed010 100644
--- a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceContentProvider.java
+++ b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceContentProvider.java
@@ -314,7 +314,7 @@
 				pipelinedContentProvider.getPipelinedChildren(aParentOrPath,
 						pipelinedChildren);
 				
-				pipelinedChildren.setContributor(null);
+				//pipelinedChildren.setContributor(null);
 				
 				overridingExtensions = theOverridingExtensions[i]
 						.getOverridingExtensionsForTriggerPoint(aParentOrPath);
diff --git a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceLabelProvider.java b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceLabelProvider.java
index cd5249e..70b1a3a 100644
--- a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceLabelProvider.java
+++ b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/NavigatorContentServiceLabelProvider.java
@@ -13,6 +13,8 @@
 
 import java.util.Iterator;
 import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 
 import org.eclipse.core.commands.common.EventManager;
 import org.eclipse.core.runtime.SafeRunner;
@@ -32,10 +34,13 @@
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.internal.navigator.extensions.ExtensionPriorityComparator;
+import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension;
 import org.eclipse.ui.navigator.CommonViewer;
 import org.eclipse.ui.navigator.ICommonLabelProvider;
 import org.eclipse.ui.navigator.INavigatorContentDescriptor;
+import org.eclipse.ui.navigator.INavigatorContentExtension;
 import org.eclipse.ui.navigator.INavigatorContentService;
 
 /**
@@ -140,23 +145,50 @@
 	 * @see org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider#getStyledText(java.lang.Object)
 	 */
 	public StyledString getStyledText(Object anElement) {
-		ILabelProvider[] labelProviders = contentService.findRelevantLabelProviders(anElement);
-		String text = null;
-		for (int i = 0; i < labelProviders.length; i++) {
-			if (labelProviders[i] instanceof IStyledLabelProvider) {
-				StyledString styledText= ((IStyledLabelProvider) labelProviders[i]).getStyledText(anElement);
-				// paranoia check for null, although null is not a valid return value for IStyledLabelProvider.getStyledText
-				if (styledText != null && styledText.getString().length() > 0) {
-					return styledText;
-				}
-			} else {
-				text= labelProviders[i].getText(anElement);
-				if (text != null) {
-					return new StyledString(text);
-				}
+		SortedSet extensions = new TreeSet(ExtensionPriorityComparator.INSTANCE);
+		NavigatorContentDescriptor ncd = contentService.getSourceOfContribution(anElement);
+		if (ncd != null) {
+			extensions.add(contentService.getExtension(ncd));
+		}
+		Set possibleChildDescriptors = contentService.findContentExtensionsWithPossibleChild(anElement, true);
+		for (Iterator iter = possibleChildDescriptors.iterator(); iter.hasNext();) {
+			INavigatorContentExtension ext = (INavigatorContentExtension) iter.next();
+			extensions.add(ext);
+		}
+
+		StyledString text = null; 
+		for (Iterator itr = extensions.iterator(); itr.hasNext() && text == null; ) { 
+			text = findStyledText((NavigatorContentExtension) itr.next(), anElement);
+		}
+		// decorate the element
+		return (text == null) ? new StyledString(NLS.bind(CommonNavigatorMessages.NavigatorContentServiceLabelProvider_Error_no_label_provider_for_0_, makeSmallString(anElement))) : text;	
+	}
+	
+	/**
+	 * Search for a styled text label and take overrides into account. 
+	 * Uses only simple ITreeContentProvider.getParent() style semantics. 
+	 * 
+	 * @returns the styled text or <code>null</code> if no extension has been found that provides a label
+	 */
+	private StyledString findStyledText(NavigatorContentExtension foundExtension, Object anElement) { 
+		INavigatorContentDescriptor foundDescriptor;
+		ICommonLabelProvider labelProvider= foundExtension.getLabelProvider();
+		if (labelProvider instanceof IStyledLabelProvider) {
+			StyledString styledText= ((IStyledLabelProvider) labelProvider).getStyledText(anElement);
+			// paranoia check for null, although null is not a valid return value for IStyledLabelProvider.getStyledText
+			if (styledText != null && styledText.length() > 0) {
+				return styledText;
+			}
+		} else {
+			String text= labelProvider.getText(anElement);
+			if (text != null) {
+				return new StyledString(text);
 			}
 		}
-		return new StyledString(NLS.bind(CommonNavigatorMessages.NavigatorContentServiceLabelProvider_Error_no_label_provider_for_0_, makeSmallString(anElement)));	
+		if ((foundDescriptor = foundExtension.getDescriptor()).getOverriddenDescriptor() != null) {
+			return findStyledText(contentService.getExtension(foundDescriptor.getOverriddenDescriptor()), anElement);
+		}  
+		return null;
 	}
 	
 	private String makeSmallString(Object obj) {
@@ -165,7 +197,6 @@
 		return str.substring(0, len < 50 ? len : 49);
 	}
 	
-	
 	/**
 	 * Search for image and take overrides into account. 
 	 * Uses only simple ITreeContentProvider.getParent() style semantics. 
diff --git a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/extensions/StructuredViewerManager.java b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/extensions/StructuredViewerManager.java
index 86f7956..ad0e24e 100644
--- a/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/extensions/StructuredViewerManager.java
+++ b/bundles/org.eclipse.ui.navigator/src/org/eclipse/ui/internal/navigator/extensions/StructuredViewerManager.java
@@ -58,6 +58,10 @@
 			}
 			public void associate(Object element, Item item) {
 				NavigatorContentDescriptor desc = contentService.getContribution(element);
+				if (item.getData(NavigatorContentService.WIDGET_KEY) != null) {
+					//System.out.println("associate: SKIPPED " + element + " item: " + item + " desc: " + desc + " found: " + item.getData(NavigatorContentService.WIDGET_KEY)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+					return;
+				}
 				item.setData(NavigatorContentService.WIDGET_KEY, desc);
 				//System.out.println("associate: " + element + " item: " + item + " desc: " + desc); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 			}
diff --git a/tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF b/tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF
index f6d4f9f..ca0519e 100644
--- a/tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF
@@ -14,7 +14,7 @@
  org.junit,
  org.eclipse.ui.navigator.resources,
  org.eclipse.ui.tests.harness,
- org.eclipse.ui.editors;bundle-version="3.5.0"
+ org.eclipse.ui.editors
 Bundle-Vendor: Eclipse.org
 Bundle-ClassPath: uinavtests.jar
 Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/tests/org.eclipse.ui.tests.navigator/plugin.xml b/tests/org.eclipse.ui.tests.navigator/plugin.xml
index dfa00de..403e81f 100644
--- a/tests/org.eclipse.ui.tests.navigator/plugin.xml
+++ b/tests/org.eclipse.ui.tests.navigator/plugin.xml
@@ -288,6 +288,20 @@
 		<override suppressedExtensionId="org.eclipse.ui.tests.navigator.testContentOverridden2"/>
 	  </navigatorContent>      
 
+      <navigatorContent 
+            id="org.eclipse.ui.tests.navigator.testContentOverride2Blank" 
+            name="Test Content Override 2 (Label only - Blank)"
+            contentProvider="org.eclipse.ui.internal.navigator.resources.workbench.ResourceExtensionContentProvider"
+            labelProvider="org.eclipse.ui.tests.navigator.extension.TestLabelProviderBlank"
+            priority="lower">
+         <triggerPoints>
+            <instanceof
+                  value="org.eclipse.core.resources.IResource">
+            </instanceof>
+         </triggerPoints>
+		<override suppressedExtensionId="org.eclipse.ui.tests.navigator.testContentOverridden2"/>
+	  </navigatorContent>      
+
       <navigatorContent
             id="org.eclipse.ui.tests.navigator.testContentSorterModel"
             contentProvider="org.eclipse.ui.tests.navigator.extension.TestContentProvider"
diff --git a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/LabelProviderTest.java b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/LabelProviderTest.java
index 00e6596..a085d20 100644
--- a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/LabelProviderTest.java
+++ b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/LabelProviderTest.java
@@ -11,17 +11,14 @@
  *******************************************************************************/
 package org.eclipse.ui.tests.navigator;
 
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.tests.harness.util.DisplayHelper;
 import org.eclipse.ui.tests.navigator.extension.TestLabelProvider;
+import org.eclipse.ui.tests.navigator.extension.TestLabelProviderBlank;
 import org.eclipse.ui.tests.navigator.extension.TestLabelProviderCyan;
 import org.eclipse.ui.tests.navigator.extension.TestLabelProviderGreen;
 
 public class LabelProviderTest extends NavigatorTestBase {
 
-	private static final boolean DEBUG = false;
-
 	public LabelProviderTest() {
 		_navigatorInstanceId = "org.eclipse.ui.tests.navigator.OverrideTestView";
 	}
@@ -30,7 +27,7 @@
 	// used to signify no label content  see bug 268250
 	public void XXXtestBlankLabelProvider() throws Exception {
 
-		TestLabelProvider._blank = true;
+		TestLabelProvider._blankStatic = true;
 		
 		_contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN1,
 				TEST_CONTENT_OVERRIDE1 }, false);
@@ -41,10 +38,6 @@
 
 		TreeItem[] rootItems = _viewer.getTree().getItems();
 
-		if (DEBUG) {
-			DisplayHelper.sleep(Display.getCurrent(), 10000000);
-		}
-
 		if (!rootItems[0].getText().equals(""))
 			fail("Wrong text: " + rootItems[0].getText());
 	}
@@ -61,9 +54,6 @@
 
 		TreeItem[] rootItems = _viewer.getTree().getItems();
 
-		if (DEBUG) {
-			DisplayHelper.sleep(Display.getCurrent(), 10000000);
-		}
 
 		if (!rootItems[0].getText().startsWith("Green"))
 			fail("Wrong text: " + rootItems[0].getText());
@@ -74,18 +64,42 @@
 	
 	// bug 252293 [CommonNavigator] LabelProviders do not obey override rules
 	public void testSimpleResLast() throws Exception {
-
 		_contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2,
 				TEST_CONTENT_OVERRIDE2 }, false);
 		_contentService.getActivationService().activateExtensions(
 				new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2 }, true);
 
 		refreshViewer();
+
 		TreeItem[] rootItems = _viewer.getTree().getItems();
 		if (!rootItems[0].getText().startsWith("Cyan"))
 			fail("Wrong text: " + rootItems[0].getText());
 		assertEquals(TestLabelProviderCyan.getTestColor(), rootItems[0]
 				.getBackground(0));
 	}
+
+	
+	// Make sure that it finds label providers that are in overridden content extensions
+	// if none of the label providers from the desired content extensions return anything
+	public void testUsingOverriddenLabelProvider() throws Exception {
+
+		_contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2,
+				TEST_CONTENT_OVERRIDE2_BLANK }, true);
+		_contentService.getActivationService().activateExtensions(
+				new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2_BLANK }, true);
+
+		refreshViewer();
+		
+		TreeItem[] rootItems = _viewer.getTree().getItems();
+		
+		//DisplayHelper.sleep(10000000);
+		
+		// But we get the text from the overridden label provider
+		if (!rootItems[0].getText().startsWith("Blue"))
+			fail("Wrong text: " + rootItems[0].getText());
+		// We get the color from the blank label provider
+		assertEquals(TestLabelProviderBlank.getTestColor(), rootItems[0]
+				.getBackground(0));
+	}
 	
 }
diff --git a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestBase.java b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestBase.java
index 57f3f71..b1a6811 100644
--- a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestBase.java
+++ b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestBase.java
@@ -65,6 +65,7 @@
 	public static final String TEST_CONTENT_OVERRIDDEN2 = "org.eclipse.ui.tests.navigator.testContentOverridden2";
 	public static final String TEST_CONTENT_OVERRIDE1 = "org.eclipse.ui.tests.navigator.testContentOverride1";
 	public static final String TEST_CONTENT_OVERRIDE2 = "org.eclipse.ui.tests.navigator.testContentOverride2";
+	public static final String TEST_CONTENT_OVERRIDE2_BLANK = "org.eclipse.ui.tests.navigator.testContentOverride2Blank";
 	
 	public static final String TEST_CONTENT_LABEL1 = "org.eclipse.ui.tests.navigator.testContentLabel1";
 	public static final String TEST_CONTENT_LABEL2 = "org.eclipse.ui.tests.navigator.testContentLabel2";
diff --git a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProvider.java b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProvider.java
index 6429147..39d5ecd 100644
--- a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProvider.java
+++ b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProvider.java
@@ -37,10 +37,11 @@
 
 	private Font boldFont;
 
-	public static boolean _blank;
+	public static boolean _blankStatic;
+	public boolean _blank;
 	
 	public static void resetTest() {
-		_blank = false;
+		_blankStatic = false;
 	}
 	
 	public void init(ICommonContentExtensionSite aSite) {
@@ -60,7 +61,7 @@
 	}
 
 	public String getText(Object element) {
-		if (_blank)
+		if (_blankStatic || _blank)
 			return "";
 		
 		if (element instanceof TestExtensionTreeData) {
@@ -74,7 +75,7 @@
 	}
 
 	public StyledString getStyledText(Object element) {
-		if (_blank)
+		if (_blankStatic || _blank)
 			return new StyledString("");
 		return new StyledString(getText(element));
 	}
diff --git a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProviderBlank.java b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProviderBlank.java
new file mode 100644
index 0000000..c813b77
--- /dev/null
+++ b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/extension/TestLabelProviderBlank.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Oakland Software Incorporated 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:
+ *     Oakland Software Incorporated - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.tests.navigator.extension;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+
+/**
+ * @since 3.3
+ *
+ */
+public class TestLabelProviderBlank extends TestLabelProvider {
+
+	public void init(ICommonContentExtensionSite aSite) {
+		super.init(aSite);
+		_blank = true;
+	}
+	
+	public static Color backgroundColor = Display.getCurrent().getSystemColor(
+			SWT.COLOR_RED);
+	
+	public static Color getTestColor() {
+		return backgroundColor;
+	}
+	public Color getBackground(Object element) {
+		return backgroundColor;
+	}
+
+	public String getColorName() {
+		return "Red";
+	}
+
+}