Bug 372934 - Support dynamic tracing
diff --git a/org.eclipse.jdt.debug.jdi.tests/.cvsignore b/org.eclipse.jdt.debug.jdi.tests/.cvsignore
deleted file mode 100644
index ba077a4..0000000
--- a/org.eclipse.jdt.debug.jdi.tests/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/org.eclipse.jdt.debug.ui/plugin.properties b/org.eclipse.jdt.debug.ui/plugin.properties
index 199d3e4..e6eeb91 100644
--- a/org.eclipse.jdt.debug.ui/plugin.properties
+++ b/org.eclipse.jdt.debug.ui/plugin.properties
@@ -92,11 +92,7 @@
 javaVariableHoverDescription=Shows the value of the selected variable when debugging.
 
 JDTDebugActionSet.label=Java Debug
-
-
-
 manageMethodBreakpointAction.label=Toggle &Method Breakpoint
-
 manageWatchpointAction.label=Toggle &Watchpoint
 
 toggleClassPrepareAction.label=Toggle Class Load Break&point
@@ -310,4 +306,6 @@
 OpenFromClipboardAction.label = Open from Clipboar&d
 OpenFromClipboardAction.tooltip = Opens a Java element or Java Stack Trace from Clipboard
 OpenFromClipboardAction.description = Opens a Java element or a Java stack trace from clipboard
-OpenFromClipboardAction.name = Open from Clipboard
\ No newline at end of file
+OpenFromClipboardAction.name = Open from Clipboard
+JDTDebugCoreTrace.name = JDT Debug Core
+JDTLaunchingTrace.name = JDT Launching
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index 37b027c..8f0fc90 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -3639,4 +3639,23 @@
           variableName="project_classpath">
     </variablePresentation>
  </extension>
+ <extension
+       point="org.eclipse.ui.trace.traceComponents">
+    <component
+          id="org.eclipse.jdt.debug.core.component"
+          label="%JDTDebugCoreTrace.name">
+       <bundle
+             consumed="true"
+             name="org.eclipse.jdt.debug">
+       </bundle>
+    </component>
+    <component
+          id="org.eclipse.jdt.launching.component"
+          label="%JDTLaunchingTrace.name">
+       <bundle
+             consumed="true"
+             name="org.eclipse.jdt.launching">
+       </bundle>
+    </component>
+ </extension>
 </plugin>
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java
index c2e9e9a..3b74518 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 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
@@ -10,7 +10,11 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.core;
 
-import org.eclipse.core.runtime.Platform;
+import java.util.Hashtable;
+
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
+import org.osgi.framework.BundleContext;
 
 import com.ibm.icu.text.DateFormat;
 import com.ibm.icu.text.SimpleDateFormat;
@@ -20,31 +24,40 @@
  * 
  * @since 3.5
  */
-public class JDIDebugOptions {
-	// debug option flags
+public class JDIDebugOptions implements DebugOptionsListener {
+	
+	public static final String DEBUG_AST_EVALUATIONS_CALLING_THREADS_FLAG = "org.eclipse.jdt.debug/debug/astEvaluations/callingThreads"; //$NON-NLS-1$
+	public static final String DEBUG_AST_EVALUATIONS_FLAG = "org.eclipse.jdt.debug/debug/astEvaluations"; //$NON-NLS-1$
+	public static final String DEBUG_JDI_REQUEST_TIMES_FLAG = "org.eclipse.jdt.debug/debug/jdiRequestTimes"; //$NON-NLS-1$
+	public static final String DEBUG_JDI_EVENTS_FLAG = "org.eclipse.jdt.debug/debug/jdiEvents"; //$NON-NLS-1$
+	public static final String DEBUG_FLAG = "org.eclipse.jdt.debug/debug"; //$NON-NLS-1$
+	
 	public static boolean DEBUG = false;
 	public static boolean DEBUG_JDI_EVENTS = false;
 	public static boolean DEBUG_JDI_REQUEST_TIMES = false;
 	public static boolean DEBUG_AST_EVAL = false;
 	public static boolean DEBUG_AST_EVAL_THREAD_TRACE = false;
 
+	/**
+	 * Constructor
+	 */
+	public JDIDebugOptions(BundleContext context) {
+		Hashtable<String, String> props = new Hashtable<String, String>(2);
+		props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, JDIDebugPlugin.getUniqueIdentifier());
+		context.registerService(DebugOptionsListener.class.getName(), this, props);
+	}
+	
 	// used to format debug messages
-	public static final DateFormat FORMAT = new SimpleDateFormat(
-			"yyyy-MM-dd HH:mm:ss.SSS"); //$NON-NLS-1$
+	public static final DateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //$NON-NLS-1$
 
-	public static void initDebugOptions() {
-		DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.jdt.debug/debug")); //$NON-NLS-1$//$NON-NLS-2$
-		DEBUG_JDI_EVENTS = DEBUG
-				&& "true".equals( //$NON-NLS-1$
-						Platform.getDebugOption("org.eclipse.jdt.debug/debug/jdiEvents")); //$NON-NLS-1$
-		DEBUG_JDI_REQUEST_TIMES = DEBUG
-				&& "true".equals( //$NON-NLS-1$
-						Platform.getDebugOption("org.eclipse.jdt.debug/debug/jdiRequestTimes")); //$NON-NLS-1$
-		DEBUG_AST_EVAL = DEBUG
-				&& "true".equals( //$NON-NLS-1$
-						Platform.getDebugOption("org.eclipse.jdt.debug/debug/astEvaluations")); //$NON-NLS-1$
-		DEBUG_AST_EVAL_THREAD_TRACE = DEBUG
-				&& "true".equals( //$NON-NLS-1$
-						Platform.getDebugOption("org.eclipse.jdt.debug/debug/astEvaluations/callingThreads")); //$NON-NLS-1$
+	/* (non-Javadoc)
+	 * @see org.eclipse.osgi.service.debug.DebugOptionsListener#optionsChanged(org.eclipse.osgi.service.debug.DebugOptions)
+	 */
+	public void optionsChanged(DebugOptions options) {
+		DEBUG = options.getBooleanOption(DEBUG_FLAG, false);
+		DEBUG_JDI_EVENTS = DEBUG && options.getBooleanOption(DEBUG_JDI_EVENTS_FLAG, false);
+		DEBUG_JDI_REQUEST_TIMES = DEBUG && options.getBooleanOption(DEBUG_JDI_REQUEST_TIMES_FLAG, false);
+		DEBUG_AST_EVAL = DEBUG && options.getBooleanOption(DEBUG_AST_EVALUATIONS_FLAG, false);
+		DEBUG_AST_EVAL_THREAD_TRACE = DEBUG && options.getBooleanOption(DEBUG_AST_EVALUATIONS_CALLING_THREADS_FLAG, false);
 	}
 }
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
index 84d5212..cd60a06 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -270,7 +270,7 @@
 	@Override
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
-		JDIDebugOptions.initDebugOptions();
+		new JDIDebugOptions(context);
 		ResourcesPlugin.getWorkspace().addSaveParticipant(getUniqueIdentifier(),
 				new ISaveParticipant() {
 					public void doneSaving(ISaveContext c) {
diff --git a/org.eclipse.jdt.launching.macosx/.cvsignore b/org.eclipse.jdt.launching.macosx/.cvsignore
deleted file mode 100644
index ba077a4..0000000
--- a/org.eclipse.jdt.launching.macosx/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainer.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainer.java
index 1c0e4da..a7fdcdd 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainer.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainer.java
@@ -19,7 +19,6 @@
 import java.util.Map;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.jdt.core.IAccessRule;
 import org.eclipse.jdt.core.IClasspathAttribute;
 import org.eclipse.jdt.core.IClasspathContainer;
@@ -64,9 +63,6 @@
 	 */
 	private static IAccessRule[] EMPTY_RULES = new IAccessRule[0];
 	
-	// debug flags
-	public static boolean DEBUG_JRE_CONTAINER = false;
-	
 	/**
 	 * Map of {IVMInstall -> Map of {{IExeuctionEnvironment, IAccessRule[][]} -> {IClasspathEntry[]}} 
 	 */
@@ -241,14 +237,6 @@
 	}
 	
 	/**
-	 * Initialize debug flags
-	 */
-	static {
-		DEBUG_JRE_CONTAINER =LaunchingPlugin.DEBUG && "true".equals( //$NON-NLS-1$
-		 Platform.getDebugOption("org.eclipse.jdt.launching/debug/classpath/jreContainer")); //$NON-NLS-1$
-	}
-	
-	/**
 	 * Returns the classpath entries associated with the given VM
 	 * in the context of the given path and project.
 	 * 
@@ -268,7 +256,7 @@
 				fgClasspathEntries.put(vm, entries);
 			}
 		} else {
-			if (DEBUG_JRE_CONTAINER) {
+			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 				System.out.println("\tEE:\t" + id); //$NON-NLS-1$
 			}
 			// dynamically compute entries when bound to an EE
@@ -363,14 +351,14 @@
 	 * @see IClasspathContainer#getClasspathEntries()
 	 */
 	public IClasspathEntry[] getClasspathEntries() {
-		if (DEBUG_JRE_CONTAINER) {
+		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 			System.out.println("<JRE_CONTAINER> getClasspathEntries() " + this.toString()); //$NON-NLS-1$
 			System.out.println("\tJRE:\t" + fVMInstall.getName()); //$NON-NLS-1$
 			System.out.println("\tPath:\t" + getPath().toString()); //$NON-NLS-1$
 			System.out.println("\tProj:\t" + fProject.getProject().getName()); //$NON-NLS-1$
 		}
 		IClasspathEntry[] entries = getClasspathEntries(fVMInstall, getPath(), fProject);
-		if (DEBUG_JRE_CONTAINER) {
+		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 			System.out.println("\tResolved " + entries.length + " entries:");  //$NON-NLS-1$//$NON-NLS-2$
 		}
 		return entries;
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainerInitializer.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainerInitializer.java
index f5b89fd..5da716e 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainerInitializer.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainerInitializer.java
@@ -46,7 +46,7 @@
 	 */
 	@Override
 	public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
-		if (JREContainer.DEBUG_JRE_CONTAINER) {
+		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 			System.out.println("<JRE_CONTAINER> initialize()"); //$NON-NLS-1$
 			System.out.println("\tPath: " + containerPath.toString()); //$NON-NLS-1$
 			System.out.println("\tProj: " + project.getProject().getName()); //$NON-NLS-1$
@@ -57,23 +57,23 @@
 				IVMInstall vm = resolveVM(containerPath);
 				JREContainer container = null;
 				if (vm != null) {
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\tResolved VM: " + vm.getName()); //$NON-NLS-1$
 					}
 					container = new JREContainer(vm, containerPath, project);
 				} else {
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\t*** FAILED RESOLVE VM ***"); //$NON-NLS-1$
 					}
 				}
 				JavaCore.setClasspathContainer(containerPath, new IJavaProject[] {project}, new IClasspathContainer[] {container}, null);
 			} else {
-				if (JREContainer.DEBUG_JRE_CONTAINER) {
+				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 					System.out.println("\t*** INVALID JRE CONTAINER PATH ***"); //$NON-NLS-1$
 				}	
 			}
 		} else {
-			if (JREContainer.DEBUG_JRE_CONTAINER) {
+			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 				System.out.println("\t*** NO SEGMENTS IN CONTAINER PATH ***"); //$NON-NLS-1$
 			}
 		}
@@ -94,25 +94,25 @@
 				IVMInstall vm = resolveVM(containerPath);
 				IClasspathContainer[] containers = new JREContainer[length];
 				if (vm != null) {
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\tResolved VM: " + vm.getName()); //$NON-NLS-1$
 					}
 					for (int i=0; i<length; i++) {
 						containers[i] = new JREContainer(vm, containerPath, projects[i]);
 					}
 				} else {
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\t*** FAILED RESOLVE VM ***"); //$NON-NLS-1$
 					}
 				}
 				JavaCore.setClasspathContainer(containerPath, projects, containers, null);
 			} else {
-				if (JREContainer.DEBUG_JRE_CONTAINER) {
+				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 					System.out.println("\t*** INVALID JRE CONTAINER PATH ***"); //$NON-NLS-1$
 				}	
 			}
 		} else {
-			if (JREContainer.DEBUG_JRE_CONTAINER) {
+			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 				System.out.println("\t*** NO SEGMENTS IN CONTAINER PATH ***"); //$NON-NLS-1$
 			}
 		}
@@ -130,7 +130,7 @@
 			// specific JRE
 			String id = getExecutionEnvironmentId(containerPath);
 			if (id != null) {
-				if (JREContainer.DEBUG_JRE_CONTAINER) {
+				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 					System.out.println("<JRE_CONTAINER> resolveVM(IPath)"); //$NON-NLS-1$
 					System.out.println("\tEE: " + id); //$NON-NLS-1$
 				}
@@ -139,7 +139,7 @@
 				if (environment != null) {
 					vm = resolveVM(environment);
 				} else {
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\t*** NO ENVIRONMENT ***"); //$NON-NLS-1$
 					}
 				}
@@ -167,21 +167,21 @@
 	 * @since 3.2
 	 */
 	public static IVMInstall resolveVM(IExecutionEnvironment environment) {
-		if (JREContainer.DEBUG_JRE_CONTAINER) {
+		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 			System.out.println("<JRE_CONTAINER> resolveVM(IExecutionEnvironment)"); //$NON-NLS-1$
 		}
 		IVMInstall vm = environment.getDefaultVM();
 		if (vm == null) {
 			IVMInstall[] installs = environment.getCompatibleVMs();
 			// take the first strictly compatible VM if there is no default
-			if (installs.length == 0 && JREContainer.DEBUG_JRE_CONTAINER) {
+			if (installs.length == 0 && LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 				System.out.println("\t*** NO COMPATIBLE VMS ***"); //$NON-NLS-1$
 			}
 			for (int i = 0; i < installs.length; i++) {
 				IVMInstall install = installs[i];
 				if (environment.isStrictlyCompatible(install)) {
 					vm = install;
-					if (JREContainer.DEBUG_JRE_CONTAINER) {
+					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 						System.out.println("\tPerfect Match: " + vm.getName()); //$NON-NLS-1$
 					}
 					break;
@@ -194,12 +194,12 @@
 			// use the first VM failing that
 			if (vm == null && installs.length > 0) {
 				vm = installs[0];
-				if (JREContainer.DEBUG_JRE_CONTAINER) {
+				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 					System.out.println("\tFirst Match: " + vm.getName()); //$NON-NLS-1$
 				}
 			}
 		} else {
-			if (JREContainer.DEBUG_JRE_CONTAINER) {
+			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
 				System.out.println("\tUser Default VM: " + vm.getName()); //$NON-NLS-1$
 			}
 		}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
index 4e17b0a..806cce9 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -75,6 +76,8 @@
 import org.eclipse.jdt.launching.JavaRuntime;
 import org.eclipse.jdt.launching.VMStandin;
 import org.eclipse.jdt.launching.sourcelookup.ArchiveSourceLocation;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
 import org.eclipse.osgi.util.NLS;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.prefs.BackingStoreException;
@@ -87,8 +90,17 @@
 import org.xml.sax.helpers.DefaultHandler;
 
 @SuppressWarnings("deprecation")
-public class LaunchingPlugin extends Plugin implements IEclipsePreferences.IPreferenceChangeListener, IVMInstallChangedListener, IResourceChangeListener, ILaunchesListener, IDebugEventSetListener {
+public class LaunchingPlugin extends Plugin implements DebugOptionsListener, IEclipsePreferences.IPreferenceChangeListener, IVMInstallChangedListener, IResourceChangeListener, ILaunchesListener, IDebugEventSetListener {
+
+	/**
+	 * Whether debug options are turned on for this plug-in.
+	 */
+	public static boolean DEBUG = false;
+	public static boolean DEBUG_JRE_CONTAINER = false;
 	
+	public static final String DEBUG_JRE_CONTAINER_FLAG = "org.eclipse.jdt.launching/debug/classpath/jreContainer"; //$NON-NLS-1$
+	public static final String DEBUG_FLAG = "org.eclipse.jdt.launching/debug"; //$NON-NLS-1$
+
 	/**
 	 * The id of the JDT launching plug-in (value <code>"org.eclipse.jdt.launching"</code>).
 	 */
@@ -150,18 +162,13 @@
 	 * the plug-in can ignore processing and changes.
 	 */
 	private boolean fBatchingChanges = false;
-	
+
 	/**
 	 * Shared XML parser
 	 */
 	private static DocumentBuilder fgXMLParser = null;
 	
 	/**
-	 * Whether debug options are turned on for this plug-in.
-	 */
-	public static boolean DEBUG = false;
-	
-	/**
 	 * Stores VM changes resulting from a JRE preference change.
 	 */
 	class VMChanges implements IVMInstallChangedListener {
@@ -513,7 +520,9 @@
 	@Override
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
-		DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.jdt.launching/debug"));  //$NON-NLS-1$//$NON-NLS-2$
+		Hashtable<String, String> props = new Hashtable<String, String>(2);
+		props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, getUniqueIdentifier());
+		context.registerService(DebugOptionsListener.class.getName(), this, props);
 		ResourcesPlugin.getWorkspace().addSaveParticipant(ID_PLUGIN, new ISaveParticipant() {
 			public void doneSaving(ISaveContext context1) {}
 			public void prepareToSave(ISaveContext context1)	throws CoreException {}
@@ -1245,4 +1254,12 @@
 			}
 		}
 	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.osgi.service.debug.DebugOptionsListener#optionsChanged(org.eclipse.osgi.service.debug.DebugOptions)
+	 */
+	public void optionsChanged(DebugOptions options) {
+		DEBUG = options.getBooleanOption(DEBUG_FLAG, false);
+		DEBUG_JRE_CONTAINER = DEBUG && options.getBooleanOption(DEBUG_JRE_CONTAINER_FLAG, false);
+	}
 }
\ No newline at end of file