Tweaks to OnGUI and OnPostRender per sarbian's recommendation.
Tweaks to OnGUI and OnPostRender per sarbian's recommendation.

--- a/API/IVOID_Module.cs
+++ b/API/IVOID_Module.cs
@@ -38,15 +38,16 @@
 		bool InValidScene { get; }
 		bool InValidGame { get; }
 
-		void DrawGUI();
+		void DrawGUI(object sender);
 		void StartGUI();
 		void StopGUI();
 
 		void DrawConfigurables();
 
-		void LoadConfig();
+		// void LoadConfig();
+		void LoadConfig(KSP.IO.PluginConfiguration config);
 
-		void Save(KSP.IO.PluginConfiguration config);
+		void Save(KSP.IO.PluginConfiguration config, string sceneKey);
 	}
 
 	public interface IVOID_BehaviorModule : IVOID_Module

--- a/API/VOIDCore.cs
+++ b/API/VOIDCore.cs
@@ -29,8 +29,8 @@
 using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
+using System.Linq;
 using System.Collections.Generic;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -42,6 +42,11 @@
 
 		public abstract int ConfigVersion { get; }
 		public virtual bool configNeedsUpdate { get; set; }
+
+		public virtual string SaveGamePath { get; protected set; }
+		public virtual string VOIDSettingsPath { get; protected set; }
+
+		public abstract string SceneKey { get; }
 
 		public abstract int WindowID { get; }
 		public abstract bool configDirty { get; set; }
@@ -57,7 +62,6 @@
 		public abstract GUISkin Skin { get; }
 
 		public abstract CelestialBody HomeBody { get; }
-		public abstract IList<CelestialBody> AllBodies { get; }
 		public abstract List<CelestialBody> SortedBodyList { get; protected set; }
 
 		public abstract VesselType[] AllVesselTypes { get; protected set; }
@@ -68,19 +72,37 @@
 
 		public abstract event VOIDEventHandler onApplicationQuit;
 		public abstract event VOIDEventHandler onSkinChanged;
+		public abstract event VOIDEventHandler onUpdate;
+		public virtual event VOIDEventHandler onPostRender;
+		public virtual event VOIDEventHandler onPreRender;
 
-		public virtual void OnGUI() {}
+		public virtual bool MethodInPostRenderQueue(VOIDEventHandler method)
+		{
+			if (this.onPostRender != null)
+			{
+				ToadicusTools.Logging.PostDebugMessage(this, "Looking for method {0} in onGui", method);
 
-		public override void LoadConfig()
-		{
-			base.LoadConfig();
+				foreach (var invoker in this.onPostRender.GetInvocationList())
+				{
+					ToadicusTools.Logging.PostDebugMessage(this, "Checking invoker {0}", invoker);
+
+					if (invoker == method)
+					{
+						return true;
+					}
+				}
+			}
+
+			return false;
 		}
+
+		public abstract void OnGUI();
 
 		public abstract void SaveConfig();
 
-		public override void Save(KSP.IO.PluginConfiguration config)
+		public override void Save(KSP.IO.PluginConfiguration config, string sceneKey)
 		{
-			base.Save(config);
+			base.Save(config, sceneKey);
 		}
 	}
 

--- a/API/VOIDMaster.cs
+++ b/API/VOIDMaster.cs
@@ -43,7 +43,7 @@
 using System;
 using UnityEngine;
 using KerbalEngineer.VesselSimulator;
-using ToadicusTools;
+using ToadicusTools.Extensions;
 
 namespace VOID
 {
@@ -80,6 +80,8 @@
 				this.LogDebug("Factory reset is true; deleting config and disposing!");
 
 				KSP.IO.File.Delete<T>("config.xml");
+				System.IO.File.Delete(this.Core.VOIDSettingsPath);
+
 				this.Core.Dispose();
 				this.Core = null;
 			}
@@ -127,8 +129,11 @@
 
 		protected virtual bool InValidScene()
 		{
-			foreach (var attr in this.GetType().GetCustomAttributes(true))
+			object[] attributes = this.GetType().GetCustomAttributes(true);
+			object attr;
+			for (int idx = 0; idx < attributes.Length; idx++)
 			{
+				attr = attributes[idx];
 				if (attr is KSPAddon)
 				{
 					KSPAddon addonAttr = (KSPAddon)attr;

--- a/API/VOID_HUDModule.cs
+++ b/API/VOID_HUDModule.cs
@@ -31,7 +31,7 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
-using ToadicusTools;
+using ToadicusTools.GUIUtils;
 using UnityEngine;
 
 namespace VOID
@@ -91,7 +91,7 @@
 			this.Windows = new List<HUDWindow>();
 		}
 
-		public override void DrawGUI()
+		public override void DrawGUI(object sender)
 		{
 			VOID_Styles.labelHud.normal.textColor = textColors [ColorIndex];
 
@@ -104,8 +104,11 @@
 				SimManager.RequestSimulation();
 			}
 
-			foreach (HUDWindow window in this.Windows)
-			{
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				window.WindowPos = GUILayout.Window(
 					this.core.WindowID,
 					window.WindowPos,
@@ -127,24 +130,29 @@
 
 			if (GUILayout.Button(string.Intern("Reset HUD Positions"), GUILayout.ExpandWidth(false)))
 			{
-				foreach (HUDWindow window in this.Windows)
+				HUDWindow window;
+				for (int idx = 0; idx < this.Windows.Count; idx++)
 				{
+					window = this.Windows[idx];
+
 					window.WindowPos = new Rect(window.defaultWindowPos);
 				}
 			}
 
-			this.positionsLocked.value = GUITools.Toggle(this.positionsLocked, "Lock HUD Positions");
-		}
-
-		public override void LoadConfig()
-		{
-			base.LoadConfig();
-
-			var config = KSP.IO.PluginConfiguration.CreateForType<VOID_HUDModule>();
+			this.positionsLocked.value = Layout.Toggle(this.positionsLocked, "Lock HUD Positions");
+		}
+
+		public override void LoadConfig(KSP.IO.PluginConfiguration config)
+		{
+			base.LoadConfig(config);
+
 			config.load();
 
-			foreach (HUDWindow window in this.Windows)
-			{
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				string saveName = string.Format("{0}_{1}", this.GetType().Name, window.WindowName);
 				Rect loadedPos = config.GetValue(saveName, window.defaultWindowPos);
 
@@ -152,12 +160,15 @@
 			}
 		}
 
-		public override void Save(KSP.IO.PluginConfiguration config)
-		{
-			base.Save(config);
-
-			foreach (HUDWindow window in this.Windows)
-			{
+		public override void Save(KSP.IO.PluginConfiguration config, string sceneKey)
+		{
+			base.Save(config, sceneKey);
+
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				string saveName = string.Format("{0}_{1}", this.GetType().Name, window.WindowName);
 				config.SetValue(saveName, window.WindowPos);
 			}

--- a/API/VOID_Module.cs
+++ b/API/VOID_Module.cs
@@ -26,11 +26,13 @@
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// TODO: Remove ToadicusTools. prefixes after refactor is done.
+
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Reflection;
-using ToadicusTools;
+using ToadicusTools.Extensions;
+using ToadicusTools.GUIUtils;
 using UnityEngine;
 
 namespace VOID
@@ -68,7 +70,7 @@
 		{
 			get
 			{
-				if (
+				/*if (
 					RenderingManager.fetch == null ||
 					RenderingManager.fetch.postDrawQueue == null ||
 					RenderingManager.fetch.postDrawQueue.Length < 4
@@ -85,7 +87,8 @@
 					}
 
 					return callback.GetInvocationList().Contains((Callback)this.DrawGUI);
-				}
+				}*/
+				return this.core != null && this.core.MethodInPostRenderQueue(this.DrawGUI);
 			}
 		}
 
@@ -117,16 +120,21 @@
 			{
 				if (this.validModes == null)
 				{
-					Tools.PostDebugMessage(this, "validModes is null when checking inValidGame; fetching attribute.");
-					foreach (var attr in this.GetType().GetCustomAttributes(false))
+					ToadicusTools.Logging.PostDebugMessage(this, "validModes is null when checking inValidGame; fetching attribute.");
+
+					object[] attributes = this.GetType().GetCustomAttributes(false);
+					object attr;
+					for (int idx = 0; idx < attributes.Length; idx++)
 					{
+						attr = attributes[idx];
+
 						if (attr is VOID_GameModesAttribute)
 						{
 							VOID_GameModesAttribute addonAttr = (VOID_GameModesAttribute)attr;
 
 							this.validModes = addonAttr.ValidModes;
 
-							Tools.PostDebugMessage("Found VOID_GameModesAttribute; validScenes set.");
+							ToadicusTools.Logging.PostDebugMessage("Found VOID_GameModesAttribute; validScenes set.");
 
 							break;
 						}
@@ -143,7 +151,7 @@
 							Game.Modes.SCIENCE_SANDBOX
 						};
 
-						Tools.PostDebugMessage("No VOID_GameModesAttribute found; validScenes defaulted to flight.");
+						ToadicusTools.Logging.PostDebugMessage("No VOID_GameModesAttribute found; validScenes defaulted to flight.");
 					}
 				}
 
@@ -157,16 +165,20 @@
 			{
 				if (this.validScenes == null)
 				{
-					Tools.PostDebugMessage(this, "validScenes is null when checking inValidScene; fetching attribute.");
-					foreach (var attr in this.GetType().GetCustomAttributes(false))
+					ToadicusTools.Logging.PostDebugMessage(this, "validScenes is null when checking inValidScene; fetching attribute.");
+					object[] attributes = this.GetType().GetCustomAttributes(false);
+					object attr;
+					for (int idx = 0; idx < attributes.Length; idx++)
 					{
+						attr = attributes[idx];
+
 						if (attr is VOID_ScenesAttribute)
 						{
 							VOID_ScenesAttribute addonAttr = (VOID_ScenesAttribute)attr;
 
 							this.validScenes = addonAttr.ValidScenes;
 
-							Tools.PostDebugMessage("Found VOID_ScenesAttribute; validScenes set.");
+							ToadicusTools.Logging.PostDebugMessage("Found VOID_ScenesAttribute; validScenes set.");
 
 							break;
 						}
@@ -175,7 +187,7 @@
 					if (this.validScenes == null)
 					{
 						this.validScenes = new GameScenes[] { GameScenes.FLIGHT };
-						Tools.PostDebugMessage("No VOID_ScenesAttribute found; validScenes defaulted to flight.");
+						ToadicusTools.Logging.PostDebugMessage("No VOID_ScenesAttribute found; validScenes defaulted to flight.");
 					}
 				}
 
@@ -220,8 +232,9 @@
 				return;
 			}
 
-			Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name));
-			RenderingManager.AddToPostDrawQueue (3, this.DrawGUI);
+			ToadicusTools.Logging.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name));
+			// RenderingManager.AddToPostDrawQueue (3, this.DrawGUI);
+			this.core.onPostRender += this.DrawGUI;
 		}
 
 		public virtual void StopGUI()
@@ -230,17 +243,16 @@
 			{
 				return;
 			}
-			Tools.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name));
-			RenderingManager.RemoveFromPostDrawQueue (3, this.DrawGUI);
-		}
-
-		public abstract void DrawGUI();
+			ToadicusTools.Logging.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name));
+			this.core.onPostRender -= this.DrawGUI;
+		}
+
+		public abstract void DrawGUI(object sender);
 
 		public virtual void DrawConfigurables() {}
 
-		public virtual void LoadConfig()
-		{
-			var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Module> ();
+		public virtual void LoadConfig(KSP.IO.PluginConfiguration config)
+		{
 			config.load ();
 
 			if (this is VOIDCore)
@@ -253,30 +265,40 @@
 				}
 			}
 
-			foreach (var field in this.GetType().GetMembers(
-				BindingFlags.NonPublic |
-				BindingFlags.Public |
-				BindingFlags.Instance |
-				BindingFlags.FlattenHierarchy
-			))
-			{
-				if (!(field is FieldInfo || field is PropertyInfo))
+			MemberInfo[] members = this.GetType().GetMembers(
+				                         BindingFlags.NonPublic |
+				                         BindingFlags.Public |
+				                         BindingFlags.Instance |
+				                         BindingFlags.FlattenHierarchy
+			                         );
+			MemberInfo member;
+
+			for (int fIdx = 0; fIdx < members.Length; fIdx++)
+			{
+				member = members[fIdx];
+
+				if (!(member is FieldInfo || member is PropertyInfo))
 				{
 					continue;
 				}
 
-				if (field is PropertyInfo && (field as PropertyInfo).GetIndexParameters().Length > 0)
+				if (member is PropertyInfo && (member as PropertyInfo).GetIndexParameters().Length > 0)
 				{
 					continue;
 				}
 
-				object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
-
-				if (attrs.Length == 0) {
+				object[] attrs = member.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+				AVOID_SaveValue attr;
+
+				if (attrs.Length > 0)
+				{
+					attr = (AVOID_SaveValue)attrs[0];
+				}
+				else
+				{
 					continue;
 				}
-
-				AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
 
 				string fieldName = string.Empty;
 
@@ -308,17 +330,17 @@
 					);
 				}
 
-				Tools.PostDebugMessage(string.Format("{0}: Loading field {1}.", this.GetType().Name, fieldName));
+				ToadicusTools.Logging.PostDebugMessage(string.Format("{0}: Loading field {1}.", this.GetType().Name, fieldName));
 
 				object fieldValue;
 
-				if (field is FieldInfo)
-				{
-					fieldValue = (field as FieldInfo).GetValue(this);
-				}
-				else
-				{
-					fieldValue = (field as PropertyInfo).GetValue(this, null);
+				if (member is FieldInfo)
+				{
+					fieldValue = (member as FieldInfo).GetValue(this);
+				}
+				else
+				{
+					fieldValue = (member as PropertyInfo).GetValue(this, null);
 				}
 
 				bool convertBack = false;
@@ -338,35 +360,61 @@
 					fieldValue = convertValue;
 				}
 
-				if (field is FieldInfo)
-				{
-					(field as FieldInfo).SetValue(this, fieldValue);
-				}
-				else
-				{
-					(field as PropertyInfo).SetValue(this, fieldValue, null);
-				}
-
-				Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
-			}
-		}
-
-		public virtual void Save(KSP.IO.PluginConfiguration config)
-		{
-			foreach (var field in this.GetType().GetMembers(
-				BindingFlags.Instance |
+				if (member is FieldInfo)
+				{
+					(member as FieldInfo).SetValue(this, fieldValue);
+				}
+				else
+				{
+					(member as PropertyInfo).SetValue(this, fieldValue, null);
+				}
+
+				ToadicusTools.Logging.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
+			}
+		}
+
+		public virtual void Save(KSP.IO.PluginConfiguration config, string sceneKey)
+		{
+			if (config == null)
+			{
+				ToadicusTools.Logging.PostErrorMessage(
+					"{0}: config argument was null, bailing out.",
+					this.GetType().Name
+				);
+			}
+
+			if (sceneKey == null)
+			{
+				ToadicusTools.Logging.PostErrorMessage(
+					"{0}: sceneKey argument was null, bailing out.",
+					this.GetType().Name
+				);
+			}
+
+			MemberInfo[] members = this.GetType().GetMembers(
 				BindingFlags.NonPublic |
 				BindingFlags.Public |
+				BindingFlags.Instance |
 				BindingFlags.FlattenHierarchy
-				))
-			{
-				object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
-
-				if (attrs.Length == 0) {
+			);
+			MemberInfo member;
+
+			for (int fIdx = 0; fIdx < members.Length; fIdx++)
+			{
+				member = members[fIdx];
+
+				object[] attrs = member.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+				AVOID_SaveValue attr;
+
+				if (attrs.Length > 0)
+				{
+					attr = (AVOID_SaveValue)attrs[0];
+				}
+				else
+				{
 					continue;
 				}
-
-				AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
 
 				string fieldName;
 
@@ -379,20 +427,20 @@
 					fieldName = string.Format(
 						"{0}_{1}_{2}",
 						this.GetType().Name,
-						Enum.GetName(typeof(GameScenes), HighLogic.LoadedScene),
+						sceneKey,
 						attr.Name
 					);
 				}
 
 				object fieldValue;
 
-				if (field is FieldInfo)
-				{
-					fieldValue = (field as FieldInfo).GetValue(this);
-				}
-				else
-				{
-					fieldValue = (field as PropertyInfo).GetValue(this, null);
+				if (member is FieldInfo)
+				{
+					fieldValue = (member as FieldInfo).GetValue(this);
+				}
+				else
+				{
+					fieldValue = (member as PropertyInfo).GetValue(this, null);
 				}
 
 				if (fieldValue is IVOID_SaveValue)
@@ -402,7 +450,7 @@
 
 				config.SetValue(fieldName, fieldValue);
 
-				Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName));
+				ToadicusTools.Logging.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName));
 			}
 		}
 	}
@@ -463,7 +511,7 @@
 			GUI.DragWindow();
 		}
 
-		public override void DrawGUI()
+		public override void DrawGUI(object sender)
 		{
 			GUI.skin = this.core.Skin;
 
@@ -491,11 +539,11 @@
 
 			if (HighLogic.LoadedSceneIsEditor)
 			{
-				_Pos = Tools.ClampRectToEditorPad(_Pos);
+				_Pos = WindowTools.ClampRectToEditorPad(_Pos);
 			}
 			else
 			{
-				_Pos = Tools.ClampRectToScreen(_Pos);
+				_Pos = WindowTools.ClampRectToScreen(_Pos);
 			}
 
 			if (_Pos != this.WindowPos)

--- a/API/VOID_SingletonCore.cs
+++ b/API/VOID_SingletonCore.cs
@@ -25,7 +25,9 @@
 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 using System;
+using UnityEngine;
 
 namespace VOID
 {

--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -39,10 +39,9 @@
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("0.18.1.*")]
+[assembly: AssemblyVersion("0.18.5.*")]
 // The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
 
-

--- a/Tools/VOID_DataValue.cs
+++ b/Tools/VOID_DataValue.cs
@@ -26,8 +26,11 @@
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// TODO: Remove ToadicusTools. prefixes after refactor is done.
+
 using System;
-using ToadicusTools;
+using ToadicusTools.MuMechTools;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -148,7 +151,7 @@
 	public abstract class VOID_NumValue<T> : VOID_DataValue<T>, IFormattable
 		where T : IFormattable, IConvertible, IComparable
 	{
-		public static IFormatProvider formatProvider = Tools.SIFormatter;
+		public static IFormatProvider formatProvider = SIFormatProvider.SIFormatter;
 
 		public static implicit operator Double(VOID_NumValue<T> v)
 		{
@@ -218,7 +221,7 @@
 		{
 			return string.Format (
 				"{0}{1}",
-				Tools.MuMech_ToSI (this, digits, MinMagnitude, MaxMagnitude),
+				MuMechTools.MuMech_ToSI (this, digits, MinMagnitude, MaxMagnitude),
 				this.Units
 			);
 		}
@@ -234,7 +237,7 @@
 
 		public virtual string ValueUnitString(int digits, int MinMagnitude, int MaxMagnitude)
 		{
-			return Tools.MuMech_ToSI(this, digits, MinMagnitude, MaxMagnitude) + this.Units;
+			return MuMechTools.MuMech_ToSI(this, digits, MinMagnitude, MaxMagnitude) + this.Units;
 		}
 
 		public virtual void DoGUIHorizontal(string format)
@@ -282,7 +285,7 @@
 				Rect lastRect = GUILayoutUtility.GetLastRect();
 				if (lastRect.Contains(Event.current.mousePosition))
 				{
-					Tools.PostDebugMessage(string.Format("{0}: Changing digits from {1}",
+					ToadicusTools.Logging.PostDebugMessage(string.Format("{0}: Changing digits from {1}",
 						this.GetType().Name,
 						digits
 					));
@@ -301,7 +304,7 @@
 						digits += 9;
 					}
 
-					Tools.PostDebugMessage(string.Format("{0}: Changed digits to {1}.",
+					ToadicusTools.Logging.PostDebugMessage(string.Format("{0}: Changed digits to {1}.",
 						this.GetType().Name,
 						digits
 					));
@@ -332,9 +335,9 @@
 		public VOID_StrValue(string Label, Func<string> ValueFunc) : base(Label, ValueFunc, "") {}
 	}
 
-	public class VOID_Vector3dValue : VOID_DataValue<Vector3d>
-	{
-		public VOID_Vector3dValue(string Label, Func<Vector3d> ValueFunc, string Units)
+	public class VOID_Vector3Value : VOID_DataValue<Vector3>
+	{
+		public VOID_Vector3Value(string Label, Func<Vector3> ValueFunc, string Units)
 			: base(Label, ValueFunc, Units)
 		{}
 

--- a/Tools/VOID_SaveValue.cs
+++ b/Tools/VOID_SaveValue.cs
@@ -26,10 +26,11 @@
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// TODO: Remove ToadicusTools. prefixes after refactor is done.
+
 using KSP;
 using System;
 using System.Collections.Generic;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -65,13 +66,11 @@
 			{
 				if (this.Core != null && !System.Object.Equals(this._value, value))
 				{
-					Tools.PostDebugMessage (string.Format (
+					ToadicusTools.Logging.PostDebugMessage (string.Format (
 						"VOID: Dirtying config for type {0}." +
-						"\n\t Old Value: {2}, New Value: {3}" +
-						"\n\t Object.Equals(New, Old): {4}\n" +
-						"{1}",
+						"\n\t Old Value: {1}, New Value: {2}" +
+						"\n\t Object.Equals(New, Old): {3}\n" +
 						this._type,
-						new System.Diagnostics.StackTrace().ToString(),
 						this._value,
 						value,
 						System.Object.Equals(this._value, value)

--- a/Tools/VOID_Tools.cs
+++ b/Tools/VOID_Tools.cs
@@ -335,21 +335,16 @@
 					{
 						func(id);
 					}
-					#if DEBUG
+					#if !DEBUG
 					catch (ArgumentException)
-					#else
-					catch (ArgumentException)
-					#endif
 					{
 						Debug.LogWarning(
-							string.Format("[{0}]: ArgumentException caught during window call.  This is not a bug.",
+							string.Format("[{0}]: ArgumentException caught during window call." +
+								"  This may not be a bug when occuring during scene changes.",
 								func.Target.GetType().Name
 							));
-
-						/*#if DEBUG
-						Debug.LogException(ex);
-						#endif*/
 					}
+					#endif
 					catch (Exception ex)
 					{
 						Debug.LogError(
@@ -709,8 +704,8 @@
 
 		public static double mrenigma03_calcphase(Vessel vessel, CelestialBody target)   //calculates phase angle between the current body and target body
 		{
-			Vector3d vecthis = new Vector3d();
-			Vector3d vectarget = new Vector3d();
+			Vector3 vecthis = new Vector3();
+			Vector3 vectarget = new Vector3();
 			vectarget = target.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
 
 			if ((vessel.mainBody.name == "Sun") || (vessel.mainBody.referenceBody.referenceBody.name == "Sun"))
@@ -722,15 +717,15 @@
 				vecthis = vessel.mainBody.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
 			}
 
-			vecthis = Vector3d.Project(new Vector3d(vecthis.x, 0, vecthis.z), vecthis);
-			vectarget = Vector3d.Project(new Vector3d(vectarget.x, 0, vectarget.z), vectarget);
-
-			Vector3d prograde = new Vector3d();
-			prograde = Quaternion.AngleAxis(90, Vector3d.forward) * vecthis;
-
-			double phase = Vector3d.Angle(vecthis, vectarget);
-
-			if (Vector3d.Angle(prograde, vectarget) > 90)
+			vecthis = Vector3.Project(new Vector3(vecthis.x, 0, vecthis.z), vecthis);
+			vectarget = Vector3.Project(new Vector3(vectarget.x, 0, vectarget.z), vectarget);
+
+			Vector3 prograde = new Vector3();
+			prograde = Quaternion.AngleAxis(90, Vector3.forward) * vecthis;
+
+			double phase = Vector3.Angle(vecthis, vectarget);
+
+			if (Vector3.Angle(prograde, vectarget) > 90)
 				phase = 360 - phase;
 
 			return (phase + 360) % 360;
@@ -1022,75 +1017,75 @@
 	{
 		public int Compare(CelestialBody bodyA, CelestialBody bodyB)
 		{
-			Tools.PostDebugMessage(this, "got bodyA: {0} & bodyB: {1}", bodyA, bodyB);
+			Logging.PostDebugMessage(this, "got bodyA: {0} & bodyB: {1}", bodyA, bodyB);
 
 			if (bodyA == null && bodyB == null)
 			{
-				Tools.PostDebugMessage(this, "both bodies are null, returning 0");
+				Logging.PostDebugMessage(this, "both bodies are null, returning 0");
 				return 0;
 			}
 			if (bodyA == null)
 			{
-				Tools.PostDebugMessage(this, "bodyA is null, returning -1");
+				Logging.PostDebugMessage(this, "bodyA is null, returning -1");
 				return -1;
 			}
 			if (bodyB == null)
 			{
-				Tools.PostDebugMessage(this, "bodyB is null, returning 1");
+				Logging.PostDebugMessage(this, "bodyB is null, returning 1");
 				return 1;
 			}
 
-			Tools.PostDebugMessage(this, "bodies are not null, carrying on");
+			Logging.PostDebugMessage(this, "bodies are not null, carrying on");
 
 			if (object.ReferenceEquals(bodyA, bodyB))
 			{
-				Tools.PostDebugMessage(this, "bodies are equal, returning 0");
+				Logging.PostDebugMessage(this, "bodies are equal, returning 0");
 				return 0;
 			}
 
-			Tools.PostDebugMessage(this, "bodies are not equal, carrying on");
+			Logging.PostDebugMessage(this, "bodies are not equal, carrying on");
 
 			if (bodyA.orbitDriver == null)
 			{
-				Tools.PostDebugMessage(this, "bodyA.orbit is null (bodyA is the sun, returning 1");
+				Logging.PostDebugMessage(this, "bodyA.orbit is null (bodyA is the sun, returning 1");
 				return 1;
 			}
 			if (bodyB.orbitDriver == null)
 			{
-				Tools.PostDebugMessage(this, "bodyB.orbit is null (bodyB is the sun, returning -1");
+				Logging.PostDebugMessage(this, "bodyB.orbit is null (bodyB is the sun, returning -1");
 				return -1;
 			}
 
-			Tools.PostDebugMessage(this, "orbits are not null, carrying on");
+			Logging.PostDebugMessage(this, "orbits are not null, carrying on");
 
 			if (bodyA.orbit.referenceBody == bodyB.orbit.referenceBody)
 			{
-				Tools.PostDebugMessage(this, "bodies share a parent, comparing SMAs");
+				Logging.PostDebugMessage(this, "bodies share a parent, comparing SMAs");
 				return -bodyA.orbit.semiMajorAxis.CompareTo(bodyB.orbit.semiMajorAxis);
 			}
 
-			Tools.PostDebugMessage(this, "orbits do not share a parent, carrying on");
+			Logging.PostDebugMessage(this, "orbits do not share a parent, carrying on");
 
 			if (bodyA.hasAncestor(bodyB))
 			{
-				Tools.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning -1");
+				Logging.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning -1");
 				return -1;
 			}
 			if (bodyB.hasAncestor(bodyA))
 			{
-				Tools.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning 1");
+				Logging.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning 1");
 				return 1;
 			}
 
-			Tools.PostDebugMessage(this, "bodies do not have an obvious relationship, searching for one");
+			Logging.PostDebugMessage(this, "bodies do not have an obvious relationship, searching for one");
 
 			if (VOID_Tools.NearestRelatedParents(ref bodyA, ref bodyB))
 			{
-				Tools.PostDebugMessage(this, "good relation {0} and {1}, comparing", bodyA.bodyName, bodyB.bodyName);
+				Logging.PostDebugMessage(this, "good relation {0} and {1}, comparing", bodyA.bodyName, bodyB.bodyName);
 				return this.Compare(bodyA, bodyB);
 			}
 
-			Tools.PostDebugMessage(this, "bad relation {0} and {1}, giving up", bodyA.bodyName, bodyB.bodyName);
+			Logging.PostDebugMessage(this, "bad relation {0} and {1}, giving up", bodyA.bodyName, bodyB.bodyName);
 
 			return 0;
 		}

--- a/VOID.csproj
+++ b/VOID.csproj
@@ -136,6 +136,15 @@
     <Reference Include="UnityEngine">
       <HintPath>..\_KSPAssemblies\UnityEngine.dll</HintPath>
     </Reference>
+    <Reference Include="KSPUtil">
+      <HintPath>..\_KSPAssemblies\KSPUtil.dll</HintPath>
+    </Reference>
+    <Reference Include="UnityEngine.UI">
+      <HintPath>..\_KSPAssemblies\UnityEngine.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="Assembly-CSharp-firstpass">
+      <HintPath>..\_KSPAssemblies\Assembly-CSharp-firstpass.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\ToadicusTools\ToadicusTools.csproj">

--- a/VOIDCore_Editor.cs
+++ b/VOIDCore_Editor.cs
@@ -30,8 +30,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -39,6 +37,15 @@
 	[VOID_Scenes(GameScenes.EDITOR)]
 	public class VOIDCore_Editor : VOIDCore_Generic<VOIDCore_Editor>
 	{
+		public override string SceneKey
+		{
+			get
+			{
+				return "EDITOR";
+			}
+		}
+
+
 		public override void FixedUpdate() {}
 	}
 }

--- a/VOIDCore_Flight.cs
+++ b/VOIDCore_Flight.cs
@@ -29,18 +29,27 @@
 using KSP;
 using System;
 using UnityEngine;
-using ToadicusTools;
+using ToadicusTools.GUIUtils;
 
 namespace VOID
 {
 	[VOID_Scenes(GameScenes.FLIGHT)]
 	public class VOIDCore_Flight : VOIDCore_Generic<VOIDCore_Flight>
 	{
+		public override string SceneKey
+		{
+			get
+			{
+				return "FLIGHT";
+			}
+		}
+
+
 		public override void DrawConfigurables()
 		{
 			if (HighLogic.LoadedSceneIsFlight)
 			{
-				this.consumeResource.value = GUITools.Toggle(this.consumeResource, "Consume Resources");
+				this.consumeResource.value = Layout.Toggle(this.consumeResource, "Consume Resources");
 			}
 
 			base.DrawConfigurables();

--- a/VOIDCore_Generic.cs
+++ b/VOIDCore_Generic.cs
@@ -30,11 +30,15 @@
 using KerbalEngineer.Helpers;
 using KerbalEngineer.VesselSimulator;
 using KSP;
+using KSP.UI.Screens;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.DebugTools;
+using ToadicusTools.Extensions;
+using ToadicusTools.GUIUtils;
+using ToadicusTools.Wrappers;
 using UnityEngine;
 
 namespace VOID
@@ -60,7 +64,8 @@
 		protected string VOIDIconOffActivePath;
 		protected string VOIDIconOffInactivePath;
 
-		private bool _useToolbarManager;
+		[AVOID_SaveValue("useToolbarManager")]
+		protected VOID_SaveValue<bool> useToolbarManager;
 
 		protected GUIStyle iconStyle;
 
@@ -95,8 +100,9 @@
 		[AVOID_SaveValue("timeScaleFlags")]
 		protected VOID_SaveValue<UInt32> timeScaleFlags;
 
-		// Vessel Type Housekeeping
+		// Load-up housekeeping
 		protected bool vesselTypesLoaded = false;
+		protected bool simManagerLoaded = false;
 
 		protected string defaultSkin = "KSP window 2";
 
@@ -105,7 +111,7 @@
 		protected int skinIdx;
 
 		protected Dictionary<string, GUISkin> validSkins;
-		protected string[] skinNames;
+		protected List<string> skinNames;
 		protected string[] forbiddenSkins =
 			{
 				"PlaqueDialogSkin",
@@ -147,13 +153,6 @@
 				base.Active = value;
 			}
 		}
-		public override IList<CelestialBody> AllBodies
-		{
-			get
-			{
-				return FlightGlobals.Bodies.AsReadOnly();
-			}
-		}
 
 		public override VesselType[] AllVesselTypes
 		{
@@ -314,49 +313,20 @@
 			}
 		}
 
-		protected bool useToolbarManager
-		{
-			get
-			{
-				return _useToolbarManager & ToolbarManager.ToolbarAvailable;
-			}
-			set
-			{
-				if (_useToolbarManager == value)
-				{
-					return;
-				}
-
-				if (value == false && this.ToolbarButton != null)
-				{
-					this.ToolbarButton.Destroy();
-					this.ToolbarButton = null;
-				}
-				if (value == true)
-				{
-					if (this.AppLauncherButton != null)
-					{
-						ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
-						this.AppLauncherButton = null;
-					}
-
-					this.InitializeToolbarButton();
-				}
-
-				_useToolbarManager = value;
-			}
-		}
-
 		/*
 		 * Events
 		 * */
+		// public 
 		public override event VOIDEventHandler onApplicationQuit;
 		public override event VOIDEventHandler onSkinChanged;
+		public override event VOIDEventHandler onUpdate;
+		public override event VOIDEventHandler onPostRender;
+		public override event VOIDEventHandler onPreRender;
 
 		/*
 		 * Methods
 		 * */
-		public override void DrawGUI()
+		public override void DrawGUI(object sender)
 		{
 			this.windowID = this.windowBaseID;
 
@@ -376,40 +346,26 @@
 			{
 				this.LoadGUIStyles();
 
-				Tools.PostDebugMessage(
+				Logging.PostDebugMessage(
 					this,
 					"ToolbarAvailable: {0}, UseToobarManager: {1}",
 					ToolbarManager.ToolbarAvailable,
 					this.useToolbarManager);
 			}
 
-			if (!this.useToolbarManager)
-			{
-				if (this.AppLauncherButton == null)
-				{
-					Tools.PostDebugMessage(this,
-						"UseToolbarManager = false (ToolbarAvailable = {0}) and " +
-						"AppLauncherButton is null, making AppLauncher button.",
-						ToolbarManager.ToolbarAvailable
-					);
-					this.InitializeAppLauncherButton();
-				}
-			}
-			else if (this.ToolbarButton == null)
-			{
-				Tools.PostDebugMessage(this,
-					"UseToolbarManager = true (ToolbarAvailable = {0}) and " +
-					"ToolbarButton is null, making Toolbar button.",
-					ToolbarManager.ToolbarAvailable
-				);
-				this.InitializeToolbarButton();
-			}
-
-			this.SetIconTexture();
+			if (
+				this.iconState != (this.powerState | this.activeState) ||
+				(this.VOIDIconTexture == null && this.AppLauncherButton != null)
+			)
+			{
+				this.iconState = this.powerState | this.activeState;
+
+				this.SetIconTexture(this.iconState);
+			}
 
 			if (this.Active)
 			{
-				base.DrawGUI();
+				base.DrawGUI(sender);
 			}
 		}
 
@@ -429,7 +385,7 @@
 				)
 			)
 			{
-				Tools.PostDebugMessage(this, "Updating SimManager.");
+				Logging.PostDebugMessage(this, "Updating SimManager.");
 				this.UpdateSimManager();
 			}
 
@@ -438,8 +394,11 @@
 				this.StartGUI();
 			}
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (
 					!module.GUIRunning &&
 					module.Active &&
@@ -475,8 +434,58 @@
 				}
 			}
 
-			this.CheckAndSave();
+			if (this.useToolbarManager)
+			{
+				if (this.AppLauncherButton != null)
+				{
+					ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
+					this.AppLauncherButton = null;
+				}
+
+				if (this.ToolbarButton == null)
+				{
+					this.InitializeToolbarButton();
+				}
+			}
+			else
+			{
+				if (this.ToolbarButton != null)
+				{
+					this.ToolbarButton.Destroy();
+					this.ToolbarButton = null;
+				}
+
+				if (this.AppLauncherButton == null)
+				{
+					this.InitializeAppLauncherButton();
+				}
+
+			}
+
+			this.saveTimer += Time.deltaTime;
+
+			if (this.modulesLoaded && this.saveTimer > 2f)
+			{
+				if (this.configDirty)
+				{
+
+					Logging.PostDebugMessage(string.Format(
+							"{0}: Time to save, checking if configDirty: {1}",
+							this.GetType().Name,
+							this.configDirty
+						));
+
+					this.SaveConfig();
+					this.saveTimer = 0;
+				}
+			}
+
 			this.UpdateTimer += Time.deltaTime;
+
+			if (this.onUpdate != null)
+			{
+				this.onUpdate(this);
+			}
 		}
 
 		public virtual void FixedUpdate()
@@ -507,8 +516,11 @@
 				}
 			}
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (module is IVOID_BehaviorModule)
 				{
 					((IVOID_BehaviorModule)module).FixedUpdate();
@@ -516,10 +528,31 @@
 			}
 		}
 
+		public override void OnGUI()
+		{
+			if (Event.current.type == EventType.Repaint || Event.current.isMouse)
+			{
+				if (this.onPreRender != null)
+				{
+					Logging.PostDebugMessage(this, "In OnGUI; doing 'pre draw' stuff");
+					this.onPreRender(this);
+				}
+			}
+
+			if (this.onPostRender != null)
+			{
+				Logging.PostDebugMessage(this, "In OnGUI; doing 'post draw' stuff");
+				this.onPostRender(this);
+			}
+		}
+
 		public void OnDestroy()
 		{
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (module is IVOID_BehaviorModule)
 				{
 					((IVOID_BehaviorModule)module).OnDestroy();
@@ -543,7 +576,9 @@
 		{
 			if (!this.GUIRunning)
 			{
-				RenderingManager.AddToPostDrawQueue(3, this.DrawGUI);
+				// RenderingManager.AddToPostDrawQueue(3, this.DrawGUI);
+				Logging.PostDebugMessage(this, "Adding DrawGUI to onGui");
+				this.onPostRender += this.DrawGUI;
 			}
 		}
 
@@ -551,8 +586,11 @@
 		{
 			this.StopGUI();
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				module.StopGUI();
 				module.StartGUI();
 			}
@@ -579,14 +617,17 @@
 
 				if (togglePower || !HighLogic.LoadedSceneIsFlight)
 				{
-					foreach (IVOID_Module module in this.modules)
+					IVOID_Module module;
+					for (int idx = 0; idx < this.modules.Count; idx++)
 					{
+						module = this.modules[idx];
+
 						if (module is VOID_ConfigWindow)
 						{
 							continue;
 						}
 
-						module.Active = GUITools.Toggle(module.Active, module.Name);
+						module.Active = Layout.Toggle(module.Active, module.Name);
 					}
 				}
 			}
@@ -595,7 +636,7 @@
 				GUILayout.Label("-- POWER LOST --", VOID_Styles.labelRed);
 			}
 
-			VOID_ConfigWindow.Instance.Active = GUITools.Toggle(
+			VOID_ConfigWindow.Instance.Active = Layout.Toggle(
 				VOID_ConfigWindow.Instance.Active,
 				"Configuration"
 			);
@@ -609,20 +650,20 @@
 		{
 			GUIContent _content;
 
-			this.useToolbarManager = GUITools.Toggle(this.useToolbarManager, "Use Blizzy's Toolbar If Available");
-
-			this.vesselSimActive.value = GUITools.Toggle(this.vesselSimActive.value,
+			this.useToolbarManager.value = Layout.Toggle(this.useToolbarManager, "Use Blizzy's Toolbar If Available");
+
+			this.vesselSimActive.value = Layout.Toggle(this.vesselSimActive.value,
 				"Enable Engineering Calculations");
 
 			bool useEarthTime = (this.TimeScale & VOID_TimeScale.KERBIN_TIME) == 0u;
 			bool useSiderealTime = (this.TimeScale & VOID_TimeScale.SOLAR_DAY) == 0u;
 			bool useRoundedScale = (this.TimeScale & VOID_TimeScale.ROUNDED_SCALE) != 0u;
 
-			useEarthTime = GUITools.Toggle(useEarthTime, "Use Earth Time (changes KSP option)");
+			useEarthTime = Layout.Toggle(useEarthTime, "Use Earth Time (changes KSP option)");
 
 			GameSettings.KERBIN_TIME = !useEarthTime;
 
-			useSiderealTime = GUITools.Toggle(
+			useSiderealTime = Layout.Toggle(
 				useSiderealTime,
 				string.Format(
 					"Time Scale: {0}",
@@ -630,7 +671,7 @@
 				)
 			);
 
-			useRoundedScale = GUITools.Toggle(
+			useRoundedScale = Layout.Toggle(
 				useRoundedScale,
 				string.Format(
 					"Time Scale: {0}",
@@ -676,7 +717,7 @@
 			if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
 			{
 				this.skinIdx--;
-				Tools.PostDebugMessage(string.Format(
+				Logging.PostDebugMessage(string.Format(
 					"{0}: new this.skinIdx = {1} :: skin_list.Count = {2}",
 					this.GetType().Name,
 					this.skinName,
@@ -693,7 +734,7 @@
 			if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
 			{
 				this.skinIdx++;
-				Tools.PostDebugMessage(string.Format(
+				Logging.PostDebugMessage(string.Format(
 					"{0}: new this.skinIdx = {1} :: skin_list.Count = {2}",
 					this.GetType().Name,
 					this.skinName,
@@ -701,10 +742,10 @@
 				));
 			}
 
-			this.skinIdx %= this.skinNames.Length;
+			this.skinIdx %= this.skinNames.Count;
 			if (this.skinIdx < 0)
 			{
-				this.skinIdx += this.skinNames.Length;
+				this.skinIdx += this.skinNames.Count;
 			}
 
 			if (this.skinName != skinNames[this.skinIdx])
@@ -731,28 +772,27 @@
 			}
 			GUILayout.EndHorizontal();
 
-			foreach (IVOID_Module mod in this.modules)
-			{
-				mod.DrawConfigurables();
-			}
-
-			this.FactoryReset = GUITools.Toggle(this.FactoryReset, "Factory Reset");
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
+				module.DrawConfigurables();
+			}
+
+			this.FactoryReset = Layout.Toggle(this.FactoryReset, "Factory Reset");
 		}
 
 		protected void UpdateSimManager()
 		{
-			if (HighLogic.LoadedSceneIsEditor)
-			{
-				SimManager.Gravity = VOID_Data.KerbinGee;
-			}
-			else
+			if (HighLogic.LoadedSceneIsFlight)
 			{
 				double radius = this.Vessel.Radius();
 				SimManager.Gravity = this.Vessel.mainBody.gravParameter / (radius * radius);
 				SimManager.Atmosphere = this.Vessel.staticPressurekPa * PhysicsGlobals.KpaToAtmospheres;
-				SimManager.Mach = HighLogic.LoadedSceneIsEditor ? 1d :  this.Vessel.mach;
-				BuildAdvanced.Altitude = HighLogic.LoadedSceneIsEditor ? 0d : this.Vessel.altitude;
-				CelestialBodies.SelectedBody = HighLogic.LoadedSceneIsEditor ? this.HomeBody : this.Vessel.mainBody;
+				SimManager.Mach = this.Vessel.mach;
+				BuildAdvanced.Altitude = this.Vessel.altitude;
+				CelestialBodies.SelectedBody = this.Vessel.mainBody;
 			}
 
 			#if DEBUG
@@ -761,7 +801,7 @@
 
 			SimManager.TryStartSimulation();
 
-			Tools.PostDebugMessage(this, "Started Engineer simulation with Atmosphere={0} atm and Gravity={1} m/s²",
+			Logging.PostDebugMessage(this, "Started Engineer simulation with Atmosphere={0} atm and Gravity={1} m/s²",
 				SimManager.Atmosphere,
 				SimManager.Gravity
 			);
@@ -769,71 +809,81 @@
 
 		protected void GetSimManagerResults()
 		{
-			Tools.PostDebugMessage(this, "VesselSimulator results ready, setting Stages.");
+			Logging.PostDebugMessage(this, "VesselSimulator results ready, setting Stages.");
 
 			this.Stages = SimManager.Stages;
 
-			if (this.Stages != null)
-			{
-				this.LastStage = this.Stages.Last();
+			if (this.Stages != null && this.Stages.Length > 0)
+			{
+				this.LastStage = this.Stages[this.Stages.Length - 1];
 			}
 		}
 
 		protected void LoadModulesOfType<U>()
 		{
-			Tools.DebugLogger sb = Tools.DebugLogger.New(this);
-			sb.AppendLine("Loading modules...");
-
-			foreach (AssemblyLoader.LoadedAssembly assy in AssemblyLoader.loadedAssemblies)
-			{
-				foreach (Type loadedType in assy.assembly.GetExportedTypes())
-				{
-					if (
-						loadedType.IsInterface ||
-						loadedType.IsAbstract ||
-						!typeof(U).IsAssignableFrom(loadedType) ||
-						typeof(VOIDCore).IsAssignableFrom(loadedType)
-					)
+			using (PooledDebugLogger sb = PooledDebugLogger.New(this))
+			{
+				sb.AppendLine("Loading modules...");
+
+				AssemblyLoader.LoadedAssembly assy;
+				for (int aIdx = 0; aIdx < AssemblyLoader.loadedAssemblies.Count; aIdx++)
+				{
+					assy = AssemblyLoader.loadedAssemblies[aIdx];
+
+					Type[] loadedTypes = assy.assembly.GetExportedTypes();
+					Type loadedType;
+					for (int tIdx = 0; tIdx < loadedTypes.Length; tIdx++)
 					{
-						continue;
+						loadedType = loadedTypes[tIdx];
+
+						if (
+							loadedType.IsInterface ||
+							loadedType.IsAbstract ||
+							!typeof(U).IsAssignableFrom(loadedType) ||
+							typeof(VOIDCore).IsAssignableFrom(loadedType))
+						{
+							continue;
+						}
+
+						sb.AppendFormat("Checking IVOID_Module type {0}...", loadedType.Name);
+
+						try
+						{
+							this.LoadModule(loadedType);
+							sb.AppendLine("Success.");
+						}
+						catch (Exception ex)
+						{
+							sb.AppendFormat("Failed, caught {0}\n", ex.GetType().Name);
+
+							#if DEBUG
+						Debug.LogException(ex);
+							#endif
+						}
 					}
-
-					sb.AppendFormat("Checking IVOID_Module type {0}...", loadedType.Name);
-
-					try
-					{
-						this.LoadModule(loadedType);
-						sb.AppendLine("Success.");
-					}
-					catch (Exception ex)
-					{
-						sb.AppendFormat("Failed, caught {0}\n", ex.GetType().Name);
-
-						#if DEBUG
-						Debug.LogException(ex);
-						#endif
-					}
-				}
-			}
-
-			this.modulesLoaded = true;
-
-			sb.AppendFormat("Loaded {0} modules.\n", this.Modules.Count);
-
-			sb.Print();
+				}
+
+				this.LoadConfig();
+
+				this.modulesLoaded = true;
+
+				sb.AppendFormat("Loaded {0} modules.\n", this.Modules.Count);
+
+				sb.Print();
+			}
 		}
 
 		protected void LoadModule(Type T)
 		{
-			var existingModules = this.modules.Where(mod => mod.GetType().Name == T.Name);
-			if (existingModules.Any())
-			{
-				Tools.PostDebugMessage(string.Format(
-					"{0}: refusing to load {1}: already loaded",
-					this.GetType().Name,
-					T.Name
-				));
-				return;
+			/*var existingModules = this.modules.Where(mod => mod.GetType().Name == T.Name);
+			if (existingModules.Any())*/
+			for (int mIdx = 0; mIdx < this.modules.Count; mIdx++)
+			{
+				if (this.modules[mIdx].Name == T.Name)
+				{
+					Logging.PostErrorMessage("{0}: refusing to load {1}: already loaded", this.GetType().Name, T.Name);
+					return;
+				}
 			}
 
 			var InstanceProperty = T.GetProperty(
@@ -862,10 +912,9 @@
 
 			if (module.InValidGame && module.InValidScene)
 			{
-				module.LoadConfig();
 				this.modules.Add(module);
 
-				Tools.PostDebugMessage(string.Format(
+				Logging.PostDebugMessage(string.Format(
 						"{0}: loaded module {1}.",
 						this.GetType().Name,
 						T.Name
@@ -882,33 +931,33 @@
 
 		protected void LoadSkins()
 		{
-			Tools.PostDebugMessage("AssetBase has skins: \n" +
-				string.Join("\n\t",
-					Resources.FindObjectsOfTypeAll(typeof(GUISkin))
-					.Select(s => s.ToString())
-					.ToArray()
-				)
-			);
-
-			this.validSkins = Resources.FindObjectsOfTypeAll(typeof(GUISkin))
-				.Where(s => !this.forbiddenSkins.Contains(s.name))
-				.Select(s => s as GUISkin)
-				.GroupBy(s => s.name)
-				.Select(g => g.First())
-				.ToDictionary(s => s.name);
-
-			Tools.PostDebugMessage(string.Format(
+			this.validSkins = new Dictionary<string, GUISkin>();
+			this.skinNames = new List<string>();
+
+			UnityEngine.Object[] skins = Resources.FindObjectsOfTypeAll(typeof(GUISkin));
+			GUISkin skin;
+			for (int sIdx = 0; sIdx < skins.Length; sIdx++)
+			{
+				skin = (GUISkin)skins[sIdx];
+
+				if (!this.forbiddenSkins.Contains(skin.name))
+				{
+					this.validSkins[skin.name] = skin;
+					this.skinNames.Add(skin.name);
+				}
+			}
+
+			Logging.PostDebugMessage(string.Format(
 				"{0}: loaded {1} GUISkins.",
 				this.GetType().Name,
 				this.validSkins.Count
 			));
 
-			this.skinNames = this.validSkins.Keys.ToArray();
-			Array.Sort(this.skinNames);
+			this.skinNames.Sort();
 
 			int defaultIdx = int.MinValue;
 
-			for (int i = 0; i < this.skinNames.Length; i++)
+			for (int i = 0; i < this.skinNames.Count; i++)
 			{
 				if (this.skinNames[i] == this.skinName)
 				{
@@ -929,7 +978,7 @@
 				this.skinIdx = defaultIdx;
 			}
 
-			Tools.PostDebugMessage(string.Format(
+			Logging.PostDebugMessage(string.Format(
 				"{0}: _skinIdx = {1}.",
 				this.GetType().Name,
 				this.skinName.ToString()
@@ -950,17 +999,19 @@
 			this.GUIStylesLoaded = true;
 		}
 
-		protected void LoadVesselTypes()
-		{
-			this.AllVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToArray();
-			this.vesselTypesLoaded = true;
-		}
-
 		protected void LoadBeforeUpdate()
 		{
 			if (!this.vesselTypesLoaded)
 			{
-				this.LoadVesselTypes();
+				Array typeObjs = Enum.GetValues(typeof(VesselType));
+				this.AllVesselTypes = new VesselType[typeObjs.Length];
+
+				for (int idx = 0; idx < typeObjs.Length; idx++)
+				{
+					this.AllVesselTypes[idx] = (VesselType)typeObjs.GetValue(idx);
+				}
+
+				this.vesselTypesLoaded = true;
 			}
 
 			if (this.SortedBodyList == null && FlightGlobals.Bodies != null && FlightGlobals.Bodies.Count > 0)
@@ -968,10 +1019,20 @@
 				this.SortedBodyList = new List<CelestialBody>(FlightGlobals.Bodies);
 				this.SortedBodyList.Sort(new CBListComparer());
 				this.SortedBodyList.Reverse();
-
-				Debug.Log(string.Format("sortedBodyList: {0}", string.Join("\n\t", this.SortedBodyList.Select(b => b.bodyName).ToArray())));
-			}
-
+			}
+
+			// SimManager initialization that we don't necessarily want to repeat every Update.
+			if (!this.simManagerLoaded && this.HomeBody != null)
+			{
+				SimManager.Gravity = VOID_Data.KerbinGee;
+				SimManager.Atmosphere = 0d;
+				SimManager.Mach = 1d;
+				CelestialBodies.SelectedBody = this.HomeBody;
+				BuildAdvanced.Altitude = 0d;
+				SimManager.OnReady += this.GetSimManagerResults;
+
+				this.simManagerLoaded = true;
+			}
 		}
 
 		protected void InitializeToolbarButton()
@@ -979,7 +1040,7 @@
 			// Do nothing if (the Toolbar is not available.
 			if (!ToolbarManager.ToolbarAvailable)
 			{
-				Tools.PostDebugMessage(this, "Refusing to make a ToolbarButton: ToolbarAvailable = false");
+				Logging.PostDebugMessage(this, "Refusing to make a ToolbarButton: ToolbarAvailable = false");
 				return;
 			}
 
@@ -995,7 +1056,7 @@
 				this.ToggleMainWindow();
 			};
 
-			Tools.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name));
+			Logging.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name));
 		}
 
 		protected void InitializeAppLauncherButton()
@@ -1008,7 +1069,7 @@
 					this.VOIDIconTexture
 				);
 
-				Tools.PostDebugMessage(
+				Logging.PostDebugMessage(
 					this,
 					"AppLauncherButton initialized in {0}",
 					Enum.GetName(
@@ -1022,19 +1083,6 @@
 		protected void ToggleMainWindow()
 		{
 			this.Active = !this.Active;
-		}
-
-		protected void SetIconTexture()
-		{
-			if (
-				this.iconState != (this.powerState | this.activeState) ||
-				(this.VOIDIconTexture == null && this.AppLauncherButton != null)
-			)
-			{
-				this.iconState = this.powerState | this.activeState;
-
-				this.SetIconTexture(this.iconState);
-			}
 		}
 
 		protected void SetIconTexture(IconState state)
@@ -1078,35 +1126,34 @@
 			}
 		}
 
-		protected virtual void CheckAndSave()
-		{
-			this.saveTimer += Time.deltaTime;
-
-			if (this.saveTimer > 2f)
-			{
-				if (!this.configDirty)
-				{
-					return;
-				}
-
-				Tools.PostDebugMessage(string.Format(
-					"{0}: Time to save, checking if configDirty: {1}",
-					this.GetType().Name,
-					this.configDirty
-				));
-
-				this.SaveConfig();
-				this.saveTimer = 0;
-			}
-		}
-
-		public override void LoadConfig()
-		{
-			base.LoadConfig();
-
-			foreach (IVOID_Module module in this.modules)
-			{
-				module.LoadConfig();
+		public void LoadConfig()
+		{
+
+			if (!System.IO.File.Exists(this.VOIDSettingsPath) && KSP.IO.File.Exists<VOID_Module>("config.xml"))
+			{
+				Logging.PostLogMessage(
+					"VOID: No per-save config file but old file detected; copying from old file."
+				);
+
+				System.IO.File.Copy(
+					KSP.IO.IOUtils.GetFilePathFor(typeof(VOID_Module), "config.xml"),
+					this.VOIDSettingsPath
+				);
+			}
+
+			this.LoadConfig(new PluginConfiguration(this.VOIDSettingsPath));
+		}
+
+		public override void LoadConfig(KSP.IO.PluginConfiguration config)
+		{
+			base.LoadConfig(config);
+
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
+				module.LoadConfig(config);
 			}
 
 			this.TimeScale |= GameSettings.KERBIN_TIME ? VOID_TimeScale.KERBIN_TIME : 0u;
@@ -1117,17 +1164,21 @@
 			if (this.configNeedsUpdate && this is VOIDCore_Flight)
 			{
 				KSP.IO.File.Delete<T>("config.xml");
-			}
-
-			var config = KSP.IO.PluginConfiguration.CreateForType<T>();
+				System.IO.File.Delete(this.VOIDSettingsPath);
+			}
+
+			KSP.IO.PluginConfiguration config = new PluginConfiguration(this.VOIDSettingsPath);
 
 			config.load();
 
-			this.Save(config);
-
-			foreach (IVOID_Module module in this.modules)
-			{
-				module.Save(config);
+			this.Save(config, this.SceneKey);
+
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
+				module.Save(config, this.SceneKey);
 			}
 
 			config.save();
@@ -1160,18 +1211,10 @@
 
 			this.vesselSimActive = (VOID_SaveValue<bool>)true;
 
-			SimManager.Atmosphere = 0d;
-			SimManager.Mach = 1d;
-			CelestialBodies.SelectedBody = this.HomeBody;
-			BuildAdvanced.Altitude = 0d;
-
-			SimManager.OnReady += this.GetSimManagerResults;
-
-			this.useToolbarManager = ToolbarManager.ToolbarAvailable;
-
-			this.LoadConfig();
-
-			this.configVersion = (VOID_SaveValue<int>)VOIDCore.CONFIG_VERSION;
+			this.useToolbarManager = (VOID_SaveValue<bool>)ToolbarManager.ToolbarAvailable;
+
+			this.SaveGamePath = string.Format("{0}saves/{1}", IOTools.KSPRootPath, HighLogic.SaveFolder);
+			this.VOIDSettingsPath = string.Format("{0}/VOIDConfig.xml", this.SaveGamePath);
 
 			this.FactoryReset = false;
 		}

--- a/VOIDCore_SpaceCentre.cs
+++ b/VOIDCore_SpaceCentre.cs
@@ -32,6 +32,14 @@
 	[VOID_Scenes(GameScenes.SPACECENTER)]
 	public class VOIDCore_SpaceCentre : VOIDCore_Generic<VOIDCore_SpaceCentre>
 	{
+		public override string SceneKey
+		{
+			get
+			{
+				return "SPACECENTER";
+			}
+		}
+
 		public override void FixedUpdate() {}
 	}
 }

--- a/VOIDMaster_Editor.cs
+++ b/VOIDMaster_Editor.cs
@@ -43,7 +43,7 @@
 using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
-using ToadicusTools;
+using ToadicusTools.Extensions;
 using UnityEngine;
 
 namespace VOID
@@ -53,10 +53,10 @@
 	{
 		public override void Awake()
 		{
-			Tools.PostDebugMessage ("VOIDEditorMaster: Waking up.");
+			this.LogDebug("VOIDEditorMaster: Waking up.");
 			this.Core = VOIDCore_Editor.Instance;
 			this.Core.ResetGUI ();
-			Tools.PostDebugMessage ("VOIDEditorMaster: Awake.");
+			this.LogDebug("VOIDEditorMaster: Awake.");
 		}
 	}
 }

--- a/VOIDMaster_Flight.cs
+++ b/VOIDMaster_Flight.cs
@@ -43,7 +43,7 @@
 using System;
 using UnityEngine;
 using KerbalEngineer.VesselSimulator;
-using ToadicusTools;
+using ToadicusTools.Extensions;
 
 namespace VOID
 {

--- a/VOIDMaster_SpaceCentre.cs
+++ b/VOIDMaster_SpaceCentre.cs
@@ -43,7 +43,7 @@
 using System;
 using UnityEngine;
 using KerbalEngineer.VesselSimulator;
-using ToadicusTools;
+using ToadicusTools.Extensions;
 
 namespace VOID
 {

--- a/VOID_CBInfoBrowser.cs
+++ b/VOID_CBInfoBrowser.cs
@@ -29,7 +29,7 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using ToadicusTools;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -73,6 +73,12 @@
 		{
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 
+			if (this.core.SortedBodyList.Count < 1)
+			{
+				GUILayout.Label("Non-positive number of CelestialBodies here, bailing out.");
+				GUILayout.EndHorizontal();
+			}
+
 			GUILayout.BeginVertical(GUILayout.Width(150));
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			GUILayout.Label("", GUILayout.ExpandWidth(true));
@@ -82,8 +88,28 @@
 
 			GUILayout.BeginVertical(GUILayout.Width(150));
 
-			selectedBody1 = this.core.AllBodies[selectedBodyIdx1];
-			selectedBody2 = this.core.AllBodies[selectedBodyIdx2];
+			if (selectedBodyIdx1 >= this.core.SortedBodyList.Count)
+			{
+				selectedBodyIdx1.value %= this.core.SortedBodyList.Count;
+			}
+
+			if (selectedBodyIdx1 < 0)
+			{
+				selectedBodyIdx1.value += this.core.SortedBodyList.Count;
+			}
+
+			if (selectedBodyIdx2 >= this.core.SortedBodyList.Count)
+			{
+				selectedBodyIdx2.value %= this.core.SortedBodyList.Count;
+			}
+
+			if (selectedBodyIdx2 < 0)
+			{
+				selectedBodyIdx2.value += this.core.SortedBodyList.Count;
+			}
+
+			selectedBody1 = this.core.SortedBodyList[selectedBodyIdx1];
+			selectedBody2 = this.core.SortedBodyList[selectedBodyIdx2];
 
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			if (GUILayout.Button("<", GUILayout.ExpandWidth(false)))
@@ -91,14 +117,14 @@
 				selectedBodyIdx1.value--;
 				if (selectedBodyIdx1 < 0)
 				{
-					selectedBodyIdx1.value = this.core.AllBodies.Count - 1;
+					selectedBodyIdx1.value = this.core.SortedBodyList.Count - 1;
 				}
 			}
-			GUILayout.Label(this.core.AllBodies[selectedBodyIdx1].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
+			GUILayout.Label(this.core.SortedBodyList[selectedBodyIdx1].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
 			if (GUILayout.Button(">", GUILayout.ExpandWidth(false)))
 			{
 				selectedBodyIdx1.value++;
-				if (selectedBodyIdx1 > this.core.AllBodies.Count - 1)
+				if (selectedBodyIdx1 > this.core.SortedBodyList.Count - 1)
 				{
 					selectedBodyIdx1.value = 0;
 				}
@@ -113,14 +139,14 @@
 				selectedBodyIdx2.value--;
 				if (selectedBodyIdx2 < 0)
 				{
-					selectedBodyIdx2.value = this.core.AllBodies.Count - 1;
+					selectedBodyIdx2.value = this.core.SortedBodyList.Count - 1;
 				}
 			}
-			GUILayout.Label(this.core.AllBodies[selectedBodyIdx2].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
+			GUILayout.Label(this.core.SortedBodyList[selectedBodyIdx2].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
 			if (GUILayout.Button(">", GUILayout.ExpandWidth(false)))
 			{
 				selectedBodyIdx2.value++;
-				if (selectedBodyIdx2 > this.core.AllBodies.Count - 1)
+				if (selectedBodyIdx2 > this.core.SortedBodyList.Count - 1)
 				{
 					selectedBodyIdx2.value = 0;
 				}
@@ -373,15 +399,19 @@
 
 			GUILayout.Label(p.ToString("##,#") + "kg/m³", VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
 
-			if (body.bodyName == "Sun") GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
-			else GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
+			if (body.bodyName == "Sun") GUILayout.Label(SIFormatProvider.ToSI(body.sphereOfInfluence, 3), VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
+			else GUILayout.Label(SIFormatProvider.ToSI(body.sphereOfInfluence, 3), VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
 
 			GUILayout.Label(body.orbitingBodies.Count.ToString(), VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
 
 			//show # artificial satellites
 			int num_art_sats = 0;
-			foreach (Vessel v in FlightGlobals.Vessels)
-			{
+
+			Vessel v;
+			for (int idx = 0; idx < FlightGlobals.Vessels.Count; idx++)
+			{
+				v = FlightGlobals.Vessels[idx];
+
 				if (v.mainBody == body && v.situation.ToString() == "ORBITING") num_art_sats++;
 			}
 
@@ -389,11 +419,11 @@
 
 			double g_ASL = (VOIDCore.Constant_G * body.Mass) / (body.Radius * body.Radius);
 
-			GUILayout.Label(Tools.MuMech_ToSI(g_ASL) + "m/s²", VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
+			GUILayout.Label(SIFormatProvider.ToSI(g_ASL, 3) + "m/s²", VOID_Styles.labelRight, GUILayout.ExpandWidth(true));
 
 			if (body.atmosphere)
 			{
-				GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.atmosphereDepth) + "m",
+				GUILayout.Label("≈ " + SIFormatProvider.ToSI(body.atmosphereDepth, 3) + "m",
 					VOID_Styles.labelRight,
 					GUILayout.ExpandWidth(true));
 

--- a/VOID_CareerStatus.cs
+++ b/VOID_CareerStatus.cs
@@ -30,6 +30,7 @@
 using System;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -42,11 +43,11 @@
 		{
 			if (delta > 0)
 			{
-				return string.Format("<color='lime'>{0}↑</color>", delta.ToString(numberFormat, Tools.SIFormatter));
+				return string.Format("<color='lime'>{0}↑</color>", delta.ToString(numberFormat, SIFormatProvider.SIFormatter));
 			}
 			else if (delta < 0)
 			{
-				return string.Format("<color='red'>{0}↓</color>", delta.ToString(numberFormat, Tools.SIFormatter));
+				return string.Format("<color='red'>{0}↓</color>", delta.ToString(numberFormat, SIFormatProvider.SIFormatter));
 			}
 			else
 			{
@@ -116,7 +117,7 @@
 		{
 			get
 			{
-				Tools.PostDebugMessage(
+				Logging.PostDebugMessage(
 					this,
 					"Checking init state:" +
 					"\n\tcurrentFunds={0}" +
@@ -135,14 +136,14 @@
 			}
 		}
 
-		public override void DrawGUI()
+		public override void DrawGUI(object sender)
 		{
 			if (Event.current.type != EventType.Layout && !this.currenciesInitialized)
 			{
 				this.initCurrencies();
 			}
 
-			base.DrawGUI();
+			base.DrawGUI(sender);
 		}
 
 		public override void ModuleWindow(int id)
@@ -201,7 +202,7 @@
 
 		private void initCurrencies()
 		{
-			Tools.PostDebugMessage(
+			Logging.PostDebugMessage(
 				this,
 				"Initializing currencies." +
 				"\n\tFunding.Instance={0}" +

--- a/VOID_ConfigWindow.cs
+++ b/VOID_ConfigWindow.cs
@@ -28,7 +28,6 @@
 
 using KSP;
 using System;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID

--- a/VOID_Data.cs
+++ b/VOID_Data.cs
@@ -31,6 +31,8 @@
 using System;
 using System.Collections.Generic;
 using ToadicusTools;
+using ToadicusTools.Extensions;
+using ToadicusTools.MuMechTools;
 using UnityEngine;
 
 namespace VOID
@@ -230,8 +232,8 @@
 		public static readonly VOID_FloatValue mainThrottle =
 			new VOID_FloatValue(
 				"Throttle",
-				new Func<float>(() => Core.Vessel.ctrlState.mainThrottle * 100f),
-				"%"
+				new Func<float>(() => Core.Vessel.ctrlState.mainThrottle),
+				""
 			);
 
 		#endregion
@@ -352,6 +354,19 @@
 				}
 			);
 
+		public static readonly VOID_DoubleValue currThrust =
+			new VOID_DoubleValue(
+				"Current Thrust",
+				delegate()
+				{
+					if (Core.Stages == null || Core.LastStage == null)
+						return double.NaN;
+
+					return Core.LastStage.actualThrust;
+				},
+				"kN"
+			);
+
 		public static readonly VOID_StrValue currmaxThrust =
 			new VOID_StrValue(
 				"Thrust (curr/max)",
@@ -471,24 +486,26 @@
 				""
 			);
 
-		public static readonly VOID_Vector3dValue vesselThrustOffset =
-			new VOID_Vector3dValue(
+		public static readonly VOID_Vector3Value vesselThrustOffset =
+			new VOID_Vector3Value(
 				"Thrust Offset",
 				delegate()
 				{
 					if (Core.Vessel == null)
 					{
-						return Vector3d.zero;
-					}
-
-					List<PartModule> engineModules = Core.Vessel.getModulesOfType<PartModule>();
-
-					Vector3d thrustPos = Vector3d.zero;
-					Vector3d thrustDir = Vector3d.zero;
+						return Vector3.zero;
+					}
+
+					IList<PartModule> engineModules = Core.Vessel.getModulesOfType<PartModule>();
+
+					Vector3 thrustPos = Vector3.zero;
+					Vector3 thrustDir = Vector3.zero;
 					float thrust = 0;
 
-					foreach (PartModule engine in engineModules)
-					{
+					PartModule engine;
+					for (int idx = 0; idx < engineModules.Count; idx++)
+					{
+						engine = engineModules[idx];
 						float moduleThrust = 0;
 
 						switch (engine.moduleName)
@@ -545,10 +562,10 @@
 					thrustPos = vesselTransform.InverseTransformPoint(thrustPos);
 					thrustDir = vesselTransform.InverseTransformDirection(thrustDir);
 
-					Vector3d thrustOffset = VectorTools.PointDistanceToLine(
+					Vector3 thrustOffset = VectorTools.PointDistanceToLine(
 						                        thrustPos, thrustDir.normalized, Core.Vessel.findLocalCenterOfMass());
 
-					Tools.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" +
+					Logging.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" +
 					"\tthrustPos: {0}\n" +
 					"\tthrustDir: {1}\n" +
 					"\tthrustOffset: {2}\n" +
@@ -579,8 +596,11 @@
 					currentAmount = 0d;
 					currentRequirement = 0d;
 
-					foreach (Part part in Core.Vessel.Parts)
-					{
+					Part part;
+					for (int idx = 0; idx < Core.Vessel.Parts.Count; idx++)
+					{
+						part = Core.Vessel.Parts[idx];
+
 						if (part.enabled)
 						{
 							ModuleEngines engineModule;
@@ -598,8 +618,11 @@
 
 							if (propellantList != null)
 							{
-								foreach (Propellant propellant in propellantList)
+								Propellant propellant;
+								for (int propIdx = 0; propIdx < propellantList.Count; propIdx++)
 								{
+									propellant = propellantList[propIdx];
+
 									if (propellant.name == "IntakeAir")
 									{
 										currentRequirement += propellant.currentRequirement / TimeWarp.fixedDeltaTime;
@@ -715,16 +738,57 @@
 				"m"
 			);
 
-		public static readonly VOID_StrValue surfLatitude =
+		public static readonly VOID_StrValue surfLatitudeString =
 			new VOID_StrValue(
 				"Latitude",
 				new Func<string>(() => VOID_Tools.GetLatitudeString(Core.Vessel))
 			);
 
-		public static readonly VOID_StrValue surfLongitude =
+		public static readonly VOID_DoubleValue surfLatitude =
+			new VOID_DoubleValue(
+				"Latitude",
+				delegate()
+				{
+					if (CoreInitialized && Core.Vessel != null)
+					{
+						return Core.Vessel.latitude;
+					}
+					return double.NaN;
+				},
+				"°"
+			);
+
+		public static readonly VOID_StrValue surfLongitudeString =
 			new VOID_StrValue(
 				"Longitude",
 				new Func<string>(() => VOID_Tools.GetLongitudeString(Core.Vessel))
+			);
+
+		public static readonly VOID_DoubleValue surfLongitude =
+			new VOID_DoubleValue(
+				"Longitude",
+				delegate()
+				{
+					if (CoreInitialized && Core.Vessel != null)
+					{
+						double longitude = Core.Vessel.longitude;
+
+						longitude = VOID_Tools.FixDegreeDomain(longitude);
+
+						if (longitude < -180d)
+						{
+							longitude += 360d;
+						}
+						if (longitude >= 180)
+						{
+							longitude -= 360d;
+						}
+
+						return longitude;
+					}
+					return double.NaN;
+				},
+				"°"
 			);
 
 		public static readonly VOID_DoubleValue trueAltitude =
@@ -756,7 +820,10 @@
 		public static readonly VOID_DoubleValue horzVelocity =
 			new VOID_DoubleValue(
 				"Horizontal speed",
-				new Func<double>(() => Core.Vessel.horizontalSrfSpeed),
+				delegate
+				{
+					return Core.Vessel.horizontalSrfSpeed;
+				},
 				"m/s"
 			);
 
@@ -1222,7 +1289,7 @@
 
 		private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust)
 		{
-			Tools.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" +
+			Logging.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" +
 			"\tdeltaV: {0}\n" +
 			"\tinitialMass: {1}\n" +
 			"\tmassFlow: {2}\n" +

--- a/VOID_DataLogger.cs
+++ b/VOID_DataLogger.cs
@@ -32,6 +32,9 @@
 using System.IO;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.DebugTools;
+using ToadicusTools.GUIUtils;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -103,14 +106,11 @@
 			{
 				if (this._fileName == null || this._fileName == string.Empty)
 				{
-					this._fileName = KSP.IO.IOUtils.GetFilePathFor(
-						typeof(VOIDCore),
-						string.Format(
-							"{0}_{1}",
-							this.Vessel.vesselName,
-							"data.csv"
-						),
-						null
+					this._fileName = string.Format(
+						"{0}/{1}_{2}",
+						this.core.SaveGamePath,
+						this.Vessel.vesselName,
+						"data.csv"
 					);
 				}
 
@@ -124,44 +124,46 @@
 			{
 				if (this._outputFile == null)
 				{
-					Tools.DebugLogger logger = Tools.DebugLogger.New(this);
-					logger.AppendFormat("Initializing output file '{0}' with mode ", this.fileName);
-
-					if (File.Exists(this.fileName))
+					using (PooledDebugLogger logger = PooledDebugLogger.New(this))
 					{
-						logger.Append("append");
-						this._outputFile = new FileStream(
-							this.fileName,
-							FileMode.Append,
-							FileAccess.Write,
-							FileShare.Read,
-							512,
-							true
-						);
+						logger.AppendFormat("Initializing output file '{0}' with mode ", this.fileName);
+
+						if (File.Exists(this.fileName))
+						{
+							logger.Append("append");
+							this._outputFile = new FileStream(
+								this.fileName,
+								FileMode.Append,
+								FileAccess.Write,
+								FileShare.Read,
+								512,
+								true
+							);
+						}
+						else
+						{
+							logger.Append("create");
+							this._outputFile = new FileStream(
+								this.fileName,
+								FileMode.Create,
+								FileAccess.Write,
+								FileShare.Read,
+								512,
+								true
+							);
+
+							byte[] byteOrderMark = utf8Encoding.GetPreamble();
+
+							logger.Append(" and writing preamble");
+							this._outputFile.Write(byteOrderMark, 0, byteOrderMark.Length);
+						}
+
+						logger.Append('.');
+
+						logger.AppendFormat("  File is {0}opened asynchronously.", this._outputFile.IsAsync ? "" : "not ");
+
+						logger.Print();
 					}
-					else
-					{
-						logger.Append("create");
-						this._outputFile = new FileStream(
-							this.fileName,
-							FileMode.Create,
-							FileAccess.Write,
-							FileShare.Read,
-							512,
-							true
-						);
-
-						byte[] byteOrderMark = utf8Encoding.GetPreamble();
-
-						logger.Append(" and writing preamble");
-						this._outputFile.Write(byteOrderMark, 0, byteOrderMark.Length);
-					}
-
-					logger.Append('.');
-
-					logger.AppendFormat("  File is {0}opened asynchronously.", this._outputFile.IsAsync ? "" : "not ");
-
-					logger.Print();
 				}
 
 				return this._outputFile;
@@ -216,23 +218,24 @@
 
 		public void OnDestroy()
 		{
-			Tools.DebugLogger logger = Tools.DebugLogger.New(this);
-
-			logger.Append("Destroying...");
-
-			this.CloseFileIfOpen();
-
-			logger.Append(" Done.");
-			logger.Print(false);
+			using (PooledDebugLogger logger = PooledDebugLogger.New(this))
+			{
+				logger.Append("Destroying...");
+
+				this.CloseFileIfOpen();
+
+				logger.Append(" Done.");
+				logger.Print(false);
+			}
 		}
 
 		#endregion
 
 		#region VOID_Module Overrides
 
-		public override void LoadConfig()
-		{
-			base.LoadConfig();
+		public override void LoadConfig(KSP.IO.PluginConfiguration config)
+		{
+			base.LoadConfig(config);
 
 			this.logIntervalStr = this.logInterval.value.ToString("#.0##");
 		}
@@ -258,14 +261,14 @@
 				activeLabelStyle = VOID_Styles.labelGreen;
 			}
 
-			this.loggingActive = GUITools.Toggle(
+			this.loggingActive = Layout.Toggle(
 				loggingActive,
 				string.Format("Data logging: {0}", activeLabelText),
 				null,
 				activeLabelStyle
 			);
 
-			this.waitForLaunch.value = GUITools.Toggle(
+			this.waitForLaunch.value = Layout.Toggle(
 				this.waitForLaunch,
 				"Wait for launch"
 			);
@@ -305,109 +308,125 @@
 			//called if logging is on and interval has passed
 			//writes one line to the csvList
 
-			StringBuilder line = new StringBuilder();
-
-			if (firstWrite)
-			{
-				firstWrite = false;
-				line.Append(
-					"\"Kerbin Universal Time (s)\"," +
-					"\"Mission Elapsed Time (s)\t\"," +
-					"\"Altitude ASL (m)\"," +
-					"\"Altitude above terrain (m)\"," +
-					"\"Surface Latitude (°)\"," +
-					"\"Surface Longitude (°)\"," +
-					"\"Apoapsis Altitude (m)\"," +
-					"\"Periapsis Altitude (m)\"," +
-					"\"Orbital Velocity (m/s)\"," +
-					"\"Surface Velocity (m/s)\"," +
-					"\"Vertical Speed (m/s)\"," +
-					"\"Horizontal Speed (m/s)\"," +
-					"\"Gee Force (gees)\"," +
-					"\"Temperature (°C)\"," +
-					"\"Gravity (m/s²)\"," +
-					"\"Atmosphere Density (g/m³)\"," +
-					"\"Downrange Distance  (m)\"," +
-					"\n"
-				);
-			}
-
-			// Universal time
-			line.Append(Planetarium.GetUniversalTime().ToString("F2"));
-			line.Append(',');
-
-			//Mission time
-			line.Append(Vessel.missionTime.ToString("F3"));
-			line.Append(',');
-
-			//Altitude ASL
-			line.Append(VOID_Data.orbitAltitude.Value.ToString("F3"));
-			line.Append(',');
-
-			//Altitude (true)
-			line.Append(VOID_Data.trueAltitude.Value.ToString("F3"));
-			line.Append(',');
-
-			// Surface Latitude
-			line.Append('"');
-			line.Append(VOID_Data.surfLatitude.Value);
-			line.Append('"');
-			line.Append(',');
-
-			// Surface Longitude
-			line.Append('"');
-			line.Append(VOID_Data.surfLongitude.Value);
-			line.Append('"');
-			line.Append(',');
-
-			// Apoapsis Altitude
-			line.Append(VOID_Data.orbitApoAlt.Value.ToString("G3"));
-			line.Append(',');
-
-			// Periapsis Altitude
-			line.Append(VOID_Data.oribtPeriAlt.Value.ToString("G3"));
-			line.Append(',');
-
-			//Orbital velocity
-			line.Append(VOID_Data.orbitVelocity.Value.ToString("F3"));
-			line.Append(',');
-
-			//surface velocity
-			line.Append(VOID_Data.surfVelocity.Value.ToString("F3"));
-			line.Append(',');
-
-			//vertical speed
-			line.Append(VOID_Data.vertVelocity.Value.ToString("F3"));
-			line.Append(',');
-
-			//horizontal speed
-			line.Append(VOID_Data.horzVelocity.Value.ToString("F3"));
-			line.Append(',');
-
-			//gee force
-			line.Append(VOID_Data.geeForce.Value.ToString("F3"));
-			line.Append(',');
-
-			//temperature
-			line.Append(VOID_Data.temperature.Value.ToString("F2"));
-			line.Append(',');
-
-			//gravity
-			line.Append(VOID_Data.gravityAccel.Value.ToString("F3"));
-			line.Append(',');
-
-			//atm density
-			line.Append(VOID_Data.atmDensity.Value.ToString("G3"));
-			line.Append(',');
-
-			// Downrange Distance
-			line.Append((VOID_Data.downrangeDistance.Value.ToString("G3")));
-
-			line.Append('\n');
-
-			csvBytes.AddRange(this.utf8Encoding.GetBytes(line.ToString()));
-
-			this.csvCollectTimer = 0f;
+			using (PooledStringBuilder line = PooledStringBuilder.Get())
+			{
+				if (firstWrite)
+				{
+					firstWrite = false;
+					line.Append(
+						"\"Kerbin Universal Time (s)\"," +
+						"\"Mission Elapsed Time (s)\t\"," +
+						"\"Altitude ASL (m)\"," +
+						"\"Altitude above terrain (m)\"," +
+						"\"Surface Latitude (°)\"," +
+						"\"Surface Longitude (°)\"," +
+						"\"Apoapsis Altitude (m)\"," +
+						"\"Periapsis Altitude (m)\"," +
+						"\"Orbital Inclination (°)\"," +
+						"\"Orbital Velocity (m/s)\"," +
+						"\"Surface Velocity (m/s)\"," +
+						"\"Vertical Speed (m/s)\"," +
+						"\"Horizontal Speed (m/s)\"," +
+						"\"Current Thrust (kN)\"," +
+						"\"Gee Force (gees)\"," +
+						"\"Temperature (°C)\"," +
+						"\"Gravity (m/s²)\"," +
+						"\"Atmosphere Density (g/m³)\"," +
+						"\"Downrange Distance  (m)\"," +
+						"\"Main Throttle\"," +
+						"\n"
+					);
+				}
+
+				// Universal time
+				line.Append(Planetarium.GetUniversalTime().ToString("F2"));
+				line.Append(',');
+
+				//Mission time
+				line.Append(Vessel.missionTime.ToString("F3"));
+				line.Append(',');
+
+				//Altitude ASL
+				line.Append(VOID_Data.orbitAltitude.Value.ToString("G9"));
+				line.Append(',');
+
+				//Altitude (true)
+				line.Append(VOID_Data.trueAltitude.Value.ToString("G9"));
+				line.Append(',');
+
+				// Surface Latitude
+				line.Append('"');
+				line.Append(VOID_Data.surfLatitude.Value.ToString("F3"));
+				line.Append('"');
+				line.Append(',');
+
+				// Surface Longitude
+				line.Append('"');
+				line.Append(VOID_Data.surfLongitude.Value.ToString("F3"));
+				line.Append('"');
+				line.Append(',');
+
+				// Apoapsis Altitude
+				line.Append(VOID_Data.orbitApoAlt.Value.ToString("G9"));
+				line.Append(',');
+
+				// Periapsis Altitude
+				line.Append(VOID_Data.oribtPeriAlt.Value.ToString("G9"));
+				line.Append(',');
+
+				// Orbital Inclination
+				line.Append(VOID_Data.orbitInclination.Value.ToString("F2"));
+				line.Append(',');
+
+				//Orbital velocity
+				line.Append(VOID_Data.orbitVelocity.Value.ToString("G9"));
+				line.Append(',');
+
+				//surface velocity
+				line.Append(VOID_Data.surfVelocity.Value.ToString("G9"));
+				line.Append(',');
+
+				//vertical speed
+				line.Append(VOID_Data.vertVelocity.Value.ToString("G9"));
+				line.Append(',');
+
+				//horizontal speed
+				line.Append(VOID_Data.horzVelocity.Value.ToString("G9"));
+				line.Append(',');
+
+				// Current Thrust
+				line.Append(VOID_Data.currThrust.Value.ToString("G9"));
+				line.Append(',');
+
+				//gee force
+				line.Append(VOID_Data.geeForce.Value.ToString("G9"));
+				line.Append(',');
+
+				//temperature
+				line.Append(VOID_Data.temperature.Value.ToString("F3"));
+				line.Append(',');
+
+				//gravity
+				line.Append(VOID_Data.gravityAccel.Value.ToString("G9"));
+				line.Append(',');
+
+				//atm density
+				line.Append(VOID_Data.atmDensity.Value.ToString("G9"));
+				line.Append(',');
+
+				// Downrange Distance
+				line.Append((VOID_Data.downrangeDistance.Value.ToString("G9")));
+				line.Append(',');
+
+				// Main Throttle
+				line.Append(VOID_Data.mainThrottle.Value.ToString("P2"));
+
+				line.Append('\n');
+
+				csvBytes.AddRange(this.utf8Encoding.GetBytes(line.ToString()));
+
+				this.csvCollectTimer = 0f;
+			}
 		}
 
 		#endregion
@@ -416,7 +435,7 @@
 
 		protected void AsyncWriteCallback(IAsyncResult result)
 		{
-			Tools.PostDebugMessage(this, "Got async callback, IsCompleted = {0}", result.IsCompleted);
+			Logging.PostDebugMessage(this, "Got async callback, IsCompleted = {0}", result.IsCompleted);
 
 			this.outputFile.EndWrite(result);
 			this.outstandingWrites--;
@@ -439,31 +458,32 @@
 
 		private void CloseFileIfOpen()
 		{
-			Tools.DebugLogger logger = Tools.DebugLogger.New(this);
-
-			logger.AppendFormat("Cleaning up file {0}...", this.fileName);
-
-			if (this.csvBytes != null && this.csvBytes.Count > 0)
-			{
-				logger.Append(" Writing remaining data...");
-				this.AsyncWriteData();
-			}
-
-			logger.Append(" Waiting for writes to finish.");
-			while (this.outstandingWrites > 0)
-			{
-				logger.Append('.');
-				System.Threading.Thread.Sleep(10);
-			}
-
-			if (this._outputFile != null)
-			{
-				this._outputFile.Close();
-				this._outputFile = null;
-				logger.Append(" File closed.");
-			}
-
-			logger.Print(false);
+			using (PooledDebugLogger logger = PooledDebugLogger.New(this))
+			{
+				logger.AppendFormat("Cleaning up file {0}...", this.fileName);
+
+				if (this.csvBytes != null && this.csvBytes.Count > 0)
+				{
+					logger.Append(" Writing remaining data...");
+					this.AsyncWriteData();
+				}
+
+				logger.Append(" Waiting for writes to finish.");
+				while (this.outstandingWrites > 0)
+				{
+					logger.Append('.');
+					System.Threading.Thread.Sleep(10);
+				}
+
+				if (this._outputFile != null)
+				{
+					this._outputFile.Close();
+					this._outputFile = null;
+					logger.Append(" File closed.");
+				}
+
+				logger.Print(false);
+			}
 		}
 
 		#endregion

--- a/VOID_EditorHUD.cs
+++ b/VOID_EditorHUD.cs
@@ -30,9 +30,9 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -58,9 +58,12 @@
 			{
 				if (this._vesselOverlays == null)
 				{
-					this._vesselOverlays = (EditorVesselOverlays)Resources
-						.FindObjectsOfTypeAll(typeof(EditorVesselOverlays))
-						.FirstOrDefault();
+					UnityEngine.Object[] overlayObjs = Resources.FindObjectsOfTypeAll(typeof(EditorVesselOverlays));
+
+					if (overlayObjs.Length > 0)
+					{
+						this._vesselOverlays = (EditorVesselOverlays)overlayObjs[0];
+					}
 				}
 
 				return this._vesselOverlays;
@@ -107,114 +110,113 @@
 			this.ehudWindow = new HUDWindow(
 				"editorHUD",
 				this.ehudWindowFunc,
-				new Rect(EditorPanels.Instance.partsPanelWidth + 10f, 125f, 300f, 64f)
+				new Rect(/*EditorPanels.Instance.partsPanelWidth + */10f, 125f, 300f, 64f)
 			);
 			this.Windows.Add(this.ehudWindow);
 
-			Tools.PostDebugMessage (this.GetType().Name + ": Constructed.");
+			Logging.PostDebugMessage (this.GetType().Name + ": Constructed.");
 		}
 
 		public void ehudWindowFunc(int id)
 		{
-			StringBuilder hudString = new StringBuilder();
-
-			SimManager.TryStartSimulation();
-
-			if (this.core.LastStage == null)
+			using (PooledStringBuilder hudString = PooledStringBuilder.Get())
+			{
+				if (this.core.LastStage == null)
+				{
+					return;
+				}
+
+				VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
+
+				hudString.Append("Total Mass: ");
+				hudString.Append(this.core.LastStage.totalMass.ToString("F3"));
+				hudString.Append('t');
+
+				hudString.Append(' ');
+
+				hudString.Append("Part Count: ");
+				hudString.Append(EditorLogic.SortedShipList.Count);
+
+				hudString.Append('\n');
+
+				hudString.Append("Total Delta-V: ");
+				hudString.Append(SIFormatProvider.ToSI(this.core.LastStage.totalDeltaV));
+				hudString.Append("m/s");
+
+				hudString.Append('\n');
+
+				hudString.Append("Bottom Stage Delta-V: ");
+				hudString.Append(SIFormatProvider.ToSI(this.core.LastStage.deltaV));
+				hudString.Append("m/s");
+
+				hudString.Append('\n');
+
+				hudString.Append("Bottom Stage T/W Ratio: ");
+				hudString.Append(this.core.LastStage.thrustToWeight.ToString("F3"));
+
+				Logging.PostDebugMessage(this,
+					"CoMmarker.gameObject.activeInHierarchy: {0};" +
+					"CoTmarker.gameObject.activeInHierarchy: {1}",
+					this.CoMmarker.gameObject.activeInHierarchy,
+					this.CoTmarker.gameObject.activeInHierarchy
+				);
+
+				if (this.CoMmarker.gameObject.activeInHierarchy && this.CoTmarker.gameObject.activeInHierarchy)
+				{
+					Logging.PostDebugMessage(this, "CoM and CoT markers are active, doing thrust offset.");
+					hudString.Append('\n');
+
+					hudString.Append("Thrust Offset: ");
+					hudString.Append(
+						Vector3.Cross(
+							this.CoTmarker.dirMarkerObject.transform.forward,
+							this.CoMmarker.posMarkerObject.transform.position - this.CoTmarker.posMarkerObject.transform.position
+						).ToString("F3"));
+				}
+				#if DEBUG
+			else
+			{
+				Logging.PostDebugMessage(this, "CoM and CoT markers are not active, thrust offset skipped.");
+			}
+				#endif
+
+				GUILayout.Label(
+					hudString.ToString(),
+					VOID_Styles.labelHud,
+					GUILayout.ExpandWidth(true),
+					GUILayout.ExpandHeight(true)
+				);
+
+				if (!this.positionsLocked)
+				{
+					GUI.DragWindow();
+				}
+
+				GUI.BringWindowToBack(id);
+			}
+		}
+
+		public override void DrawGUI(object sender)
+		{
+			float hudLeft;
+
+			if (EditorLogic.fetch.editorScreen == EditorScreen.Parts)
+			{
+				hudLeft = /*EditorPanels.Instance.partsPanelWidth + */10f;
+				hudLeft += /*EditorPartList.Instance.transformTopLeft.position.x -*/
+					/*EditorPartList.Instance.transformTopLeft.parent.parent.position.x -*/
+					72f;
+			}
+			else if (EditorLogic.fetch.editorScreen == EditorScreen.Actions)
+			{
+				hudLeft = /*EditorPanels.Instance.actionsPanelWidth +*/ 10f;
+			}
+			else
 			{
 				return;
 			}
 
-			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
-
-			hudString.Append("Total Mass: ");
-			hudString.Append(this.core.LastStage.totalMass.ToString("F3"));
-			hudString.Append('t');
-
-			hudString.Append(' ');
-
-			hudString.Append("Part Count: ");
-			hudString.Append(EditorLogic.SortedShipList.Count);
-
-			hudString.Append('\n');
-
-			hudString.Append("Total Delta-V: ");
-			hudString.Append(Tools.MuMech_ToSI(this.core.LastStage.totalDeltaV));
-			hudString.Append("m/s");
-
-			hudString.Append('\n');
-
-			hudString.Append("Bottom Stage Delta-V");
-			hudString.Append(Tools.MuMech_ToSI(this.core.LastStage.deltaV));
-			hudString.Append("m/s");
-
-			hudString.Append('\n');
-
-			hudString.Append("Bottom Stage T/W Ratio: ");
-			hudString.Append(this.core.LastStage.thrustToWeight.ToString("F3"));
-
-			Tools.PostDebugMessage(this,
-				"CoMmarker.gameObject.activeInHierarchy: {0};" +
-				"CoTmarker.gameObject.activeInHierarchy: {1}",
-				this.CoMmarker.gameObject.activeInHierarchy,
-				this.CoTmarker.gameObject.activeInHierarchy
-			);
-
-			if (this.CoMmarker.gameObject.activeInHierarchy && this.CoTmarker.gameObject.activeInHierarchy)
-			{
-				Tools.PostDebugMessage(this, "CoM and CoT markers are active, doing thrust offset.");
-				hudString.Append('\n');
-
-				hudString.Append("Thrust Offset: ");
-				hudString.Append(
-					Vector3.Cross(
-						this.CoTmarker.dirMarkerObject.transform.forward,
-						this.CoMmarker.posMarkerObject.transform.position - this.CoTmarker.posMarkerObject.transform.position
-					).ToString("F3"));
-			}
-			#if DEBUG
-			else
-			{
-				Tools.PostDebugMessage(this, "CoM and CoT markers are not active, thrust offset skipped.");
-			}
-			#endif
-
-			GUILayout.Label(
-				hudString.ToString(),
-				VOID_Styles.labelHud,
-				GUILayout.ExpandWidth(true),
-				GUILayout.ExpandHeight(true)
-			);
-
-			if (!this.positionsLocked)
-			{
-				GUI.DragWindow();
-			}
-
-			GUI.BringWindowToBack(id);
-		}
-
-		public override void DrawGUI()
-		{
-			float hudLeft;
-
-			if (EditorLogic.fetch.editorScreen == EditorScreen.Parts)
-			{
-				hudLeft = EditorPanels.Instance.partsPanelWidth + 10f;
-				hudLeft += EditorPartList.Instance.transformTopLeft.position.x -
-					EditorPartList.Instance.transformTopLeft.parent.parent.position.x -
-					72f;
-			}
-			else if (EditorLogic.fetch.editorScreen == EditorScreen.Actions)
-			{
-				hudLeft = EditorPanels.Instance.actionsPanelWidth + 10f;
-			}
-			else
-			{
-				return;
-			}
-
-			Tools.PostDebugMessage(this,
+			/*Logging.PostDebugMessage(this,
 				"EditorPartList topLeft.parent.parent.position: {0}\n" +
 				"EditorPartList topLeft.parent.position: {1}\n" +
 				"EditorPartList topLeft.position: {2}\n" +
@@ -223,9 +225,9 @@
 				EditorPartList.Instance.transformTopLeft.parent.position,
 				EditorPartList.Instance.transformTopLeft.position,
 				this.snapToLeft, this.ehudWindow.WindowPos.xMin, hudLeft
-			);
-
-			base.DrawGUI();
+			);*/
+
+			base.DrawGUI(this);
 
 			Rect hudPos = this.ehudWindow.WindowPos;
 

--- a/VOID_HUD.cs
+++ b/VOID_HUD.cs
@@ -32,6 +32,7 @@
 using System.Collections.Generic;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -63,125 +64,122 @@
 			this.rightHUD = new HUDWindow("rightHUD", this.rightHUDWindow, new Rect(Screen.width * .625f, 0f, 300f, 90f));
 			this.Windows.Add(this.rightHUD);
 
-			Tools.PostDebugMessage ("VOID_HUD: Constructed.");
+			Logging.PostDebugMessage ("VOID_HUD: Constructed.");
 		}
 
 		protected void leftHUDWindow(int id)
 		{
-			StringBuilder leftHUD;
+			using (PooledStringBuilder leftHUD = PooledStringBuilder.Get())
+			{
+				VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
 
-			leftHUD = new StringBuilder();
+				if (this.core.powerAvailable)
+				{
+					leftHUD.AppendFormat("Primary: {0} Inc: {1}",
+						VOID_Data.primaryName.ValueUnitString(),
+						VOID_Data.orbitInclination.ValueUnitString("F3")
+					);
+					leftHUD.AppendFormat("\nObt Alt: {0} Obt Vel: {1}",
+						VOID_Data.orbitAltitude.ToSIString(),
+						VOID_Data.orbitVelocity.ToSIString()
+					);
+					leftHUD.AppendFormat("\nAp: {0} ETA {1}",
+						VOID_Data.orbitApoAlt.ToSIString(),
+						VOID_Data.timeToApo.ValueUnitString()
+					);
+					leftHUD.AppendFormat("\nPe: {0} ETA {1}",
+						VOID_Data.oribtPeriAlt.ToSIString(),
+						VOID_Data.timeToPeri.ValueUnitString()
+					);
+					leftHUD.AppendFormat("\nTot Δv: {0} Stg Δv: {1}",
+						VOID_Data.totalDeltaV.ToSIString(2),
+						VOID_Data.stageDeltaV.ToSIString(2)
+					);
+				}
+				else
+				{
+					VOID_Styles.labelHud.normal.textColor = Color.red;
+					leftHUD.Append(string.Intern("-- POWER LOST --"));
+				}
 
-			VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
+				GUILayout.Label(
+					leftHUD.ToString(),
+					VOID_Styles.labelHud,
+					GUILayout.ExpandWidth(true),
+					GUILayout.ExpandHeight(true)
+				);
 
-			if (this.core.powerAvailable)
-			{
-				leftHUD.AppendFormat("Primary: {0} Inc: {1}",
-					VOID_Data.primaryName.ValueUnitString(),
-					VOID_Data.orbitInclination.ValueUnitString("F3")
-				);
-				leftHUD.AppendFormat("\nObt Alt: {0} Obt Vel: {1}",
-					VOID_Data.orbitAltitude.ToSIString(),
-					VOID_Data.orbitVelocity.ToSIString()
-				);
-				leftHUD.AppendFormat("\nAp: {0} ETA {1}",
-					VOID_Data.orbitApoAlt.ToSIString(),
-					VOID_Data.timeToApo.ValueUnitString()
-				);
-				leftHUD.AppendFormat("\nPe: {0} ETA {1}",
-					VOID_Data.oribtPeriAlt.ToSIString(),
-					VOID_Data.timeToPeri.ValueUnitString()
-				);
-				leftHUD.AppendFormat("\nTot Δv: {0} Stg Δv: {1}",
-					VOID_Data.totalDeltaV.ToSIString(2),
-					VOID_Data.stageDeltaV.ToSIString(2)
-				);
+				if (!this.positionsLocked)
+				{
+					GUI.DragWindow();
+				}
+
+				GUI.BringWindowToBack(id);
 			}
-			else
-			{
-				VOID_Styles.labelHud.normal.textColor = Color.red;
-				leftHUD.Append(string.Intern("-- POWER LOST --"));
-			}
-
-			GUILayout.Label(
-				leftHUD.ToString(),
-				VOID_Styles.labelHud,
-				GUILayout.ExpandWidth(true),
-				GUILayout.ExpandHeight(true)
-			);
-
-			if (!this.positionsLocked)
-			{
-				GUI.DragWindow();
-			}
-
-			GUI.BringWindowToBack(id);
 		}
 
 		protected void rightHUDWindow(int id)
 		{
-			StringBuilder rightHUD;
+			using (PooledStringBuilder rightHUD = PooledStringBuilder.Get())
+			{
+				VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
 
-			rightHUD = new StringBuilder();
+				if (this.core.powerAvailable)
+				{
+					rightHUD.AppendFormat("Biome: {0} Sit: {1}",
+						VOID_Data.currBiome.ValueUnitString(),
+						VOID_Data.expSituation.ValueUnitString()
+					);
+					rightHUD.AppendFormat("\nSrf Alt: {0} Srf Vel: {1}",
+						VOID_Data.trueAltitude.ToSIString(),
+						VOID_Data.surfVelocity.ToSIString()
+					);
+					rightHUD.AppendFormat("\nVer: {0} Hor: {1}",
+						VOID_Data.vertVelocity.ToSIString(),
+						VOID_Data.horzVelocity.ToSIString()
+					);
+					rightHUD.AppendFormat("\nLat: {0} Lon: {1}",
+						VOID_Data.surfLatitudeString.ValueUnitString(),
+						VOID_Data.surfLongitudeString.ValueUnitString()
+					);
+					rightHUD.AppendFormat("\nHdg: {0} Pit: {1}",
+						VOID_Data.vesselHeading.ValueUnitString(),
+						VOID_Data.vesselPitch.ToSIString(2)
+					);
 
-			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
+					if (
+						this.core.Vessel.mainBody == this.core.HomeBody &&
+						(
+						    this.core.Vessel.situation == Vessel.Situations.FLYING ||
+						    this.core.Vessel.situation == Vessel.Situations.SUB_ORBITAL ||
+						    this.core.Vessel.situation == Vessel.Situations.LANDED ||
+						    this.core.Vessel.situation == Vessel.Situations.SPLASHED
+						))
+					{
+						rightHUD.AppendFormat("\nRange to KSC: {0}", VOID_Data.downrangeDistance.ValueUnitString(2));
+					}
+				}
+				else
+				{
+					VOID_Styles.labelHud.normal.textColor = Color.red;
+					rightHUD.Append(string.Intern("-- POWER LOST --"));
+				}
 
-			if (this.core.powerAvailable)
-			{
-				rightHUD.AppendFormat("Biome: {0} Sit: {1}",
-					VOID_Data.currBiome.ValueUnitString(),
-					VOID_Data.expSituation.ValueUnitString()
-				);
-				rightHUD.AppendFormat("\nSrf Alt: {0} Srf Vel: {1}",
-					VOID_Data.trueAltitude.ToSIString(),
-					VOID_Data.surfVelocity.ToSIString()
-				);
-				rightHUD.AppendFormat("\nVer: {0} Hor: {1}",
-					VOID_Data.vertVelocity.ToSIString(),
-					VOID_Data.horzVelocity.ToSIString()
-				);
-				rightHUD.AppendFormat("\nLat: {0} Lon: {1}",
-					VOID_Data.surfLatitude.ValueUnitString(),
-					VOID_Data.surfLongitude.ValueUnitString()
-				);
-				rightHUD.AppendFormat("\nHdg: {0} Pit: {1}",
-					VOID_Data.vesselHeading.ValueUnitString(),
-					VOID_Data.vesselPitch.ToSIString(2)
+
+				GUILayout.Label(
+					rightHUD.ToString(),
+					VOID_Styles.labelHud,
+					GUILayout.ExpandWidth(true),
+					GUILayout.ExpandHeight(true)
 				);
 
-				if (
-					this.core.Vessel.mainBody == this.core.HomeBody &&
-					(
-						this.core.Vessel.situation == Vessel.Situations.FLYING ||
-						this.core.Vessel.situation == Vessel.Situations.SUB_ORBITAL ||
-						this.core.Vessel.situation == Vessel.Situations.LANDED ||
-						this.core.Vessel.situation == Vessel.Situations.SPLASHED
-					)
-				)
+				if (!this.positionsLocked)
 				{
-					rightHUD.AppendFormat("\nRange to KSC: {0}", VOID_Data.downrangeDistance.ValueUnitString(2));
+					GUI.DragWindow();
 				}
+
+				GUI.BringWindowToBack(id);
 			}
-			else
-			{
-				VOID_Styles.labelHud.normal.textColor = Color.red;
-				rightHUD.Append(string.Intern("-- POWER LOST --"));
-			}
-
-
-			GUILayout.Label(
-				rightHUD.ToString(),
-				VOID_Styles.labelHud,
-				GUILayout.ExpandWidth(true),
-				GUILayout.ExpandHeight(true)
-			);
-
-			if (!this.positionsLocked)
-			{
-				GUI.DragWindow();
-			}
-
-			GUI.BringWindowToBack(id);
 		}
 	}
 }

--- a/VOID_HUDAdvanced.cs
+++ b/VOID_HUDAdvanced.cs
@@ -30,9 +30,10 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
+using ToadicusTools.GUIUtils;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -79,7 +80,7 @@
 			this.leftHUD = new HUDWindow("leftHUD",
 				this.leftHUDWindow,
 				new Rect(
-					Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f,
+					Screen.width * .5f - (float)GameSettings.UI_SCALE * .25f - 300f,
 					Screen.height - 200f,
 					300f, 90f)
 			);
@@ -89,7 +90,7 @@
 				"rightHUD",
 				this.rightHUDWindow,
 				new Rect(
-					Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f,
+					Screen.width * .5f + (float)GameSettings.UI_SCALE * .25f,
 					Screen.height - 200f,
 					300f, 90f)
 			);
@@ -97,143 +98,144 @@
 
 			this.positionsLocked.value = true;
 
-			Tools.PostDebugMessage (this, "Constructed.");
+			Logging.PostDebugMessage (this, "Constructed.");
 		}
 
 		protected void leftHUDWindow(int id)
 		{
-			StringBuilder leftHUD;
-
-			leftHUD = new StringBuilder();
-
-			VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
-
-			if (this.core.powerAvailable)
-			{
-				leftHUD.AppendFormat(
-					string.Intern("Mass: {0}\n"),
-					VOID_Data.totalMass.ToSIString(2)
+			using (PooledStringBuilder leftHUD = PooledStringBuilder.Get())
+			{
+				VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
+
+				if (this.core.powerAvailable)
+				{
+					leftHUD.AppendFormat(
+						string.Intern("Mass: {0}\n"),
+						VOID_Data.totalMass.ToSIString(2)
+					);
+
+					if (VOID_Data.vesselCrewCapacity > 0)
+					{
+						leftHUD.AppendFormat(
+							string.Intern("Crew: {0} / {1}\n"),
+							VOID_Data.vesselCrewCount.Value,
+							VOID_Data.vesselCrewCapacity.Value
+						);
+					}
+
+					leftHUD.AppendFormat(
+						string.Intern("Acc: {0} T:W: {1}\n"),
+						VOID_Data.vesselAccel.ToSIString(2),
+						VOID_Data.currThrustWeight.Value.ToString("f2")
+					);
+
+					leftHUD.AppendFormat(
+						string.Intern("Ang Vel: {0}\n"),
+						VOID_Data.vesselAngularVelocity.ToSIString(2)
+					);
+
+					if (VOID_Data.stageNominalThrust != 0d)
+					{
+						leftHUD.AppendFormat(
+							string.Intern("Thrust Offset: {0}\n"),
+							VOID_Data.vesselThrustOffset.Value.ToString("F1")
+						);
+					}
+				}
+				else
+				{
+					VOID_Styles.labelHud.normal.textColor = Color.red;
+					leftHUD.Append(string.Intern("-- POWER LOST --"));
+				}
+
+				GUILayout.Label(
+					leftHUD.ToString(),
+					VOID_Styles.labelHud,
+					GUILayout.ExpandWidth(true),
+					GUILayout.ExpandHeight(true)
 				);
 
-				if (VOID_Data.vesselCrewCapacity > 0)
-				{
-					leftHUD.AppendFormat(
-						string.Intern("Crew: {0} / {1}\n"),
-						VOID_Data.vesselCrewCount.Value,
-						VOID_Data.vesselCrewCapacity.Value
-					);
-				}
-
-				leftHUD.AppendFormat(
-					string.Intern("Acc: {0} T:W: {1}\n"),
-					VOID_Data.vesselAccel.ToSIString(2),
-					VOID_Data.currThrustWeight.Value.ToString("f2")
+				if (!this.positionsLocked)
+				{
+					GUI.DragWindow();
+				}
+
+				GUI.BringWindowToBack(id);
+			}
+		}
+
+		protected void rightHUDWindow(int id)
+		{
+			using (PooledStringBuilder rightHUD = PooledStringBuilder.Get())
+			{
+				VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
+
+				if (this.core.powerAvailable)
+				{
+					rightHUD.AppendFormat(
+						"Burn Δv (Rem/Tot): {0} / {1}\n",
+						VOID_Data.currManeuverDVRemaining.ValueUnitString("f2"),
+						VOID_Data.currManeuverDeltaV.ValueUnitString("f2")
+					);
+
+					if (VOID_Data.upcomingManeuverNodes > 1)
+					{
+						rightHUD.AppendFormat("Next Burn Δv: {0}\n",
+							VOID_Data.nextManeuverDeltaV.ValueUnitString("f2")
+						);
+					}
+
+					rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n",
+						VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnRemaining.Value),
+						VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnDuration.Value)
+					);
+
+					if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty)
+					{
+						rightHUD.AppendFormat("{0} (done @ node)\n",
+							VOID_Data.burnTimeDoneAtNode.Value
+						);
+
+						rightHUD.AppendFormat("{0} (½ done @ node)",
+							VOID_Data.burnTimeHalfDoneAtNode.Value
+						);
+					}
+					else
+					{
+						rightHUD.Append("Node is past");
+					}
+				}
+				else
+				{
+					VOID_Styles.labelHud.normal.textColor = Color.red;
+					rightHUD.Append(string.Intern("-- POWER LOST --"));
+				}
+
+				GUILayout.Label(
+					rightHUD.ToString(),
+					VOID_Styles.labelHud,
+					GUILayout.ExpandWidth(true),
+					GUILayout.ExpandHeight(true)
 				);
 
-				leftHUD.AppendFormat(
-					string.Intern("Ang Vel: {0}\n"),
-					VOID_Data.vesselAngularVelocity.ToSIString(2)
-				);
-
-				if (VOID_Data.stageNominalThrust != 0d)
-				{
-					leftHUD.AppendFormat(
-						string.Intern("Thrust Offset: {0}\n"),
-						VOID_Data.vesselThrustOffset.Value.ToString("F1")
-					);
-				}
-			}
-			else
-			{
-				VOID_Styles.labelHud.normal.textColor = Color.red;
-				leftHUD.Append(string.Intern("-- POWER LOST --"));
-			}
-
-			GUILayout.Label(
-				leftHUD.ToString(),
-				VOID_Styles.labelHud,
-				GUILayout.ExpandWidth(true),
-				GUILayout.ExpandHeight(true)
-			);
-
-			if (!this.positionsLocked)
-			{
-				GUI.DragWindow();
-			}
-
-			GUI.BringWindowToBack(id);
-		}
-
-		protected void rightHUDWindow(int id)
-		{
-			StringBuilder rightHUD;
-
-			rightHUD = new StringBuilder();
-
-			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
-
-			if (this.core.powerAvailable)
-			{
-				rightHUD.AppendFormat(
-					"Burn Δv (Rem/Tot): {0} / {1}\n",
-					VOID_Data.currManeuverDVRemaining.ValueUnitString("f2"),
-					VOID_Data.currManeuverDeltaV.ValueUnitString("f2")
-				);
-
-				if (VOID_Data.upcomingManeuverNodes > 1)
-				{
-					rightHUD.AppendFormat("Next Burn Δv: {0}\n",
-						VOID_Data.nextManeuverDeltaV.ValueUnitString("f2")
-					);
-				}
-
-				rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n",
-					VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnRemaining.Value),
-					VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnDuration.Value)
-				);
-
-				if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty)
-				{
-					rightHUD.AppendFormat("{0} (done @ node)\n",
-						VOID_Data.burnTimeDoneAtNode.Value
-					);
-
-					rightHUD.AppendFormat("{0} (½ done @ node)",
-						VOID_Data.burnTimeHalfDoneAtNode.Value
-					);
-				}
-				else
-				{
-					rightHUD.Append("Node is past");
-				}
-			}
-			else
-			{
-				VOID_Styles.labelHud.normal.textColor = Color.red;
-				rightHUD.Append(string.Intern("-- POWER LOST --"));
-			}
-
-			GUILayout.Label(
-				rightHUD.ToString(),
-				VOID_Styles.labelHud,
-				GUILayout.ExpandWidth(true),
-				GUILayout.ExpandHeight(true)
-			);
-
-			if (!this.positionsLocked)
-			{
-				GUI.DragWindow();
-			}
-
-			GUI.BringWindowToBack(id);
-		}
-
-		public override void DrawGUI()
+				if (!this.positionsLocked)
+				{
+					GUI.DragWindow();
+				}
+
+				GUI.BringWindowToBack(id);
+			}
+		}
+
+		public override void DrawGUI(object sender)
 		{
 			if (this.primaryHUD == null)
 			{
-				foreach (IVOID_Module module in this.core.Modules)
-				{
+				IVOID_Module module;
+				for (int idx = 0; idx < this.core.Modules.Count; idx++)
+				{
+					module = this.core.Modules[idx];
+
 					if (module is VOID_HUD)
 					{
 						this.primaryHUD = module as VOID_HUD;
@@ -250,7 +252,7 @@
 				this.Windows.Add(this.rightHUD);
 			}
 
-			base.DrawGUI();
+			base.DrawGUI(sender);
 		}
 
 		public override void DrawConfigurables()
@@ -259,13 +261,16 @@
 
 			if (GUILayout.Button(string.Intern("Reset Advanced HUD Positions"), GUILayout.ExpandWidth(false)))
 			{
-				foreach (HUDWindow window in this.Windows)
-				{
+				HUDWindow window;
+				for (int idx = 0; idx < this.Windows.Count; idx++)
+				{
+					window = this.Windows[idx];
+
 					window.WindowPos = new Rect(window.defaultWindowPos);
 				}
 			}
 
-			this.positionsLocked.value = GUITools.Toggle(this.positionsLocked, string.Intern("Lock Advanced HUD Positions"));
+			this.positionsLocked.value = Layout.Toggle(this.positionsLocked, string.Intern("Lock Advanced HUD Positions"));
 		}
 	}
 }

--- a/VOID_Orbital.cs
+++ b/VOID_Orbital.cs
@@ -29,6 +29,7 @@
 using KSP;
 using System;
 using ToadicusTools;
+using ToadicusTools.GUIUtils;
 using UnityEngine;
 
 namespace VOID
@@ -83,7 +84,7 @@
 			this.precisionValues [idx]= (ushort)VOID_Data.gravityAccel.DoGUIHorizontal (this.precisionValues [idx]);
 			idx++;
 
-			this.toggleExtended.value = GUITools.Toggle(this.toggleExtended, "Extended info");
+			this.toggleExtended.value = Layout.Toggle(this.toggleExtended, "Extended info");
 
 			if (this.toggleExtended)
             {
@@ -116,18 +117,18 @@
 			base.ModuleWindow(id);
 		}
 
-		public override void LoadConfig ()
+		public override void LoadConfig(KSP.IO.PluginConfiguration config)
 		{
-			base.LoadConfig ();
+			base.LoadConfig(config);
 
 			this.precisionValues = new IntCollection (4, this._precisionValues);
 		}
 
-		public override void Save (KSP.IO.PluginConfiguration config)
+		public override void Save (KSP.IO.PluginConfiguration config, string sceneKey)
 		{
 			this._precisionValues.value = this.precisionValues.collection;
 
-			base.Save (config);
+			base.Save (config, sceneKey);
 		}
 	}
 }

--- a/VOID_Rendezvous.cs
+++ b/VOID_Rendezvous.cs
@@ -29,8 +29,9 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
+using ToadicusTools.GUIUtils;
+using ToadicusTools.Text;
 using UnityEngine;
 
 namespace VOID
@@ -58,12 +59,19 @@
 
 		public override void ModuleWindow(int id)
 		{
-			Vessel rendezvessel = new Vessel();
-			CelestialBody rendezbody = new CelestialBody();
+			Vessel rendezvessel;
+			CelestialBody rendezbody;
 
 			if (this.RegisterModule == null)
 			{
-				this.RegisterModule = this.core.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister;
+				for (int idx = 0; idx < this.core.Modules.Count; idx++)
+				{
+					if (this.core.Modules[idx] is VOID_VesselRegister)
+					{
+						this.RegisterModule = this.core.Modules[idx] as VOID_VesselRegister;
+						break;
+					}
+				}
 			}
 
 			GUILayout.BeginVertical();
@@ -90,7 +98,7 @@
 				if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false)))
 				{
 					FlightGlobals.fetch.SetVesselTarget(null);
-					Tools.PostDebugMessage("VOID_Rendezvous: KSP Target set to null");
+					Logging.PostDebugMessage("VOID_Rendezvous: KSP Target set to null");
 				}
 
 			}
@@ -117,7 +125,7 @@
 						if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
 						{
 							FlightGlobals.fetch.SetVesselTarget(rendezvessel);
-							Tools.PostDebugMessage("[VOID] KSP Target set to " + rendezvessel.vesselName);
+							Logging.PostDebugMessage("[VOID] KSP Target set to " + rendezvessel.vesselName);
 						}
 					}
 				}
@@ -129,7 +137,7 @@
 				}
 			}
 
-			untoggleRegisterInfo.value = GUITools.Toggle(untoggleRegisterInfo, "Hide Vessel Register Info");
+			untoggleRegisterInfo.value = Layout.Toggle(untoggleRegisterInfo, "Hide Vessel Register Info");
 
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			GUILayout.Label(" ", GUILayout.ExpandWidth(true));
@@ -160,12 +168,12 @@
 					//display orbital info for orbiting/flying/suborbital/escaping vessels only
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Ap/Pe:");
-					GUILayout.Label(Tools.MuMech_ToSI(v.orbit.ApA) + "m / " + Tools.MuMech_ToSI(v.orbit.PeA) + "m", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI(v.orbit.ApA, 3) + "m / " + SIFormatProvider.ToSI(v.orbit.PeA, 3) + "m", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Altitude:");
-					GUILayout.Label(Tools.MuMech_ToSI(v.orbit.altitude) + "m", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI(v.orbit.altitude, 3) + "m", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
@@ -177,24 +185,24 @@
 					{
 						GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 						GUILayout.Label("Relative inclination:");
-						GUILayout.Label(Vector3d.Angle(Vessel.orbit.GetOrbitNormal(), v.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
+						GUILayout.Label(Vector3.Angle(Vessel.orbit.GetOrbitNormal(), v.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
 						GUILayout.EndHorizontal();
 					}
 					//if (debugging) Debug.Log("[CHATR] v -> v relative incl OK");
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Velocity:");
-					GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI(v.orbit.vel.magnitude, 3) + "m/s", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Relative velocity:");
-					GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude - Vessel.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI(v.orbit.vel.magnitude - Vessel.orbit.vel.magnitude, 3) + "m/s", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Distance:");
-					GUILayout.Label(Tools.MuMech_ToSI((Vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI((Vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude, 3) + "m", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 
 					// Toadicus edit: added local sidereal longitude.
@@ -203,7 +211,7 @@
 					GUILayout.Label(LSL.ToString("F3") + "°", VOID_Styles.labelRight);
 					GUILayout.EndHorizontal();
 
-					toggleExtendedOrbital.value = GUITools.Toggle(toggleExtendedOrbital, "Extended info");
+					toggleExtendedOrbital.value = Layout.Toggle(toggleExtendedOrbital, "Extended info");
 
 					if (toggleExtendedOrbital)
 					{
@@ -264,7 +272,7 @@
 
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Distance:");
-					GUILayout.Label(Tools.MuMech_ToSI((Vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false));
+					GUILayout.Label(SIFormatProvider.ToSI((Vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude, 3) + "m", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 				}
 			}
@@ -275,7 +283,7 @@
 
 				GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 				GUILayout.Label("Ap/Pe:");
-				GUILayout.Label(Tools.MuMech_ToSI(cb.orbit.ApA) + "m / " + Tools.MuMech_ToSI(cb.orbit.PeA) + "m", GUILayout.ExpandWidth(false));
+				GUILayout.Label(SIFormatProvider.ToSI(cb.orbit.ApA, 3) + "m / " + SIFormatProvider.ToSI(cb.orbit.PeA, 3) + "m", GUILayout.ExpandWidth(false));
 				GUILayout.EndHorizontal();
 				//if (debugging) Debug.Log("[VOID] Ap/Pe OK");
 
@@ -289,14 +297,14 @@
 				{
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					GUILayout.Label("Relative inclination:");
-					GUILayout.Label(Vector3d.Angle(Vessel.orbit.GetOrbitNormal(), cb.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
+					GUILayout.Label(Vector3.Angle(Vessel.orbit.GetOrbitNormal(), cb.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
 					GUILayout.EndHorizontal();
 					//if (debugging) Debug.Log("[VOID] cb Relative inclination OK");
 				}
 
 				GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 				GUILayout.Label("Distance:");
-				GUILayout.Label(Tools.MuMech_ToSI((Vessel.mainBody.position - cb.position).magnitude) + "m", GUILayout.ExpandWidth(false));
+				GUILayout.Label(SIFormatProvider.ToSI((Vessel.mainBody.position - cb.position).magnitude, 3) + "m", GUILayout.ExpandWidth(false));
 				GUILayout.EndHorizontal();
 
 				//if (debugging) Debug.Log("[VOID] Distance OK");

--- a/VOID_StageInfo.cs
+++ b/VOID_StageInfo.cs
@@ -7,8 +7,7 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using ToadicusTools;
+using ToadicusTools.GUIUtils;
 using UnityEngine;
 
 namespace VOID
@@ -117,9 +116,9 @@
 			);
 		}
 
-		public override void DrawGUI()
-		{
-			base.DrawGUI();
+		public override void DrawGUI(object sender)
+		{
+			base.DrawGUI(sender);
 
 			if (this.showBodyList)
 			{
@@ -171,8 +170,11 @@
 				SimManager.Atmosphere = 0d;
 			}
 
-			foreach (Stage stage in core.Stages)
-			{
+			Stage stage;
+			for (int idx = 0; idx < core.Stages.Length; idx++)
+			{
+				stage = core.Stages[idx];
+
 				if (stage.deltaV == 0 && stage.mass == 0)
 				{
 					continue;
@@ -257,7 +259,7 @@
 			{
 				GUILayout.BeginHorizontal();
 
-				this.useSeaLevel.value = GUITools.Toggle(this.useSeaLevel, this.seaLevelToggle, false);
+				this.useSeaLevel.value = Layout.Toggle(this.useSeaLevel, this.seaLevelToggle, false);
 
 				GUILayout.EndHorizontal();
 			}
@@ -288,8 +290,10 @@
 
 		private void BodyPickerWindow(int _)
 		{
-			foreach (CelestialBody body in core.SortedBodyList)
-			{
+			CelestialBody body;
+			for (int idx = 0; idx < core.SortedBodyList.Count; idx++)
+			{
+				body = core.SortedBodyList[idx];
 				if (GUILayout.Button(body.bodyName, VOID_Styles.labelDefault))
 				{
 					Debug.Log("Picked new body focus: " + body.bodyName);

--- a/VOID_SurfAtmo.cs
+++ b/VOID_SurfAtmo.cs
@@ -58,9 +58,9 @@
 			this.precisionValues[idx] = (ushort)VOID_Data.trueAltitude.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			VOID_Data.surfLatitude.DoGUIHorizontal();
+			VOID_Data.surfLatitudeString.DoGUIHorizontal();
 
-			VOID_Data.surfLongitude.DoGUIHorizontal();
+			VOID_Data.surfLongitudeString.DoGUIHorizontal();
 
 			VOID_Data.vesselHeading.DoGUIHorizontal();
 
@@ -98,18 +98,18 @@
 			base.ModuleWindow(id);
 		}
 
-		public override void LoadConfig()
+		public override void LoadConfig(KSP.IO.PluginConfiguration config)
 		{
-			base.LoadConfig();
+			base.LoadConfig(config);
 
 			this.precisionValues = new IntCollection(4, this._precisionValues);
 		}
 
-		public override void Save(KSP.IO.PluginConfiguration config)
+		public override void Save(KSP.IO.PluginConfiguration config, string sceneKey)
 		{
 			this._precisionValues.value = this.precisionValues.collection;
 
-			base.Save(config);
+			base.Save(config, sceneKey);
 		}
 	}
 }

--- a/VOID_TWR.cs
+++ b/VOID_TWR.cs
@@ -3,11 +3,9 @@
 // This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
 // copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
 
+using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -28,7 +26,7 @@
 				(TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)
 			)
 			{
-				KerbalEngineer.VesselSimulator.SimManager.RequestSimulation();
+				SimManager.RequestSimulation();
 			}
 
 			GUILayout.BeginVertical();
@@ -43,8 +41,11 @@
 			}
 			else
 			{
-				foreach (CelestialBody body in core.SortedBodyList)
+				CelestialBody body;
+				for (int idx = 0; idx < core.SortedBodyList.Count; idx++)
 				{
+					body = core.SortedBodyList[idx];
+
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 
 					GUILayout.Label(body.bodyName);

--- a/VOID_Transfer.cs
+++ b/VOID_Transfer.cs
@@ -29,7 +29,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 
@@ -50,12 +49,16 @@
 
 		public override void ModuleWindow(int id)
 		{
+			CelestialBody body;
+
 			GUILayout.BeginVertical();
 
 			if (Vessel.mainBody.name == "Sun")  //Vessel is orbiting the Sun
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.orbitingBodies)
+			    for (int idx = 0; idx < Vessel.mainBody.orbitingBodies.Count; idx++)
 			    {
+					body = Vessel.mainBody.orbitingBodies[idx];
+
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					if (GUILayout.Button(body.bodyName))
 					{
@@ -75,8 +78,9 @@
 			}
 			else if (Vessel.mainBody.referenceBody.name == "Sun")	//Vessel is orbiting a planet
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.referenceBody.orbitingBodies)
-			    {
+			    for (int idx = 0; idx < Vessel.mainBody.referenceBody.orbitingBodies.Count; idx++)
+				{
+					body = Vessel.mainBody.referenceBody.orbitingBodies[idx];
 			        if (body.name != Vessel.mainBody.name)	// show other planets
 			        {
 			            GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
@@ -96,8 +100,10 @@
 			            }
 			        }
 			    }
-			    foreach (CelestialBody body in Vessel.mainBody.orbitingBodies)	// show moons
+			    for (int moonIdx = 0; moonIdx < Vessel.mainBody.orbitingBodies.Count; moonIdx++)
 			    {
+					body = Vessel.mainBody.orbitingBodies[moonIdx];
+
 			        GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			        if (GUILayout.Button(body.bodyName))
 			        {
@@ -117,8 +123,10 @@
 			}
 			else if (Vessel.mainBody.referenceBody.referenceBody.name == "Sun")	// Vessel is orbiting a moon
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.referenceBody.orbitingBodies)
+			    for (int idx = 0; idx < Vessel.mainBody.referenceBody.orbitingBodies.Count; idx++)
 			    {
+					body = Vessel.mainBody.referenceBody.orbitingBodies[idx];
+
 					if (body.name != Vessel.mainBody.name)	// show other moons
 					{
 						GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
@@ -155,7 +163,7 @@
 		            if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
 		            {
 		                FlightGlobals.fetch.SetVesselTarget(body);
-						Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
+						Logging.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
 		            }
 		        }
 		        else if ((CelestialBody)FlightGlobals.fetch.VesselTarget == body)
@@ -163,7 +171,7 @@
 		            if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false)))
 		            {
 		                FlightGlobals.fetch.SetVesselTarget(null);
-		                Tools.PostDebugMessage("[VOID] KSP Target set to null");
+		                Logging.PostDebugMessage("[VOID] KSP Target set to null");
 		            }
 		        }
 		    }
@@ -173,7 +181,7 @@
 		        if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
 		        {
 		            FlightGlobals.fetch.SetVesselTarget(body);
-		            Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
+		            Logging.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
 		        }
 		    }
 		}

--- a/VOID_VesselInfo.cs
+++ b/VOID_VesselInfo.cs
@@ -31,7 +31,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -60,27 +59,27 @@
 				VOID_Styles.labelCenterBold,
 				GUILayout.ExpandWidth(true));
 
-			VOID_Data.geeForce.DoGUIHorizontal ("F2");
+			VOID_Data.geeForce.DoGUIHorizontal("F2");
 
-			VOID_Data.partCount.DoGUIHorizontal ();
+			VOID_Data.partCount.DoGUIHorizontal();
 
-			VOID_Data.totalMass.DoGUIHorizontal ("F3");
+			VOID_Data.totalMass.DoGUIHorizontal("F3");
 
 			VOID_Data.stageResourceMass.DoGUIHorizontal("F3");
 
 			VOID_Data.resourceMass.DoGUIHorizontal("F3");
 
-			VOID_Data.stageDeltaV.DoGUIHorizontal (3, false);
+			VOID_Data.stageDeltaV.DoGUIHorizontal(3, false);
 
-			VOID_Data.totalDeltaV.DoGUIHorizontal (3, false);
+			VOID_Data.totalDeltaV.DoGUIHorizontal(3, false);
 
-			VOID_Data.mainThrottle.DoGUIHorizontal ("F0");
+			VOID_Data.mainThrottle.DoGUIHorizontal("P0");
 
-			VOID_Data.currmaxThrust.DoGUIHorizontal ();
+			VOID_Data.currmaxThrust.DoGUIHorizontal();
 
-			VOID_Data.currmaxThrustWeight.DoGUIHorizontal ();
+			VOID_Data.currmaxThrustWeight.DoGUIHorizontal();
 
-			VOID_Data.surfaceThrustWeight.DoGUIHorizontal ("F2");
+			VOID_Data.surfaceThrustWeight.DoGUIHorizontal("F2");
 
 			VOID_Data.intakeAirStatus.DoGUIHorizontal();
 

--- a/VOID_VesselRegister.cs
+++ b/VOID_VesselRegister.cs
@@ -28,8 +28,6 @@
 
 using KSP;
 using System;
-using System.Linq;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -76,9 +74,19 @@
 
 		public override void ModuleWindow(int id)
 		{
-			if (!this.core.AllVesselTypes.Any())
+			if (this.core.AllVesselTypes.Length < 1)
 			{
 				return;
+			}
+
+			if (selectedBodyIdx >= this.core.SortedBodyList.Count)
+			{
+				selectedBodyIdx.value %= this.core.SortedBodyList.Count;
+			}
+
+			if (selectedBodyIdx < 0)
+			{
+				selectedBodyIdx.value += this.core.SortedBodyList.Count;
 			}
 
 			GUILayout.BeginVertical();
@@ -89,21 +97,21 @@
 				selectedBodyIdx.value--;
 				if (selectedBodyIdx < 0)
 				{
-					selectedBodyIdx.value = this.core.AllBodies.Count - 1;
+					selectedBodyIdx.value = this.core.SortedBodyList.Count - 1;
 				}
 			}
-			GUILayout.Label(this.core.AllBodies[selectedBodyIdx].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
+			GUILayout.Label(this.core.SortedBodyList[selectedBodyIdx].bodyName, VOID_Styles.labelCenterBold, GUILayout.ExpandWidth(true));
 			if (GUILayout.Button(">"))
 			{
 				selectedBodyIdx.value++;
-				if (selectedBodyIdx > this.core.AllBodies.Count - 1)
+				if (selectedBodyIdx > this.core.SortedBodyList.Count - 1)
 				{
 					selectedBodyIdx.value = 0;
 				}
 			}
 			GUILayout.EndHorizontal();
 
-			seletedBody = this.core.AllBodies[selectedBodyIdx];
+			seletedBody = this.core.SortedBodyList[selectedBodyIdx];
 
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			if (GUILayout.Button("<"))
@@ -141,8 +149,11 @@
 
 			selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false);
 
-			foreach (Vessel v in FlightGlobals.Vessels)
+			Vessel v;
+			for (int idx = 0; idx < FlightGlobals.Vessels.Count; idx++)
 			{
+				v = FlightGlobals.Vessels[idx];
+
 				if (v != Vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody)
 				{
 					if ((vesselSituation == "Landed" &&