diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java
index 424337a652..599854750c 100644
--- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java
+++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java
@@ -30,7 +30,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -56,7 +56,7 @@ public class BasicFileDetector {
 	private String fileName;
 	private int maxDepth = 5;
 	private boolean includeNested = true;
-	private Set<String> exclusions = new HashSet<>(1);
+	private Set<String> exclusions = new LinkedHashSet<>(1);
 
 	/**
 	 * Constructs a new BasicFileDetector for the given root directory, searching for a fileName.
@@ -172,13 +172,19 @@ private boolean isExcluded(Path dir) {
 		if (dir.getFileName() == null) {
 			return true;
 		}
+		boolean excluded = false;
 		for (String pattern : exclusions) {
+			boolean includePattern = false;
+			if (pattern.startsWith("!")) {
+				includePattern = true;
+				pattern = pattern.substring(1);
+			}
 			PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
 			if (matcher.matches(dir)) {
-				return true;
+				excluded = includePattern ? false : true;
 			}
 		}
-		return false;
+		return excluded;
 	}
 
 	private boolean hasTargetFile(Path dir) {
diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java
index fb04359f60..38fa428133 100644
--- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java
+++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java
@@ -96,15 +96,21 @@ public boolean applies(IProgressMonitor monitor) throws OperationCanceledExcepti
 
 	private boolean exclude(java.nio.file.Path path) {
 		List<String> javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions();
+		boolean excluded = false;
 		if (javaImportExclusions != null) {
 			for (String pattern : javaImportExclusions) {
+				boolean includePattern = false;
+				if (pattern.startsWith("!")) {
+					includePattern = true;
+					pattern = pattern.substring(1);
+				}
 				PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
 				if (matcher.matches(path)) {
-					return true;
+					excluded = includePattern ? false : true;
 				}
 			}
 		}
-		return false;
+		return excluded;
 	}
 
 	synchronized Set<MavenProjectInfo> getMavenProjectInfo(IProgressMonitor monitor) throws OperationCanceledException {
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java
index 415205dbd3..4fb7c101c8 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java
@@ -19,12 +19,14 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
 import java.util.stream.Collectors;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
+import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.junit.Test;
 
 /**
@@ -72,6 +74,74 @@ public void testScanExcludingNestedBuildFilesDepth3() throws Exception {
 		assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size());
 	}
 
+	@Test
+	public void testInclusions() throws Exception {
+		List<String> javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions();
+		List<String> javaImportInclusions = new LinkedList<>();
+		javaImportInclusions.addAll(javaImportExclusions);
+		javaImportInclusions.add("**/parent/**");
+		javaImportInclusions.add("!**/parent");
+		javaImportInclusions.add("!**/parent/1_0");
+		javaImportInclusions.add("!**/parent/1_0/*");
+		try {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions);
+			BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3);
+			Collection<Path> dirs = detector.scan(null);
+			assertEquals("Found " + dirs, 2, dirs.size());
+			List<String> missingDirs = separatorsToSystem(list("projects/buildfiles/parent/1_0/0_2_0", "projects/buildfiles/parent/1_0/0_2_1"));
+			dirs.stream().map(Path::toString).forEach(missingDirs::remove);
+			assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size());
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions);
+			detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3);
+			dirs = detector.scan(null);
+			assertEquals("Found " + dirs, 3, dirs.size());
+		} finally {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions);
+		}
+	}
+
+	@Test
+	public void testInclusions2() throws Exception {
+		List<String> javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions();
+		List<String> javaImportInclusions = new LinkedList<>();
+		javaImportInclusions.addAll(javaImportExclusions);
+		javaImportInclusions.add("**/parent/**");
+		javaImportInclusions.add("!**/parent");
+		javaImportInclusions.add("!**/parent/1_0");
+		javaImportInclusions.add("!**/parent/1_0/0_2_0");
+		try {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions);
+			BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3);
+			Collection<Path> dirs = detector.scan(null);
+			assertEquals("Found " + dirs, 1, dirs.size());
+			List<String> missingDirs = separatorsToSystem(list("projects/buildfiles/parent/1_0/0_2_0"));
+			dirs.stream().map(Path::toString).forEach(missingDirs::remove);
+			assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size());
+		} finally {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions);
+		}
+	}
+
+	@Test
+	public void testInclusions3() throws Exception {
+		List<String> javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions();
+		List<String> javaImportInclusions = new LinkedList<>();
+		javaImportInclusions.addAll(javaImportExclusions);
+		javaImportInclusions.add("!**/parent");
+		javaImportInclusions.add("!**/parent/1_0");
+		javaImportInclusions.add("!**/parent/1_0/0_2_0");
+		javaImportInclusions.add("**/parent/**");
+		try {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions);
+			BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3);
+			Collection<Path> dirs = detector.scan(null);
+			assertEquals("Found " + dirs, 0, dirs.size());
+		} finally {
+			JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions);
+		}
+	}
+
+
 	@Test
 	public void testScanNestedBuildFilesDepth2() throws Exception {
 		BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile")