/*******************************************************************************
 * Copyright (c) 2009, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.osgi.tests.debugoptions;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.tests.harness.CoreTest;
import org.eclipse.osgi.internal.debug.FrameworkDebugOptions;
import org.eclipse.osgi.internal.debug.FrameworkDebugTraceEntry;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.osgi.service.debug.DebugTrace;
import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

public class DebugOptionsTestCase extends CoreTest {
	public static Test suite() {
		return new TestSuite(DebugOptionsTestCase.class);
	}

	DebugOptions debugOptions;
	ServiceReference ref;
	Dictionary props = null;
	TestDebugOptionsListener listener = null;
	ServiceRegistration reg = null;
	private final static String TRACE_ELEMENT_DELIMITER = "|"; //$NON-NLS-1$ // this value needs to match EclipseDebugTrace#TRACE_ELEMENT_DELIMITER
	private final static String TRACE_ELEMENT_DELIMITER_ENCODED = "&#124;"; //$NON-NLS-1$ // this value needs to match EclipseDebugTrace#TRACE_ELEMENT_DELIMITER_ENCODED
	private final static SimpleDateFormat TRACE_FILE_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //$NON-NLS-1$
	private final static String LINE_SEPARATOR;
	private boolean verboseDebug = true; // default is true
	static {
		String s = System.getProperty("line.separator"); //$NON-NLS-1$
		LINE_SEPARATOR = s == null ? "\n" : s; //$NON-NLS-1$
	}
	private final static String TAB_CHARACTER = "\t"; //$NON-NLS-1$

	protected void setUp() throws Exception {
		ref = OSGiTestsActivator.getContext().getServiceReference(DebugOptions.class.getName());
		assertNotNull("DebugOptions service is not available", ref); //$NON-NLS-1$
		debugOptions = (DebugOptions) OSGiTestsActivator.getContext().getService(ref);
		assertNotNull("DebugOptions service is not available", debugOptions); //$NON-NLS-1$
		props = new Hashtable();
		props.put(DebugOptions.LISTENER_SYMBOLICNAME, getName());
		listener = new TestDebugOptionsListener();
		reg = OSGiTestsActivator.getContext().registerService(DebugOptionsListener.class.getName(), listener, props);
	}

	protected void tearDown() throws Exception {
		if (debugOptions == null)
			return;
		debugOptions.setDebugEnabled(false);
		debugOptions = null;
		OSGiTestsActivator.getContext().ungetService(ref);
		if (reg != null)
			reg.unregister();
	}

	public void testRegistration01() {
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
	}

	/**
	 * Test that a new {@link FrameworkDebugTraceEntry} object created without a trace class
	 * has 'org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase' as the class name and
	 * 'testTracingEntry01' as the method name that it determined as the caller of it.
	 * 
	 * This test mimics the tracing framework to ensure that the correct class name and method name
	 * are returned and written to the trace file.
	 */
	public void testTracingEntry01() {

		String bundleName = OSGiTestsActivator.getContext().getBundle().getSymbolicName();
		String optionPath = "/debug"; //$NON-NLS-1$
		String message = "Test message"; //$NON-NLS-1$
		FrameworkDebugTraceEntry traceEntry = new FrameworkDebugTraceEntry(bundleName, optionPath, message, null);
		String correctClassName = "org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase"; //$NON-NLS-1$
		String correctMethodName = "testTracingEntry01"; //$NON-NLS-1$
		assertEquals("The class calling the trace API does not match the expected value.", correctClassName, traceEntry.getClassName()); //$NON-NLS-1$  
		assertEquals("The method calling the trace API does not match the expected value.", correctMethodName, traceEntry.getMethodName()); //$NON-NLS-1$
	}

	/**
	 * Test that a new {@link FrameworkDebugTraceEntry} object created with a trace class
	 * of 'org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase' has the correct class name and
	 * method name of the caller.
	 * 
	 * This test mimics the tracing framework to ensure that the correct class name and method name
	 * are returned and written to the trace file.
	 */
	public void testTracingEntry02() {

		String correctClassName = Runner1.class.getName();
		String correctMethodName = "run"; //$NON-NLS-1$
		FrameworkDebugTraceEntry traceEntry = new Runner1().run();
		assertEquals("The class calling the trace API does not match the expected value.", correctClassName, traceEntry.getClassName()); //$NON-NLS-1$  
		assertEquals("The method calling the trace API does not match the expected value.", correctMethodName, traceEntry.getMethodName()); //$NON-NLS-1$
	}

	static class Runner1 {
		public FrameworkDebugTraceEntry run() {
			return new Runner2().run();
		}
	}

	static class Runner2 {
		public FrameworkDebugTraceEntry run() {
			String bundleName = OSGiTestsActivator.getContext().getBundle().getSymbolicName();
			String optionPath = "/debug"; //$NON-NLS-1$
			String message = "Test message"; //$NON-NLS-1$
			String tracingClass = this.getClass().getName();
			return new FrameworkDebugTraceEntry(bundleName, optionPath, message, tracingClass);
		}
	}

	public void testDyanmicEnablement01() {
		if (debugOptions.isDebugEnabled())
			return; // cannot test
		debugOptions.setDebugEnabled(true);
		assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		listener.clear();
		Map checkValues = new HashMap();
		checkValues.put(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		listener.setCheckValues(checkValues);
		debugOptions.setOption(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNull("Found bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$
	}

	public void testDyanmicEnablement02() {
		if (debugOptions.isDebugEnabled())
			return; // cannot test
		debugOptions.setDebugEnabled(true);
		assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		listener.clear();
		Map checkValues = new HashMap();
		checkValues.put(getName() + "/debug", "false"); //$NON-NLS-1$ //$NON-NLS-2$
		listener.setCheckValues(checkValues);
		debugOptions.setOption(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNotNull("Should find bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$
	}

	public void testDyanmicEnablement03() {
		listener.clear();
		if (debugOptions.isDebugEnabled())
			return; // cannot test
		TestDebugOptionsListener anotherListener = new TestDebugOptionsListener();
		Dictionary anotherProps = new Hashtable();
		anotherProps.put(DebugOptions.LISTENER_SYMBOLICNAME, "anotherListener"); //$NON-NLS-1$
		ServiceRegistration anotherReg = OSGiTestsActivator.getContext().registerService(DebugOptionsListener.class.getName(), anotherListener, anotherProps);
		assertTrue("Not called", anotherListener.gotCalled()); //$NON-NLS-1$

		debugOptions.setDebugEnabled(true);
		assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$

		listener.clear();
		anotherListener.clear();

		Map checkValues = new HashMap();
		checkValues.put(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		listener.setCheckValues(checkValues);
		debugOptions.setOption(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		assertFalse("Should not call wrong listener", anotherListener.gotCalled()); //$NON-NLS-1$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNull("Found bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$
		listener.clear();
		anotherListener.clear();
		debugOptions.setOption("anotherListener/test", "blah"); //$NON-NLS-1$ //$NON-NLS-2$
		assertFalse("Listener should not have been called", listener.gotCalled()); //$NON-NLS-1$
		assertTrue("Another listener should have been called", anotherListener.gotCalled()); //$NON-NLS-1$

		listener.clear();
		anotherListener.clear();
		anotherProps.put(DebugOptions.LISTENER_SYMBOLICNAME, getName());
		anotherReg.setProperties(anotherProps);
		debugOptions.setOption(getName() + "/debug", "false"); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertTrue("Another listener did not get called", anotherListener.gotCalled()); //$NON-NLS-1$

		anotherReg.unregister();
	}

	public void testDyanmicEnablement04() {
		if (debugOptions.isDebugEnabled())
			return; // cannot test
		debugOptions.setDebugEnabled(true);
		listener.clear();
		assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		Map checkValues = new HashMap();
		checkValues.put(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		listener.setCheckValues(checkValues);
		debugOptions.setOption(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNull("Found bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$

		listener.clear();
		checkValues.put(getName() + "/debug", null); //$NON-NLS-1$ 
		listener.setCheckValues(checkValues);
		debugOptions.setDebugEnabled(false);
		assertFalse("Debug is enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNull("Found bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$

		listener.clear();
		checkValues.put(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		listener.setCheckValues(checkValues);
		debugOptions.setDebugEnabled(true);
		assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		assertTrue("Listener did not get called", listener.gotCalled()); //$NON-NLS-1$
		assertNull("Found bad value: " + listener.getIncorrectValue(), listener.getIncorrectValue()); //$NON-NLS-1$

	}

	public void testBatchSetOptionsWhenEnabled() {

		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		String key1 = getName() + "/debug/disableCheck1";
		String key2 = getName() + "/debug/disableCheck2";
		String key3 = getName() + "/debug/disableCheck3";
		Map /* <String, String> */ newOptions = new HashMap();
		newOptions.put(key1, "ok1");
		newOptions.put(key2, "ok2");
		newOptions.put(key3, "ok3");
		// create the new set of options
		listener.clear();
		// create the new set of options
		debugOptions.setOptions(newOptions);
		// make sure the listener got called
		assertTrue("Listener did not get called when setting batch options when tracing is enabled", listener.gotCalled()); //$NON-NLS-1$
		// get all of the options
		Map/* <String, String> */ currentOptions = debugOptions.getOptions();
		// make sure the Map object returned is not the same Map object that was set
		assertNotSame("The Map object set is the exact same Map object returned", newOptions, currentOptions);
		// make sure the size is correct (it should be the same as the original Map)
		assertEquals("The amount of options retrieved is not correct", newOptions.size(), currentOptions.size());
		// make sure the values are correct
		String actualValue = (String) currentOptions.get(key1);
		assertEquals("The original option for key1 does not match the retrieved option when tracing is enabled", "ok1", actualValue);
		actualValue = (String) currentOptions.get(key2);
		assertEquals("The original option for key1 does not match the retrieved option when tracing is enabled", "ok2", actualValue);
		actualValue = (String) currentOptions.get(key3);
		assertEquals("The original option for key1 does not match the retrieved option when tracing is enabled", "ok3", actualValue);
		// add a new batch of options
		String key4 = getName() + "/debug/disableCheck4";
		String key5 = getName() + "/debug/disableCheck5";
		String key6 = getName() + "/debug/disableCheck6";
		Map /* <String, String> */ newOptions2 = new HashMap();
		newOptions2.put(key4, "ok4");
		newOptions2.put(key5, "ok5");
		newOptions2.put(key6, "ok6");
		listener.clear();
		// create the new set of options
		debugOptions.setOptions(newOptions2);
		// make sure the listener got called
		assertTrue("Listener did not get called when setting batch options when tracing is enabled", listener.gotCalled()); //$NON-NLS-1$
		// make sure the Map object returned is not the same Map object that was set
		Map currentOptions2 = debugOptions.getOptions();
		assertNotSame("The Map object set is the exact same Map object returned", newOptions, currentOptions2);
		// make sure the size is correct (it should be the same as the original Map)
		assertEquals("The amount of options retrieved is not correct", newOptions.size(), currentOptions2.size());
		// make sure the old values do not exist
		actualValue = (String) currentOptions2.get(key1);
		assertNull("The original option for key1 is in the returned options (it should not be there)", actualValue);
		actualValue = (String) currentOptions2.get(key2);
		assertNull("The original option for key2 is in the returned options (it should not be there)", actualValue);
		actualValue = (String) currentOptions2.get(key3);
		assertNull("The original option for key3 is in the returned options (it should not be there)", actualValue);
		// make sure the new values are correct
		actualValue = (String) currentOptions2.get(key4);
		assertEquals("The new option for key4 does not match the retrieved option when tracing is enabled", "ok4", actualValue);
		actualValue = (String) currentOptions2.get(key5);
		assertEquals("The new option for key5 does not match the retrieved option when tracing is enabled", "ok5", actualValue);
		actualValue = (String) currentOptions2.get(key6);
		assertEquals("The new option for key6 does not match the retrieved option when tracing is enabled", "ok6", actualValue);
	}

	public void testSetNullOptions() {

		// make sure setOptions() doesn't like an empty Map
		boolean exceptionThrown = false;
		try {
			debugOptions.setOptions(null);
		} catch (Exception ex) {
			exceptionThrown = true;
		}
		assertTrue("An exception was not thrown when calling setOptions() with a null parameter", exceptionThrown);
		// make sure setOption(key,value) doesn't like a null key or value
		exceptionThrown = false;
		try {
			debugOptions.setOption("key", null);
		} catch (Exception ex) {
			exceptionThrown = true;
		}
		assertTrue("An exception was not thrown when calling setOption() with a null value", exceptionThrown);
		exceptionThrown = false;
		try {
			debugOptions.setOption(null, "value");
		} catch (Exception ex) {
			exceptionThrown = true;
		}
		assertTrue("An exception was not thrown when calling setOption() with a null key", exceptionThrown);
	}

	public void testBatchSetOptionsWhenDisabled() {

		// enable tracing initially.
		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}

		String key1 = getName() + "/debug/disableCheck1";
		String key2 = getName() + "/debug/disableCheck2";
		String key3 = getName() + "/debug/disableCheck3";
		Map /* <String, String> */ newOptions = new HashMap();
		newOptions.put(key1, "ok1");
		newOptions.put(key2, "ok2");
		newOptions.put(key3, "ok3");
		listener.clear();
		// create the new set of options
		debugOptions.setOptions(newOptions);
		// make sure the listener got called
		assertTrue("Listener did not get called when setting batch options when tracing is enabled", listener.gotCalled()); //$NON-NLS-1$
		// disable tracing
		debugOptions.setDebugEnabled(false);
		// get all of the options (should be the disabled option set - which should contain only the recently set options)
		Map currentOptions = debugOptions.getOptions();
		// make sure the Map returned is not the same Map object that was set
		assertNotSame("The Map object retrieved is the exact same Map object returned when tracing is disabled.", newOptions, currentOptions);
		// make sure the size is correct (it should be the same as the original Map)
		assertEquals("The amount of options retrieved is not the same after tracing is disabled", newOptions.size(), currentOptions.size());
		// make sure the values are correct - check key1
		String actualValue = (String) currentOptions.get(key1);
		assertNotNull("The value for key1 is null", actualValue);
		assertEquals("The original option for key1 does not match the retrieved option when tracing is disabled", "ok1", actualValue);
		// check key2
		actualValue = (String) currentOptions.get(key2);
		assertNotNull("The value for key2 is null", actualValue);
		assertEquals("The original option for key2 does not match the retrieved option when tracing is disabled", "ok2", actualValue);
		// check key3
		actualValue = (String) currentOptions.get(key3);
		assertNotNull("The value for key3 is null", actualValue);
		assertEquals("The original option for key3 does not match the retrieved option when tracing is disabled", "ok3", actualValue);
		// add a new batch of options when tracing is disabled
		String key4 = getName() + "/debug/disableCheck4";
		String key5 = getName() + "/debug/disableCheck5";
		String key6 = getName() + "/debug/disableCheck6";
		Map /* <String, String> */ newOptions2 = new HashMap();
		newOptions2.put(key4, "ok4");
		newOptions2.put(key5, "ok5");
		newOptions2.put(key6, "ok6");
		listener.clear();
		// create the new set of options
		debugOptions.setOptions(newOptions2);
		// make sure the listener did not get called
		assertFalse("Listener got called when settings batch options with tracing disabled", listener.gotCalled()); //$NON-NLS-1$
		// make sure the Map object returned is not the same Map object that was set
		Map currentOptions2 = debugOptions.getOptions();
		assertNotSame("The Map object set is the exact same Map object returned", newOptions, currentOptions2);
		// make sure the size is correct (it should be the same as the original Map)
		assertEquals("The amount of options retrieved is not correct", newOptions.size(), currentOptions2.size());
		// make sure the old values do not exist
		actualValue = (String) currentOptions2.get(key1);
		assertNull("The original option for key1 is in the returned options (it should not be there)", actualValue);
		actualValue = (String) currentOptions2.get(key2);
		assertNull("The original option for key2 is in the returned options (it should not be there)", actualValue);
		actualValue = (String) currentOptions2.get(key3);
		assertNull("The original option for key3 is in the returned options (it should not be there)", actualValue);
		// make sure the new values are correct
		actualValue = (String) currentOptions2.get(key4);
		assertEquals("The new option for key4 does not match the retrieved option when tracing is disabled", "ok4", actualValue);
		actualValue = (String) currentOptions2.get(key5);
		assertEquals("The new option for key5 does not match the retrieved option when tracing is disabled", "ok5", actualValue);
		actualValue = (String) currentOptions2.get(key6);
		assertEquals("The new option for key6 does not match the retrieved option when tracing is disabled", "ok6", actualValue);
		// testing of options when tracing is re-enabled is done in testSetOptionsWhenDisabled so it is not needed here
	}

	public void testSetOptionsWhenDisabled() {

		// enable tracing initially.
		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		// create a new key to add.
		String testKey = getName() + "/debug/disableCheck";
		// set its value to 'ok'
		debugOptions.setOption(testKey, "ok");
		// make sure the right value is added
		String actualValue = debugOptions.getOption(testKey, "not ok");
		assertEquals("The correct option value was not returned from the debug option: " + testKey, "ok", actualValue);
		// disable tracing
		debugOptions.setDebugEnabled(false);
		// check for the value
		actualValue = debugOptions.getOption(testKey, "not ok");
		assertEquals("The 'default' value supplied was not returned when tracing is disabled.", "not ok", actualValue);
		// try setting the value to "ok" (this should be a no-op and return the 'default' value)
		debugOptions.setOption(testKey, "ok");
		actualValue = debugOptions.getOption(testKey, "not ok");
		assertEquals("The 'default' value supplied was not returned when tracing is disabled.", "not ok", actualValue);
		// remove the option and check for the value (it should still exist after re-enabling tracing)
		debugOptions.removeOption(testKey);
		// re-enable tracing
		debugOptions.setDebugEnabled(true);
		// check that the value is still the initial "ok"
		actualValue = debugOptions.getOption(testKey, "not ok");
		assertEquals("The value after re-enabling tracing is invalid.", "ok", actualValue);
	}

	public void testStringValues() {

		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		// create a new key to add.
		String testKey = getName() + "/debug/stringValue";
		// set its value to 'test'
		debugOptions.setOption(testKey, "test");
		// check to make sure the value returned is correct
		String actualValue = debugOptions.getOption(testKey, "default");
		assertEquals("The correct option value was not returned from the debug option: " + testKey, "test", actualValue);
		// remove the option and check for the value (it should not exist so the default value should be returned)
		debugOptions.removeOption(testKey);
		actualValue = debugOptions.getOption(testKey, "default");
		assertEquals("The 'default' value supplied was not returned when the key does not exist in the DebugOptions.", "default", actualValue);
	}

	public void testIntegerValues() {

		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		// create a new key to add.
		String testKey = getName() + "/debug/intValue";
		// set its value to 42.
		debugOptions.setOption(testKey, "42");
		// check to make sure the value returned is correct
		int actualValue = debugOptions.getIntegerOption(testKey, 0);
		assertEquals("The correct option value was not returned from the debug option: " + testKey, 42, actualValue);
		// set the value of this key so that a NumberFormatException will occur
		debugOptions.setOption(testKey, "test");
		actualValue = debugOptions.getIntegerOption(testKey, 0);
		assertEquals("The 'default' value supplied was not returned when a NumberFormatException occurs.", 0, actualValue);
		// remove the option and check for the value (it should not exist so the default value should be returned)
		debugOptions.removeOption(testKey);
		actualValue = debugOptions.getIntegerOption(testKey, 0);
		assertEquals("The 'default' value supplied was not returned when the key does not exist in the DebugOptions.", 0, actualValue);
	}

	public void testBooleanValues() {
		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		String testKey = getName() + "/debug";
		boolean testValue = debugOptions.getBooleanOption(testKey, false);
		assertFalse(testKey + " is true", testValue);
		debugOptions.setOption(testKey, "false");
		testValue = debugOptions.getBooleanOption(testKey, true);
		assertFalse(testKey + " is true", testValue);

		debugOptions.setOption(testKey, "true");
		testValue = debugOptions.getBooleanOption(testKey, false);
		assertTrue(testKey + " is false", testValue);
		testValue = debugOptions.getBooleanOption(testKey, true);
		assertTrue(testKey + " is false", testValue);
	}

	private TestDebugTrace createDebugTrace(final File traceFile) {

		TestDebugTrace debugTrace = null;
		if (!debugOptions.isDebugEnabled()) {
			/** Setup the DebugOptions */
			debugOptions.setDebugEnabled(true);
			assertTrue("Debug is not enabled", debugOptions.isDebugEnabled()); //$NON-NLS-1$
		}
		debugOptions.setOption(getName() + "/debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		debugOptions.setFile(traceFile);
		DebugTrace wrapped = debugOptions.newDebugTrace(getName(), TestDebugTrace.class);
		debugTrace = new TestDebugTrace(wrapped);
		return debugTrace;
	}

	/**
	 * Test all DebugTrace.trace*() API when verbose debugging is disabled
	 */
	public void testVerboseDebugging() {

		// TODO: Convert this back to {@link DebugOptions} once is/setVerbose becomes API
		FrameworkDebugOptions fwDebugOptions = (FrameworkDebugOptions) debugOptions;
		if (!debugOptions.isDebugEnabled()) {
			debugOptions.setDebugEnabled(true);
		}
		// create a tracing record
		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		final String exceptionMessage1 = "An error 1"; //$NON-NLS-1$
		try {
			fwDebugOptions.setVerbose(false);
			debugTrace.trace("/debug", "testing 1", new Exception(exceptionMessage1)); //$NON-NLS-1$ //$NON-NLS-2$
			fwDebugOptions.setVerbose(true);
			debugTrace.trace("/debug", "testing 2"); //$NON-NLS-1$ //$NON-NLS-2$
			fwDebugOptions.setVerbose(false);
			debugTrace.trace("/debug", "testing 3"); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceEntry("/debug"); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceEntry("/debug", "arg"); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceEntry("/debug", new String[] {"arg1", "arg2"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			debugTrace.traceExit("/debug"); //$NON-NLS-1$
			debugTrace.traceExit("/debug", "returnValue"); //$NON-NLS-1$ //$NON-NLS-2$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.trace(option, message)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		// make sure all 3 entries exist
		assertEquals("Wrong number of trace entries", 8, traceOutput.length); //$NON-NLS-1$
		// validate the trace("/debug", "testing 1", new Exception(exceptionMessage1)) call when verbose tracing is disabled
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertNull("A bundle was found when it should be null", traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertNull("A class name was found when it should be null", traceOutput[0].getClassName()); //$NON-NLS-1$
		assertNull("A method name was found when it should be null", traceOutput[0].getMethodName()); //$NON-NLS-1$
		assertTrue("A line number other than -1 was read in", traceOutput[0].getLineNumber() == -1); //$NON-NLS-1$
		assertEquals("trace message is incorrect", "testing 1", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		final StringBuilder expectedThrowableText1 = new StringBuilder("java.lang.Exception: "); //$NON-NLS-1$
		expectedThrowableText1.append(exceptionMessage1);
		expectedThrowableText1.append(DebugOptionsTestCase.LINE_SEPARATOR);
		expectedThrowableText1.append(DebugOptionsTestCase.TAB_CHARACTER);
		expectedThrowableText1.append("at org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase.testVerboseDebugging(DebugOptionsTestCase.java:"); //$NON-NLS-1$		
		if (!traceOutput[0].getThrowableText().startsWith(expectedThrowableText1.toString())) {
			final StringBuilder errorMessage = new StringBuilder("The expected throwable text does not start with the actual throwable text."); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Expected"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(expectedThrowableText1.toString());
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Actual"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(traceOutput[0].getThrowableText());
			fail(errorMessage.toString());
		}
		// validate the trace("/debug", "testing 2") call when verbose tracing is re-enabled
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testVerboseDebugging", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("trace message is incorrect", "testing 2", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("The throwable text was found when it should be null", traceOutput[1].getThrowableText());
		// validate the trace("/debug", "testing 3") call when verbose is disabled
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[2].getThreadName()); //$NON-NLS-1$
		assertNull("A bundle was found when it should be null", traceOutput[2].getBundleSymbolicName()); //$NON-NLS-1$
		assertNull("A class name was found when it should be null", traceOutput[2].getClassName()); //$NON-NLS-1$
		assertNull("A method name was found when it should be null", traceOutput[2].getMethodName()); //$NON-NLS-1$
		assertTrue("A line number other than -1 was read in", traceOutput[2].getLineNumber() == -1); //$NON-NLS-1$
		assertEquals("trace message is incorrect", "testing 3", traceOutput[2].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("The throwable text was found when it should be null", traceOutput[2].getThrowableText());
		// validate the traceEntry("/debug") call when verbose is disabled
		assertEquals("trace message is incorrect", "Entering method org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase#testVerboseDebugging with no parameters", traceOutput[3].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		// validate the traceEntry("/debug", "arg") call when verbose is disabled
		assertEquals("trace message is incorrect", "Entering method org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase#testVerboseDebugging with parameters: (arg)", traceOutput[4].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		// validate the traceEntry("/debug", new String[] {"arg1", "arg2"}) call when verbose is disabled
		assertEquals("trace message is incorrect", "Entering method org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase#testVerboseDebugging with parameters: (arg1 arg2)", traceOutput[5].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		// validate the traceExit("/debug") call when verbose is disabled
		assertEquals("trace message is incorrect", "Exiting method org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase#testVerboseDebugging with a void return", traceOutput[6].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		// validate the traceExit("/debug", "returnValue") call when verbose is disabled
		assertEquals("trace message is incorrect", "Exiting method org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase#testVerboseDebugging with result: returnValue", traceOutput[7].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		// make sure the file is deleted
		traceFile.delete();
		// reset verbose debugging to the default (true)
		fwDebugOptions.setVerbose(true);
	}

	/**
	 * test DebugTrace.trace(option, message);
	*/
	public void testTraceFile01() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.trace("/debug", "testing 1"); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.trace("/notset", "testing 2"); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.trace("/debug", "testing 3"); //$NON-NLS-1$ //$NON-NLS-2$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.trace(option, message)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile01", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("trace message is incorrect", "testing 1", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile01", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("trace message is incorrect", "testing 3", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.trace(option, message, Throwable)
	 */
	public void testTraceFile02() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		final String exceptionMessage1 = "An error 1"; //$NON-NLS-1$
		final String exceptionMessage2 = "An error 2"; //$NON-NLS-1$
		final String exceptionMessage3 = "An error 3"; //$NON-NLS-1$
		try {
			debugTrace.trace("/debug", "testing 1", new Exception(exceptionMessage1)); //$NON-NLS-1$ //$NON-NLS-2$ 
			debugTrace.trace("/notset", "testing 2", new Exception(exceptionMessage2)); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.trace("/debug", "testing 3", new Exception(exceptionMessage3)); //$NON-NLS-1$ //$NON-NLS-2$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.trace(option, message, Throwable)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}

		final StringBuilder expectedThrowableText1 = new StringBuilder("java.lang.Exception: "); //$NON-NLS-1$
		expectedThrowableText1.append(exceptionMessage1);
		expectedThrowableText1.append(DebugOptionsTestCase.LINE_SEPARATOR);
		expectedThrowableText1.append(DebugOptionsTestCase.TAB_CHARACTER);
		expectedThrowableText1.append("at org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase.testTraceFile02(DebugOptionsTestCase.java:"); //$NON-NLS-1$		

		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile02", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("trace message is incorrect", "testing 1", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull("throwable text should not be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		if (!traceOutput[0].getThrowableText().startsWith(expectedThrowableText1.toString())) {
			final StringBuilder errorMessage = new StringBuilder("The expected throwable text does not start with the actual throwable text."); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Expected"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(expectedThrowableText1.toString());
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Actual"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(traceOutput[0].getThrowableText());
			fail(errorMessage.toString());
		}
		assertNotNull("throwable should not be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$

		final StringBuilder expectedThrowableText2 = new StringBuilder("java.lang.Exception: "); //$NON-NLS-1$
		expectedThrowableText2.append(exceptionMessage3);
		expectedThrowableText2.append(DebugOptionsTestCase.LINE_SEPARATOR);
		expectedThrowableText2.append(DebugOptionsTestCase.TAB_CHARACTER);
		expectedThrowableText2.append("at org.eclipse.osgi.tests.debugoptions.DebugOptionsTestCase.testTraceFile02(DebugOptionsTestCase.java:"); //$NON-NLS-1$		

		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile02", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("trace message is incorrect", "testing 3", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull("throwable text should not be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		if (!traceOutput[1].getThrowableText().startsWith(expectedThrowableText2.toString())) {
			final StringBuilder errorMessage = new StringBuilder("The expected throwable text does not start with the actual throwable text."); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Expected"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(expectedThrowableText2.toString());
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("Actual"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append("--------"); //$NON-NLS-1$
			errorMessage.append(DebugOptionsTestCase.LINE_SEPARATOR);
			errorMessage.append(traceOutput[1].getThrowableText());
			fail(errorMessage.toString());
		}
		assertNotNull("throwable should not be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceDumpStack(option)
	*/
	public void testTraceFile03() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceDumpStack("/debug"); //$NON-NLS-1$
			debugTrace.traceDumpStack("/notset"); //$NON-NLS-1$
			debugTrace.traceDumpStack("/debug"); //$NON-NLS-1$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceDumpStack(option)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile03", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Trace message is not a stack dump", traceOutput[0].getMessage().startsWith("Thread Stack dump: ")); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile03", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Trace message is not a stack dump", traceOutput[1].getMessage().startsWith("Thread Stack dump: ")); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceEntry(option)
	*/
	public void testTraceFile04() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceEntry("/debug"); //$NON-NLS-1$
			debugTrace.traceEntry("/notset"); //$NON-NLS-1$
			debugTrace.traceEntry("/debug"); //$NON-NLS-1$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceEntry(option)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile04", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with no parameters", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile04", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with no parameters", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceEntry(option, methodArgument)
	 */
	public void testTraceFile05() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceEntry("/debug", new String("arg1")); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceEntry("/notset", new String("arg2")); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceEntry("/debug", new String("arg3")); //$NON-NLS-1$ //$NON-NLS-2$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceEntry(option, methodArgument)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile05", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with parameters: (arg1)", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile05", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with parameters: (arg3)", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceEntry(option, methodArgument[])
	 */
	public void testTraceFile06() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceEntry("/debug", new String[] {"arg1", "arg2"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			debugTrace.traceEntry("/notset", new String[] {"arg3", "arg4"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			debugTrace.traceEntry("/debug", new String[] {"arg5", "arg6"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceEntry(option, methodArgument[])' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile06", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with parameters: (arg1 arg2)", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile06", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Entering method with parameters: (arg5 arg6)", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceExit(option)
	*/
	public void testTraceFile07() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceExit("/debug"); //$NON-NLS-1$
			debugTrace.traceExit("/notset"); //$NON-NLS-1$
			debugTrace.traceExit("/debug"); //$NON-NLS-1$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceExit(option)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile07", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Exiting method with a void return", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile07", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Exiting method with a void return", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * test DebugTrace.traceExit(option, result)
	*/
	public void testTraceFile08() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.traceExit("/debug", new String("returnValue1")); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceExit("/notset", new String("returnValue2")); //$NON-NLS-1$ //$NON-NLS-2$
			debugTrace.traceExit("/debug", new String("returnValue3")); //$NON-NLS-1$ //$NON-NLS-2$
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.traceExit(option, result)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of trace entries", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[0].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[0].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[0].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[0].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile08", traceOutput[0].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Exiting method with result: returnValue1", traceOutput[0].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[0].getThrowableText()); //$NON-NLS-1$
		assertEquals("Wrong number of trace entries for trace without an exception", 2, traceOutput.length); //$NON-NLS-1$
		assertEquals("Thread name is incorrect", Thread.currentThread().getName(), traceOutput[1].getThreadName()); //$NON-NLS-1$
		assertEquals("Bundle name is incorrect", getName(), traceOutput[1].getBundleSymbolicName()); //$NON-NLS-1$
		assertEquals("option-path value is incorrect", "/debug", traceOutput[1].getOptionPath()); //$NON-NLS-1$//$NON-NLS-2$
		assertEquals("class name value is incorrect", DebugOptionsTestCase.class.getName(), traceOutput[1].getClassName()); //$NON-NLS-1$
		assertEquals("method name value is incorrect", "testTraceFile08", traceOutput[1].getMethodName()); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Exiting method with result: returnValue3", traceOutput[1].getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("throwable should be null", traceOutput[1].getThrowableText()); //$NON-NLS-1$
		// delete the trace file
		traceFile.delete();
	}

	/**
	 * tests DebugTrace.trace(option, message) where the 'option' and 'message contain a '|' character (the delimiter).
	*/
	public void testTraceFile09() {

		final File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		TestDebugTrace debugTrace = this.createDebugTrace(traceFile);
		debugOptions.setOption(getName() + "/debug|path", "true");
		TraceEntry[] traceOutput = null;
		try {
			debugTrace.trace("/debug|path", "A message with a | character.");
			debugTrace.trace("/debug|path", "|A message with | multiple || characters.|");
			traceOutput = readTraceFile(traceFile); // Note: this call will also delete the trace file
		} catch (InvalidTraceEntry invalidEx) {
			fail("Failed 'DebugTrace.trace(option, message)' test as an invalid trace entry was found.  Actual Value: '" + invalidEx.getActualValue() + "'.", invalidEx); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of entries", 2, traceOutput.length);
		String optionPath = decodeString(traceOutput[0].getOptionPath());
		String message = decodeString(traceOutput[0].getMessage());
		assertEquals("option-path value is incorrect", "/debug|path", optionPath); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "A message with a | character.", message); //$NON-NLS-1$ //$NON-NLS-2$
		optionPath = decodeString(traceOutput[1].getOptionPath());
		message = decodeString(traceOutput[1].getMessage());
		assertEquals("option-path value is incorrect", "/debug|path", optionPath); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "|A message with | multiple || characters.|", message); //$NON-NLS-1$ //$NON-NLS-2$
		// delete the trace file
		traceFile.delete();
	}

	public void testTraceSystemOut() throws IOException {
		PrintStream old = System.out;
		File traceFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".trace"); //$NON-NLS-1$
		OutputStream out = new FileOutputStream(traceFile);
		final AtomicReference<Boolean> closed = new AtomicReference<Boolean>(Boolean.FALSE);
		out = new FilterOutputStream(out) {

			@Override
			public void close() throws IOException {
				super.close();
				closed.set(Boolean.TRUE);
			}

		};
		System.setOut(new PrintStream(out));
		try {
			TestDebugTrace debugTrace = this.createDebugTrace(new File("/does/not/exist/trace.out"));
			debugOptions.setOption(getName() + "/debug", "true");
			debugTrace.trace("/debug", "A message to System.out.");
			debugTrace.trace("/debug", "Another message.");
			assertFalse("Closed System.out.", closed.get().booleanValue());
		} finally {
			System.setOut(old);
			out.close();
		}
		TraceEntry[] traceOutput = null;
		try {
			traceOutput = readTraceFile(traceFile);
		} catch (InvalidTraceEntry e) {
			fail("Failed 'DebugTrace.trace(option, message)' test as an invalid trace entry was found.  Actual Value: '" + e.getActualValue() + "'.", e); //$NON-NLS-1$ //$NON-NLS-2$
		}
		assertEquals("Wrong number of entries", 2, traceOutput.length);
		String optionPath = decodeString(traceOutput[0].getOptionPath());
		String message = decodeString(traceOutput[0].getMessage());
		assertEquals("option-path value is incorrect", "/debug", optionPath); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "A message to System.out.", message); //$NON-NLS-1$ //$NON-NLS-2$
		optionPath = decodeString(traceOutput[1].getOptionPath());
		message = decodeString(traceOutput[1].getMessage());
		assertEquals("option-path value is incorrect", "/debug", optionPath); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Trace message is not correct", "Another message.", message); //$NON-NLS-1$ //$NON-NLS-2$
		// delete the trace file
		traceFile.delete();
	}

	private static String decodeString(final String inputString) {
		if (inputString == null || inputString.indexOf(TRACE_ELEMENT_DELIMITER_ENCODED) < 0)
			return inputString;
		final StringBuilder tempBuffer = new StringBuilder(inputString);
		int currentIndex = tempBuffer.indexOf(TRACE_ELEMENT_DELIMITER_ENCODED);
		while (currentIndex >= 0) {
			tempBuffer.replace(currentIndex, currentIndex + TRACE_ELEMENT_DELIMITER_ENCODED.length(), TRACE_ELEMENT_DELIMITER);
			currentIndex = tempBuffer.indexOf(TRACE_ELEMENT_DELIMITER_ENCODED);
		}
		return tempBuffer.toString();
	}

	private TraceEntry[] readTraceFile(File traceFile) throws InvalidTraceEntry {

		BufferedReader traceReader = null;
		List traceEntries = new ArrayList();
		this.verboseDebug = true; // default is true
		try {
			traceReader = new BufferedReader(new InputStreamReader(new FileInputStream(traceFile), StandardCharsets.UTF_8));
			TraceEntry entry = null;
			while ((entry = this.readMessage(traceReader)) != null) {
				traceEntries.add(entry);
			}
		} catch (IOException ex) {
			fail("Failed to read trace file", ex); //$NON-NLS-1$
		} finally {
			if (traceReader != null) {
				try {
					traceReader.close();
				} catch (Exception ex) {
					// do nothing
				}
			}
		}
		return (TraceEntry[]) traceEntries.toArray(new TraceEntry[traceEntries.size()]);
	}

	private TraceEntry readMessage(final BufferedReader traceReader) throws IOException, InvalidTraceEntry {

		TraceEntry result = null;
		int input = traceReader.read();
		while (input != -1) {
			char inputChar = (char) input;
			if (inputChar == '#') {
				String comment = traceReader.readLine();
				if (comment != null) {
					comment = comment.trim();
				}
				if (comment.startsWith("verbose")) {
					int splitIndex = comment.indexOf(':');
					String verboseValue = comment.substring(splitIndex + 1, comment.length()).trim();
					this.verboseDebug = Boolean.valueOf(verboseValue).booleanValue();
				}
			}
			if (inputChar == DebugOptionsTestCase.TRACE_ELEMENT_DELIMITER.charAt(0)) {
				// first entry - thread name (valid if verbose debugging is off)
				final String threadName = this.readEntry(traceReader);
				if ((threadName == null) || (threadName.length() == 0)) {
					throw new InvalidTraceEntry("The thread name in a trace entry is null or empty", threadName); //$NON-NLS-1$
				}
				// second entry - timestamp (valid if verbose debugging is off)
				final String date = this.readEntry(traceReader);
				if ((date == null) || (date.length() == 0)) {
					throw new InvalidTraceEntry("The timestamp in a trace entry is null or empty", date); //$NON-NLS-1$
				}
				long timestamp = 0;
				try {
					timestamp = DebugOptionsTestCase.TRACE_FILE_DATE_FORMATTER.parse(date).getTime();
				} catch (ParseException parseEx) {
					throw new InvalidTraceEntry("The date in a trace entry '" + date + "' could not be parsed.", date); //$NON-NLS-1$ //$NON-NLS-2$
				}
				String symbolicName = null;
				String optionPath = null;
				String className = null;
				String methodName = null;
				int lineNumber = -1;
				if (this.verboseDebug) {
					// third entry - bundle symbolic name
					symbolicName = this.readEntry(traceReader);
					if ((symbolicName == null) || (symbolicName.length() == 0)) {
						throw new InvalidTraceEntry("The bundle symbolic name in a trace entry is null or empty", symbolicName); //$NON-NLS-1$
					}
					// fourth entry - option path
					optionPath = this.readEntry(traceReader);
					if ((optionPath == null) || (optionPath.length() == 0)) {
						throw new InvalidTraceEntry("The option-path in a trace entry is null or empty", optionPath); //$NON-NLS-1$
					}
					// fifth entry - class name
					className = this.readEntry(traceReader);
					if ((className == null) || (className.length() == 0)) {
						throw new InvalidTraceEntry("The class name in a trace entry is null or empty", className); //$NON-NLS-1$
					}
					// sixth entry - method name
					methodName = this.readEntry(traceReader);
					if ((methodName == null) || (methodName.length() == 0)) {
						throw new InvalidTraceEntry("The method name in a trace entry is null or empty", methodName); //$NON-NLS-1$
					}
					// seventh entry - line number
					final String lineNumberString = this.readEntry(traceReader);
					if ((lineNumberString == null) || (lineNumberString.length() == 0)) {
						throw new InvalidTraceEntry("The line number in a trace entry is null or empty", lineNumberString); //$NON-NLS-1$
					}
					lineNumber = Integer.valueOf(lineNumberString).intValue();
				}
				// eighth entry - message  (valid if verbose debugging is off)
				final String message = this.readEntry(traceReader);
				// read in the next character. if it is \r or \n then the throwable was not supplied  (valid if verbose debugging is off)
				traceReader.mark(1);
				inputChar = (char) traceReader.read();
				String throwable = null;
				if (inputChar != '\n' && inputChar != '\r') {
					traceReader.reset();
					// ninth entry (optional) - throwable
					throwable = this.readEntry(traceReader);
					if ((throwable == null) || (throwable.length() == 0)) {
						throw new InvalidTraceEntry("The throwable in a trace entry is null or empty", throwable); //$NON-NLS-1$
					}
				}
				// create the entry
				result = new TraceEntry(threadName, timestamp, symbolicName, optionPath, className, methodName, lineNumber, message, throwable);
				break; // no point in reading any more information since the TraceEntry is created
			}
			// read the next character
			input = traceReader.read();
		}
		return result;
	}

	private String readEntry(final Reader traceReader) throws IOException {

		char inputChar = (char) traceReader.read();
		StringBuilder buffer = new StringBuilder();
		while (inputChar != DebugOptionsTestCase.TRACE_ELEMENT_DELIMITER.charAt(0)) {
			inputChar = (char) traceReader.read();
			if (inputChar != DebugOptionsTestCase.TRACE_ELEMENT_DELIMITER.charAt(0)) {
				buffer.append(inputChar);
			}
		}
		return buffer.toString().trim();
	}

	static public class TraceEntry {
		/** If a bundles symbolic name is not specified then the default value of /debug can be used */
		public final static String DEFAULT_OPTION_PATH = "/debug"; //$NON-NLS-1$

		/**
		 * The name of the thread executing the code
		 */
		private final String threadName;

		/**
		 * The date and time when the trace occurred.
		 * 
		 */
		private final long timestamp;

		/**
		 * The trace option-path
		 */
		private final String optionPath;

		/**
		 * The symbolic name of the bundle being traced
		 */
		private final String bundleSymbolicName;

		/**
		 * The class being traced
		 */
		private final String className;

		/**
		 * The method being traced
		 */
		private String methodName = null;

		/**
		 * The line number
		 */
		private final int lineNumber;

		/**
		 * The trace message
		 */
		private final String message;

		/**
		 * The trace exception
		 */
		private final String throwableText;

		public TraceEntry(final String traceThreadName, final long traceTimestamp, final String traceBundleName, final String traceOptionPath, final String traceClassName, final String traceMethodName, final int traceLineNumber, final String traceMessage) {

			this.threadName = traceThreadName;
			this.bundleSymbolicName = traceBundleName;
			this.optionPath = traceOptionPath;
			this.className = traceClassName;
			this.methodName = traceMethodName;
			this.lineNumber = traceLineNumber;
			this.message = traceMessage;
			this.timestamp = traceTimestamp;
			this.throwableText = null;
		}

		public TraceEntry(final String traceThreadName, final long traceTimestamp, final String traceBundleName, final String traceOptionPath, final String traceClassName, final String traceMethodName, final int traceLineNumber, final String traceMessage, final String traceThrowable) {

			this.threadName = traceThreadName;
			this.bundleSymbolicName = traceBundleName;
			this.optionPath = traceOptionPath;
			this.className = traceClassName;
			this.methodName = traceMethodName;
			this.lineNumber = traceLineNumber;
			this.message = traceMessage;
			this.timestamp = traceTimestamp;
			this.throwableText = traceThrowable;
		}

		public final String getThreadName() {

			return threadName;
		}

		public final long getTimestamp() {

			return timestamp;
		}

		public final String getBundleSymbolicName() {

			return bundleSymbolicName;
		}

		public final String getMessage() {

			return message;
		}

		public final String getThrowableText() {

			return throwableText;
		}

		public final String getClassName() {

			return className;
		}

		public final String getMethodName() {

			return methodName;
		}

		public final String getOptionPath() {

			return optionPath;
		}

		public final int getLineNumber() {

			return lineNumber;
		}
	}

	static class InvalidTraceEntry extends Exception {

		private static final long serialVersionUID = -63837787081750344L;

		public InvalidTraceEntry(String message, String actual) {
			super(message);
			this.actualValue = actual;
		}

		public final String getActualValue() {
			return this.actualValue;
		}

		String actualValue;
		String expectedValue;
	}

	static class TestDebugTrace implements DebugTrace {
		private final DebugTrace wrapped;

		public TestDebugTrace(DebugTrace wrapped) {
			this.wrapped = wrapped;
		}

		public void trace(String option, String message) {
			wrapped.trace(option, message);
		}

		public void trace(String option, String message, Throwable error) {
			wrapped.trace(option, message, error);
		}

		public void traceDumpStack(String option) {
			wrapped.traceDumpStack(option);
		}

		public void traceEntry(String option) {
			wrapped.traceEntry(option);
		}

		public void traceEntry(String option, Object methodArgument) {
			wrapped.traceEntry(option, methodArgument);
		}

		public void traceEntry(String option, Object[] methodArguments) {
			wrapped.traceEntry(option, methodArguments);
		}

		public void traceExit(String option) {
			wrapped.traceExit(option);
		}

		public void traceExit(String option, Object result) {
			wrapped.traceExit(option, result);
		}
	}

	class TestDebugOptionsListener implements DebugOptionsListener {
		boolean called = false;
		String incorrectValue;
		Map checkValues;

		public void optionsChanged(DebugOptions options) {
			called = true;
			if (checkValues == null)
				return;
			for (Iterator entries = checkValues.entrySet().iterator(); entries.hasNext();) {
				Map.Entry entry = (Entry) entries.next();
				String debugValue = options.getOption((String) entry.getKey());
				String error = "Value is incorrect for key: " + entry.getKey() + " " + debugValue; //$NON-NLS-1$//$NON-NLS-2$
				if (debugValue == null) {
					if (entry.getValue() != null) {
						incorrectValue = error;
						return;
					}
					continue;
				}
				if (!debugValue.equals(entry.getValue())) {
					incorrectValue = error;
					return;
				}
			}
		}

		public boolean gotCalled() {
			return called;
		}

		public void clear() {
			called = false;
			checkValues = null;
			incorrectValue = null;
		}

		public void setCheckValues(Map checkValues) {
			this.checkValues = checkValues;
		}

		public String getIncorrectValue() {
			return incorrectValue;
		}
	}
}