diff --git a/build.gradle b/build.gradle
index 5c60b176..f45c065e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2246,6 +2246,8 @@ task gitTagRelease(type: Exec) {
 //   - Conflicting dependencies
 //   - FAT ABI vs. single ABI selection
 
+// TODO: Build and run NUnit tests for #602
+
 // TODO: iOS Resolver tests (on OSX only)
 // - Import plugin test Cocoapods bootstrap
 // - Pod specification, with reflection & XML, validate both are present in the
diff --git a/source/AndroidResolver/src/PlayServicesResolver.cs b/source/AndroidResolver/src/PlayServicesResolver.cs
index bbfb5ead..5353a4a1 100644
--- a/source/AndroidResolver/src/PlayServicesResolver.cs
+++ b/source/AndroidResolver/src/PlayServicesResolver.cs
@@ -18,6 +18,7 @@ namespace GooglePlayServices {
     using System;
     using System.Collections.Generic;
     using System.IO;
+    using System.Linq;
     using System.Text.RegularExpressions;
     using System.Threading;
     using System.Xml;
@@ -992,7 +993,7 @@ private static bool Initialize() {
             }
 
             // Monitor Android dependency XML files to perform auto-resolution.
-            AddAutoResolutionFilePatterns(xmlDependencies.fileRegularExpressions);
+            autoResolveFilePatterns.Add(XmlDependencies.IsDependenciesFile);
 
             svcSupport = PlayServicesSupport.CreateInstance(
                 "PlayServicesResolver",
@@ -1079,7 +1080,7 @@ internal static void Log(string message, Google.LogLevel level = LogLevel.Info)
         /// 
         /// Patterns of files that are monitored to trigger auto resolution.
         /// 
-        private static HashSet autoResolveFilePatterns = new HashSet();
+        private static HashSet> autoResolveFilePatterns = new HashSet>();
 
         /// 
         /// Add file patterns to monitor to trigger auto resolution.
@@ -1087,7 +1088,8 @@ internal static void Log(string message, Google.LogLevel level = LogLevel.Info)
         /// Set of file patterns to monitor to trigger auto
         /// resolution.
         public static void AddAutoResolutionFilePatterns(IEnumerable patterns) {
-            autoResolveFilePatterns.UnionWith(patterns);
+            // Only regex patterns are supported in the public API, but a more performant default is used internally.
+            autoResolveFilePatterns.UnionWith(patterns.Select>(p => p.IsMatch));
         }
 
         /// 
@@ -1099,7 +1101,7 @@ private static bool CheckFilesForAutoResolution(HashSet filesToCheck) {
             bool resolve = false;
             foreach (var asset in filesToCheck) {
                 foreach (var pattern in autoResolveFilePatterns) {
-                    if (pattern.Match(asset).Success) {
+                    if (pattern.Invoke(asset)) {
                         Log(String.Format("Found asset {0} matching {1}, attempting " +
                                           "auto-resolution.",
                                           asset, pattern.ToString()),
diff --git a/source/AndroidResolver/src/XmlDependencies.cs b/source/AndroidResolver/src/XmlDependencies.cs
index 24a02594..d0ea5bf5 100644
--- a/source/AndroidResolver/src/XmlDependencies.cs
+++ b/source/AndroidResolver/src/XmlDependencies.cs
@@ -28,14 +28,6 @@ namespace GooglePlayServices {
     /// 
     internal class XmlDependencies {
 
-        /// 
-        /// Set of regular expressions that match files which contain dependency
-        /// specifications.
-        /// 
-        internal HashSet fileRegularExpressions = new HashSet {
-            new Regex(@".*[/\\]Editor[/\\].*Dependencies\.xml$")
-        };
-
         /// 
         /// Human readable name for dependency files managed by this class.
         /// 
@@ -44,15 +36,13 @@ internal class XmlDependencies {
         /// 
         /// Determines whether a filename matches an XML dependencies file.
         /// 
-        /// 
         /// true if it is a match, false otherwise.
-        internal bool IsDependenciesFile(string filename) {
-            foreach (var regex in fileRegularExpressions) {
-                if (regex.Match(filename).Success) {
-                    return true;
-                }
+        internal static bool IsDependenciesFile(string filename) {
+            if (!filename.EndsWith("Dependencies.xml")) {
+                return false;
             }
-            return false;
+            // This method was optimized to avoid using regex after profiling results from a large Unity project.
+            return filename.Contains("/Editor/") || filename.Contains(@"\Editor\");
         }
 
         /// 
diff --git a/source/AndroidResolver/unit_tests/AndroidResolverTests.csproj b/source/AndroidResolver/unit_tests/AndroidResolverTests.csproj
new file mode 100644
index 00000000..d4df5848
--- /dev/null
+++ b/source/AndroidResolver/unit_tests/AndroidResolverTests.csproj
@@ -0,0 +1,61 @@
+
+
+	
+	
+		Debug
+		AnyCPU
+		{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}
+		{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+		Library
+		Properties
+		Google
+		Google.AndroidResolverTests
+		v3.5
+		512
+	
+	
+		AnyCPU
+		true
+		full
+		false
+		bin\Debug\
+		DEBUG;TRACE
+		prompt
+		4
+	
+	
+		AnyCPU
+		pdbonly
+		true
+		bin\Release\
+		TRACE
+		prompt
+		4
+	
+	
+		
+		
+		
+		
+		
+	
+	
+		
+		
+	
+	
+	  
+	    {82eedfbe-afe4-4def-99d9-bc929747dd9a}
+	    AndroidResolver
+	  
+	
+	
+	
+
+
diff --git a/source/AndroidResolver/unit_tests/Properties/AssemblyInfo.cs b/source/AndroidResolver/unit_tests/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..db9ba593
--- /dev/null
+++ b/source/AndroidResolver/unit_tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("AndroidResolverTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("AndroidResolverTests")]
+[assembly: AssemblyCopyright("Copyright ©  2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("12F40968-4B80-4DCF-8D51-4C8E06F9CC4B")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/source/AndroidResolver/unit_tests/XmlDependenciesTests.cs b/source/AndroidResolver/unit_tests/XmlDependenciesTests.cs
new file mode 100644
index 00000000..f71d880e
--- /dev/null
+++ b/source/AndroidResolver/unit_tests/XmlDependenciesTests.cs
@@ -0,0 +1,28 @@
+using System.Text.RegularExpressions;
+
+namespace GooglePlayServices.Tests {
+	using System;
+	using NUnit.Framework;
+
+	[TestFixture]
+	public class XmlDependenciesTests
+	{
+		[TestCase("Assets/Editor/Dependencies.xml")]
+		[TestCase("Assets/Editor/MyFolder/Dependencies.xml")]
+		[TestCase("Editor/Dependencies.xml")]
+		[TestCase("Editor/MyFolder/Dependencies.xml")]
+		[TestCase("Assets/Editor/SomeDependencies.xml")]
+		[TestCase("Assets/MyEditorCode/Dependencies.xml")]
+		[TestCase("Assets/MyEditorCode/SomeDependencies.xml")]
+		[TestCase("Assets/Editor/")]
+		[TestCase("Assets/Editor/Dependendencies")]
+		public void IsDependenciesFileReturnsExpected(string path) {
+			bool actualResult = XmlDependencies.IsDependenciesFile(path);
+
+			// This was the previous implementation before the optimization attempt and acts as a test reference.
+			bool expectedResult = Regex.IsMatch(input: path, pattern: @".*[/\\]Editor[/\\].*Dependencies\.xml$");
+
+			Assert.AreEqual(expectedResult, actualResult);
+		}
+	}
+}
\ No newline at end of file
diff --git a/source/AndroidResolver/unit_tests/packages.config b/source/AndroidResolver/unit_tests/packages.config
new file mode 100644
index 00000000..ad37a528
--- /dev/null
+++ b/source/AndroidResolver/unit_tests/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/source/ExternalDependencyManager.sln b/source/ExternalDependencyManager.sln
index 9dda1103..2702c081 100644
--- a/source/ExternalDependencyManager.sln
+++ b/source/ExternalDependencyManager.sln
@@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageManagerClientIntegra
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageMigratorIntegrationTests", "PackageManagerResolver\test\PackageMigratorIntegrationTests.csproj", "{4DBDEE33-4B6C-A866-93FE-04C15486BB03}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidResolverTests", "AndroidResolver\unit_tests\AndroidResolverTests.csproj", "{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -85,5 +87,9 @@ Global
 		{4DBDEE33-4B6C-A866-93FE-04C15486BB03}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4DBDEE33-4B6C-A866-93FE-04C15486BB03}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{4DBDEE33-4B6C-A866-93FE-04C15486BB03}.Release|Any CPU.Build.0 = Release|Any CPU
+		{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{12F40968-4B80-4DCF-8D51-4C8E06F9CC4B}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 EndGlobal
diff --git a/source/IOSResolver/src/IOSResolver.cs b/source/IOSResolver/src/IOSResolver.cs
index ab6c2cf1..d1311909 100644
--- a/source/IOSResolver/src/IOSResolver.cs
+++ b/source/IOSResolver/src/IOSResolver.cs
@@ -1939,7 +1939,7 @@ private static void OnPostprocessAllAssets(string[] importedAssets,
         var changedAssets = new List(importedAssets);
         changedAssets.AddRange(deletedAssets);
         foreach (var asset in changedAssets) {
-            dependencyFileChanged = xmlDependencies.IsDependenciesFile(asset);
+            dependencyFileChanged = XmlDependencies.IsDependenciesFile(asset);
             if (dependencyFileChanged) break;
         }
         if (dependencyFileChanged) RefreshXmlDependencies();