diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index 0c83dc776e24deec20e2c6c7473a94f2bffd515a..f3aa4c9c0df6c74aa4547deae1af885c40c6c3e6 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -21,7 +21,6 @@ file.reference.commons-collections-3.2.2.jar=release\\modules\\ext\\commons-coll
 file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.1.jar
 file.reference.commons-digester-1.8.1.jar=release\\modules\\ext\\commons-digester-1.8.1.jar
 file.reference.commons-lang-2.6.jar=release\\modules\\ext\\commons-lang-2.6.jar
-file.reference.commons-lang3-3.5.jar=release\\modules\\ext\\commons-lang3-3.5.jar
 file.reference.commons-logging-1.2.jar=release\\modules\\ext\\commons-logging-1.2.jar
 file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
 file.reference.commons-validator-1.6.jar=release\\modules\\ext\\commons-validator-1.6.jar
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index 68aec2e8eeaad18c8ccd314a3793cd4ed3dc98e3..e1aec851e1832cd967d83a88c2baaa7a04b54bc5 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -623,10 +623,6 @@
                 <runtime-relative-path>ext/jackson-core-2.9.7.jar</runtime-relative-path>
                 <binary-origin>release\modules\ext\jackson-core-2.9.7.jar</binary-origin>
             </class-path-extension>
-            <class-path-extension>
-                <runtime-relative-path>ext/commons-lang3-3.5.jar</runtime-relative-path>
-                <binary-origin>release\modules\ext\commons-lang3-3.5.jar</binary-origin>
-            </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/log4j-1.2.16.jar</runtime-relative-path>
                 <binary-origin>release\modules\ext\log4j-1.2.16.jar</binary-origin>
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/EnvironmentSetupUtil.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/EnvironmentSetupUtil.java
index 89c4f85fb9635d1898f0a6e194208d4f62249d70..e6c0325e01a79e48476a2a737a29b181fa17927d 100644
--- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/EnvironmentSetupUtil.java
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/EnvironmentSetupUtil.java
@@ -140,11 +140,12 @@ private IngestModuleTemplate getTemplate(String pathToIngestModuleSettings, Inge
      * Sets up the Autopsy environment based on the case config and returns the
      * ingest job settings to be used for ingest.
      *
+     * @param config The overall configuration.
      * @param caseConfig The case configuration.
      * @return The IngestJobSettings to be used with ingest.
      */
-    public IngestJobSettings setupEnvironment(CaseConfig caseConfig) {
-        return getIngestSettings(caseConfig.getCaseName(),
+    public IngestJobSettings setupEnvironment(IntegrationTestConfig config, CaseConfig caseConfig) {
+        return getIngestSettings(PathUtil.getAbsolutePath(config.getWorkingDirectory(), caseConfig.getCaseName()),
                 DEFAULT_INGEST_TYPE,
                 caseConfig.getIngestModules(), caseConfig.getIngestModuleSettingsPath());
     }
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTestConfig.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTestConfig.java
index 4a4cb9fd0d061810a158fda254d52c5b1852a350..b9c83a4fd24387d7a3650cf915add02e14383b7e 100644
--- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTestConfig.java
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTestConfig.java
@@ -32,29 +32,13 @@
  * parameters, datasource locations, cases to create, tests to run, etc.
  */
 public class IntegrationTestConfig {
-    private static final Type listOfCasesType = new TypeToken<List<CaseConfig>>(){}.getType();
-        
-    /**
-     * Gson Json deserializer to handle proper construction of this 
-     */
-    public static final JsonDeserializer<IntegrationTestConfig> DESERIALIZER = new JsonDeserializer<IntegrationTestConfig>() {
-        @Override
-        public IntegrationTestConfig deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
-            JsonObject jObj = je.getAsJsonObject();
-            String rootCaseOutputPath = jObj.get("rootCaseOutputPath").getAsString();
-            String rootTestOutputPath = jObj.get("rootTestOutputPath").getAsString();
-            List<CaseConfig> cases = jdc.deserialize(jObj.get("cases"), listOfCasesType);
-            
-            return new IntegrationTestConfig(rootCaseOutputPath, rootTestOutputPath, cases);
-        }
-    };
-    
-    
+
     private final String rootCaseOutputPath;
     private final String rootTestOutputPath;
     private final List<CaseConfig> cases;
+    private String workingDirectory;
 
-    public IntegrationTestConfig(String rootCaseOutputPath, 
+    public IntegrationTestConfig(String rootCaseOutputPath,
             String rootTestOutputPath, List<CaseConfig> cases) {
         this.rootCaseOutputPath = rootCaseOutputPath;
         this.rootTestOutputPath = rootTestOutputPath;
@@ -81,4 +65,25 @@ public String getRootTestOutputPath() {
     public List<CaseConfig> getCases() {
         return cases;
     }
+
+    /**
+     * @return The working directory. In practice, this is the folder that the
+     * configuration is located within. Any relative paths will be relative to
+     * this.
+     */
+    public String getWorkingDirectory() {
+        return workingDirectory;
+    }
+
+    /**
+     * Sets the working directory.
+     *
+     * @param workingDirectory The working directory. In practice, this is the
+     * folder that the configuration is located within. Any relative paths will
+     * be relative to this.
+     */
+    public void setWorkingDirectory(String workingDirectory) {
+        this.workingDirectory = workingDirectory;
+    }
+
 }
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java
index 3454dc86846bad8411983f0b7d902ddd5acf06b0..c2d081fd1fd8207fdc5cbe6d75b11701eed77f4e 100644
--- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java
@@ -94,6 +94,9 @@ public void runIntegrationTests() {
         IntegrationTestConfig config;
         try {
             config = getConfigFromFile(configFile);
+            if (config.getWorkingDirectory() == null) {
+                config.setWorkingDirectory(new File(configFile).getParentFile().getAbsolutePath());
+            }
         } catch (IOException ex) {
             logger.log(Level.WARNING, "There was an error processing integration test config at " + configFile, ex);
             return;
@@ -108,7 +111,7 @@ public void runIntegrationTests() {
                 for (CaseType caseType : IntegrationCaseType.getCaseTypes(caseConfig.getCaseTypes())) {
                     // create an autopsy case for each case in the config and for each case type for the specified case.
                     // then run ingest for the case.
-                    Case autopsyCase = runIngest(caseConfig, caseType);
+                    Case autopsyCase = runIngest(config, caseConfig, caseType);
                     if (autopsyCase == null || autopsyCase != Case.getCurrentCase()) {
                         logger.log(Level.WARNING,
                                 String.format("Case was not properly ingested or setup correctly for environment.  Case is %s and current case is %s.",
@@ -135,11 +138,12 @@ public void runIntegrationTests() {
     /**
      * Create a case and run ingest with the current case.
      *
+     * @param config The overall configuration.
      * @param caseConfig The configuration for the case.
      * @param caseType The type of case.
      * @return The currently open case after ingest.
      */
-    private Case runIngest(CaseConfig caseConfig, CaseType caseType) {
+    private Case runIngest(IntegrationTestConfig config, CaseConfig caseConfig, CaseType caseType) {
         Case openCase = null;
         switch (caseType) {
             case SINGLE_USER_CASE:
@@ -156,11 +160,11 @@ private Case runIngest(CaseConfig caseConfig, CaseType caseType) {
             return null;
         }
 
-        addDataSourcesToCase(caseConfig.getDataSourceResources(), caseConfig.getCaseName());
+        addDataSourcesToCase(PathUtil.getAbsolutePaths(config.getWorkingDirectory(), caseConfig.getDataSourceResources()), caseConfig.getCaseName());
         
         
         try {
-            IngestJobSettings ingestJobSettings = SETUP_UTIL.setupEnvironment(caseConfig);
+            IngestJobSettings ingestJobSettings = SETUP_UTIL.setupEnvironment(config, caseConfig);
             IngestUtils.runIngestJob(openCase.getDataSources(), ingestJobSettings);
         } catch (TskCoreException ex) {
             logger.log(Level.WARNING, String.format("There was an error while ingesting datasources for case %s", caseConfig.getCaseName()), ex);
@@ -203,8 +207,6 @@ private void addDataSourcesToCase(List<String> pathStrings, String caseName) {
      */
     private IntegrationTestConfig getConfigFromFile(String filePath) throws IOException {
         GsonBuilder builder = new GsonBuilder();
-        builder.registerTypeAdapter(IntegrationTestConfig.class,
-                IntegrationTestConfig.DESERIALIZER);
         Gson gson = builder.create();
         return gson.fromJson(new FileReader(new File(filePath)), IntegrationTestConfig.class);
     }
@@ -253,7 +255,12 @@ private void runIntegrationTests(IntegrationTestConfig config, CaseConfig caseCo
         }
 
         // write the results for the case to a file
-        serializeFile(results, config.getRootTestOutputPath(), caseConfig.getCaseName(), getCaseTypeId(caseType));
+        serializeFile(
+                results, 
+                PathUtil.getAbsolutePath(config.getWorkingDirectory(), config.getRootTestOutputPath()), 
+                caseConfig.getCaseName(), 
+                getCaseTypeId(caseType)
+        );
     }
 
     /**
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/PathUtil.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/PathUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..d00fd46fe296e8f18cce51a766e4729bae07e332
--- /dev/null
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/PathUtil.java
@@ -0,0 +1,55 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2020 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.integrationtesting;
+
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Retrieves absolute paths relative to a working directory.
+ */
+final class PathUtil {
+
+    static String getAbsolutePath(String workingDirectory, String relPath) {
+        if (StringUtils.isBlank(workingDirectory)) {
+            return relPath;
+        } else {
+            if (Paths.get(relPath).isAbsolute()) {
+                return relPath;
+            } else {
+                return Paths.get(workingDirectory, relPath).toString();   
+            }
+        }
+    }
+
+    static List<String> getAbsolutePaths(String workingDirectory, List<String> relPaths) {
+        if (relPaths == null) {
+            return null;
+        }
+        
+        return relPaths.stream()
+                .map((relPath) -> getAbsolutePath(workingDirectory, relPath))
+                .collect(Collectors.toList());
+    }
+
+    private PathUtil() {
+    }
+}
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/TestingConfig.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/TestingConfig.java
index 07b37718e827041eae671352aab998f74e790ecb..74d6d9cf84f02d2b1649b52db5aca8ba7843ed6e 100644
--- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/TestingConfig.java
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/TestingConfig.java
@@ -18,40 +18,29 @@
  */
 package org.sleuthkit.autopsy.integrationtesting;
 
-import java.util.Collections;
 import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * Configuration for which integration test suites to run.
  */
 public class TestingConfig {
 
-    private final Set<String> excludeAllExcept;
-    private final Set<String> includeAllExcept;
+    private final List<String> excludeAllExcept;
+    private final List<String> includeAllExcept;
 
-    private static Set<String> convert(List<String> orig) {
-        if (orig == null) {
-            return Collections.emptySet();
-        }
-
-        return orig.stream()
-                .map((item) -> item.toUpperCase())
-                .collect(Collectors.toSet());
-    }
 
     public TestingConfig(List<String> excludeAllExcept, List<String> includeAllExcept) {
-        this.excludeAllExcept = convert(excludeAllExcept);
-        this.includeAllExcept = convert(includeAllExcept);
+        this.excludeAllExcept = excludeAllExcept;
+        this.includeAllExcept = includeAllExcept;
     }
 
     /**
      * @return The test suites to be run. If not specified, getIncludeAllExcept
      *         will be used. If that is not specified, all tests will be run.
      */
-    public Set<String> getExcludeAllExcept() {
+    public List<String> getExcludeAllExcept() {
         return excludeAllExcept;
     }
 
@@ -60,7 +49,7 @@ public Set<String> getExcludeAllExcept() {
      *         getExcludeAllExcept will be used. If that is not specified, all
      *         tests will be run.
      */
-    public Set<String> getIncludeAllExcept() {
+    public List<String> getIncludeAllExcept() {
         return includeAllExcept;
     }
 
@@ -75,13 +64,13 @@ public boolean hasIncludedTest(String itemType) {
         }
 
         if (!CollectionUtils.isEmpty(includeAllExcept)) {
-            if (includeAllExcept.contains(itemType.toUpperCase())) {
+            if (includeAllExcept.stream().anyMatch((test) -> StringUtils.equalsIgnoreCase(test, itemType))) {
                 return false;
             }
         }
 
         if (!CollectionUtils.isEmpty(excludeAllExcept)) {
-            return excludeAllExcept.contains(itemType.toUpperCase());
+            return excludeAllExcept.stream().anyMatch((test) -> StringUtils.equalsIgnoreCase(test, itemType));
         }
 
         return true;
diff --git a/Tika/nbproject/project.properties b/Tika/nbproject/project.properties
index a13897ecd493e2cd3903aeb59e859d9b54f4fb31..3476473c2d16afd84f2b0983e3e323f8ca8797e9 100755
--- a/Tika/nbproject/project.properties
+++ b/Tika/nbproject/project.properties
@@ -15,7 +15,6 @@ file.reference.commons-compress-1.19.jar=release\\modules\\ext\\commons-compress
 file.reference.commons-csv-1.7.jar=release\\modules\\ext\\commons-csv-1.7.jar
 file.reference.commons-exec-1.3.jar=release\\modules\\ext\\commons-exec-1.3.jar
 file.reference.commons-io-2.6.jar=release\\modules\\ext\\commons-io-2.6.jar
-file.reference.commons-lang3-3.9.jar=release\\modules\\ext\\commons-lang3-3.9.jar
 file.reference.commons-math3-3.6.1.jar=release\\modules\\ext\\commons-math3-3.6.1.jar
 file.reference.curvesapi-1.06.jar=release\\modules\\ext\\curvesapi-1.06.jar
 file.reference.cxf-core-3.3.4.jar=release\\modules\\ext\\cxf-core-3.3.4.jar
diff --git a/Tika/nbproject/project.xml b/Tika/nbproject/project.xml
index 6b56417a15ee60b7df8780339dcdd4d79c19fe01..a3d37f12515d8f97449f944fb1a7474258f0498a 100755
--- a/Tika/nbproject/project.xml
+++ b/Tika/nbproject/project.xml
@@ -522,10 +522,6 @@
                 <runtime-relative-path>ext/ehcache-core-2.6.2.jar</runtime-relative-path>
                 <binary-origin>release\modules\ext\ehcache-core-2.6.2.jar</binary-origin>
             </class-path-extension>
-            <class-path-extension>
-                <runtime-relative-path>ext/commons-lang3-3.9.jar</runtime-relative-path>
-                <binary-origin>release\modules\ext\commons-lang3-3.9.jar</binary-origin>
-            </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/dec-0.1.2.jar</runtime-relative-path>
                 <binary-origin>release\modules\ext\dec-0.1.2.jar</binary-origin>
diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml
index 6643e72e0a6806340b57caf42e754fdc545cbdd9..4c32aa38610912759b22fe89d0b5a575eccf7fa8 100644
--- a/thunderbirdparser/nbproject/project.xml
+++ b/thunderbirdparser/nbproject/project.xml
@@ -56,6 +56,15 @@
                         <specification-version>10.22</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>3</release-version>
+                        <specification-version>1.4</specification-version>
+                    </run-dependency>
+                </dependency>
                 <dependency>
                     <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
                     <build-prerequisite/>
@@ -67,10 +76,6 @@
                 </dependency>
             </module-dependencies>
             <public-packages/>
-            <class-path-extension>
-                <runtime-relative-path>ext/commons-lang3-3.8.1.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/commons-lang3-3.8.1.jar</binary-origin>
-            </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/apache-mime4j-mbox-iterator-0.8.0-SNAPSHOT.jar</runtime-relative-path>
                 <binary-origin>release/modules/ext/apache-mime4j-mbox-iterator-0.8.0-SNAPSHOT.jar</binary-origin>