diff --git a/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/tasks/maven/SynchronizeMavenArtifact.java b/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/tasks/maven/SynchronizeMavenArtifact.java
index c4a1f96..bb61c45 100644
--- a/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/tasks/maven/SynchronizeMavenArtifact.java
+++ b/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/tasks/maven/SynchronizeMavenArtifact.java
@@ -10,20 +10,22 @@
  *******************************************************************************/
 package org.eclipse.tea.library.build.tasks.maven;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Comparator;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.TreeSet;
 import java.util.regex.Matcher;
+import java.util.stream.Collectors;
 
 import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
 import org.apache.maven.wagon.ConnectionException;
@@ -42,6 +44,7 @@
 import org.eclipse.aether.repository.RemoteRepository;
 import org.eclipse.aether.repository.RepositoryPolicy;
 import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
 import org.eclipse.aether.resolution.ArtifactResult;
 import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
 import org.eclipse.aether.spi.connector.transport.TransporterFactory;
@@ -49,6 +52,7 @@
 import org.eclipse.aether.transport.wagon.WagonProvider;
 import org.eclipse.aether.transport.wagon.WagonTransporterFactory;
 import org.eclipse.core.internal.variables.StringVariableManager;
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
@@ -56,7 +60,6 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.jdt.apt.core.util.AptConfig;
 import org.eclipse.jdt.core.IClasspathEntry;
@@ -213,7 +216,7 @@
 			System.runFinalization();
 
 			for (PluginBuild pb : classpathManipulatorOfPlugin.keySet()) {
-				runSingle(log, tracker, pb, system, session, remotes);
+				synchronizePlugin(log, tracker, pb, system, session, remotes);
 			}
 		} catch (Exception e) {
 			log.error("error synchronizing maven artifacts", e);
@@ -251,23 +254,28 @@
 		return new MavenConfig(file);
 	}
 
-	private void runSingle(TaskingLog log, TaskProgressTracker tracker, PluginBuild hostPlugin, RepositorySystem system,
-			RepositorySystemSession session, List<RemoteRepository> remotes) throws CoreException {
+	private void synchronizePlugin(TaskingLog log, TaskProgressTracker tracker, PluginBuild hostPlugin,
+			RepositorySystem system, RepositorySystemSession session, List<RemoteRepository> remotes)
+			throws CoreException {
+		NullProgressMonitor monitor = new NullProgressMonitor();
 		IProject prj = hostPlugin.getData().getProject();
-		IFolder folder = prj.getFolder(MAVEN_DIRNAME);
-		if (!folder.exists()) {
-			folder.create(false, true, null);
-			log.warn("creating " + folder.getName() + "; make sure to add to the classpath of "
+		IFolder targetFolder = prj.getFolder(MAVEN_DIRNAME);
+		if (!targetFolder.exists()) {
+			targetFolder.create(false, true, monitor);
+			log.warn("creating " + targetFolder.getName() + "; make sure to add to the classpath of "
 					+ hostPlugin.getPluginName());
+			// write .gitignore
+			IFile gitignore = targetFolder.getFile(".gitignore");
+			gitignore.create(new ByteArrayInputStream("*.jar".getBytes(Charsets.UTF_8)), false, null);
 		}
-		File target = folder.getRawLocation().toFile();
 
-		Set<File> valid = new TreeSet<>(Comparator.comparing(File::getName));
+		List<ArtifactRequest> artifactRequests = new ArrayList<>();
+		log.info("synchronize maven artifacts for '" + hostPlugin.getPluginName() + "': "
+				+ hostPlugin.getMavenExternalJarDependencies().stream().map(artifact -> artifact.getCoordinates())
+						.collect(Collectors.joining(", ")));
 		for (MavenExternalJarBuild artifact : hostPlugin.getMavenExternalJarDependencies()) {
 			tracker.setTaskName(artifact.getCoordinates());
 			tracker.worked(1);
-			log.info("synchronize nexus coordinate " + artifact.getCoordinates() + " into "
-					+ hostPlugin.getPluginName());
 
 			Coordinate coord = new Coordinate(artifact.getCoordinates());
 
@@ -289,166 +297,132 @@
 			{
 				ArtifactRequest remoterq = new ArtifactRequest().setArtifact(mvn)
 						.setRepositories(remote ? remotes : null);
-				resolveArtifact(log, target, system, session, remoterq, valid);
+				artifactRequests.add(remoterq);
 			}
 
 			// resolve source bundle.
-			try {
-				Artifact srcmvn = new DefaultArtifact(coord.group, coord.artifact, "sources", coord.extension,
-						coord.version);
-				ArtifactRequest srcrq = new ArtifactRequest().setArtifact(srcmvn)
-						.setRepositories(remote ? remotes : null);
+			Artifact srcmvn = new DefaultArtifact(coord.group, coord.artifact, "sources", coord.extension,
+					coord.version);
+			ArtifactRequest srcrq = new ArtifactRequest().setArtifact(srcmvn).setRepositories(remote ? remotes : null);
+			artifactRequests.add(srcrq);
+		}
 
-				resolveArtifact(log, target, system, session, srcrq, valid);
-			} catch (Exception e) {
-				log.warn("No sources available for " + artifact.getCoordinates());
+		List<ArtifactResult> results = resolveArtifacts(log, system, session, artifactRequests);
+		Set<IFile> resolvedFiles = new HashSet<>();
+		for (ArtifactResult result : results) {
+			ArtifactRequest rq = result.getRequest();
+			Artifact mvn = rq.getArtifact();
+			String c = mvn.getClassifier();
+			if (result.isMissing() || !result.isResolved() || !result.getExceptions().isEmpty()) {
+				if ("sources".equals(c)) {
+					log.warn("No sources available for " + mvn.getGroupId() + ":" + mvn.getArtifactId() + ":"
+							+ mvn.getVersion());
+				} else {
+					String classifier = c == null || c.isEmpty() ? "" : (":" + c);
+					log.error("cannot resolve " + mvn.getGroupId() + ":" + mvn.getArtifactId() + classifier + ":"
+							+ mvn.getVersion());
+				}
+			} else {
+				// copy file to maven directory
+				File resolvedFile = result.getArtifact().getFile();
+				IFile targetFile = targetFolder.getFile(resolvedFile.getName());
+				resolvedFiles.add(targetFile);
+
+				Artifact artifact = result.getArtifact();
+				if (needUpdateFileInProjectsMavenFolder(log, targetFile, artifact)) {
+					updateFileInProjectsMavenFolder(log, targetFile, artifact);
+				}
 			}
 		}
 
 		// cleanup old files
-		for (File file : target.listFiles()) {
+		for (IResource file : targetFolder.members()) {
 			if (file.getName().equals(".gitignore")) {
 				continue;
 			}
 
-			boolean isValid = false;
-			for (File validFile : valid) {
-				if (file.equals(validFile)) {
-					isValid = true;
-				}
-			}
-
-			if (!isValid) {
+			if (!resolvedFiles.contains(file)) {
 				log.info("removing old maven artifact: " + file);
-				FileUtils.delete(file);
+				file.delete(true, null);
 			}
 		}
-
-		// write .gitignore
-		File gitignore = new File(target, ".gitignore");
-		if (!gitignore.exists()) {
-			try {
-				FileUtils.writeFileFromString(gitignore, Charsets.UTF_8, "*.jar");
-			} catch (IOException e) {
-				throw new CoreException(Status.error(e.getMessage(), e));
-			}
-		}
-
-		folder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
+		return;
 	}
 
 	/**
-	 * Resolves an {@link ArtifactRequest}. Resolving means that it looks up the
-	 * bundle on the local repository and all servers. After successful
+	 * Resolves multiple {@link ArtifactRequest}. Resolving means that it looks
+	 * up the bundle on the local repository and all servers. After successful
 	 * resolution, the bundles is located in the local repository. After that,
 	 * this method copies the according file to the target location.
 	 *
 	 * @param controller
 	 *            used for logging
-	 * @param target
-	 *            the target directory to put the bundle into
 	 * @param system
 	 *            the {@link RepositorySystem} providing the resolution
 	 *            algorithm
 	 * @param session
 	 *            the {@link RepositorySystemSession} to use
-	 * @param rq
-	 *            the {@link ArtifactRequest} that defines what to resolve
-	 * @param resolved
-	 *            all resolved artifacts will be added to this list, even if no
-	 *            file has been changed on disk.
+	 * @param requests
+	 *            A Collection of {@link ArtifactRequest} that defines what to
+	 *            resolve
+	 * @returns list of {@link ArtifactResult}
 	 */
-	private void resolveArtifact(TaskingLog log, File target, RepositorySystem system, RepositorySystemSession session,
-			ArtifactRequest rq, Set<File> resolved) {
-		Artifact mvn = rq.getArtifact();
-
+	private List<ArtifactResult> resolveArtifacts(TaskingLog log, RepositorySystem system,
+			RepositorySystemSession session, Collection<ArtifactRequest> requests) {
+		List<ArtifactResult> results;
 		try {
-			ArtifactResult result = system.resolveArtifact(session, rq);
-			if (result.isMissing() || !result.isResolved()) {
-				log.warn("cannot resolve " + mvn.getGroupId() + ":" + mvn.getArtifactId() + ":" + mvn.getVersion() + ":"
-						+ mvn.getClassifier());
-				if (!result.getExceptions().isEmpty()) {
-					for (Exception e : result.getExceptions()) {
-						e.printStackTrace(log.error());
-					}
-				}
-				return;
-			}
-			if (properties.isVerboseMavenOutput()) {
-				if (!result.getExceptions().isEmpty()) {
-					for (Exception e : result.getExceptions()) {
-						e.printStackTrace(log.debug());
-					}
-				}
-			}
-			// download file to maven directory
-			File file = result.getArtifact().getFile();
-			addFileToProjectsMavenFolder(log, target, resolved, result, file);
-		} catch (Exception e) {
-			String c = mvn.getClassifier();
-			if (!"sources".equals(c)) {
-				String classifier = c == null || c.isEmpty() ? "" : (":" + c);
-				log.error("cannot resolve " + mvn.getGroupId() + ":" + mvn.getArtifactId() + classifier + ":"
-						+ mvn.getVersion());
-			}
-			throw new RuntimeException("failed to synchronize " + rq.getArtifact().getArtifactId(), e);
+			results = system.resolveArtifacts(session, requests);
+		} catch (ArtifactResolutionException e) {
+			results = e.getResults();
 		}
+		return results;
 	}
 
-	private static void addFileToProjectsMavenFolder(TaskingLog log, File target, Set<File> resolved,
-			ArtifactResult result, File file) throws IOException {
-		File targetFile = new File(target, file.getName());
-		resolved.add(targetFile);
+	private static boolean needUpdateFileInProjectsMavenFolder(TaskingLog log, IFile targetResource,
+			Artifact artifact) {
+		File targetFile = targetResource.getRawLocation().toFile();
+		File resolvedFile = artifact.getFile();
+		// no need to update if files are equal:
+		return !FileUtils.equals(targetFile, resolvedFile);
+	}
 
-		if (targetFile.exists() && !result.getArtifact().isSnapshot()) {
-			// it is a released file. try to update but don't fail if (for
-			// example) windows locks
-			// the file...
+	private static void updateFileInProjectsMavenFolder(TaskingLog log, IFile targetResource, Artifact artifact)
+			throws CoreException {
+		File targetFile = targetResource.getRawLocation().toFile();
+		File resolvedFile = artifact.getFile();
+		// update = delete existing + copy or link new file:
+		if (targetFile.exists()) {
 			if (!targetFile.delete()) {
-				if (targetFile.length() != file.length()) {
-					// would need update but can't
-					log.error("cannot update " + targetFile + " to new version, please make sure file is not locked");
-				}
-
-				return; // don't update
+				log.error("cannot update " + targetFile + ". Please make sure file is not locked");
+				return;
 			}
 		}
 
-		boolean copyNeeded = true;
-		// refresh of file/link:
 		try {
-			FileUtils.delete(targetFile);
-		} catch (java.lang.IllegalStateException e) { // cannot delete
-			if (FileUtils.equals(targetFile, file)) {
-				// ignore
-				log.info("Could not update file. Probably in use. Can be ignored since contents is the same: "
-						+ targetFile);
-				copyNeeded = false;
-			} else {
-				throw e;
-			}
-		}
-
-		if (copyNeeded) {
-			try {
-				targetFile = java.nio.file.Files.createSymbolicLink(targetFile.toPath(), file.toPath()).toFile();
-			} catch (IOException e) {
-				String exName = e.getClass().getName();
-				// don't spam missing rights for symlink creation
-				if (!Objects.equals(exName, lastExceptionName)) {
-					lastExceptionName = exName;
-					// Windows 10:
-					// "$file: Dem Client fehlt ein erforderliches Recht.\r\n"
-					String msg = e.getMessage();
-					if (msg != null) {
-						msg = msg.replace("\n", "\\n");
-						msg = msg.replace("\r", "\\r");
-					}
-					log.warn("cannot create symlink for: " + targetFile + " (" + exName + " " + msg + ")");
+			java.nio.file.Files.createSymbolicLink(targetFile.toPath(), resolvedFile.toPath());
+		} catch (IOException e) {
+			String exName = e.getClass().getName();
+			// don't spam missing rights for symlink creation
+			if (!Objects.equals(exName, lastExceptionName)) {
+				lastExceptionName = exName;
+				// Windows 10:
+				// "$file: Dem Client fehlt ein erforderliches Recht.\r\n"
+				String msg = e.getMessage();
+				if (msg != null) {
+					msg = msg.replace("\n", "\\n");
+					msg = msg.replace("\r", "\\r");
 				}
-				FileUtils.copyFileToDirectory(file, target);
+				log.warn("cannot create symlink for: " + targetFile + " (" + exName + " " + msg + ")");
+			}
+			try {
+				FileUtils.copyFile(resolvedFile, targetFile);
+			} catch (IOException copyException) {
+				log.error("Could not copy file.", copyException);
+				return;
 			}
 		}
+		targetResource.refreshLocal(IResource.DEPTH_ZERO, null);
+		return;
 	}
 
 	private List<RemoteRepository> createRemoteRepositories() {
