Basic start on support for prepositions.
Basic start on support for prepositions.

--- a/EVAManager.cs
+++ b/EVAManager.cs
@@ -29,6 +29,7 @@
 using System.Linq;
 using System.Text.RegularExpressions;
 using ToadicusTools;
+using ToadicusTools.Extensions;
 using UnityEngine;
 
 namespace EVAManager
@@ -36,15 +37,18 @@
 	[KSPAddon(KSPAddon.Startup.MainMenu, true)]
 	public class EVAManager : MonoBehaviour
 	{
-		private const string patchPattern = @"^((DELETE|EDIT)_)?EVA_([a-zA-Z_]+)(\[(.+)\])?";
+		private const string patchPattern = @"^((DELETE|EDIT)_)?EVA_([a-zA-Z_]+)(\[(.+)\])?(\:([a-zA-Z]+)\[(.+)\])?";
 		private const int operatorIdx = 2;
 		private const int classIdx = 3;
 		private const int nameIdx = 5;
+		private const int prepositionIdx = 7;
+		private const int conditionIdx = 8;
 
 		private const string empty = "";
 
 		private const string MODULE = "MODULE";
 		private const string RESOURCE = "RESOURCE";
+		private const string WHERE = "WHERE";
 
 		private List<ConfigAction> evaConfigs;
 		private List<ConfigAction> passQueue;
@@ -68,7 +72,7 @@
 			}
 
 			#if DEBUG
-			Tools.DebugLogger log;
+			Logging.DebugLogger log;
 			#endif
 
 			if (this.passQueue.Count > 0 && this.evaConfigs != null)
@@ -86,7 +90,7 @@
 					AvailablePart loadedPart;
 					for (int idx = 0; idx < PartLoader.LoadedPartsList.Count; idx++)
 					{
-						loadedPart = PartLoader.LoadedPartsList[operatorIdx];
+						loadedPart = PartLoader.LoadedPartsList[idx];
 						string lowerName = loadedPart.name.ToLower();
 
 						if (lowerName == "kerbaleva" || lowerName == "kerbalevafemale")
@@ -96,7 +100,7 @@
 							evaParts.Add(loadedPart.partPrefab);
 
 							#if DEBUG
-							log = Tools.DebugLogger.New(this);
+							log = Logging.DebugLogger.New(this);
 
 							log.AppendLine("Modules before run:");
 
@@ -136,7 +140,7 @@
 					while (enumerator.MoveNext())
 					{
 						urlConfig = enumerator.Current;
-						Tools.PostDebugMessage(
+						Logging.PostDebugMessage(
 							this,
 							"Checking urlconfig; name: {0}, type: {1}, config.name: {2}",
 							urlConfig.name,
@@ -175,7 +179,7 @@
 						{
 							this.LogDebug("Trying delete action on {0}", action);
 
-							if (action.MatchName == string.Empty)
+							if (action.MatchName == empty)
 							{
 								this.LogWarning("Match name required for 'delete' action but not present; ignoring.");
 								continue;
@@ -209,7 +213,7 @@
 						{
 							this.LogDebug("Trying edit action on {0}", action);
 
-							if (action.MatchName == string.Empty)
+							if (action.MatchName == empty)
 							{
 								this.LogWarning("Match name required for 'edit' action but not present; ignoring.");
 								continue;
@@ -240,7 +244,7 @@
 						action = this.evaConfigs[idx];
 						if (action.Operator == empty)
 						{
-							if (action.MatchName != string.Empty)
+							if (action.MatchName != empty)
 							{
 								this.LogWarning("match name ('{0}') not used for 'add' action; ignoring.",
 									action.MatchName);
@@ -267,7 +271,7 @@
 					break;
 				case Pass.Done:
 					#if DEBUG
-					log = Tools.DebugLogger.New(this);
+					log = Logging.DebugLogger.New(this);
 
 					log.AppendLine("Modules after run:");
 
@@ -304,11 +308,11 @@
 
 			if (evaModuleNode.TryGetValue("name", out moduleName))
 			{
-				if (evaPart.GetComponents<PartModule>().Any(m => m.GetType().Name == moduleName))
-				{
-					this.LogWarning("Skipping module {1}: already present in kerbalEVA", moduleName);
+				/*if (evaPart.GetComponents<PartModule>().Any(m => m.GetType().Name == moduleName))
+				{
+					this.LogWarning("Skipping module {0}: already present in kerbalEVA", moduleName);
 					return;
-				}
+				}*/
 
 				Type moduleClass = AssemblyLoader.GetClassByName(typeof(PartModule), moduleName);
 
@@ -334,7 +338,8 @@
 				}
 				catch (Exception ex)
 				{
-					this.LogError("Handled exception {0} while adding modules to kerbalEVA.", ex.GetType().Name);
+					this.LogError("Handled exception {0} while adding modules to {1}.",
+						ex.GetType().Name, evaPart);
 
 					#if DEBUG
 					Debug.LogException(ex);
@@ -343,11 +348,11 @@
 
 				if (evaPart.GetComponents<PartModule>().Any(m => m.GetType().Name == moduleName))
 				{
-					this.Log("Added module {0} to kerbalEVA part.",	moduleName);
+					this.Log("Added module {0} to {1}.", moduleName, evaPart);
 				}
 				else
 				{
-					this.LogWarning("Failed to add {0} to kerbalEVA part.", moduleName);
+					this.LogWarning("Failed to add {0} to {1}.", moduleName, evaPart);
 				}
 			}
 			else
@@ -393,7 +398,7 @@
 				resource.SetInfo(resourceInfo);
 				((EVAPartResource)resource).Load(evaResourceNode);
 
-				this.Log("Added resource {0} to kerbalEVA part.", resource.resourceName);
+				this.Log("Added resource {0} to {1}", resource.resourceName, evaPart);
 
 				this.LogDebug("Resource '{0}' loaded.", resourceName);
 			}
@@ -410,7 +415,10 @@
 
 			if (module != null)
 			{
-				GameObject.Destroy(module);
+				evaPart.Modules.Remove(module);
+				GameObject.DestroyImmediate(module);
+
+				this.Log("Removed module {0} from {1} and marked for destruction.", matchName, evaPart);
 			}
 		}
 
@@ -420,12 +428,10 @@
 
 			if (resource != null)
 			{
+				evaPart.Resources.list.Remove(resource);
 				GameObject.Destroy(resource);
 
-				Tools.PostDebugMessage(
-					this,
-					"EVA resource {0} marked for destruction.",
-					resource.resourceName);
+				this.Log("Removed resource {0} from {1} and marked for destruction.", matchName, evaPart);
 			}
 		}
 
@@ -447,7 +453,7 @@
 
 					this.passQueue.Add(copyAction);
 
-					Tools.PostDebugMessage(
+					Logging.PostDebugMessage(
 						this,
 						"EVA module {0} marked for insertion\n(action: {1})",
 						config.GetValue("name"),
@@ -479,7 +485,7 @@
 
 					this.passQueue.Add(copyAction);
 
-					Tools.PostDebugMessage(
+					Logging.PostDebugMessage(
 						this,
 						"EVA resource {0} marked for insertion\n(action: {1})",
 						config.GetValue("name"),
@@ -524,7 +530,7 @@
 				resource = resources[idx];
 				Match match = rgx.Match(resource.resourceName);
 
-				Tools.PostDebugMessage(
+				Logging.PostDebugMessage(
 					this,
 					"EVA resource {0} is {1}a match for action.",
 					resource.resourceName,

--- a/EVAManager.csproj
+++ b/EVAManager.csproj
@@ -82,12 +82,45 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="EVAManager.cs" />
-    <Compile Include="..\ToadicusTools\Tools.cs">
-      <Link>Tools.cs</Link>
+    <Compile Include="EVAPartResource.cs" />
+    <Compile Include="..\ToadicusTools\Extensions\ComponentExtensions.cs">
+      <Link>ToadicusTools\ComponentExtensions.cs</Link>
     </Compile>
-    <Compile Include="EVAPartResource.cs" />
-    <Compile Include="..\ToadicusTools\ConfigNodeExtensions.cs">
-      <Link>ConfigNodeExtensions.cs</Link>
+    <Compile Include="..\ToadicusTools\Enums.cs">
+      <Link>ToadicusTools\Enums.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Text\Extensions.cs">
+      <Link>ToadicusTools\Extensions.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Logging.cs">
+      <Link>ToadicusTools\Logging.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\MathTools.cs">
+      <Link>ToadicusTools\MathTools.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\MuMechTools\MuMech_Tools.cs">
+      <Link>ToadicusTools\MuMech_Tools.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Extensions\PartExtensions.cs">
+      <Link>ToadicusTools\PartExtensions.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Debug\PooledDebugLogger.cs">
+      <Link>ToadicusTools\PooledDebugLogger.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\APIHelpers\PooledObject.cs">
+      <Link>ToadicusTools\PooledObject.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Text\PooledStringBuilder.cs">
+      <Link>ToadicusTools\PooledStringBuilder.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Text\SIFormatProvider.cs">
+      <Link>ToadicusTools\SIFormatProvider.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Text\TextTools.cs">
+      <Link>ToadicusTools\TextTools.cs</Link>
+    </Compile>
+    <Compile Include="..\ToadicusTools\Extensions\ConfigNodeExtensions.cs">
+      <Link>ToadicusTools\ConfigNodeExtensions.cs</Link>
     </Compile>
   </ItemGroup>
   <ProjectExtensions>
@@ -101,6 +134,7 @@
   </ProjectExtensions>
   <ItemGroup>
     <Folder Include="GameData\EVAManager\" />
+    <Folder Include="ToadicusTools\" />
   </ItemGroup>
   <ItemGroup>
     <None Include="GameData\EVAManager\EVAManager.cfg.example" />

--- a/EVAPartResource.cs
+++ b/EVAPartResource.cs
@@ -26,6 +26,7 @@
 using KSP;
 using System;
 using ToadicusTools;
+using ToadicusTools.Extensions;
 using UnityEngine;
 
 namespace EVAManager
@@ -49,7 +50,7 @@
 
 				baseAwake.Invoke(this, null);
 
-				Tools.PostDebugMessage(this, "base Awake.");
+				Logging.PostDebugMessage(this, "base Awake.");
 			}
 			#if DEBUG
 			catch (Exception ex)
@@ -69,7 +70,7 @@
 			GameEvents.onCrewOnEva.Add(this.onEvaHandler);
 			GameEvents.onCrewBoardVessel.Add(this.onBoardHandler);
 
-			Tools.PostDebugMessage(this, "Awake");
+			Logging.PostDebugMessage(this, "Awake");
 		}
 
 		public void OnDestroy()
@@ -84,7 +85,7 @@
 
 			this.FillFromPod = node.GetValue("FillFromPod", this.FillFromPod);
 
-			Tools.PostDebugMessage(this, "Loaded.");
+			Logging.PostDebugMessage(this, "Loaded.");
 		}
 
 		public new void Save(ConfigNode node)
@@ -100,7 +101,7 @@
 				node.AddValue("FillFromPod", this.FillFromPod.ToString());
 			}
 
-			Tools.PostDebugMessage(this, "Saved.");
+			Logging.PostDebugMessage(this, "Saved.");
 		}
 
 		private void onEvaHandler(GameEvents.FromToAction<Part, Part> data)
@@ -128,7 +129,7 @@
 
 					this.amount += gotAmount;
 
-					Tools.PostDebugMessage(this, "Filled {0} {1} from {2}",
+					Logging.PostDebugMessage(this, "Filled {0} {1} from {2}",
 						gotAmount,
 						this.resourceName,
 						data.to.partInfo.title
@@ -155,7 +156,7 @@
 
 					this.amount += sentAmount;
 
-					Tools.PostDebugMessage(this, "Returned {0} {1} to {2}",
+					Logging.PostDebugMessage(this, "Returned {0} {1} to {2}",
 						-sentAmount,
 						this.resourceName,
 						data.to.partInfo.title