Bug 313428 - Use Eclipse tracing to enable debug output
diff --git a/bundles/org.eclipse.e4.core.contexts/.options b/bundles/org.eclipse.e4.core.contexts/.options
new file mode 100644
index 0000000..98b0761
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.contexts/.options
@@ -0,0 +1,6 @@
+# Turn on debugging for the eclipse contexts
+org.eclipse.e4.core.contexts/debug=false
+# Show names that changed
+org.eclipse.e4.core.contexts/debug/names=false
+# Debug listeners
+org.eclipse.e4.core.contexts/debug/listeners=false
diff --git a/bundles/org.eclipse.e4.core.contexts/build.properties b/bundles/org.eclipse.e4.core.contexts/build.properties
index aa1a008..e6abbde 100644
--- a/bundles/org.eclipse.e4.core.contexts/build.properties
+++ b/bundles/org.eclipse.e4.core.contexts/build.properties
@@ -2,4 +2,5 @@
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               plugin.properties
+               plugin.properties,\
+               .options
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/Computation.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/Computation.java
index f4e7faa..c225a24 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/Computation.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/Computation.java
@@ -107,9 +107,9 @@
 	}
 
 	void startListening(EclipseContext originatingContext) {
-		if (EclipseContext.DEBUG)
-			System.out.println(toString() + " now listening to: " //$NON-NLS-1$
-					+ mapToString(dependencies));
+		if (DebugHelper.DEBUG_LISTENERS)
+			System.out.println("[context] " + toString() + " now listening to: " + mapToString(dependencies));//$NON-NLS-1$ //$NON-NLS-2$
+
 		for (Iterator<IEclipseContext> it = dependencies.keySet().iterator(); it.hasNext();) {
 			EclipseContext c = (EclipseContext) it.next();
 			Computation existingComputation = c.listeners.get(this);
@@ -131,19 +131,16 @@
 	}
 
 	protected void stopListening(IEclipseContext context, String name) {
-
 		if (name == null) {
-			if (EclipseContext.DEBUG)
-				System.out.println(toString() + " no longer listening to " + context); //$NON-NLS-1$
+			if (DebugHelper.DEBUG_LISTENERS)
+				System.out.println("[context] " + toString() + " no longer listening to " + context);//$NON-NLS-1$ //$NON-NLS-2$
 			dependencies.remove(context);
 			return;
 		}
 		Set<String> properties = dependencies.get(context);
 		if (properties != null) {
-			if (EclipseContext.DEBUG)
-				System.out.println(toString() + " no longer listening to " + context + ',' + name); //$NON-NLS-1$
-			// Bug 304859 - causes reordering of listeners
-			// ((EclipseContext) context).listeners.remove(this);
+			if (DebugHelper.DEBUG_LISTENERS)
+				System.out.println("[context] " + toString() + " no longer listening to " + context + ',' + name);//$NON-NLS-1$ //$NON-NLS-2$
 			properties.remove(name);
 			// if we no longer track any values in the context, remove dependency
 			if (properties.isEmpty())
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/DebugHelper.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/DebugHelper.java
new file mode 100644
index 0000000..1bd8317
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/DebugHelper.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.core.internal.contexts;
+
+public final class DebugHelper {
+
+	private static final String PLUGIN_NAME = "org.eclipse.e4.core.contexts"; //$NON-NLS-1$
+	private static final String OPTION_DEBUG = PLUGIN_NAME + "/debug"; //$NON-NLS-1$
+	private static final String OPTION_DEBUG_NAMES = OPTION_DEBUG + "/names"; //$NON-NLS-1$
+	private static final String OPTION_DEBUG_LISTENERS = OPTION_DEBUG + "/listeners"; //$NON-NLS-1$
+
+	public static boolean DEBUG = false;
+	public static boolean DEBUG_NAMES = false;
+	public static boolean DEBUG_LISTENERS = false;
+
+	static {
+		try {
+			// use qualified name for ContextsActivator to ensure that it won't be loaded outside of this block
+			DEBUG = org.eclipse.e4.core.internal.contexts.osgi.ContextsActivator.getBooleanDebugOption(OPTION_DEBUG, false);
+			DEBUG_NAMES = org.eclipse.e4.core.internal.contexts.osgi.ContextsActivator.getBooleanDebugOption(OPTION_DEBUG_NAMES, false);
+			DEBUG_LISTENERS = org.eclipse.e4.core.internal.contexts.osgi.ContextsActivator.getBooleanDebugOption(OPTION_DEBUG_LISTENERS, false);
+		} catch (NoClassDefFoundError noClass) {
+			// no OSGi - OK
+		}
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
index 7734952..b8a4126 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
@@ -190,11 +190,6 @@
 
 	static ThreadLocal<Computation> currentComputation = new ThreadLocal<Computation>();
 
-	// TODO replace with variable on bundle-specific class
-	public static boolean DEBUG = false;
-	public static boolean DEBUG_VERBOSE = false;
-	public static String DEBUG_VERBOSE_NAME = null;
-
 	private DebugSnap snapshot;
 
 	final Map<Computation, Computation> listeners = Collections.synchronizedMap(new LinkedHashMap<Computation, Computation>());
@@ -324,10 +319,6 @@
 
 	public Object internalGet(EclipseContext originatingContext, String name, boolean local) {
 		trackAccess(name);
-		if (DEBUG_VERBOSE) {
-			System.out.println("IEC.get(" + name + ", " + local + "):" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-					+ originatingContext + " for " + toString()); //$NON-NLS-1$
-		}
 		if (this == originatingContext) {
 			ValueComputation valueComputation = localValueComputations.get(name);
 			if (valueComputation != null) {
@@ -345,17 +336,12 @@
 		if (result != null) {
 			if (result instanceof IContextFunction) {
 				ValueComputation valueComputation = new ValueComputation(this, originatingContext, name, ((IContextFunction) result));
-				if (EclipseContext.DEBUG)
-					System.out.println("created " + valueComputation); //$NON-NLS-1$
 				originatingContext.localValueComputations.put(name, valueComputation);
 				// value computation depends on parent if function is defined in a parent
 				if (this != originatingContext)
 					valueComputation.addDependency(originatingContext, PARENT);
 				result = valueComputation.get();
 			}
-			if (DEBUG_VERBOSE) {
-				System.out.println("IEC.get(" + name + "): " + result); //$NON-NLS-1$ //$NON-NLS-2$
-			}
 			return result;
 		}
 		// 3. delegate to parent
@@ -373,8 +359,8 @@
 	 * computations and listeners that depend on this name.
 	 */
 	public void invalidate(String name, int eventType, Object oldValue, List<Scheduled> scheduled) {
-		if (EclipseContext.DEBUG)
-			System.out.println("invalidating " + this + ',' + name); //$NON-NLS-1$
+		if (DebugHelper.DEBUG_NAMES)
+			System.out.println("[context] invalidating \"" + name + "\" on " + toString()); //$NON-NLS-1$ //$NON-NLS-2$
 		removeLocalValueComputations(name);
 		handleInvalid(name, eventType, oldValue, scheduled);
 	}
@@ -446,6 +432,9 @@
 	}
 
 	public void set(String name, Object value) {
+		if (DebugHelper.DEBUG_NAMES)
+			System.out.println("[context] set(" + name + ',' + value + ")" + " on " + toString());//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
 		if (PARENT.equals(name)) {
 			setParent((IEclipseContext) value);
 			return;
@@ -453,10 +442,6 @@
 		boolean containsKey = localValues.containsKey(name);
 		Object oldValue = localValues.put(name, value);
 		if (!containsKey || value != oldValue) {
-			if (DEBUG_VERBOSE) {
-				System.out.println("IEC.set(" + name + ',' + value + "):" + oldValue + " for " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-						+ toString());
-			}
 			List<Scheduled> scheduled = new ArrayList<Scheduled>();
 			invalidate(name, ContextChangeEvent.ADDED, oldValue, scheduled);
 			processScheduled(scheduled);
@@ -478,12 +463,8 @@
 				throw new IllegalArgumentException(tmp);
 			}
 			Object oldValue = localValues.put(name, value);
-			if (value != oldValue) {
-				if (DEBUG_VERBOSE)
-					System.out.println("IEC.set(" + name + ',' + value + "):" + oldValue + " for " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-							+ toString());
+			if (value != oldValue)
 				invalidate(name, ContextChangeEvent.ADDED, oldValue, scheduled);
-			}
 			return true;
 		}
 
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/osgi/ContextsActivator.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/osgi/ContextsActivator.java
index c242b8a..a3b0da7 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/osgi/ContextsActivator.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/osgi/ContextsActivator.java
@@ -41,12 +41,19 @@
 		bundleContext = null;
 	}
 
-	public boolean getBooleanDebugOption(String option, boolean defaultValue) {
-		if (debugTracker == null) {
-			debugTracker = new ServiceTracker(bundleContext, DebugOptions.class.getName(), null);
-			debugTracker.open();
+	public BundleContext getBundleContext() {
+		return bundleContext;
+	}
+
+	public static boolean getBooleanDebugOption(String option, boolean defaultValue) {
+		BundleContext myBundleContext = getDefault().bundleContext;
+		if (myBundleContext == null)
+			return defaultValue;
+		if (getDefault().debugTracker == null) {
+			getDefault().debugTracker = new ServiceTracker(getDefault().bundleContext, DebugOptions.class.getName(), null);
+			getDefault().debugTracker.open();
 		}
-		DebugOptions options = (DebugOptions) debugTracker.getService();
+		DebugOptions options = (DebugOptions) getDefault().debugTracker.getService();
 		if (options != null) {
 			String value = options.getOption(option);
 			if (value != null)