diff --git a/bundles/org.eclipse.test/META-INF/MANIFEST.MF b/bundles/org.eclipse.test/META-INF/MANIFEST.MF
index 5b9f607..d9d11e9 100644
--- a/bundles/org.eclipse.test/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.test/META-INF/MANIFEST.MF
@@ -7,16 +7,11 @@
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.apache.ant,
+ org.junit;bundle-version="4.12.0",
  org.eclipse.ui,
  org.eclipse.core.runtime,
  org.eclipse.ui.ide.application,
- org.eclipse.equinox.app,
- org.junit.jupiter.api,
- org.junit.jupiter.engine,
- org.junit.platform.commons,
- org.junit.platform.engine,
- org.junit.platform.launcher,
- org.junit.vintage.engine
+ org.eclipse.equinox.app
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.eclipse.test
diff --git a/bundles/org.eclipse.test/src/org/eclipse/test/AbstractJUnitResultFormatter.java b/bundles/org.eclipse.test/src/org/eclipse/test/AbstractJUnitResultFormatter.java
deleted file mode 100644
index 5d681aa..0000000
--- a/bundles/org.eclipse.test/src/org/eclipse/test/AbstractJUnitResultFormatter.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Red Hat Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Lucas Bullen (Red Hat Inc.) - initial API and implementation
- *******************************************************************************/
-package org.eclipse.test;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.Closeable;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.optional.junitlauncher.TestExecutionContext;
-import org.apache.tools.ant.taskdefs.optional.junitlauncher.TestResultFormatter;
-import org.apache.tools.ant.util.FileUtils;
-import org.junit.platform.engine.TestSource;
-import org.junit.platform.engine.support.descriptor.ClassSource;
-import org.junit.platform.launcher.TestIdentifier;
-import org.junit.platform.launcher.TestPlan;
-
-/**
- * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s
- */
-abstract class AbstractJUnitResultFormatter implements TestResultFormatter {
-
-
-	protected static String NEW_LINE = System.getProperty("line.separator");
-	protected TestExecutionContext context;
-
-	private SysOutErrContentStore sysOutStore;
-	private SysOutErrContentStore sysErrStore;
-
-	@Override
-	public void sysOutAvailable(final byte[] data) {
-		if (this.sysOutStore == null) {
-			this.sysOutStore = new SysOutErrContentStore(true);
-		}
-		try {
-			this.sysOutStore.store(data);
-		} catch (IOException e) {
-			handleException(e);
-			return;
-		}
-	}
-
-	@Override
-	public void sysErrAvailable(final byte[] data) {
-		if (this.sysErrStore == null) {
-			this.sysErrStore = new SysOutErrContentStore(false);
-		}
-		try {
-			this.sysErrStore.store(data);
-		} catch (IOException e) {
-			handleException(e);
-			return;
-		}
-	}
-
-	@Override
-	public void setContext(final TestExecutionContext context) {
-		this.context = context;
-	}
-
-	/**
-	 * @return Returns true if there's any stdout data, that was generated during the
-	 * tests, is available for use. Else returns false.
-	 */
-	boolean hasSysOut() {
-		return this.sysOutStore != null && this.sysOutStore.hasData();
-	}
-
-	/**
-	 * @return Returns true if there's any stderr data, that was generated during the
-	 * tests, is available for use. Else returns false.
-	 */
-	boolean hasSysErr() {
-		return this.sysErrStore != null && this.sysErrStore.hasData();
-	}
-
-	/**
-	 * @return Returns a {@link Reader} for reading any stdout data that was generated
-	 * during the test execution. It is expected that the {@link #hasSysOut()} be first
-	 * called to see if any such data is available and only if there is, then this method
-	 * be called
-	 * @throws IOException If there's any I/O problem while creating the {@link Reader}
-	 */
-	Reader getSysOutReader() throws IOException {
-		return this.sysOutStore.getReader();
-	}
-
-	/**
-	 * @return Returns a {@link Reader} for reading any stderr data that was generated
-	 * during the test execution. It is expected that the {@link #hasSysErr()} be first
-	 * called to see if any such data is available and only if there is, then this method
-	 * be called
-	 * @throws IOException If there's any I/O problem while creating the {@link Reader}
-	 */
-	Reader getSysErrReader() throws IOException {
-		return this.sysErrStore.getReader();
-	}
-
-	/**
-	 * Writes out any stdout data that was generated during the
-	 * test execution. If there was no such data then this method just returns.
-	 *
-	 * @param writer The {@link Writer} to use. Cannot be null.
-	 * @throws IOException If any I/O problem occurs during writing the data
-	 */
-	void writeSysOut(final Writer writer) throws IOException {
-		Objects.requireNonNull(writer, "Writer cannot be null");
-		this.writeFrom(this.sysOutStore, writer);
-	}
-
-	/**
-	 * Writes out any stderr data that was generated during the
-	 * test execution. If there was no such data then this method just returns.
-	 *
-	 * @param writer The {@link Writer} to use. Cannot be null.
-	 * @throws IOException If any I/O problem occurs during writing the data
-	 */
-	void writeSysErr(final Writer writer) throws IOException {
-		Objects.requireNonNull(writer, "Writer cannot be null");
-		this.writeFrom(this.sysErrStore, writer);
-	}
-
-	static Optional<TestIdentifier> traverseAndFindTestClass(final TestPlan testPlan, final TestIdentifier testIdentifier) {
-		if (isTestClass(testIdentifier).isPresent()) {
-			return Optional.of(testIdentifier);
-		}
-		final Optional<TestIdentifier> parent = testPlan.getParent(testIdentifier);
-		return parent.isPresent() ? traverseAndFindTestClass(testPlan, parent.get()) : Optional.empty();
-	}
-
-	static Optional<ClassSource> isTestClass(final TestIdentifier testIdentifier) {
-		if (testIdentifier == null) {
-			return Optional.empty();
-		}
-		final Optional<TestSource> source = testIdentifier.getSource();
-		if (!source.isPresent()) {
-			return Optional.empty();
-		}
-		final TestSource testSource = source.get();
-		if (testSource instanceof ClassSource) {
-			return Optional.of((ClassSource) testSource);
-		}
-		return Optional.empty();
-	}
-
-	private void writeFrom(final SysOutErrContentStore store, final Writer writer) throws IOException {
-		final char[] chars = new char[1024];
-		int numRead = -1;
-		try (final Reader reader = store.getReader()) {
-			while ((numRead = reader.read(chars)) != -1) {
-				writer.write(chars, 0, numRead);
-			}
-		}
-	}
-
-	@Override
-	public void close() throws IOException {
-		FileUtils.close(this.sysOutStore);
-		FileUtils.close(this.sysErrStore);
-	}
-
-	protected void handleException(final Throwable t) {
-		// we currently just log it and move on.
-		this.context.getProject().ifPresent((p) -> p.log("Exception in listener "
-				+ AbstractJUnitResultFormatter.this.getClass().getName(), t, Project.MSG_DEBUG));
-	}
-
-
-	/*
-    A "store" for sysout/syserr content that gets sent to the AbstractJUnitResultFormatter.
-    This store first uses a relatively decent sized in-memory buffer for storing the sysout/syserr
-    content. This in-memory buffer will be used as long as it can fit in the new content that
-    keeps coming in. When the size limit is reached, this store switches to a file based store
-    by creating a temporarily file and writing out the already in-memory held buffer content
-    and any new content that keeps arriving to this store. Once the file has been created,
-    the in-memory buffer will never be used any more and in fact is destroyed as soon as the
-    file is created.
-    Instances of this class are not thread-safe and users of this class are expected to use necessary thread
-    safety guarantees, if they want to use an instance of this class by multiple threads.
-	 */
-	private static final class SysOutErrContentStore implements Closeable {
-		private static final int DEFAULT_CAPACITY_IN_BYTES = 50 * 1024; // 50 KB
-		private static final Reader EMPTY_READER = new Reader() {
-			@Override
-			public int read(final char[] cbuf, final int off, final int len) throws IOException {
-				return -1;
-			}
-
-			@Override
-			public void close() throws IOException {
-			}
-		};
-
-		private final String tmpFileSuffix;
-		private ByteBuffer inMemoryStore = ByteBuffer.allocate(DEFAULT_CAPACITY_IN_BYTES);
-		private boolean usingFileStore = false;
-		private Path filePath;
-		private FileOutputStream fileOutputStream;
-
-		SysOutErrContentStore(final boolean isSysOut) {
-			this.tmpFileSuffix = isSysOut ? ".sysout" : ".syserr";
-		}
-
-		void store(final byte[] data) throws IOException {
-			if (this.usingFileStore) {
-				this.storeToFile(data, 0, data.length);
-				return;
-			}
-			// we haven't yet created a file store and the data can fit in memory,
-			// so we write it in our buffer
-			try {
-				this.inMemoryStore.put(data);
-				return;
-			} catch (BufferOverflowException boe) {
-				// the buffer capacity can't hold this incoming data, so this
-				// incoming data hasn't been transferred to the buffer. let's
-				// now fall back to a file store
-				this.usingFileStore = true;
-			}
-			// since the content couldn't be transferred into in-memory buffer,
-			// we now create a file and transfer already (previously) stored in-memory
-			// content into that file, before finally transferring this new content
-			// into the file too. We then finally discard this in-memory buffer and
-			// just keep using the file store instead
-			this.fileOutputStream = createFileStore();
-			// first the existing in-memory content
-			storeToFile(this.inMemoryStore.array(), 0, this.inMemoryStore.position());
-			storeToFile(data, 0, data.length);
-			// discard the in-memory store
-			this.inMemoryStore = null;
-		}
-
-		private void storeToFile(final byte[] data, final int offset, final int length) throws IOException {
-			if (this.fileOutputStream == null) {
-				// no backing file was created so we can't do anything
-				return;
-			}
-			this.fileOutputStream.write(data, offset, length);
-		}
-
-		private FileOutputStream createFileStore() throws IOException {
-			this.filePath = Files.createTempFile(null, this.tmpFileSuffix);
-			this.filePath.toFile().deleteOnExit();
-			return new FileOutputStream(this.filePath.toFile());
-		}
-
-		/*
-		 * Returns a Reader for reading the sysout/syserr content. If there's no data
-		 * available in this store, then this returns a Reader which when used for read operations,
-		 * will immediately indicate an EOF.
-		 */
-		Reader getReader() throws IOException {
-			if (this.usingFileStore && this.filePath != null) {
-				// we use a FileReader here so that we can use the system default character
-				// encoding for reading the contents on sysout/syserr stream, since that's the
-				// encoding that System.out/System.err uses to write out the messages
-				return new BufferedReader(new FileReader(this.filePath.toFile()));
-			}
-			if (this.inMemoryStore != null) {
-				return new InputStreamReader(new ByteArrayInputStream(this.inMemoryStore.array(), 0, this.inMemoryStore.position()));
-			}
-			// no data to read, so we return an "empty" reader
-			return EMPTY_READER;
-		}
-
-		/*
-		 *  Returns true if this store has any data (either in-memory or in a file). Else
-		 *  returns false.
-		 */
-		boolean hasData() {
-			if (this.inMemoryStore != null && this.inMemoryStore.position() > 0) {
-				return true;
-			}
-			if (this.usingFileStore && this.filePath != null) {
-				return true;
-			}
-			return false;
-		}
-
-		@Override
-		public void close() throws IOException {
-			this.inMemoryStore = null;
-			FileUtils.close(this.fileOutputStream);
-			FileUtils.delete(this.filePath.toFile());
-		}
-	}
-}
diff --git a/bundles/org.eclipse.test/src/org/eclipse/test/ClassLoaderTools.java b/bundles/org.eclipse.test/src/org/eclipse/test/ClassLoaderTools.java
deleted file mode 100644
index 28fe538..0000000
--- a/bundles/org.eclipse.test/src/org/eclipse/test/ClassLoaderTools.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Red Hat Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Lucas Bullen (Red Hat Inc.) - initial API and implementation
- *******************************************************************************/
-package org.eclipse.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.osgi.internal.framework.EquinoxBundle;
-import org.osgi.framework.Bundle;
-
-@SuppressWarnings("restriction")
-class ClassLoaderTools {
-	public static ClassLoader getPluginClassLoader(String getfTestPluginName, ClassLoader currentTCCL) {
-		Bundle bundle = Platform.getBundle(getfTestPluginName);
-		if (bundle == null) {
-			throw new IllegalArgumentException("Bundle \"" + getfTestPluginName + "\" not found. Possible causes include missing dependencies, too restrictive version ranges, or a non-matching required execution environment."); //$NON-NLS-1$ //$NON-NLS-2$
-		}
-		return new TestBundleClassLoader(bundle, currentTCCL);
-	}
-
-	public static String getClassPlugin(String className) {
-		int index = className.lastIndexOf('.');
-		String plugin = null;
-		while (index != -1) {
-			plugin = className.substring(0, index);
-			if(Platform.getBundle(plugin) != null) {
-				break;
-			}
-			index = className.lastIndexOf('.', index-1);
-		}
-		return plugin;
-	}
-
-	public static ClassLoader getJUnit5Classloader(List<String> platformEngine) {
-		List<Bundle> platformEngineBundles = new ArrayList<>();
-		for (Iterator<String> iterator = platformEngine.iterator(); iterator.hasNext();) {
-			String string = iterator.next();
-			Bundle bundle = Platform.getBundle(string);
-			platformEngineBundles.add(bundle);
-		}
-		return new MultiBundleClassLoader(platformEngineBundles);
-	}
-
-	static class TestBundleClassLoader extends ClassLoader {
-		protected Bundle bundle;
-		protected ClassLoader currentTCCL;
-
-		public TestBundleClassLoader(Bundle target, ClassLoader currentTCCL) {
-			this.bundle = target;
-			this.currentTCCL = currentTCCL;
-		}
-
-		@Override
-		protected Class<?> findClass(String name) throws ClassNotFoundException {
-			try {
-				return bundle.loadClass(name);
-			} catch (ClassNotFoundException e) {
-				return currentTCCL.loadClass(name);
-			}
-		}
-
-		@Override
-		protected URL findResource(String name) {
-			URL url = bundle.getResource(name);
-			if(url == null) {
-				url = currentTCCL.getResource(name);
-			}
-			return url;
-		}
-
-		@SuppressWarnings({"rawtypes", "unchecked"})
-		@Override
-		protected Enumeration findResources(String name) throws IOException {
-			Enumeration enumeration = bundle.getResources(name);
-			if(enumeration == null) {
-				enumeration = currentTCCL.getResources(name);
-			}
-			return enumeration;
-		}
-
-		@Override
-		public Enumeration<URL> getResources(String res) throws IOException {
-			Enumeration<URL> urls = currentTCCL.getResources(res);
-			if(urls.hasMoreElements())
-				return urls;
-
-			List<URL> resources = new ArrayList<>(6);
-			String location = null;
-			URL url = null;
-			if (bundle instanceof EquinoxBundle) {
-				location = ((EquinoxBundle) bundle).getLocation();
-			}
-			if (location != null && location.startsWith("reference:")) { //$NON-NLS-1$
-				location = location.substring(10, location.length());
-				URI uri = URI.create(location);
-				String newPath =( uri.getPath() == null ? "" : uri.getPath()) + "bin" + '/' + res; //$NON-NLS-1$
-				URI newUri = uri.resolve(newPath).normalize();
-				if(newUri.isAbsolute())
-					url = newUri.toURL();
-			}
-			if (url != null) {
-				File f = new File(url.getFile());
-				if (f.exists())
-					resources.add(url);
-			}
-			else
-				return Collections.emptyEnumeration();
-
-			return Collections.enumeration(resources);
-		}
-	}
-
-	static class MultiBundleClassLoader extends ClassLoader {
-		private List<Bundle> bundleList;
-
-		public MultiBundleClassLoader(List<Bundle> platformEngineBundles) {
-			this.bundleList = platformEngineBundles;
-
-		}
-		public Class<?> findClasss(String name) throws ClassNotFoundException {
-			return findClass(name);
-		}
-		@Override
-		protected Class<?> findClass(String name) throws ClassNotFoundException {
-			Class<?> c = null;
-			for (Bundle temp : bundleList) {
-				try {
-					c = temp.loadClass(name);
-					if (c != null)
-						return c;
-				} catch (ClassNotFoundException e) {
-				}
-			}
-			return c;
-		}
-
-		@Override
-		protected URL findResource(String name) {
-			URL url = null;
-			for (Bundle temp : bundleList) {
-				url = temp.getResource(name);
-				if (url != null)
-					return url;
-			}
-			return url;
-		}
-
-		@SuppressWarnings({"rawtypes", "unchecked"})
-		@Override
-		protected Enumeration findResources(String name) throws IOException {
-			Enumeration enumFinal = null;
-			for (int i = 0; i < bundleList.size(); i++) {
-				if (i == 0) {
-					enumFinal = bundleList.get(i).getResources(name);
-					continue;
-				}
-				Enumeration e2 = bundleList.get(i).getResources(name);
-				Vector temp = new Vector();
-				while (enumFinal != null && enumFinal.hasMoreElements()) {
-					temp.add(enumFinal.nextElement());
-				}
-				while (e2 != null && e2.hasMoreElements()) {
-					temp.add(e2.nextElement());
-				}
-				enumFinal = temp.elements();
-			}
-			return enumFinal;
-		}
-	}
-}
diff --git a/bundles/org.eclipse.test/src/org/eclipse/test/EclipseTestRunner.java b/bundles/org.eclipse.test/src/org/eclipse/test/EclipseTestRunner.java
index a653ebe..1a6b77d 100644
--- a/bundles/org.eclipse.test/src/org/eclipse/test/EclipseTestRunner.java
+++ b/bundles/org.eclipse.test/src/org/eclipse/test/EclipseTestRunner.java
@@ -8,12 +8,9 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Anthony Dahanne  <anthony.dahanne@compuware.com> - enhance ETF to be able to launch several tests in several bundles - https://bugs.eclipse.org/330613
- *     Lucas Bullen (Red Hat Inc.) - JUnit 5 support
  *******************************************************************************/
 package org.eclipse.test;
 
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
-
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -24,31 +21,33 @@
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Date;
+import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Optional;
 import java.util.Properties;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.Vector;
 
+import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.optional.junitlauncher.TestExecutionContext;
+import org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter;
+import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.ManifestElement;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
 import org.eclipse.swt.graphics.GC;
@@ -58,16 +57,14 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
-import org.junit.platform.engine.TestExecutionResult;
-import org.junit.platform.launcher.Launcher;
-import org.junit.platform.launcher.LauncherDiscoveryRequest;
-import org.junit.platform.launcher.TestExecutionListener;
-import org.junit.platform.launcher.TestIdentifier;
-import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
-import org.junit.platform.launcher.core.LauncherFactory;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
 
 /**
  * A TestRunner for JUnit that supports Ant JUnitResultFormatters and running
@@ -76,7 +73,20 @@
  * formatter=org.apache.tools.ant.taskdefs.optional.junit
  * .XMLJUnitResultFormatter
  */
-public class EclipseTestRunner {
+public class EclipseTestRunner implements TestListener {
+	class TestFailedException extends Exception {
+
+		private static final long serialVersionUID = 6009335074727417445L;
+
+		TestFailedException(String message) {
+			super(message);
+		}
+
+		TestFailedException(Throwable e) {
+			super(e);
+		}
+	}
+
 	static class ThreadDump extends Exception {
 
 		private static final long serialVersionUID = 1L;
@@ -122,6 +132,7 @@
 	 */
 	public static final int ERRORS = 2;
 
+	private static final String SUITE_METHODNAME = "suite";
 	/**
 	 * SECONDS_BEFORE_TIMEOUT_BUFFER is the time we allow ourselves to take stack
 	 * traces, get a screen shot, delay "SECONDS_BETWEEN_DUMPS", then do it again.
@@ -139,20 +150,68 @@
 	private static final int SECONDS_BETWEEN_DUMPS = 5;
 
 	/**
+	 * The current test result
+	 */
+	private TestResult fTestResult;
+	/**
+	 * The name of the plugin containing the test
+	 */
+	private String fTestPluginName;
+	/**
+	 * The corresponding testsuite.
+	 */
+	private Test fSuite;
+	/**
+	 * Formatters from the command line.
+	 */
+	private static Vector<JUnitResultFormatter> fgFromCmdLine = new Vector<>();
+	/**
+	 * Holds the registered formatters.
+	 */
+	private Vector<JUnitResultFormatter> formatters = new Vector<>();
+	/**
+	 * Do we stop on errors.
+	 */
+	private boolean fHaltOnError = false;
+	/**
+	 * Do we stop on test failures.
+	 */
+	private boolean fHaltOnFailure = false;
+	/**
+	 * The TestSuite we are currently running.
+	 */
+	private JUnitTest fJunitTest;
+	/**
+	 * output written during the test
+	 */
+	private PrintStream fSystemError;
+	/**
+	 * Error output during the test
+	 */
+	private PrintStream fSystemOut;
+	/**
+	 * Exception caught in constructor.
+	 */
+	private Exception fException;
+	/**
+	 * Returncode
+	 */
+	private int fRetCode = SUCCESS;
+
+	/**
 	 * The main entry point (the parameters are not yet consistent with the Ant
 	 * JUnitTestRunner, but eventually they should be). Parameters
 	 *
 	 * <pre>
-	 * -className=&lt;testSuiteName&gt;
-	 * -testPluginName&lt;containingpluginName&gt;
-	 * -formatter=&lt;classname&gt;(,&lt;path&gt;)
+	 * -className: the name of the testSuite
+	 * -testPluginName: the name of the containing plugin
+	 * haltOnError: halt test on errors?
+	 * haltOnFailure: halt test on failures?
+	 * -testlistener listenerClass: deprecated
+	 * 		print a warning that this option is deprecated
+	 * formatter: a JUnitResultFormatter given as classname,filename.
+	 *  	If filename is ommitted, System.out is assumed.
 	 * </pre>
-	 * Where &lt;classname&gt; is the formatter classname, currently ignored as only
-	 * LegacyXmlResultFormatter is used. The path is either the path to the
-	 * result file and should include the file extension (xml) if a single test
-	 * is being run or should be the path to the result directory where result
-	 * files should be created if multiple tests are being run. If no path is
-	 * given, the standard output is used.
 	 */
 	public static void main(String[] args) throws IOException {
 		System.exit(run(args));
@@ -163,10 +222,13 @@
 		String classesNames = null;
 		String testPluginName = null;
 		String testPluginsNames = null;
-		String resultPathString = null;
+		String formatterString = null;
 		String timeoutString = null;
 		String junitReportOutput = null;
 
+		boolean haltError = false;
+		boolean haltFail = false;
+
 		Properties props = new Properties();
 
 		int startArgs = 0;
@@ -200,19 +262,19 @@
 					junitReportOutput = args[i + 1];
 				i++;
 			} else if (args[i].startsWith("haltOnError=")) {
-				System.err.println("The haltOnError option is no longer supported");
+				haltError = Project.toBoolean(args[i].substring(12));
 			} else if (args[i].startsWith("haltOnFailure=")) {
-				System.err.println("The haltOnFailure option is no longer supported");
+				haltFail = Project.toBoolean(args[i].substring(14));
 			} else if (args[i].startsWith("formatter=")) {
-				String formatterString = args[i].substring(10);
-				int seperatorIndex = formatterString.indexOf(',');
-				resultPathString = formatterString.substring(seperatorIndex + 1);
+				formatterString = args[i].substring(10);
 			} else if (args[i].startsWith("propsfile=")) {
 				try (FileInputStream in = new FileInputStream(args[i].substring(10))) {
 					props.load(in);
 				}
 			} else if (args[i].equals("-testlistener")) {
-				System.err.println("The testlistener option is no longer supported");
+				System.err
+						.println("The -testlistener option is no longer supported\nuse the formatter= option instead");
+				return ERRORS;
 			} else if (args[i].equals("-timeout")) {
 				if (i < args.length - 1)
 					timeoutString = args[i + 1];
@@ -245,133 +307,44 @@
 			// names
 			String[] testPlugins = testPluginsNames.split(",");
 			String[] suiteClasses = classesNames.split(",");
+			try {
+				createAndStoreFormatter(formatterString, suiteClasses);
+			} catch (BuildException be) {
+				System.err.println(be.getMessage());
+				return ERRORS;
+			}
 			int returnCode = 0;
 			int j = 0;
-			EclipseTestRunner runner = new EclipseTestRunner();
 			for (String oneClassName : suiteClasses) {
-				int result = runner.runTests(props, testPlugins[j], oneClassName, resultPathString, true);
+				JUnitTest t = new JUnitTest(oneClassName);
+				t.setProperties(props);
+				EclipseTestRunner runner = new EclipseTestRunner(t, testPlugins[j], haltError, haltFail);
+				transferFormatters(runner, j);
+				runner.run();
 				j++;
-				if(result != 0) {
-					returnCode = result;
+				if (runner.getRetCode() != 0) {
+					returnCode = runner.getRetCode();
 				}
 			}
 			return returnCode;
 		}
+		try {
+			createAndStoreFormatter(formatterString);
+		} catch (BuildException be) {
+			System.err.println(be.getMessage());
+			return ERRORS;
+		}
 		if (className == null)
 			throw new IllegalArgumentException("Test class name not specified");
-		EclipseTestRunner runner = new EclipseTestRunner();
-		return runner.runTests(props, testPluginName, className, resultPathString, false);
-	}
 
-	private int runTests(Properties props, String testPluginName, String testClassName, String resultPath, boolean multiTest) {
-		ClassLoader currentTCCL = Thread.currentThread().getContextClassLoader();
-		ExecutionListener executionListener = new ExecutionListener();
-		if(testPluginName == null) {
-			testPluginName = ClassLoaderTools.getClassPlugin(testClassName);
-		}
-		if(testPluginName == null)
-			throw new IllegalArgumentException("Test class not found");
-		LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
-				.selectors(selectClass(testClassName))
-				.build();
+		JUnitTest t = new JUnitTest(className);
 
-		try {
-			Thread.currentThread().setContextClassLoader(ClassLoaderTools.getJUnit5Classloader(getPlatformEngines()));
-			final Launcher launcher = LauncherFactory.create();
+		t.setProperties(props);
 
-			Thread.currentThread().setContextClassLoader(ClassLoaderTools.getPluginClassLoader(testPluginName, currentTCCL));
-			try(LegacyXmlResultFormatter legacyXmlResultFormatter = new LegacyXmlResultFormatter()){
-				try (OutputStream fileOutputStream = getResultOutputStream(resultPath,testClassName,multiTest)){
-					legacyXmlResultFormatter.setDestination(fileOutputStream);
-					legacyXmlResultFormatter.setContext(new ExecutionContext(props));
-					launcher.execute(request, legacyXmlResultFormatter, executionListener);
-				}
-			} catch (IOException e) {
-				e.printStackTrace();
-				return ERRORS;
-			}
-		} finally {
-			Thread.currentThread().setContextClassLoader(currentTCCL);
-		}
-		return executionListener.didExecutionContainedFailures() ? FAILURES : SUCCESS;
-	}
-
-	private OutputStream getResultOutputStream(String resultPathString, String testClassName, boolean multiTest) throws IOException {
-		if(resultPathString == null)
-			return System.out;
-		File resultFile;
-		if(multiTest) {
-			Path resultDirectoryPath = new Path(resultPathString);
-			File testDirectory = resultDirectoryPath.toFile();
-			if(!testDirectory.exists())
-				testDirectory.mkdirs();
-			resultFile = resultDirectoryPath.append("TEST-"+testClassName+".xml").toFile();
-		}else {
-			resultFile = new Path(resultPathString).toFile();
-			File resultDirectory = resultFile.getParentFile();
-			if(!resultDirectory.exists())
-				resultDirectory.mkdirs();
-		}
-		if(!resultFile.exists()) {
-			resultFile.createNewFile();
-		}
-		return new FileOutputStream(resultFile);
-	}
-
-
-	private List<String> getPlatformEngines(){
-		List<String> platformEngines = new ArrayList<>();
-		Bundle bundle = FrameworkUtil.getBundle(getClass());
-		Bundle[] bundles = bundle.getBundleContext().getBundles();
-		for (Bundle iBundle : bundles) {
-			try {
-				BundleWiring bundleWiring = Platform.getBundle(iBundle.getSymbolicName()).adapt(BundleWiring.class);
-				Collection<String> listResources = bundleWiring.listResources("META-INF/services", "org.junit.platform.engine.TestEngine", BundleWiring.LISTRESOURCES_LOCAL);
-				if (!listResources.isEmpty())
-					platformEngines.add(iBundle.getSymbolicName());
-			} catch (Exception e) {
-				// check the next bundle
-			}
-		}
-		return platformEngines;
-	}
-
-	private final class ExecutionListener implements TestExecutionListener {
-		private boolean executionContainedFailures;
-
-		public ExecutionListener() {
-			this.executionContainedFailures = false;
-		}
-
-		public boolean didExecutionContainedFailures() {
-			return executionContainedFailures;
-		}
-
-		@Override
-		public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
-			if(testExecutionResult.getStatus() == org.junit.platform.engine.TestExecutionResult.Status.FAILED) {
-				executionContainedFailures = true;
-			}
-		}
-	}
-
-	private final class ExecutionContext implements TestExecutionContext {
-
-		private final Properties props;
-
-		ExecutionContext(Properties props) {
-			this.props = props;
-		}
-
-		@Override
-		public Properties getProperties() {
-			return this.props;
-		}
-
-		@Override
-		public Optional<Project> getProject() {
-			return null;
-		}
+		EclipseTestRunner runner = new EclipseTestRunner(t, testPluginName, haltError, haltFail);
+		transferFormatters(runner);
+		runner.run();
+		return runner.getRetCode();
 	}
 
 	/**
@@ -431,7 +404,7 @@
 						// Dump all stacks:
 						dumpStackTraces(num, System.err);
 						dumpStackTraces(num, System.out); // System.err could be blocked, see
-						// https://bugs.eclipse.org/506304
+															// https://bugs.eclipse.org/506304
 						logStackTraces(num);              // make this available in the log, see bug 533367
 
 						if (!dumpSwtDisplay(num)) {
@@ -522,7 +495,7 @@
 
 									dumpDisplayState(System.err);
 									dumpDisplayState(System.out); // System.err could be blocked, see
-									// https://bugs.eclipse.org/506304
+																	// https://bugs.eclipse.org/506304
 
 									// Take a screenshot:
 									GC gc = new GC(display);
@@ -579,6 +552,307 @@
 		}
 	}
 
+	public EclipseTestRunner(JUnitTest test, String testPluginName, boolean haltOnError, boolean haltOnFailure) {
+		fJunitTest = test;
+		fTestPluginName = testPluginName;
+		fHaltOnError = haltOnError;
+		fHaltOnFailure = haltOnFailure;
+
+		try {
+			fSuite = getTest(test.getName());
+		} catch (Exception e) {
+			fRetCode = ERRORS;
+			fException = e;
+		}
+	}
+
+	protected Test getTest(String suiteClassName) throws TestFailedException {
+		if (suiteClassName.isEmpty()) {
+			clearStatus();
+			return null;
+		}
+		Class<?> testClass = null;
+		try {
+			testClass = loadSuiteClass(suiteClassName);
+		} catch (ClassNotFoundException e) {
+			if (e.getCause() != null) {
+				runFailed(e.getCause());
+			}
+			String clazz = e.getMessage();
+			if (clazz == null)
+				clazz = suiteClassName;
+			runFailed("Class not found \"" + clazz + "\"");
+			return null;
+		} catch (Exception e) {
+			runFailed(e);
+			return null;
+		}
+		Method suiteMethod = null;
+		try {
+			suiteMethod = testClass.getMethod(SUITE_METHODNAME);
+		} catch (Exception e) {
+			// try to extract a test suite automatically
+			clearStatus();
+			return new junit.framework.JUnit4TestAdapter(testClass);
+		}
+		if (!Modifier.isStatic(suiteMethod.getModifiers())) {
+			runFailed("suite() method must be static");
+			return null;
+		}
+		Test test = null;
+		try {
+			test = (Test) suiteMethod.invoke(null); // static method
+			if (test == null)
+				return test;
+		} catch (InvocationTargetException e) {
+			runFailed("Failed to invoke suite():" + e.getTargetException().toString());
+			return null;
+		} catch (IllegalAccessException e) {
+			runFailed("Failed to invoke suite():" + e.toString());
+			return null;
+		}
+		clearStatus();
+		return test;
+	}
+
+	protected void runFailed(String message) throws TestFailedException {
+		System.err.println(message);
+		throw new TestFailedException(message);
+	}
+
+	protected void runFailed(Throwable e) throws TestFailedException {
+		e.printStackTrace();
+		throw new TestFailedException(e);
+	}
+
+	protected void clearStatus() {
+	}
+
+	/**
+	 * Loads the class either with the system class loader or a plugin class loader
+	 * if a plugin name was specified
+	 */
+	protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
+		if (fTestPluginName == null)
+			return Class.forName(suiteClassName);
+		Bundle bundle = Platform.getBundle(fTestPluginName);
+		if (bundle == null) {
+			throw new ClassNotFoundException(suiteClassName,
+					new Exception("Could not find plugin \"" + fTestPluginName + "\""));
+		}
+
+		// is the plugin a fragment?
+		Dictionary<String, String> headers = bundle.getHeaders();
+		String hostHeader = headers.get(Constants.FRAGMENT_HOST);
+		if (hostHeader != null) {
+			// we are a fragment for sure
+			// we need to find which is our host
+			ManifestElement[] hostElement = null;
+			try {
+				hostElement = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, hostHeader);
+			} catch (BundleException e) {
+				throw new RuntimeException("Could not find host for fragment:" + fTestPluginName, e);
+			}
+			Bundle host = Platform.getBundle(hostElement[0].getValue());
+			// we really want to get the host not the fragment
+			bundle = host;
+		}
+
+		return bundle.loadClass(suiteClassName);
+	}
+
+	public void run() {
+		fTestResult = new TestResult();
+		fTestResult.addListener(this);
+		for (int i = 0; i < formatters.size(); i++) {
+			fTestResult.addListener(formatters.elementAt(i));
+		}
+
+		long start = System.currentTimeMillis();
+		fireStartTestSuite();
+
+		if (fException != null) { // had an exception in the constructor
+			for (int i = 0; i < formatters.size(); i++) {
+				formatters.elementAt(i).addError(null, fException);
+			}
+			fJunitTest.setCounts(1, 0, 1);
+			fJunitTest.setRunTime(0);
+		} else {
+			ByteArrayOutputStream errStrm = new ByteArrayOutputStream();
+			fSystemError = new PrintStream(errStrm);
+
+			ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
+			fSystemOut = new PrintStream(outStrm);
+
+			try {
+				// pm.snapshot(1); // before
+				fSuite.run(fTestResult);
+			} finally {
+				// pm.snapshot(2); // after
+				fSystemError.close();
+				fSystemError = null;
+				fSystemOut.close();
+				fSystemOut = null;
+				sendOutAndErr(new String(outStrm.toByteArray()), new String(errStrm.toByteArray()));
+				fJunitTest.setCounts(fTestResult.runCount(), fTestResult.failureCount(), fTestResult.errorCount());
+				fJunitTest.setRunTime(System.currentTimeMillis() - start);
+			}
+		}
+		fireEndTestSuite();
+
+		if (fRetCode != SUCCESS || fTestResult.errorCount() != 0) {
+			fRetCode = ERRORS;
+		} else if (fTestResult.failureCount() != 0) {
+			fRetCode = FAILURES;
+		}
+
+		// pm.upload(getClass().getName());
+	}
+
+	/**
+	 * Returns what System.exit() would return in the standalone version.
+	 *
+	 * @return 2 if errors occurred, 1 if tests failed else 0.
+	 */
+	public int getRetCode() {
+		return fRetCode;
+	}
+
+	@Override
+	public void startTest(Test t) {
+	}
+
+	@Override
+	public void endTest(Test test) {
+	}
+
+	@Override
+	public void addFailure(Test test, AssertionFailedError t) {
+		if (fHaltOnFailure) {
+			fTestResult.stop();
+		}
+	}
+
+	@Override
+	public void addError(Test test, Throwable t) {
+		if (fHaltOnError) {
+			fTestResult.stop();
+		}
+	}
+
+	private void fireStartTestSuite() {
+		for (int i = 0; i < formatters.size(); i++) {
+			formatters.elementAt(i).startTestSuite(fJunitTest);
+		}
+	}
+
+	private void fireEndTestSuite() {
+		for (int i = 0; i < formatters.size(); i++) {
+			formatters.elementAt(i).endTestSuite(fJunitTest);
+		}
+	}
+
+	public void addFormatter(JUnitResultFormatter f) {
+		formatters.addElement(f);
+	}
+
+	/**
+	 * Line format is: formatter=<classname>(,<pathname>)?
+	 */
+	private static void createAndStoreFormatter(String line) throws BuildException {
+		String formatterClassName = null;
+		File formatterFile = null;
+
+		int pos = line.indexOf(',');
+		if (pos == -1) {
+			formatterClassName = line;
+		} else {
+			formatterClassName = line.substring(0, pos);
+			formatterFile = new File(line.substring(pos + 1)); // the method is
+																// package
+																// visible
+		}
+		fgFromCmdLine.addElement(createFormatter(formatterClassName, formatterFile));
+	}
+
+	/**
+	 * Line format is: formatter=<pathname>
+	 */
+	private static void createAndStoreFormatter(String line, String... suiteClassesNames) throws BuildException {
+		String formatterClassName = null;
+		File formatterFile = null;
+
+		int pos = line.indexOf(',');
+		if (pos == -1) {
+			formatterClassName = line;
+		} else {
+			formatterClassName = line.substring(0, pos);
+		}
+		File outputDirectory = new File(line.substring(pos + 1));
+		outputDirectory.mkdir();
+		for (String suiteClassName : suiteClassesNames) {
+
+			String pathname = "TEST-" + suiteClassName + ".xml";
+			if (outputDirectory.exists()) {
+				pathname = outputDirectory.getAbsolutePath() + "/" + pathname;
+			}
+			formatterFile = new File(pathname);
+			fgFromCmdLine.addElement(createFormatter(formatterClassName, formatterFile));
+		}
+
+	}
+
+	private static void transferFormatters(EclipseTestRunner runner, int j) {
+		runner.addFormatter(fgFromCmdLine.elementAt(j));
+	}
+
+	private static void transferFormatters(EclipseTestRunner runner) {
+		for (int i = 0; i < fgFromCmdLine.size(); i++) {
+			runner.addFormatter(fgFromCmdLine.elementAt(i));
+		}
+	}
+
+	/*
+	 * DUPLICATED from FormatterElement, since it is package visible only
+	 */
+	private static JUnitResultFormatter createFormatter(String classname, File outfile) throws BuildException {
+		OutputStream out = System.out;
+
+		if (classname == null) {
+			throw new BuildException("you must specify type or classname");
+		}
+		Class<?> f = null;
+		try {
+			f = EclipseTestRunner.class.getClassLoader().loadClass(classname);
+		} catch (ClassNotFoundException e) {
+			throw new BuildException(e);
+		}
+
+		Object o = null;
+		try {
+			o = f.getDeclaredConstructor().newInstance();
+		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
+				| NoSuchMethodException | SecurityException e) {
+			throw new BuildException(e);
+		}
+
+		if (!(o instanceof JUnitResultFormatter)) {
+			throw new BuildException(classname + " is not a JUnitResultFormatter");
+		}
+
+		JUnitResultFormatter r = (JUnitResultFormatter) o;
+
+		if (outfile != null) {
+			try {
+				out = new FileOutputStream(outfile);
+			} catch (java.io.IOException e) {
+				throw new BuildException(e);
+			}
+		}
+		r.setOutput(out);
+		return r;
+	}
+
 	public static void dumpAwtScreenshot(String screenshotFile) {
 		try {
 			URL location = AwtScreenshot.class.getProtectionDomain().getCodeSource().getLocation();
@@ -622,4 +896,23 @@
 			e.printStackTrace();
 		}
 	}
+
+	private void sendOutAndErr(String out, String err) {
+		for (JUnitResultFormatter formatter : formatters) {
+			formatter.setSystemOutput(out);
+			formatter.setSystemError(err);
+		}
+	}
+
+	protected void handleOutput(String line) {
+		if (fSystemOut != null) {
+			fSystemOut.println(line);
+		}
+	}
+
+	protected void handleErrorOutput(String line) {
+		if (fSystemError != null) {
+			fSystemError.println(line);
+		}
+	}
 }
diff --git a/bundles/org.eclipse.test/src/org/eclipse/test/LegacyXmlResultFormatter.java b/bundles/org.eclipse.test/src/org/eclipse/test/LegacyXmlResultFormatter.java
deleted file mode 100644
index 31e1da3..0000000
--- a/bundles/org.eclipse.test/src/org/eclipse/test/LegacyXmlResultFormatter.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Red Hat Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Lucas Bullen (Red Hat Inc.) - initial API and implementation
- *******************************************************************************/
-package org.eclipse.test;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.util.Date;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.apache.tools.ant.taskdefs.optional.junitlauncher.TestResultFormatter;
-import org.apache.tools.ant.util.DOMElementWriter;
-import org.apache.tools.ant.util.DateUtils;
-import org.junit.platform.commons.util.ExceptionUtils;
-import org.junit.platform.engine.TestExecutionResult;
-import org.junit.platform.engine.TestSource;
-import org.junit.platform.engine.reporting.ReportEntry;
-import org.junit.platform.engine.support.descriptor.ClassSource;
-import org.junit.platform.launcher.TestIdentifier;
-import org.junit.platform.launcher.TestPlan;
-
-/**
- * A {@link TestResultFormatter} which generates an XML report of the tests. The generated XML reports
- * conforms to the schema of the XML that was generated by the {@code junit} task's XML
- * report formatter and can be used by the {@code junitreport} task
- */
-public class LegacyXmlResultFormatter extends AbstractJUnitResultFormatter {
-
-	private static final double ONE_SECOND = 1000.0;
-
-	OutputStream outputStream;
-	final Map<TestIdentifier, Stats> testIds = new ConcurrentHashMap<>();
-	final Map<TestIdentifier, Optional<String>> skipped = new ConcurrentHashMap<>();
-	final Map<TestIdentifier, Optional<Throwable>> failed = new ConcurrentHashMap<>();
-	final Map<TestIdentifier, Optional<Throwable>> aborted = new ConcurrentHashMap<>();
-
-	TestPlan testPlan;
-	long testPlanStartedAt = -1;
-	long testPlanEndedAt = -1;
-	final AtomicLong numTestsRun = new AtomicLong(0);
-	final AtomicLong numTestsFailed = new AtomicLong(0);
-	final AtomicLong numTestsSkipped = new AtomicLong(0);
-	final AtomicLong numTestsAborted = new AtomicLong(0);
-
-
-	@Override
-	public void testPlanExecutionStarted(final TestPlan plan) {
-		this.testPlan = plan;
-		this.testPlanStartedAt = System.currentTimeMillis();
-	}
-
-	@Override
-	public void testPlanExecutionFinished(final TestPlan plan) {
-		this.testPlanEndedAt = System.currentTimeMillis();
-		// format and print out the result
-		try {
-			new XMLReportWriter().write();
-		} catch (IOException | XMLStreamException e) {
-			handleException(e);
-			return;
-		}
-	}
-
-	@Override
-	public void dynamicTestRegistered(final TestIdentifier testIdentifier) {
-		// nothing to do
-	}
-
-	@Override
-	public void executionSkipped(final TestIdentifier testIdentifier, final String reason) {
-		final long currentTime = System.currentTimeMillis();
-		this.numTestsSkipped.incrementAndGet();
-		this.skipped.put(testIdentifier, Optional.ofNullable(reason));
-		// a skipped test is considered started and ended now
-		final Stats stats = new Stats(testIdentifier, currentTime);
-		stats.endedAt = currentTime;
-		this.testIds.put(testIdentifier, stats);
-	}
-
-	@Override
-	public void executionStarted(final TestIdentifier testIdentifier) {
-		final long currentTime = System.currentTimeMillis();
-		this.testIds.putIfAbsent(testIdentifier, new Stats(testIdentifier, currentTime));
-		if (testIdentifier.isTest()) {
-			this.numTestsRun.incrementAndGet();
-		}
-	}
-
-	@Override
-	public void executionFinished(final TestIdentifier testIdentifier, final TestExecutionResult testExecutionResult) {
-		final long currentTime = System.currentTimeMillis();
-		final Stats stats = this.testIds.get(testIdentifier);
-		if (stats != null) {
-			stats.endedAt = currentTime;
-		}
-		switch (testExecutionResult.getStatus()) {
-		case SUCCESSFUL: {
-			break;
-		}
-		case ABORTED: {
-			this.numTestsAborted.incrementAndGet();
-			this.aborted.put(testIdentifier, testExecutionResult.getThrowable());
-			break;
-		}
-		case FAILED: {
-			this.numTestsFailed.incrementAndGet();
-			this.failed.put(testIdentifier, testExecutionResult.getThrowable());
-			break;
-		}
-		}
-	}
-
-	@Override
-	public void reportingEntryPublished(final TestIdentifier testIdentifier, final ReportEntry entry) {
-		// nothing to do
-	}
-
-	@Override
-	public void setDestination(final OutputStream os) {
-		this.outputStream = os;
-	}
-
-	private final class Stats {
-		final long startedAt;
-		long endedAt;
-
-		Stats(final TestIdentifier testIdentifier, final long startedAt) {
-			this.startedAt = startedAt;
-		}
-	}
-
-	private final class XMLReportWriter {
-
-		private static final String ELEM_TESTSUITE = "testsuite";
-		private static final String ELEM_PROPERTIES = "properties";
-		private static final String ELEM_PROPERTY = "property";
-		private static final String ELEM_TESTCASE = "testcase";
-		private static final String ELEM_SKIPPED = "skipped";
-		private static final String ELEM_FAILURE = "failure";
-		private static final String ELEM_ABORTED = "aborted";
-		private static final String ELEM_SYSTEM_OUT = "system-out";
-		private static final String ELEM_SYSTEM_ERR = "system-err";
-
-
-		private static final String ATTR_CLASSNAME = "classname";
-		private static final String ATTR_NAME = "name";
-		private static final String ATTR_VALUE = "value";
-		private static final String ATTR_TIME = "time";
-		private static final String ATTR_TIMESTAMP = "timestamp";
-		private static final String ATTR_NUM_ABORTED = "aborted";
-		private static final String ATTR_NUM_FAILURES = "failures";
-		private static final String ATTR_NUM_TESTS = "tests";
-		private static final String ATTR_NUM_SKIPPED = "skipped";
-		private static final String ATTR_MESSAGE = "message";
-		private static final String ATTR_TYPE = "type";
-
-		public XMLReportWriter() {
-			// TODO Auto-generated constructor stub
-		}
-
-		void write() throws XMLStreamException, IOException {
-			final XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(outputStream, "UTF-8");
-			try {
-				writer.writeStartDocument();
-				writeTestSuite(writer);
-				writer.writeEndDocument();
-			} finally {
-				writer.close();
-			}
-		}
-
-		void writeTestSuite(final XMLStreamWriter writer) throws XMLStreamException, IOException {
-			// write the testsuite element
-			writer.writeStartElement(ELEM_TESTSUITE);
-			final String testsuiteName = determineTestSuiteName();
-			writer.writeAttribute(ATTR_NAME, testsuiteName);
-			// time taken for the tests execution
-			writer.writeAttribute(ATTR_TIME, String.valueOf((testPlanEndedAt - testPlanStartedAt) / ONE_SECOND));
-			// add the timestamp of report generation
-			final String timestamp = DateUtils.format(new Date(), DateUtils.ISO8601_DATETIME_PATTERN);
-			writer.writeAttribute(ATTR_TIMESTAMP, timestamp);
-			writer.writeAttribute(ATTR_NUM_TESTS, String.valueOf(numTestsRun.longValue()));
-			writer.writeAttribute(ATTR_NUM_FAILURES, String.valueOf(numTestsFailed.longValue()));
-			writer.writeAttribute(ATTR_NUM_SKIPPED, String.valueOf(numTestsSkipped.longValue()));
-			writer.writeAttribute(ATTR_NUM_ABORTED, String.valueOf(numTestsAborted.longValue()));
-
-			// write the properties
-			writeProperties(writer);
-			// write the tests
-			writeTestCase(writer);
-			writeSysOut(writer);
-			writeSysErr(writer);
-			// end the testsuite
-			writer.writeEndElement();
-		}
-
-		void writeProperties(final XMLStreamWriter writer) throws XMLStreamException {
-			final Properties properties = LegacyXmlResultFormatter.this.context.getProperties();
-			if (properties == null || properties.isEmpty()) {
-				return;
-			}
-			writer.writeStartElement(ELEM_PROPERTIES);
-			for (final String prop : properties.stringPropertyNames()) {
-				writer.writeStartElement(ELEM_PROPERTY);
-				writer.writeAttribute(ATTR_NAME, prop);
-				writer.writeAttribute(ATTR_VALUE, properties.getProperty(prop));
-				writer.writeEndElement();
-			}
-			writer.writeEndElement();
-		}
-
-		void writeTestCase(final XMLStreamWriter writer) throws XMLStreamException {
-			for (final Map.Entry<TestIdentifier, Stats> entry : testIds.entrySet()) {
-				final TestIdentifier testId = entry.getKey();
-				if (!testId.isTest()) {
-					// only interested in test methods
-					continue;
-				}
-				// find the parent class of this test method
-				final Optional<TestIdentifier> parent = testPlan.getParent(testId);
-				if (!parent.isPresent()) {
-					continue;
-				}
-				final String classname = parent.get().getLegacyReportingName();
-				writer.writeStartElement(ELEM_TESTCASE);
-				writer.writeAttribute(ATTR_CLASSNAME, classname);
-				writer.writeAttribute(ATTR_NAME, testId.getDisplayName());
-				final Stats stats = entry.getValue();
-				writer.writeAttribute(ATTR_TIME, String.valueOf((stats.endedAt - stats.startedAt) / ONE_SECOND));
-				// skipped element if the test was skipped
-				writeSkipped(writer, testId);
-				// failed element if the test failed
-				writeFailed(writer, testId);
-				// aborted element if the test was aborted
-				writeAborted(writer, testId);
-
-				writer.writeEndElement();
-			}
-		}
-
-		private void writeSkipped(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
-			if (!skipped.containsKey(testIdentifier)) {
-				return;
-			}
-			writer.writeStartElement(ELEM_SKIPPED);
-			final Optional<String> reason = skipped.get(testIdentifier);
-			if (reason.isPresent()) {
-				writer.writeAttribute(ATTR_MESSAGE, reason.get());
-			}
-			writer.writeEndElement();
-		}
-
-		private void writeFailed(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
-			if (!failed.containsKey(testIdentifier)) {
-				return;
-			}
-			writer.writeStartElement(ELEM_FAILURE);
-			final Optional<Throwable> cause = failed.get(testIdentifier);
-			if (cause.isPresent()) {
-				final Throwable t = cause.get();
-				final String message = t.getMessage();
-				if (message != null && !message.trim().isEmpty()) {
-					writer.writeAttribute(ATTR_MESSAGE, message);
-				}
-				writer.writeAttribute(ATTR_TYPE, t.getClass().getName());
-				writer.writeCharacters(ExceptionUtils.readStackTrace(t));
-			}
-			writer.writeEndElement();
-		}
-
-		private void writeAborted(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
-			if (!aborted.containsKey(testIdentifier)) {
-				return;
-			}
-			writer.writeStartElement(ELEM_ABORTED);
-			final Optional<Throwable> cause = aborted.get(testIdentifier);
-			if (cause.isPresent()) {
-				final Throwable t = cause.get();
-				final String message = t.getMessage();
-				if (message != null && !message.trim().isEmpty()) {
-					writer.writeAttribute(ATTR_MESSAGE, message);
-				}
-				writer.writeAttribute(ATTR_TYPE, t.getClass().getName());
-			}
-			writer.writeEndElement();
-		}
-
-		private void writeSysOut(final XMLStreamWriter writer) throws XMLStreamException, IOException {
-			if (!LegacyXmlResultFormatter.this.hasSysOut()) {
-				return;
-			}
-			writer.writeStartElement(ELEM_SYSTEM_OUT);
-			try (final Reader reader = LegacyXmlResultFormatter.this.getSysOutReader()) {
-				writeCharactersFrom(reader, writer);
-			}
-			writer.writeEndElement();
-		}
-
-		private void writeSysErr(final XMLStreamWriter writer) throws XMLStreamException, IOException {
-			if (!LegacyXmlResultFormatter.this.hasSysErr()) {
-				return;
-			}
-			writer.writeStartElement(ELEM_SYSTEM_ERR);
-			try (final Reader reader = LegacyXmlResultFormatter.this.getSysErrReader()) {
-				writeCharactersFrom(reader, writer);
-			}
-			writer.writeEndElement();
-		}
-
-		private void writeCharactersFrom(final Reader reader, final XMLStreamWriter writer) throws IOException, XMLStreamException {
-			final char[] chars = new char[1024];
-			int numRead = -1;
-			while ((numRead = reader.read(chars)) != -1) {
-				// although it's called a DOMElementWriter, the encode method is just a
-				// straight forward XML util method which doesn't concern about whether
-				// DOM, SAX, StAX semantics.
-				// TODO: Perhaps make it a static method
-				final String encoded = new DOMElementWriter().encode(new String(chars, 0, numRead));
-				writer.writeCharacters(encoded);
-			}
-		}
-
-		private String determineTestSuiteName() {
-			// this is really a hack to try and match the expectations of the XML report in JUnit4.x
-			// world. In JUnit5, the TestPlan doesn't have a name and a TestPlan (for which this is a
-			// listener) can have numerous tests within it
-			final Set<TestIdentifier> roots = testPlan.getRoots();
-			if (roots.isEmpty()) {
-				return "UNKNOWN";
-			}
-			for (final TestIdentifier root : roots) {
-				final Optional<ClassSource> classSource = findFirstClassSource(root);
-				if (classSource.isPresent()) {
-					return classSource.get().getClassName();
-				}
-			}
-			return "UNKNOWN";
-		}
-
-		private Optional<ClassSource> findFirstClassSource(final TestIdentifier root) {
-			if (root.getSource().isPresent()) {
-				final TestSource source = root.getSource().get();
-				if (source instanceof ClassSource) {
-					return Optional.of((ClassSource) source);
-				}
-			}
-			for (final TestIdentifier child : testPlan.getChildren(root)) {
-				final Optional<ClassSource> classSource = findFirstClassSource(child);
-				if (classSource.isPresent()) {
-					return classSource;
-				}
-			}
-			return Optional.empty();
-		}
-	}
-
-}
diff --git a/bundles/org.eclipse.test/src/org/eclipse/test/UITestApplication.java b/bundles/org.eclipse.test/src/org/eclipse/test/UITestApplication.java
index 62b1288..966b0d0 100644
--- a/bundles/org.eclipse.test/src/org/eclipse/test/UITestApplication.java
+++ b/bundles/org.eclipse.test/src/org/eclipse/test/UITestApplication.java
@@ -10,17 +10,19 @@
  *******************************************************************************/
 package org.eclipse.test;
 
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
 import java.io.IOException;
 
+import junit.framework.Assert;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
 import org.eclipse.core.runtime.IPlatformRunnable;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.equinox.app.IApplication;
-import org.eclipse.equinox.app.IApplicationContext;
+
 import org.eclipse.ui.IWindowListener;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchWindow;
@@ -30,27 +32,27 @@
 
 /**
  * A Workbench that runs a test suite specified in the command line arguments.
- *
+ * 
  * @deprecated As using deprecated materials
- */
+ */ 
 @Deprecated
 public class UITestApplication  implements IPlatformRunnable, ITestHarness, IApplication {
 
 	private static final String DEFAULT_APP_3_0 = "org.eclipse.ui.ide.workbench"; //$NON-NLS-1$
 	private static final String DEFAULT_APP_PRE_3_0 = "org.eclipse.ui.workbench"; //$NON-NLS-1$
-
+	
 	private boolean fInDeprecatedMode = false;
 	private TestableObject fTestableObject;
 	int fTestRunnerResult = -1;
 	private IApplicationContext appContext;
-
-
+	
+	
 	@Override
 	public Object run(final Object args) throws Exception {
 		// Get the application to test
 		Object application = getApplication((String[])args);
-		assertNotNull(application);
-
+		Assert.assertNotNull(application);
+		
 		Object result;
 		if (fInDeprecatedMode && (application instanceof IPlatformRunnable)) {
 			result = runDeprecatedApplication((IPlatformRunnable)application, args);
@@ -63,8 +65,8 @@
 		}
 		return Integer.valueOf(fTestRunnerResult);
 	}
-
-
+	
+	
 	/*
 	 * return the application to run, or null if not even the default application
 	 * is found.
@@ -75,11 +77,11 @@
 		// If no application is specified, the 3.0 default workbench application
 		// is returned.
 		IExtension extension =
-				Platform.getExtensionRegistry().getExtension(
-						Platform.PI_RUNTIME,
-						Platform.PT_APPLICATIONS,
-						getApplicationToRun(args));
-
+		Platform.getExtensionRegistry().getExtension(
+				Platform.PI_RUNTIME,
+				Platform.PT_APPLICATIONS,
+				getApplicationToRun(args));
+		
 		// If no 3.0 extension can be found, search the registry
 		// for the pre-3.0 default workbench application, i.e. org.eclipse ui.workbench
 		// Set the deprecated flag to true
@@ -90,9 +92,9 @@
 					DEFAULT_APP_PRE_3_0);
 			fInDeprecatedMode = true;
 		}
-
-		assertNotNull(extension);
-
+		
+		Assert.assertNotNull(extension);
+		
 		// If the extension does not have the correct grammar, return null.
 		// Otherwise, return the application object.
 		IConfigurationElement[] elements = extension.getConfigurationElements();
@@ -108,13 +110,13 @@
 		}
 		return null;
 	}
-
+	
 	/**
 	 * The -testApplication argument specifies the application to be run.
 	 * If the PDE JUnit launcher did not set this argument, then return
 	 * the name of the default application.
 	 * In 3.0, the default is the "org.eclipse.ui.ide.worbench" application.
-	 *
+	 * 
 	 */
 	private String getApplicationToRun(String[] args) {
 		for (int i = 0; i < args.length; i++) {
@@ -123,21 +125,21 @@
 		}
 		return DEFAULT_APP_3_0;
 	}
-
+	
 	/**
 	 * In 3.0 mode
-	 *
+	 * 
 	 */
 	private Object runApplication(Object application, Object args) throws Exception {
 		fTestableObject = PlatformUI.getTestableObject();
 		fTestableObject.setTestHarness(this);
 		if (application instanceof IPlatformRunnable) {
 			return ((IPlatformRunnable) application).run(args);
-		}
+		} 
 		return ((IApplication) application).start(appContext);
-
+		
 	}
-
+	
 	/*
 	 * If we are in pre-3.0 mode, then the application to run is
 	 * "org.eclipse.ui.workbench" Therefore, we safely cast the runnable object
@@ -146,11 +148,11 @@
 	 * done, we explicitly call close() on the workbench.
 	 */
 	private Object runDeprecatedApplication(
-			IPlatformRunnable object,
-			final Object args)
-					throws Exception {
+		IPlatformRunnable object,
+		final Object args)
+		throws Exception {
 
-		assertNotNull(object instanceof IWorkbench);
+		Assert.assertTrue(object instanceof IWorkbench);
 
 		final IWorkbench workbench = (IWorkbench) object;
 		// the 'started' flag is used so that we only run tests when the window
@@ -212,8 +214,8 @@
 	@Override
 	public void stop() {
 		// TODO Auto-generated method stub
-
+		
 	}
-
+	
 }
 
