Updated references to use v1.0
Updated references to use v1.0

--- a/Documents/CHANGES.txt
+++ b/Documents/CHANGES.txt
@@ -1,5 +1,42 @@
-1.0.13, 16-12-2014
-	Updated for KSP version 0.90
+1.0.15.2, 13-02-2015
+    Padishar's Fixes:
+        Fixed: Calculation of per-stage resource mass.
+
+1.0.15.1, 13-02-2015
+    Rebuild
+    
+1.0.15.0, 08-02-2015
+    Padishar's Fixes:
+        Added: Support KIDS ISP thrust correction.
+        Fixed: Log spam for stage priority mode.
+        Fixed: Locked tanks preventing simulation from staging.
+        Fixed: No flow and all vessel modes to respect flow states.
+
+1.0.14.1, 28-12-2014
+    Fixed: Missing texture on the ER-7500 model.
+    
+1.0.14.0, 28-12-2014
+    Added: Career mode that limits the Flight Engineer by:
+        - Requiring an Engineer Kerbal of any level, or placement of an Engineer Chip or ER-7500 part.
+        - Tracking station level 3 enables Flight Engineer everywhere.
+
+    Added: New readouts to the orbital category:
+        - Mean Anomaly at Epoc
+
+    Added: New readouts to the miscellaneous category:
+        - System Time
+
+    Added: Editor Overlay Tab's X position is now changable in the BuildOverlay.xml settings file.
+    Changed: Editor Overlay Tabs start position moved over as to not overlap the parts menu.
+    Fixed: Bug where STAGE_PRIORITY_FLOW resources would not be corrently disabled/enabled.
+    Fixed: Issue with the formatting large Mass and Cost values.
+    Fixed: Error when loading the Engineer7500 part model.
+
+1.0.13.1, 16-12-2014
+    Fixed: Issue with manoeuvre node readouts and low tier tracking station.
+
+1.0.13.0, 16-12-2014
+    Updated for KSP version 0.90
 
     Added: New readouts to the vessel category:
         - Heading Rate
@@ -7,30 +44,30 @@
         - Roll Rate
 
     Changed: Simulation to look for fuel lines that use CModuleFuelLine module.
-	Fixed: Editor Overlay now loads the saved visibility value properly.
+    Fixed: Editor Overlay now loads the saved visibility value properly.
     Fixed: Altitude (Terrain) will no longer give a reading below sea level.
     Fixed: Suicide burn now uses radar altitude that clamps to sea level.
 
 1.0.12.0, 01-12-2014
-	Added: Setting in Build Engineer to enable/disable vectored thrust calculations.
-	Added: Thrust torque field in Build Engineer (courtesy of mic_e).
-	Added: New readouts to the vessel category:
-		- Thrust Offset Angle (courtesy of mic_e)
-		- Thrust Torque (courtesy of mic_e)
-		- Part Count:  stage/total
-		- Heading
-		- Pitch
-		- Roll
-
-	Added: New readouts to the surface category:
-		- Situation
-
-	Added: New readouts to the miscellaneous category:
-		- Vectored Thrust Toggle
-
-	Fixed: The category selection within the section editors now do not always reset back to 'Orbital'.
-	Fixed: Issue where the vessel simulation can sometimes permanently freeze.
-	Fixed: Issue where the vessel simulation would not show updates when the delay was set lower than the frame rate.
+    Added: Setting in Build Engineer to enable/disable vectored thrust calculations.
+    Added: Thrust torque field in Build Engineer (courtesy of mic_e).
+    Added: New readouts to the vessel category:
+        - Thrust Offset Angle (courtesy of mic_e)
+        - Thrust Torque (courtesy of mic_e)
+        - Part Count:  stage/total
+        - Heading
+        - Pitch
+        - Roll
+
+    Added: New readouts to the surface category:
+        - Situation
+
+    Added: New readouts to the miscellaneous category:
+        - Vectored Thrust Toggle
+
+    Fixed: The category selection within the section editors now do not always reset back to 'Orbital'.
+    Fixed: Issue where the vessel simulation can sometimes permanently freeze.
+    Fixed: Issue where the vessel simulation would not show updates when the delay was set lower than the frame rate.
 
 1.0.11.3, 11-11-2014
     Changed: Gravity measurements for Isp to 9.82.

--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -133,6 +133,7 @@
                 this.bodiesList.DrawCallback = this.DrawBodiesList;
                 this.Load();
 
+                SimManager.UpdateModSettings();
                 SimManager.OnReady -= this.GetStageInfo;
                 SimManager.OnReady += this.GetStageInfo;
             }
@@ -168,11 +169,6 @@
             }
         }
 
-        private void GetStageInfo()
-        {
-            this.stages = SimManager.Stages;
-        }
-
         protected void OnGUI()
         {
             try
@@ -380,7 +376,7 @@
             {
                 if (this.showAllStages || stage.deltaV > 0)
                 {
-                    GUILayout.Label(Units.Concat(stage.cost, stage.totalCost), this.infoStyle);
+                    GUILayout.Label(Units.Cost(stage.cost, stage.totalCost), this.infoStyle);
                 }
             }
             GUILayout.EndVertical();
@@ -479,8 +475,14 @@
 
             GUILayout.BeginHorizontal();
             GUILayout.Label("Flight Engineer activation mode:", this.settingStyle);
-            FlightEngineerPartless.IsPartless = GUILayout.Toggle(FlightEngineerPartless.IsPartless, "PARTLESS", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
-            FlightEngineerPartless.IsPartless = !GUILayout.Toggle(!FlightEngineerPartless.IsPartless, "MODULE", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+            FlightEngineerCore.IsCareerMode = GUILayout.Toggle(FlightEngineerCore.IsCareerMode, "CAREER", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+            FlightEngineerCore.IsCareerMode = !GUILayout.Toggle(!FlightEngineerCore.IsCareerMode, "PARTLESS", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+            GUILayout.EndHorizontal();
+
+            GUILayout.BeginHorizontal();
+            GUILayout.Label("Flight Engineer Career Limitations:", this.settingStyle);
+            FlightEngineerCore.IsKerbalLimited = GUILayout.Toggle(FlightEngineerCore.IsKerbalLimited, "KERBAL", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+            FlightEngineerCore.IsTrackingStationLimited = GUILayout.Toggle(FlightEngineerCore.IsTrackingStationLimited, "TRACKING", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
             GUILayout.EndHorizontal();
 
             GUILayout.BeginHorizontal();
@@ -583,6 +585,11 @@
                 BuildOverlayPartInfo.Hidden = false;
                 this.isEditorLocked = false;
             }
+        }
+
+        private void GetStageInfo()
+        {
+            this.stages = SimManager.Stages;
         }
 
         /// <summary>

--- a/KerbalEngineer/Editor/BuildOverlay.cs
+++ b/KerbalEngineer/Editor/BuildOverlay.cs
@@ -19,17 +19,21 @@
 
 #region Using Directives
 
-using System;
-
-using KerbalEngineer.Helpers;
-using KerbalEngineer.Settings;
-
-using UnityEngine;
+
 
 #endregion
 
 namespace KerbalEngineer.Editor
 {
+    #region Using Directives
+
+    using System;
+    using Helpers;
+    using Settings;
+    using UnityEngine;
+
+    #endregion
+
     [KSPAddon(KSPAddon.Startup.EditorAny, false)]
     public class BuildOverlay : MonoBehaviour
     {
@@ -191,7 +195,7 @@
 
         #endregion
 
-        #region Methods: public
+        #region Methods
 
         public static void Load()
         {
@@ -201,6 +205,7 @@
             BuildOverlayPartInfo.ClickToOpen = handler.GetSet("clickToOpen", BuildOverlayPartInfo.ClickToOpen);
             buildOverlayVessel.Open = handler.GetSet("vesselOpen", buildOverlayVessel.Open);
             buildOverlayResources.Open = handler.GetSet("resourcesOpen", buildOverlayResources.Open);
+            buildOverlayVessel.WindowX = handler.GetSet("vesselWindowX", buildOverlayVessel.WindowX);
             handler.Save("BuildOverlay.xml");
         }
 
@@ -212,12 +217,9 @@
             handler.Set("clickToOpen", BuildOverlayPartInfo.ClickToOpen);
             handler.Set("vesselOpen", buildOverlayVessel.Open);
             handler.Set("resourcesOpen", buildOverlayResources.Open);
+            handler.Set("vesselWindowX", buildOverlayVessel.WindowX);
             handler.Save("BuildOverlay.xml");
         }
-
-        #endregion
-
-        #region Methods: protected
 
         protected void Awake()
         {

--- a/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
+++ b/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
@@ -195,7 +195,7 @@
 
         private void SetCostInfo()
         {
-            this.infoItems.Add(new PartInfoItem("Cost", Units.Concat(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
+            this.infoItems.Add(new PartInfoItem("Cost", Units.ConcatF(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
         }
 
         private void SetDecouplerInfo()
@@ -222,7 +222,7 @@
 
             var engine = this.selectedPart.GetProtoModuleEngine();
             this.infoItems.Add(new PartInfoItem("Thrust", Units.ToForce(engine.MinimumThrust, engine.MaximumThrust)));
-            this.infoItems.Add(new PartInfoItem("Isp", Units.Concat(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
+            this.infoItems.Add(new PartInfoItem("Isp", Units.ConcatF(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
             if (engine.Propellants.Count > 0)
             {
                 this.infoItems.Add(new PartInfoItem("Propellants"));
@@ -291,7 +291,7 @@
             }
 
             var parachute = this.selectedPart.GetModule<ModuleParachute>();
-            this.infoItems.Add(new PartInfoItem("Deployed Drag", Units.Concat(parachute.semiDeployedDrag, parachute.fullyDeployedDrag)));
+            this.infoItems.Add(new PartInfoItem("Deployed Drag", Units.ConcatF(parachute.semiDeployedDrag, parachute.fullyDeployedDrag)));
             this.infoItems.Add(new PartInfoItem("Deployment Altitude", parachute.deployAltitude.ToDistance()));
             this.infoItems.Add(new PartInfoItem("Deployment Pressure", parachute.minAirPressureToOpen.ToString("F2")));
         }
@@ -305,7 +305,7 @@
 
             var rcs = this.selectedPart.GetModule<ModuleRCS>();
             this.infoItems.Add(new PartInfoItem("Thruster Power", rcs.thrusterPower.ToForce()));
-            this.infoItems.Add(new PartInfoItem("Specific Impulse", Units.Concat(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
+            this.infoItems.Add(new PartInfoItem("Specific Impulse", Units.ConcatF(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
         }
 
         private void SetReactionWheelInfo()

--- a/KerbalEngineer/Editor/BuildOverlayVessel.cs
+++ b/KerbalEngineer/Editor/BuildOverlayVessel.cs
@@ -19,18 +19,20 @@
 
 #region Using Directives
 
-using System;
-using System.Collections.Generic;
-
-using KerbalEngineer.Helpers;
-using KerbalEngineer.VesselSimulator;
-
-using UnityEngine;
-
 #endregion
 
 namespace KerbalEngineer.Editor
 {
+    #region Using Directives
+
+    using System;
+    using System.Collections.Generic;
+    using Helpers;
+    using UnityEngine;
+    using VesselSimulator;
+
+    #endregion
+
     public class BuildOverlayVessel : MonoBehaviour
     {
         #region Constants
@@ -51,7 +53,7 @@
         private GUIContent tabContent;
         private Rect tabPosition;
         private Vector2 tabSize;
-        private Rect windowPosition = new Rect(300.0f, 0.0f, Width, 0.0f);
+        private Rect windowPosition = new Rect(330.0f, 0.0f, Width, 0.0f);
 
         #endregion
 
@@ -74,9 +76,28 @@
             get { return this.windowPosition; }
         }
 
-        #endregion
-
-        #region Methods: protected
+        public float WindowX
+        {
+            get { return this.windowPosition.x; }
+            set { this.windowPosition.x = value; }
+        }
+
+        #endregion
+
+        #region Methods
+
+        protected void Awake()
+        {
+            try
+            {
+                SimManager.OnReady -= this.GetStageInfo;
+                SimManager.OnReady += this.GetStageInfo;
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+            }
+        }
 
         protected void OnGUI()
         {
@@ -99,19 +120,6 @@
             }
         }
 
-        protected void Awake()
-        {
-            try
-            {
-                SimManager.OnReady -= this.GetStageInfo;
-                SimManager.OnReady += this.GetStageInfo;
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex);
-            }
-        }
-
         protected void Start()
         {
             try
@@ -147,9 +155,10 @@
             }
         }
 
-        #endregion
-
-        #region Methods: private
+        private void GetStageInfo()
+        {
+            this.lastStage = SimManager.LastStage;
+        }
 
         private void SetSlidePosition()
         {
@@ -171,11 +180,6 @@
             this.tabPosition.height = this.tabSize.y;
             this.tabPosition.x = this.windowPosition.x;
             this.tabPosition.y = this.windowPosition.y - this.tabPosition.height;
-        }
-
-        private void GetStageInfo()
-        {
-            this.lastStage = SimManager.LastStage;
         }
 
         private void SetVesselInfo()

--- a/KerbalEngineer/EngineerGlobals.cs
+++ b/KerbalEngineer/EngineerGlobals.cs
@@ -33,7 +33,7 @@
         /// <summary>
         ///     Current version of the Kerbal Engineer assembly.
         /// </summary>
-        public const string AssemblyVersion = "1.0.13";
+        public const string AssemblyVersion = "1.0.16.0";
 
         #endregion
 

--- a/KerbalEngineer/Extensions/PartExtensions.cs
+++ b/KerbalEngineer/Extensions/PartExtensions.cs
@@ -83,11 +83,27 @@
         }
 
         /// <summary>
+        ///     Gets the cost of the part modules
+        ///     Same as stock but without mem allocation
+        /// </summary>
+        public static double GetModuleCostsNoAlloc(this Part part, float defaultCost)
+        {
+            float cost = 0f;
+            for (int i = 0; i < part.Modules.Count; i++)
+            {
+                PartModule pm = part.Modules[i];
+                if (pm is IPartCostModifier)
+                    cost += (pm as IPartCostModifier).GetModuleCost(defaultCost);
+            }
+            return cost;
+        }
+
+        /// <summary>
         ///     Gets the cost of the part including resources.
         /// </summary>
         public static double GetCostWet(this Part part)
         {
-            return part.partInfo.cost - GetResourceCostInverted(part) + part.GetModuleCosts(0.0f);
+            return part.partInfo.cost - GetResourceCostInverted(part) + part.GetModuleCostsNoAlloc(0.0f); // part.GetModuleCosts allocate 44B per call. 
         }
 
         /// <summary>
@@ -124,7 +140,13 @@
         /// </summary>
         public static T GetModule<T>(this Part part) where T : PartModule
         {
-            return part.Modules.OfType<T>().FirstOrDefault();
+            for (int i = 0; i < part.Modules.Count; i++)
+            {
+                PartModule pm = part.Modules[i];
+                if (pm is T)
+                    return (T)pm;
+            }
+            return null;
         }
 
         /// <summary>
@@ -264,7 +286,13 @@
         /// </summary>
         public static double GetResourceCostInverted(this Part part)
         {
-            return part.Resources.list.Sum(r => (r.maxAmount - r.amount) * r.info.unitCost);
+            double sum = 0;
+            for (int i = 0; i < part.Resources.list.Count; i++)
+            {
+                PartResource r = part.Resources.list[i];
+                sum += (r.maxAmount - r.amount) * r.info.unitCost;
+            }
+            return sum;
         }
 
         /// <summary>
@@ -309,7 +337,12 @@
         /// </summary>
         public static bool HasModule<T>(this Part part) where T : PartModule
         {
-            return part.Modules.OfType<T>().Any();
+            for (int i = 0; i < part.Modules.Count; i++)
+            {
+                if (part.Modules[i] is T)
+                    return true;
+            }
+            return false;
         }
 
         /// <summary>
@@ -317,7 +350,13 @@
         /// </summary>
         public static bool HasModule<T>(this Part part, Func<T, bool> predicate) where T : PartModule
         {
-            return part.Modules.OfType<T>().Any(predicate);
+            for (int i = 0; i < part.Modules.Count; i++)
+            {
+                PartModule pm = part.Modules[i];
+                if (pm is T && predicate(pm as T))
+                    return true;
+            }
+            return false;
         }
 
         /// <summary>
@@ -421,8 +460,9 @@
         /// </summary>
         public static bool IsPrimary(this Part part, List<Part> partsList, PartModule module)
         {
-            foreach (var vesselPart in partsList)
-            {
+            for (int i = 0; i < partsList.Count; i++)
+            {
+                var vesselPart = partsList[i];
                 if (!vesselPart.HasModule(module.ClassID))
                 {
                     continue;
@@ -464,7 +504,7 @@
         /// </summary>
         public static bool IsSolidRocket(this Part part)
         {
-            return part.HasModule<ModuleEngines>() && part.GetModuleEngines().throttleLocked;
+            return (part.HasModule<ModuleEngines>() && part.GetModuleEngines().throttleLocked) || (part.HasModule<ModuleEnginesFX>() && part.GetModuleEnginesFx().throttleLocked);
         }
 
         #endregion

--- a/KerbalEngineer/Flight/ActionMenu.cs
+++ b/KerbalEngineer/Flight/ActionMenu.cs
@@ -79,11 +79,11 @@
                 {
                     return;
                 }
-                if (FlightEngineerCore.Instance != null && this.button.State == RUIToggleButton.ButtonState.DISABLED)
+                if (FlightEngineerCore.IsDisplayable && this.button.State == RUIToggleButton.ButtonState.DISABLED)
                 {
                     this.button.Enable();
                 }
-                else if (FlightEngineerCore.Instance == null && this.button.State != RUIToggleButton.ButtonState.DISABLED)
+                else if (!FlightEngineerCore.IsDisplayable && this.button.State != RUIToggleButton.ButtonState.DISABLED)
                 {
                     this.button.Disable();
                 }

--- a/KerbalEngineer/Flight/ActionMenuGui.cs
+++ b/KerbalEngineer/Flight/ActionMenuGui.cs
@@ -132,7 +132,7 @@
         {
             try
             {
-                if (this.Hidden)
+                if (this.Hidden || !FlightEngineerCore.IsDisplayable)
                 {
                     return;
                 }

--- a/KerbalEngineer/Flight/DisplayStack.cs
+++ b/KerbalEngineer/Flight/DisplayStack.cs
@@ -33,6 +33,8 @@
 
 namespace KerbalEngineer.Flight
 {
+    using Upgradeables;
+
     /// <summary>
     ///     Graphical controller for displaying stacked sections.
     /// </summary>
@@ -150,7 +152,7 @@
         {
             try
             {
-                if (FlightEngineerCore.Instance == null)
+                if (!FlightEngineerCore.IsDisplayable)
                 {
                     return;
                 }
@@ -177,7 +179,7 @@
         {
             try
             {
-                if (FlightEngineerCore.Instance == null)
+                if (!FlightEngineerCore.IsDisplayable)
                 {
                     return;
                 }

--- a/KerbalEngineer/Flight/FlightEngineerCore.cs
+++ b/KerbalEngineer/Flight/FlightEngineerCore.cs
@@ -19,21 +19,28 @@
 
 #region Using Directives
 
-using System;
-using System.Collections.Generic;
-
-using KerbalEngineer.Flight.Readouts;
-using KerbalEngineer.Flight.Sections;
-
-using UnityEngine;
-
 #endregion
 
 namespace KerbalEngineer.Flight
 {
+    #region Using Directives
+
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using Extensions;
+    using Readouts;
+    using Sections;
+    using Settings;
+    using UnityEngine;
+    using VesselSimulator;
+
+    #endregion
+
     /// <summary>
     ///     Core management system for the Flight Engineer.
     /// </summary>
+    [KSPAddon(KSPAddon.Startup.Flight, false)]
     public sealed class FlightEngineerCore : MonoBehaviour
     {
         #region Instance
@@ -45,7 +52,210 @@
 
         #endregion
 
+        #region Fields
+
+        private static bool isCareerMode = true;
+        private static bool isKerbalLimited = true;
+        private static bool isTrackingStationLimited = true;
+
+        #endregion
+
         #region Constructors
+
+        static FlightEngineerCore()
+        {
+            try
+            {
+                var handler = SettingHandler.Load("FlightEngineerCore.xml");
+                handler.Get("isCareerMode", ref isCareerMode);
+                handler.Get("isKerbalLimited", ref isKerbalLimited);
+                handler.Get("isTrackingStationLimited", ref isTrackingStationLimited);
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+            }
+        }
+
+        #endregion
+
+        #region Properties
+
+        /// <summary>
+        ///     Gets and sets whether to the Flight Engineer should be run using career limitations.
+        /// </summary>
+        public static bool IsCareerMode
+        {
+            get { return isCareerMode; }
+            set
+            {
+                try
+                {
+                    if (isCareerMode != value)
+                    {
+                        var handler = SettingHandler.Load("FlightEngineerCore.xml");
+                        handler.Set("isCareerMode", value);
+                        handler.Save("FlightEngineerCore.xml");
+                    }
+                    isCareerMode = value;
+                }
+                catch (Exception ex)
+                {
+                    Logger.Exception(ex);
+                }
+            }
+        }
+
+        /// <summary>
+        ///     Gets whether the FlightEngineer should be displayed.
+        /// </summary>
+        public static bool IsDisplayable
+        {
+            get
+            {
+                if (isCareerMode)
+                {
+                    if (isKerbalLimited && FlightGlobals.ActiveVessel.GetVesselCrew().Exists(c => c.experienceTrait.TypeName == "Engineer"))
+                    {
+                        return true;
+                    }
+                    if (isTrackingStationLimited && ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) == 1.0f)
+                    {
+                        return true;
+                    }
+                    return FlightGlobals.ActiveVessel.parts.Any(p => p.HasModule<FlightEngineerModule>());
+                }
+
+                return true;
+            }
+        }
+
+        /// <summary>
+        ///     Gets and sets whether to the Flight Engineer should be kerbal limited.
+        /// </summary>
+        public static bool IsKerbalLimited
+        {
+            get { return isKerbalLimited; }
+            set
+            {
+                try
+                {
+                    if (isKerbalLimited != value)
+                    {
+                        var handler = SettingHandler.Load("FlightEngineerCore.xml");
+                        handler.Set("isKerbalLimited", value);
+                        handler.Save("FlightEngineerCore.xml");
+                    }
+                    isKerbalLimited = value;
+                }
+                catch (Exception ex)
+                {
+                    Logger.Exception(ex);
+                }
+            }
+        }
+
+        /// <summary>
+        ///     Gets and sets whether to the Flight Engineer should be tracking station limited.
+        /// </summary>
+        public static bool IsTrackingStationLimited
+        {
+            get { return isTrackingStationLimited; }
+            set
+            {
+                try
+                {
+                    if (isTrackingStationLimited != value)
+                    {
+                        var handler = SettingHandler.Load("FlightEngineerCore.xml");
+                        handler.Set("isTrackingStationLimited", value);
+                        handler.Save("FlightEngineerCore.xml");
+                    }
+                    isTrackingStationLimited = value;
+                }
+                catch (Exception ex)
+                {
+                    Logger.Exception(ex);
+                }
+            }
+        }
+
+        /// <summary>
+        ///     Gets the editor windows for sections with open editors.
+        /// </summary>
+        public List<SectionEditor> SectionEditors { get; private set; }
+
+        /// <summary>
+        ///     Gets the section windows for floating sections.
+        /// </summary>
+        public List<SectionWindow> SectionWindows { get; private set; }
+
+        /// <summary>
+        ///     Gets the list of currently running updatable modules.
+        /// </summary>
+        public List<IUpdatable> UpdatableModules { get; private set; }
+
+        #endregion
+
+        #region Methods
+
+        /// <summary>
+        ///     Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.
+        /// </summary>
+        public SectionEditor AddSectionEditor(SectionModule section)
+        {
+            try
+            {
+                var editor = this.gameObject.AddComponent<SectionEditor>();
+                editor.ParentSection = section;
+                editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);
+                this.SectionEditors.Add(editor);
+                return editor;
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+                return null;
+            }
+        }
+
+        /// <summary>
+        ///     Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.
+        /// </summary>
+        public SectionWindow AddSectionWindow(SectionModule section)
+        {
+            try
+            {
+                var window = this.gameObject.AddComponent<SectionWindow>();
+                window.ParentSection = section;
+                window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);
+                this.SectionWindows.Add(window);
+                return window;
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+                return null;
+            }
+        }
+
+        /// <summary>
+        ///     Adds an updatable object to be automatically updated every frame and will ignore duplicate objects.
+        /// </summary>
+        public void AddUpdatable(IUpdatable updatable)
+        {
+            try
+            {
+                if (!this.UpdatableModules.Contains(updatable))
+                {
+                    this.UpdatableModules.Add(updatable);
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+            }
+        }
 
         /// <summary>
         ///     Create base Flight Engineer child objects.
@@ -59,11 +269,58 @@
                 this.SectionWindows = new List<SectionWindow>();
                 this.SectionEditors = new List<SectionEditor>();
                 this.UpdatableModules = new List<IUpdatable>();
+
+                SimManager.UpdateModSettings();
+
                 Logger.Log("FlightEngineerCore->Awake");
             }
             catch (Exception ex)
             {
-                Logger.Exception(ex, "FlightEngineerCore->Awake");
+                Logger.Exception(ex);
+            }
+        }
+
+        /// <summary>
+        ///     Fixed update all required Flight Engineer objects.
+        /// </summary>
+        private void FixedUpdate()
+        {
+            try
+            {
+                SectionLibrary.FixedUpdate();
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
+            }
+        }
+
+        /// <summary>
+        ///     Force the destruction of child objects on core destruction.
+        /// </summary>
+        private void OnDestroy()
+        {
+            try
+            {
+                SectionLibrary.Save();
+
+                foreach (var window in this.SectionWindows)
+                {
+                    print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);
+                    Destroy(window);
+                }
+
+                foreach (var editor in this.SectionEditors)
+                {
+                    print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);
+                    Destroy(editor);
+                }
+
+                Logger.Log("FlightEngineerCore->OnDestroy");
+            }
+            catch (Exception ex)
+            {
+                Logger.Exception(ex);
             }
         }
 
@@ -80,44 +337,6 @@
             }
             catch (Exception ex)
             {
-                Logger.Exception(ex, "FlightEngineerCore->Start");
-            }
-        }
-
-        #endregion
-
-        #region Properties
-
-        /// <summary>
-        ///     Gets the section windows for floating sections.
-        /// </summary>
-        public List<SectionWindow> SectionWindows { get; private set; }
-
-        /// <summary>
-        ///     Gets the editor windows for sections with open editors.
-        /// </summary>
-        public List<SectionEditor> SectionEditors { get; private set; }
-
-        /// <summary>
-        ///     Gets the list of currently running updatable modules.
-        /// </summary>
-        public List<IUpdatable> UpdatableModules { get; private set; }
-
-        #endregion
-
-        #region Updating
-
-        /// <summary>
-        ///     Fixed update all required Flight Engineer objects.
-        /// </summary>
-        private void FixedUpdate()
-        {
-            try
-            {
-                SectionLibrary.FixedUpdate();
-            }
-            catch (Exception ex)
-            {
                 Logger.Exception(ex);
             }
         }
@@ -134,7 +353,7 @@
             }
             catch (Exception ex)
             {
-                Logger.Exception(ex, "FlightEngineerCore->Update");
+                Logger.Exception(ex);
             }
         }
 
@@ -164,102 +383,7 @@
             }
             catch (Exception ex)
             {
-                Logger.Exception(ex, "FlightEngineerCore->UpdateModules");
-            }
-        }
-
-        #endregion
-
-        #region Destruction
-
-        /// <summary>
-        ///     Force the destruction of child objects on core destruction.
-        /// </summary>
-        private void OnDestroy()
-        {
-            try
-            {
-                SectionLibrary.Save();
-
-                foreach (var window in this.SectionWindows)
-                {
-                    print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);
-                    Destroy(window);
-                }
-
-                foreach (var editor in this.SectionEditors)
-                {
-                    print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);
-                    Destroy(editor);
-                }
-
-                Logger.Log("FlightEngineerCore->OnDestroy");
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerCore->OnDestroy");
-            }
-        }
-
-        #endregion
-
-        #region Methods
-
-        /// <summary>
-        ///     Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.
-        /// </summary>
-        public SectionWindow AddSectionWindow(SectionModule section)
-        {
-            try
-            {
-                var window = this.gameObject.AddComponent<SectionWindow>();
-                window.ParentSection = section;
-                window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);
-                this.SectionWindows.Add(window);
-                return window;
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerCore->AddSectionWindow");
-                return null;
-            }
-        }
-
-        /// <summary>
-        ///     Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.
-        /// </summary>
-        public SectionEditor AddSectionEditor(SectionModule section)
-        {
-            try
-            {
-                var editor = this.gameObject.AddComponent<SectionEditor>();
-                editor.ParentSection = section;
-                editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);
-                this.SectionEditors.Add(editor);
-                return editor;
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerCore->AddSectionEditor");
-                return null;
-            }
-        }
-
-        /// <summary>
-        ///     Adds an updatable object to be automatically updated every frame and will ignore duplicate objects.
-        /// </summary>
-        public void AddUpdatable(IUpdatable updatable)
-        {
-            try
-            {
-                if (!this.UpdatableModules.Contains(updatable))
-                {
-                    this.UpdatableModules.Add(updatable);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerCore->AddUpdatable");
+                Logger.Exception(ex);
             }
         }
 

--- a/KerbalEngineer/Flight/FlightEngineerModule.cs
+++ b/KerbalEngineer/Flight/FlightEngineerModule.cs
@@ -19,9 +19,6 @@
 
 #region Using Directives
 
-using System;
-using System.Linq;
-
 #endregion
 
 namespace KerbalEngineer.Flight
@@ -29,73 +26,5 @@
     /// <summary>
     ///     Module that can be attached to parts, giving them FlightEngineerCore management.
     /// </summary>
-    public sealed class FlightEngineerModule : PartModule
-    {
-        #region Fields
-
-        /// <summary>
-        ///     Contains the current FlightEngineerCore through the lifespan of this part.
-        /// </summary>
-        private FlightEngineerCore flightEngineerCore;
-
-        #endregion
-
-        #region Updating
-
-        /// <summary>
-        ///     Logic to create and destroy the FlightEngineerCore.
-        /// </summary>
-        private void Update()
-        {
-            try
-            {
-                if (!HighLogic.LoadedSceneIsFlight || FlightEngineerPartless.IsPartless)
-                {
-                    return;
-                }
-
-                if (this.vessel == FlightGlobals.ActiveVessel)
-                {
-                    // Checks for an existing instance of FlightEngineerCore, and if this part is the first part containing FlightEngineerModule within the vessel.
-                    if (flightEngineerCore == null && this.part == this.vessel.parts.FirstOrDefault(p => p.Modules.Contains("FlightEngineerModule")))
-                    {
-                        this.flightEngineerCore = this.gameObject.AddComponent<FlightEngineerCore>();
-                    }
-                }
-                else if (flightEngineerCore != null)
-                {
-                    // Using DestroyImmediate to force early destruction and keep saving/loading in synch when switching vessels.
-                    DestroyImmediate(flightEngineerCore);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerModule->Update");
-            }
-        }
-
-        #endregion
-
-        #region Destruction
-
-        /// <summary>
-        ///     Force the destruction of the FlightEngineerCore on part destruction.
-        /// </summary>
-        private void OnDestroy()
-        {
-            try
-            {
-                if (flightEngineerCore != null)
-                {
-                    DestroyImmediate(flightEngineerCore);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerModule->OnDestroy");
-            }
-        }
-
-        #endregion
-    }
+    public class FlightEngineerModule : PartModule { }
 }

--- a/KerbalEngineer/Flight/FlightEngineerPartless.cs
+++ /dev/null
@@ -1,101 +1,1 @@
-// 
-//     Kerbal Engineer Redux
-// 
-//     Copyright (C) 2014 CYBUTEK
-// 
-//     This program is free software: you can redistribute it and/or modify
-//     it under the terms of the GNU General Public License as published by
-//     the Free Software Foundation, either version 3 of the License, or
-//     (at your option) any later version.
-// 
-//     This program is distributed in the hope that it will be useful,
-//     but WITHOUT ANY WARRANTY; without even the implied warranty of
-//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//     GNU General Public License for more details.
-// 
-//     You should have received a copy of the GNU General Public License
-//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
-// 
 
-#region Using Directives
-
-using System;
-
-using KerbalEngineer.Settings;
-
-using UnityEngine;
-
-#endregion
-
-namespace KerbalEngineer.Flight
-{
-    [KSPAddon(KSPAddon.Startup.Flight, false)]
-    public class FlightEngineerPartless : MonoBehaviour
-    {
-        #region Fields
-
-        private FlightEngineerCore flightEngineerCore;
-
-        #endregion
-
-        #region Initialisation
-
-        static FlightEngineerPartless()
-        {
-            try
-            {
-                var handler = SettingHandler.Load("FlightEngineerPartless.xml");
-                handler.Get("isPartless", ref isPartless);
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerPartless->FlightEngineerPartless");
-            }
-        }
-
-        private void Awake()
-        {
-            try
-            {
-                if (isPartless)
-                {
-                    this.flightEngineerCore = this.gameObject.AddComponent<FlightEngineerCore>();
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Exception(ex, "FlightEngineerPartless->Awake");
-            }
-        }
-
-        #endregion
-
-        #region Properties
-
-        private static bool isPartless = true;
-
-        public static bool IsPartless
-        {
-            get { return isPartless; }
-            set
-            {
-                try
-                {
-                    if (isPartless != value)
-                    {
-                        var handler = SettingHandler.Load("FlightEngineerPartless.xml");
-                        handler.Set("isPartless", value);
-                        handler.Save("FlightEngineerPartless.xml");
-                    }
-                    isPartless = value;
-                }
-                catch (Exception ex)
-                {
-                    Logger.Exception(ex, "FlightEngineerPartless->IsPartless");
-                }
-            }
-        }
-
-        #endregion
-    }
-}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/SystemTime.cs
@@ -1,1 +1,59 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2014 CYBUTEK
+// 
+//     This program is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+// 
+//     This program is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+// 
+//     You should have received a copy of the GNU General Public License
+//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
 
+#region Using Directives
+
+using System;
+
+using KerbalEngineer.Flight.Sections;
+using KerbalEngineer.Helpers;
+
+using UnityEngine;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Miscellaneous
+{
+    public class SystemTime : ReadoutModule
+    {
+
+
+        #region Constructors
+
+        public SystemTime()
+        {
+            this.Name = "System Time";
+            this.Category = ReadoutCategory.GetCategory("Miscellaneous");
+            this.HelpString = String.Empty;
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            this.DrawLine(DateTime.Now.ToLongTimeString(), section.IsHud);
+        }
+
+        #endregion
+
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/MeanAnomalyAtEpoc.cs
@@ -1,1 +1,54 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2014 CYBUTEK
+// 
+//     This program is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+// 
+//     This program is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+// 
+//     You should have received a copy of the GNU General Public License
+//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
 
+#region Using Directives
+
+using System;
+
+using KerbalEngineer.Extensions;
+using KerbalEngineer.Flight.Sections;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class MeanAnomalyAtEpoc : ReadoutModule
+    {
+        #region Constructors
+
+        public MeanAnomalyAtEpoc()
+        {
+            this.Name = "Mean Anomaly at Epoc";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = String.Empty;
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            this.DrawLine(FlightGlobals.ship_orbit.meanAnomalyAtEpoch.ToAngle(), section.IsHud);
+        }
+
+        #endregion
+    }
+}

--- a/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
@@ -85,6 +85,7 @@
                 readouts.Add(new ArgumentOfPeriapsis());
                 readouts.Add(new TrueAnomaly());
                 readouts.Add(new MeanAnomaly());
+                readouts.Add(new MeanAnomalyAtEpoc());
                 readouts.Add(new EccentricAnomaly());
                 readouts.Add(new SemiMajorAxis());
                 readouts.Add(new SemiMinorAxis());
@@ -170,13 +171,14 @@
                 readouts.Add(new Rendezvous.OrbitalPeriod());
                 readouts.Add(new Rendezvous.SemiMajorAxis());
                 readouts.Add(new Rendezvous.SemiMinorAxis());
-
+                
                 // Misc
                 readouts.Add(new Separator());
                 readouts.Add(new GuiSizeAdjustor());
                 readouts.Add(new SimulationDelay());
                 readouts.Add(new TimeReference());
                 readouts.Add(new VectoredThrustToggle());
+                readouts.Add(new SystemTime());
 
                 LoadHelpStrings();
             }

--- a/KerbalEngineer/Flight/Readouts/Vessel/PartCount.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/PartCount.cs
@@ -46,7 +46,7 @@
         {
             if (SimulationProcessor.ShowDetails)
             {
-                this.DrawLine(Units.Concat(SimulationProcessor.LastStage.partCount, SimulationProcessor.LastStage.totalPartCount), section.IsHud);
+                this.DrawLine(Units.ConcatF(SimulationProcessor.LastStage.partCount, SimulationProcessor.LastStage.totalPartCount), section.IsHud);
             }
         }
 

--- a/KerbalEngineer/Flight/Sections/SectionWindow.cs
+++ b/KerbalEngineer/Flight/Sections/SectionWindow.cs
@@ -118,7 +118,7 @@
         /// </summary>
         private void Draw()
         {
-            if (this.ParentSection == null || !this.ParentSection.IsVisible || (DisplayStack.Instance.Hidden && !this.ParentSection.IsHud))
+            if (this.ParentSection == null || !this.ParentSection.IsVisible || (DisplayStack.Instance.Hidden && !this.ParentSection.IsHud) || !FlightEngineerCore.IsDisplayable)
             {
                 return;
             }

--- a/KerbalEngineer/Helpers/Averager.cs
+++ b/KerbalEngineer/Helpers/Averager.cs
@@ -45,6 +45,12 @@
         private Vector3d sum = Vector3d.zero;
         private double totalweight = 0;
 
+        public void Reset()
+        {
+            sum = Vector3d.zero;
+            totalweight = 0;
+        }
+
         public void Add(Vector3d v, double weight) {
             sum += v * weight;
             totalweight += weight;

--- a/KerbalEngineer/Helpers/ForceAccumulator.cs
+++ b/KerbalEngineer/Helpers/ForceAccumulator.cs
@@ -19,16 +19,27 @@
 
 using System;
 using System.Collections.Generic;
+using KerbalEngineer.VesselSimulator;
+using Smooth.Pools;
 
 namespace KerbalEngineer
 {
     // a (force, application point) tuple
     public class AppliedForce
     {
+        public static readonly Pool<AppliedForce> pool = new Pool<AppliedForce>(Create, Reset);
+
         public Vector3d vector;
         public Vector3d applicationPoint;
 
-        public AppliedForce(Vector3d vector, Vector3d applicationPoint) {
+        static private AppliedForce Create()
+        {
+            return new AppliedForce();
+        }
+
+        static  private void Reset(AppliedForce appliedForce) { }
+
+        public void Set(Vector3d vector, Vector3d applicationPoint) {
             this.vector = vector;
             this.applicationPoint = applicationPoint;
         }
@@ -47,7 +58,7 @@
 	// some amount of residual torque. The line with the least amount of residual torque is chosen.
 	public class ForceAccumulator
 	{
-		// Total force.
+	    // Total force.
 		private Vector3d totalForce = Vector3d.zero;
 		// Torque needed to compensate if force were applied at origin.
 		private Vector3d totalZeroOriginTorque = Vector3d.zero;
@@ -99,5 +110,12 @@
         {
             return GetMinTorqueForceApplicationPoint(avgApplicationPoint.Get());
         }
+
+        public void Reset()
+        {
+            totalForce = Vector3d.zero;
+            totalZeroOriginTorque = Vector3d.zero;
+            avgApplicationPoint.Reset();
+        }
 	}
 }

--- a/KerbalEngineer/Helpers/Units.cs
+++ b/KerbalEngineer/Helpers/Units.cs
@@ -34,14 +34,42 @@
             return value1 + " / " + value2;
         }
 
-        public static string Concat(double value1, double value2, int decimals = 1)
+        public static string ConcatF(double value1, double value2, int decimals = 1)
         {
             return value1.ToString("F" + decimals) + " / " + value2.ToString("F" + decimals);
         }
 
-        public static string Concat(double value1, double value2, double value3, int decimals = 1)
+        public static string ConcatF(double value1, double value2, double value3, int decimals = 1)
         {
             return value1.ToString("F" + decimals) + " / " + value2.ToString("F" + decimals) + " / " + value3.ToString("F" + decimals);
+        }
+
+        public static string ConcatN(double value1, double value2, int decimals = 1)
+        {
+            return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals);
+        }
+
+        public static string ConcatN(double value1, double value2, double value3, int decimals = 1)
+        {
+            return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + " / " + value3.ToString("N" + decimals);
+        }
+
+        public static string Cost(double value, int decimals = 1)
+        {
+            if (value >= 1000000.0)
+            {
+                return (value / 1000.0).ToString("N" + decimals) + "K";
+            }
+            return value.ToString("N" + decimals);
+        }
+
+        public static string Cost(double value1, double value2, int decimals = 1)
+        {
+            if (value1 >= 1000000.0 || value2 >= 1000000.0)
+            {
+                return (value1 / 1000.0).ToString("N" + decimals) + " / " + (value2 / 1000.0).ToString("N" + decimals) + "K";
+            }
+            return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals);
         }
 
         public static string ToAcceleration(double value, int decimals = 2)
@@ -102,12 +130,22 @@
 
         public static string ToMass(double value, int decimals = 0)
         {
+            if (value >= 1000.0)
+            {
+                return value.ToString("N" + decimals + 2) + "t";
+            }
+
             value *= 1000.0;
             return value.ToString("N" + decimals) + "kg";
         }
 
         public static string ToMass(double value1, double value2, int decimals = 0)
         {
+            if (value1 >= 1000.0f || value2 >= 1000.0f)
+            {
+                return value1.ToString("N" + decimals + 2) + " / " + value2.ToString("N" + decimals + 2) + "t";
+            }
+
             value1 *= 1000.0;
             value2 *= 1000.0;
             return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + "kg";

--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -49,8 +49,8 @@
     <Compile Include="Extensions\FloatExtensions.cs" />
     <Compile Include="Extensions\OrbitExtensions.cs" />
     <Compile Include="Flight\ActionMenuGui.cs" />
-    <Compile Include="Flight\FlightEngineerPartless.cs" />
     <Compile Include="Flight\Presets\Preset.cs" />
+    <Compile Include="Flight\Readouts\Miscellaneous\SystemTime.cs" />
     <Compile Include="Flight\Readouts\Miscellaneous\VectoredThrustToggle.cs" />
     <Compile Include="Flight\Readouts\Miscellaneous\TimeReference.cs" />
     <Compile Include="Flight\Readouts\Miscellaneous\Separator.cs" />
@@ -70,6 +70,7 @@
     <Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeAngleToPrograde.cs" />
     <Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeTotalDeltaV.cs" />
     <Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeProgradeDeltaV.cs" />
+    <Compile Include="Flight\Readouts\Orbital\MeanAnomalyAtEpoc.cs" />
     <Compile Include="Flight\Readouts\Orbital\MeanAnomaly.cs" />
     <Compile Include="Flight\Readouts\Orbital\EccentricAnomaly.cs" />
     <Compile Include="Flight\Readouts\Orbital\ArgumentOfPeriapsis.cs" />
@@ -123,6 +124,11 @@
     <Compile Include="Helpers\TimeFormatter.cs" />
     <Compile Include="KeyBinder.cs" />
     <Compile Include="Control\ControlCentre.cs" />
+    <Compile Include="Smooth\Delegates\Delegates.cs" />
+    <Compile Include="Smooth\Dispose\Disposable.cs" />
+    <Compile Include="Smooth\Dispose\DisposalQueue.cs" />
+    <Compile Include="Smooth\Dispose\SmoothDisposer.cs" />
+    <Compile Include="Smooth\Pools\Pool.cs" />
     <Compile Include="UIControls\DropDown.cs" />
     <Compile Include="Logger.cs" />
     <Compile Include="EngineerGlobals.cs" />
@@ -206,8 +212,7 @@
   </ItemGroup>
   <ItemGroup>
     <Reference Include="Assembly-CSharp">
-      <HintPath>..\Game\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>
-      <Private>False</Private>
+      <HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\SteamApps\common\Kerbal Space Program\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>
     </Reference>
     <Reference Include="System">
       <HintPath>..\Game\KSP_Data\Managed\System.dll</HintPath>
@@ -218,10 +223,10 @@
       <Private>False</Private>
     </Reference>
     <Reference Include="UnityEngine">
-      <HintPath>..\Game\KSP_Data\Managed\UnityEngine.dll</HintPath>
-      <Private>False</Private>
+      <HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\SteamApps\common\Kerbal Space Program\KSP_Data\Managed\UnityEngine.dll</HintPath>
     </Reference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="PostBuildMacros">
     <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">

--- /dev/null
+++ b/KerbalEngineer/Smooth/Delegates/Delegates.cs
@@ -1,1 +1,25 @@
+using System;
 
+namespace Smooth.Delegates {
+	public delegate void DelegateAction();
+	public delegate void DelegateAction<in T1>(T1 _1);
+	public delegate void DelegateAction<in T1, in T2>(T1 _1, T2 _2);
+	public delegate void DelegateAction<in T1, in T2, in T3>(T1 _1, T2 _2, T3 _3);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4>(T1 _1, T2 _2, T3 _3, T4 _4);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9);
+
+	public delegate R DelegateFunc<out R>();
+	public delegate R DelegateFunc<in T1, out R>(T1 _1);
+	public delegate R DelegateFunc<in T1, in T2, out R>(T1 _1, T2 _2);
+	public delegate R DelegateFunc<in T1, in T2, in T3, out R>(T1 _1, T2 _2, T3 _3);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, out R>(T1 _1, T2 _2, T3 _3, T4 _4);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9);
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/Disposable.cs
@@ -1,1 +1,106 @@
+using System;
+using Smooth.Delegates;
+using Smooth.Pools;
 
+namespace Smooth.Dispose {
+
+#if UNITY_IOS || UNITY_PS3 || UNITY_XBOX360 || UNITY_WII
+
+	/// <summary>
+	/// Wrapper around a value that uses the IDisposable interface to dispose of the value.
+	/// 
+	/// On iOS, this is a struct to avoid compute_class_bitmap errors.
+	/// 
+	/// On other platforms, it is a pooled object to avoid boxing when disposed by a using block with the Unity compiler.
+	/// </summary>
+	public struct Disposable<T> : IDisposable {
+		/// <summary>
+		/// Borrows a wrapper for the specified value and disposal delegate.
+		/// </summary>
+		public static Disposable<T> Borrow(T value, DelegateAction<T> dispose) {
+			return new Disposable<T>(value, dispose);
+		}
+		
+		private readonly DelegateAction<T> dispose;
+
+		/// <summary>
+		/// The wrapped value.
+		/// </summary>
+		public readonly T value;
+
+		public Disposable(T value, DelegateAction<T> dispose) {
+			this.value = value;
+			this.dispose = dispose;
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and disposes the wrapped value.
+		/// </summary>
+		public void Dispose() {
+			dispose(value);
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and adds it to the disposal queue.
+		/// </summary>
+		public void DisposeInBackground() {
+			DisposalQueue.Enqueue(this);
+		}
+	}
+
+#else
+
+	/// <summary>
+	/// Wrapper around a value that uses the IDisposable interface to dispose of the value.
+	/// 
+	/// On IOS, this is a value type to avoid compute_class_bitmap errors.
+	/// 
+	/// On other platforms, it is a pooled object to avoid boxing when disposed by a using block with the Unity compiler.
+	/// </summary>
+	public class Disposable<T> : IDisposable {
+		private static readonly Pool<Disposable<T>> pool = new Pool<Disposable<T>>(
+			() => new Disposable<T>(),
+			wrapper => {
+				wrapper.dispose(wrapper.value);
+				wrapper.dispose = t => {};
+				wrapper.value = default(T);
+			}
+		);
+
+		/// <summary>
+		/// Borrows a wrapper for the specified value and disposal delegate.
+		/// </summary>
+		public static Disposable<T> Borrow(T value, DelegateAction<T> dispose) {
+			var wrapper = pool.Borrow();
+			wrapper.value = value;
+			wrapper.dispose = dispose;
+			return wrapper;
+		}
+
+		private DelegateAction<T> dispose;
+
+		/// <summary>
+		/// The wrapped value.
+		/// </summary>
+		public T value { get; private set; }
+		
+		private Disposable() {}
+
+		/// <summary>
+		/// Relinquishes ownership of the wrapper, disposes the wrapped value, and returns the wrapper to the pool.
+		/// </summary>
+		public void Dispose() {
+			pool.Release(this);
+		}
+
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and adds it to the disposal queue.
+		/// </summary>
+		public void DisposeInBackground() {
+			DisposalQueue.Enqueue(this);
+		}
+	}
+
+#endif
+
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/DisposalQueue.cs
@@ -1,1 +1,67 @@
+using UnityEngine;
+using System;
+using System.Collections.Generic;
+using System.Threading;
 
+namespace Smooth.Dispose {
+
+	/// <summary>
+	/// Queues pooled resources for cleanup by a background thread.
+	/// 
+	/// By default, the disposal thread is woken up at the end of LateUpdate, when there is likely to be free CPU time available while GPU operations are in progress.
+	/// 
+	/// Various pools may be locked and unlocked while resources are released, potentially causing contention if pooled resources are borrowed during the disposal process.
+	/// 
+	/// Advanced users who are using pools from the main thread during the rendering phase may want to customize the point in the Unity event loop when the queue lock is pulsed, potentially pulsing from a Camera event.
+	/// </summary>
+	public static class DisposalQueue {
+		private static readonly object queueLock = new object();
+		private static Queue<IDisposable> enqueue = new Queue<IDisposable>();
+		private static Queue<IDisposable> dispose = new Queue<IDisposable>();
+
+		/// <summary>
+		/// Adds the specified item to the disposal queue.
+		/// </summary>
+		public static void Enqueue(IDisposable item) {
+			lock (queueLock) {
+				enqueue.Enqueue(item);
+			}
+		}
+
+		/// <summary>
+		/// Pulses the queue lock, potentially waking up the disposal thread.
+		/// </summary>
+		public static void Pulse() {
+			lock (queueLock) {
+				Monitor.Pulse(queueLock);
+			}
+		}
+
+		private static void Dispose() {
+			while (true) {
+				lock (queueLock) {
+					while (enqueue.Count == 0) {
+						Monitor.Wait(queueLock);
+					}
+					var t = enqueue;
+					enqueue = dispose;
+					dispose = t;
+				}
+				while (dispose.Count > 0) {
+					try {
+						dispose.Dequeue().Dispose();
+					} catch (ThreadAbortException) {
+					} catch (Exception e) {
+						Debug.LogError(e);
+					}
+				}
+			}
+		}
+
+		static DisposalQueue() {
+			new Thread(new ThreadStart(Dispose)).Start();
+			new GameObject(typeof(SmoothDisposer).Name).AddComponent<SmoothDisposer>();
+		}
+	}
+}
+

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/SmoothDisposer.cs
@@ -1,1 +1,21 @@
+using UnityEngine;
+using System;
+using Smooth.Dispose;
 
+public class SmoothDisposer : MonoBehaviour {
+	private static SmoothDisposer instance;
+
+	private void Awake() {
+		if (instance) {
+			Debug.LogWarning("Only one " + GetType().Name + " should exist at a time, instantiated by the " + typeof(DisposalQueue).Name + " class.");
+			Destroy(this);
+		} else {
+			instance = this;
+			DontDestroyOnLoad(this);
+		}
+	}
+	
+	private void LateUpdate() {
+		DisposalQueue.Pulse();
+	}
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Pools/Pool.cs
@@ -1,1 +1,60 @@
+using System;
+using System.Collections.Generic;
+using Smooth.Delegates;
+using Smooth.Dispose;
 
+namespace Smooth.Pools {
+	/// <summary>
+	/// Pool that lends values of type T.
+	/// </summary>
+	public class Pool<T> {
+		private readonly Stack<T> values = new Stack<T>();
+
+		private readonly DelegateFunc<T> create;
+		private readonly DelegateAction<T> reset;
+		private readonly DelegateAction<T> release;
+
+		private Pool() {}
+		
+		/// <summary>
+		/// Creates a new pool with the specified value creation and reset delegates.
+		/// </summary>
+		public Pool(DelegateFunc<T> create, DelegateAction<T> reset) {
+			this.create = create;
+			this.reset = reset;
+			this.release = Release;
+		}
+
+		/// <summary>
+		/// Borrows a value from the pool.
+		/// </summary>
+		public T Borrow() {
+			lock (values) {
+				return values.Count > 0 ? values.Pop() : create();
+			}
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the specified value and returns it to the pool.
+		/// </summary>
+		public void Release(T value) {
+			reset(value);
+			lock (values) {
+				values.Push(value);
+			}
+		}
+
+		/// <summary>
+		/// Borrows a wrapped value from the pool.
+		/// </summary>
+		public Disposable<T> BorrowDisposable() {
+			return Disposable<T>.Borrow(Borrow(), release);
+		}
+
+        public int Count()
+	    {
+	        return values.Count;
+	    }
+
+	}
+}

--- a/KerbalEngineer/VesselSimulator/AttachNodeSim.cs
+++ b/KerbalEngineer/VesselSimulator/AttachNodeSim.cs
@@ -21,6 +21,7 @@
 
 using System;
 using System.Text;
+using Smooth.Pools;
 
 #endregion
 
@@ -28,16 +29,26 @@
 {
     internal class AttachNodeSim
     {
+
+        public static readonly Pool<AttachNodeSim> pool = new Pool<AttachNodeSim>(Create, Reset);
+
         public PartSim attachedPartSim;
         public String id;
         public AttachNode.NodeType nodeType;
 
-        public AttachNodeSim(PartSim partSim, String newId, AttachNode.NodeType newNodeType)
+        private static AttachNodeSim Create()
+        {
+            return new AttachNodeSim();
+        }
+
+        public void Set(PartSim partSim, String newId, AttachNode.NodeType newNodeType)
         {
             this.attachedPartSim = partSim;
             this.nodeType = newNodeType;
             this.id = newId;
         }
+
+        static private void Reset(AttachNodeSim attachNodeSim) { }
 
         public void DumpToBuffer(StringBuilder buffer)
         {

--- a/KerbalEngineer/VesselSimulator/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -23,7 +23,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
-
+using Smooth.Pools;
 using UnityEngine;
 
 #endregion
@@ -32,20 +32,41 @@
 {
     public class EngineSim
     {
+        public static readonly Pool<EngineSim> pool = new Pool<EngineSim>(Create, Reset);
+
         private readonly ResourceContainer resourceConsumptions = new ResourceContainer();
 
         public double actualThrust = 0;
         public bool isActive = false;
         public double isp = 0;
         public PartSim partSim;
-        public List<AppliedForce> appliedForces;
+        public List<AppliedForce> appliedForces = new List<AppliedForce>();
 
         public double thrust = 0;
 
         // Add thrust vector to account for directional losses
         public Vector3 thrustVec;
 
-        public EngineSim(PartSim theEngine,
+        private static EngineSim Create()
+        {
+            return new EngineSim();
+        }
+
+        private static void Reset(EngineSim engineSim)
+        {
+            engineSim.resourceConsumptions.Reset();
+            engineSim.actualThrust = 0;
+            engineSim.isActive = false;
+            engineSim.isp = 0;
+            for (int i = 0; i < engineSim.appliedForces.Count; i++)
+            {
+                AppliedForce.pool.Release(engineSim.appliedForces[i]);
+            }
+            engineSim.appliedForces.Clear();
+            engineSim.thrust = 0;
+        }
+
+        public void Set(PartSim theEngine,
                          double atmosphere,
                          double velocity,
                          float maxThrust,
@@ -186,8 +207,9 @@
             }
 
             float flowMass = 0f;
-            foreach (Propellant propellant in propellants)
-            {
+            for (int i = 0; i < propellants.Count; i++)
+            {
+                Propellant propellant = propellants[i];
                 flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id);
             }
 
@@ -196,8 +218,9 @@
                 buffer.AppendFormat("flowMass = {0:g6}\n", flowMass);
             }
 
-            foreach (Propellant propellant in propellants)
-            {
+            for (int i = 0; i < propellants.Count; i++)
+            {
+                Propellant propellant = propellants[i];
                 if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir")
                 {
                     continue;
@@ -206,7 +229,12 @@
                 double consumptionRate = propellant.ratio * flowRate / flowMass;
                 if (SimManager.logOutput)
                 {
-                    buffer.AppendFormat("Add consumption({0}, {1}:{2:d}) = {3:g6}\n", ResourceContainer.GetResourceName(propellant.id), theEngine.name, theEngine.partId, consumptionRate);
+                    buffer.AppendFormat(
+                        "Add consumption({0}, {1}:{2:d}) = {3:g6}\n",
+                        ResourceContainer.GetResourceName(propellant.id),
+                        theEngine.name,
+                        theEngine.partId,
+                        consumptionRate);
                 }
                 this.resourceConsumptions.Add(propellant.id, consumptionRate);
             }
@@ -216,12 +244,16 @@
                 MonoBehaviour.print(buffer);
             }
 
-            appliedForces = new List<AppliedForce>();
             double thrustPerThrustTransform = thrust / thrustTransforms.Count;
-            foreach (Transform thrustTransform in thrustTransforms) {
+            for (int i = 0; i < thrustTransforms.Count; i++)
+            {
+                Transform thrustTransform = thrustTransforms[i];
                 Vector3d direction = thrustTransform.forward.normalized;
                 Vector3d position = thrustTransform.position;
-                appliedForces.Add(new AppliedForce(direction * thrustPerThrustTransform, position));
+
+                AppliedForce appliedForce = AppliedForce.pool.Borrow();
+                appliedForce.Set(direction * thrustPerThrustTransform, position);
+                appliedForces.Add(appliedForce);
             }
         }
 
@@ -230,50 +262,70 @@
             get { return this.resourceConsumptions; }
         }
 
+        // A dictionary to hold a set of parts for each resource
+        Dictionary<int, HashSet<PartSim>> sourcePartSets = new Dictionary<int, HashSet<PartSim>>();
+
+        Dictionary<int, HashSet<PartSim>> stagePartSets = new Dictionary<int, HashSet<PartSim>>();
+
+        HashSet<PartSim> visited = new HashSet<PartSim>();
+
         public bool SetResourceDrains(List<PartSim> allParts, List<PartSim> allFuelLines, HashSet<PartSim> drainingParts)
         {
             LogMsg log = null;
-
-            // A dictionary to hold a set of parts for each resource
-            Dictionary<int, HashSet<PartSim>> sourcePartSets = new Dictionary<int, HashSet<PartSim>>();
-
-            foreach (int type in this.resourceConsumptions.Types)
-            {
-                HashSet<PartSim> sourcePartSet = null;
+            
+            foreach (HashSet<PartSim> sourcePartSet in sourcePartSets.Values)
+            {
+                sourcePartSet.Clear();
+            }
+
+            for (int index = 0; index < this.resourceConsumptions.Types.Count; index++)
+            {
+                int type = this.resourceConsumptions.Types[index];
+
+                HashSet<PartSim> sourcePartSet;
+                if (!sourcePartSets.TryGetValue(type, out sourcePartSet))
+                {
+                    sourcePartSet = new HashSet<PartSim>();
+                    sourcePartSets.Add(type, sourcePartSet);
+                }
                 switch (ResourceContainer.GetResourceFlowMode(type))
                 {
                     case ResourceFlowMode.NO_FLOW:
-                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN)
-                        {
-                            sourcePartSet = new HashSet<PartSim>();
+                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN && this.partSim.resourceFlowStates[type] != 0)
+                        {
+                            //sourcePartSet = new HashSet<PartSim>();
                             //MonoBehaviour.print("SetResourceDrains(" + name + ":" + partId + ") setting sources to just this");
                             sourcePartSet.Add(this.partSim);
                         }
                         break;
 
                     case ResourceFlowMode.ALL_VESSEL:
-                        foreach (PartSim aPartSim in allParts)
-                        {
-                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN)
-                            {
-                                if (sourcePartSet == null)
-                                {
-                                    sourcePartSet = new HashSet<PartSim>();
-                                }
-
+                        for (int i = 0; i < allParts.Count; i++)
+                        {
+                            PartSim aPartSim = allParts[i];
+                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
+                            {
                                 sourcePartSet.Add(aPartSim);
                             }
                         }
                         break;
 
                     case ResourceFlowMode.STAGE_PRIORITY_FLOW:
-                        var stagePartSets = new Dictionary<int, HashSet<PartSim>>();
+
+                        foreach (HashSet<PartSim> stagePartSet in stagePartSets.Values)
+                        {
+                            stagePartSet.Clear();
+                        }
                         var maxStage = -1;
 
-                        Logger.Log(type);
-                        foreach (var aPartSim in allParts)
-                        {
-                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN) continue;
+                        //Logger.Log(type);
+                        for (int i = 0; i < allParts.Count; i++)
+                        {
+                            var aPartSim = allParts[i];
+                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
+                            {
+                                continue;
+                            }
 
                             var stage = aPartSim.DecouplerCount();
                             if (stage > maxStage)
@@ -281,9 +333,11 @@
                                 maxStage = stage;
                             }
 
-                            if (!stagePartSets.TryGetValue(stage, out sourcePartSet))
-                            {
-                                sourcePartSet = new HashSet<PartSim>();
+                            if (!stagePartSets.TryGetValue(stage, out sourcePartSet) || sourcePartSet.Count == 0)
+                            {
+                                if (sourcePartSet == null)
+                                    sourcePartSet = new HashSet<PartSim>();
+
                                 stagePartSets.Add(stage, sourcePartSet);
                             }
                             sourcePartSet.Add(aPartSim);
@@ -300,14 +354,16 @@
                         break;
 
                     case ResourceFlowMode.STACK_PRIORITY_SEARCH:
-                        HashSet<PartSim> visited = new HashSet<PartSim>();
+                        visited.Clear();
 
                         if (SimManager.logOutput)
                         {
                             log = new LogMsg();
-                            log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + this.partSim.name + ":" + this.partSim.partId);
-                        }
-                        sourcePartSet = this.partSim.GetSourceSet(type, allParts, visited, log, "");
+                            log.buf.AppendLine(
+                                "Find " + ResourceContainer.GetResourceName(type) + " sources for " + this.partSim.name + ":" +
+                                this.partSim.partId);
+                        }
+                        this.partSim.GetSourceSet(type, allParts, visited, sourcePartSet, log, "");
                         if (SimManager.logOutput)
                         {
                             MonoBehaviour.print(log.buf);
@@ -315,11 +371,14 @@
                         break;
 
                     default:
-                        MonoBehaviour.print("SetResourceDrains(" + this.partSim.name + ":" + this.partSim.partId + ") Unexpected flow type for " + ResourceContainer.GetResourceName(type) + ")");
+                        MonoBehaviour.print(
+                            "SetResourceDrains(" + this.partSim.name + ":" + this.partSim.partId + ") Unexpected flow type for " +
+                            ResourceContainer.GetResourceName(type) + ")");
                         break;
                 }
 
-                if (sourcePartSet != null && sourcePartSet.Count > 0)
+
+                if (sourcePartSet.Count > 0)
                 {
                     sourcePartSets[type] = sourcePartSet;
                     if (SimManager.logOutput)
@@ -334,11 +393,13 @@
                     }
                 }
             }
-
+            
             // If we don't have sources for all the needed resources then return false without setting up any drains
-            foreach (int type in this.resourceConsumptions.Types)
-            {
-                if (!sourcePartSets.ContainsKey(type))
+            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
+            {
+                int type = this.resourceConsumptions.Types[i];
+                HashSet<PartSim> sourcePartSet; 
+                if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count() == 0)
                 {
                     if (SimManager.logOutput)
                     {
@@ -349,10 +410,10 @@
                     return false;
                 }
             }
-
             // Now we set the drains on the members of the sets and update the draining parts set
-            foreach (int type in this.resourceConsumptions.Types)
-            {
+            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
+            {
+                int type = this.resourceConsumptions.Types[i];
                 HashSet<PartSim> sourcePartSet = sourcePartSets[type];
                 // Loop through the members of the set 
                 double amount = this.resourceConsumptions[type] / sourcePartSet.Count;
@@ -360,14 +421,15 @@
                 {
                     if (SimManager.logOutput)
                     {
-                        MonoBehaviour.print("Adding drain of " + amount + " " + ResourceContainer.GetResourceName(type) + " to " + partSim.name + ":" + partSim.partId);
+                        MonoBehaviour.print(
+                            "Adding drain of " + amount + " " + ResourceContainer.GetResourceName(type) + " to " + partSim.name + ":" +
+                            partSim.partId);
                     }
 
                     partSim.resourceDrains.Add(type, amount);
                     drainingParts.Add(partSim);
                 }
             }
-
             return true;
         }
 

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -25,7 +25,7 @@
 using System.Text;
 
 using KerbalEngineer.Extensions;
-
+using Smooth.Pools;
 using UnityEngine;
 
 #endregion
@@ -36,7 +36,10 @@
 
     public class PartSim
     {
+        public static readonly Pool<PartSim> pool = new Pool<PartSim>(Create, Reset);
+
         private readonly List<AttachNodeSim> attachNodes = new List<AttachNodeSim>();
+
         public Vector3d centerOfMass;
         public double baseMass = 0d;
         public double cost;
@@ -70,8 +73,29 @@
         public double startMass = 0d;
         public String vesselName;
         public VesselType vesselType;
-
-        public PartSim(Part thePart, int id, double atmosphere, LogMsg log)
+        
+
+        private static PartSim Create()
+        {
+            return new PartSim();
+        }
+
+        private static void Reset(PartSim partSim)
+        {
+            for (int i = 0; i < partSim.attachNodes.Count; i++)
+            {
+                AttachNodeSim.pool.Release(partSim.attachNodes[i]);
+            }
+            partSim.attachNodes.Clear();
+            partSim.fuelTargets.Clear();
+            partSim.resourceDrains.Reset();
+            partSim.resourceFlowStates.Reset();
+            partSim.resources.Reset();
+            partSim.baseMass = 0d;
+            partSim.startMass = 0d;
+        }
+
+        public void Set(Part thePart, int id, double atmosphere, LogMsg log)
         {
             this.part = thePart;
             this.centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
@@ -111,8 +135,10 @@
                 MonoBehaviour.print((this.isNoPhysics ? "Ignoring" : "Using") + " part.mass of " + this.part.mass);
             }
 
-            foreach (PartResource resource in this.part.Resources)
-            {
+            for (int i = 0; i < this.part.Resources.Count; i++)
+            {
+                PartResource resource = this.part.Resources[i];
+
                 // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                 // This can happen if a resource capacity is 0 and tweakable
                 if (!Double.IsNaN(resource.amount))
@@ -170,9 +196,9 @@
             if (log != null)
             {
                 log.buf.AppendLine("CreateEngineSims for " + this.name);
-
-                foreach (PartModule partMod in this.part.Modules)
-                {
+                for (int i = 0; i < this.part.Modules.Count; i++)
+                {
+                    PartModule partMod = this.part.Modules[i];
                     log.buf.AppendLine("Module: " + partMod.moduleName);
                 }
 
@@ -185,8 +211,10 @@
                 // The mode of the engine is the engineID of the ModuleEnginesFX that is active
                 string mode = this.part.GetModule<MultiModeEngine>().mode;
 
-                foreach (ModuleEnginesFX engine in this.part.GetModules<ModuleEnginesFX>())
-                {
+                List<ModuleEnginesFX> enginesFx = this.part.GetModules<ModuleEnginesFX>();
+                for (int i = 0; i < enginesFx.Count; i++)
+                {
+                    ModuleEnginesFX engine = enginesFx[i];
                     if (engine.engineID == mode)
                     {
                         if (log != null)
@@ -196,22 +224,24 @@
 
                         Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
 
-                        EngineSim engineSim = new EngineSim(this,
-                                                            atmosphere,
-                                                            velocity,
-                                                            engine.maxThrust,
-                                                            engine.minThrust,
-                                                            engine.thrustPercentage,
-                                                            engine.requestedThrust,
-                                                            thrustvec,
-                                                            engine.realIsp,
-                                                            engine.atmosphereCurve,
-                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
-                                                            engine.throttleLocked,
-                                                            engine.propellants,
-                                                            engine.isOperational,
-                                                            correctThrust,
-                                                            engine.thrustTransforms);
+                        EngineSim engineSim = EngineSim.pool.Borrow();
+                        engineSim.Set(
+                            this,
+                            atmosphere,
+                            velocity,
+                            engine.maxThrust,
+                            engine.minThrust,
+                            engine.thrustPercentage,
+                            engine.requestedThrust,
+                            thrustvec,
+                            engine.realIsp,
+                            engine.atmosphereCurve,
+                            engine.useVelocityCurve ? engine.velocityCurve : null,
+                            engine.throttleLocked,
+                            engine.propellants,
+                            engine.isOperational,
+                            correctThrust,
+                            engine.thrustTransforms);
                         allEngines.Add(engineSim);
                     }
                 }
@@ -220,8 +250,10 @@
             {
                 if (this.hasModuleEnginesFX)
                 {
-                    foreach (ModuleEnginesFX engine in this.part.GetModules<ModuleEnginesFX>())
-                    {
+                    List<ModuleEnginesFX> enginesFx = this.part.GetModules<ModuleEnginesFX>();  // only place that still allocate some memory
+                    for (int i = 0; i < enginesFx.Count; i++)
+                    {
+                        ModuleEnginesFX engine = enginesFx[i];
                         if (log != null)
                         {
                             log.buf.AppendLine("Module: " + engine.moduleName);
@@ -229,30 +261,34 @@
 
                         Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
 
-                        EngineSim engineSim = new EngineSim(this,
-                                                            atmosphere,
-                                                            velocity,
-                                                            engine.maxThrust,
-                                                            engine.minThrust,
-                                                            engine.thrustPercentage,
-                                                            engine.requestedThrust,
-                                                            thrustvec,
-                                                            engine.realIsp,
-                                                            engine.atmosphereCurve,
-                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
-                                                            engine.throttleLocked,
-                                                            engine.propellants,
-                                                            engine.isOperational,
-                                                            correctThrust,
-                                                            engine.thrustTransforms);
+                        EngineSim engineSim = EngineSim.pool.Borrow();
+                        engineSim.Set(
+                            this,
+                            atmosphere,
+                            velocity,
+                            engine.maxThrust,
+                            engine.minThrust,
+                            engine.thrustPercentage,
+                            engine.requestedThrust,
+                            thrustvec,
+                            engine.realIsp,
+                            engine.atmosphereCurve,
+                            engine.useVelocityCurve ? engine.velocityCurve : null,
+                            engine.throttleLocked,
+                            engine.propellants,
+                            engine.isOperational,
+                            correctThrust,
+                            engine.thrustTransforms);
                         allEngines.Add(engineSim);
                     }
                 }
 
                 if (this.hasModuleEngines)
                 {
-                    foreach (ModuleEngines engine in this.part.GetModules<ModuleEngines>())
-                    {
+                    List<ModuleEngines> engines = this.part.GetModules<ModuleEngines>();  // only place that still allocate some memory
+                    for (int i = 0; i < engines.Count; i++)
+                    {
+                        ModuleEngines engine = engines[i];
                         if (log != null)
                         {
                             log.buf.AppendLine("Module: " + engine.moduleName);
@@ -260,22 +296,24 @@
 
                         Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
 
-                        EngineSim engineSim = new EngineSim(this,
-                                                            atmosphere,
-                                                            velocity,
-                                                            engine.maxThrust,
-                                                            engine.minThrust,
-                                                            engine.thrustPercentage,
-                                                            engine.requestedThrust,
-                                                            thrustvec,
-                                                            engine.realIsp,
-                                                            engine.atmosphereCurve,
-                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
-                                                            engine.throttleLocked,
-                                                            engine.propellants,
-                                                            engine.isOperational,
-                                                            correctThrust,
-                                                            engine.thrustTransforms);
+                        EngineSim engineSim = EngineSim.pool.Borrow();
+                        engineSim.Set(
+                            this,
+                            atmosphere,
+                            velocity,
+                            engine.maxThrust,
+                            engine.minThrust,
+                            engine.thrustPercentage,
+                            engine.requestedThrust,
+                            thrustvec,
+                            engine.realIsp,
+                            engine.atmosphereCurve,
+                            engine.useVelocityCurve ? engine.velocityCurve : null,
+                            engine.throttleLocked,
+                            engine.propellants,
+                            engine.isOperational,
+                            correctThrust,
+                            engine.thrustTransforms);
                         allEngines.Add(engineSim);
                     }
                 }
@@ -295,11 +333,17 @@
             }
 
             Vector3 thrustvec = Vector3.zero;
-            foreach (Transform trans in thrustTransforms)
-            {
+            for (int i = 0; i < thrustTransforms.Count; i++)
+            {
+                Transform trans = thrustTransforms[i];
                 if (log != null)
                 {
-                    log.buf.AppendFormat("Transform = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", trans.forward.x, trans.forward.y, trans.forward.z, trans.forward.magnitude);
+                    log.buf.AppendFormat(
+                        "Transform = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n",
+                        trans.forward.x,
+                        trans.forward.y,
+                        trans.forward.z,
+                        trans.forward.magnitude);
                 }
 
                 thrustvec -= trans.forward;
@@ -350,11 +394,14 @@
             }
 
             this.attachNodes.Clear();
-            foreach (AttachNode attachNode in this.part.attachNodes)
-            {
+            for (int i = 0; i < this.part.attachNodes.Count; i++)
+            {
+                AttachNode attachNode = this.part.attachNodes[i];
                 if (log != null)
                 {
-                    log.buf.AppendLine("AttachNode " + attachNode.id + " = " + (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));
+                    log.buf.AppendLine(
+                        "AttachNode " + attachNode.id + " = " +
+                        (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));
                 }
 
                 if (attachNode.attachedPart != null && attachNode.id != "Strut")
@@ -367,7 +414,9 @@
                             log.buf.AppendLine("Adding attached node " + attachedSim.name + ":" + attachedSim.partId + "");
                         }
 
-                        this.attachNodes.Add(new AttachNodeSim(attachedSim, attachNode.id, attachNode.nodeType));
+                        AttachNodeSim attachnode = AttachNodeSim.pool.Borrow();
+                        attachnode.Set(attachedSim, attachNode.id, attachNode.nodeType);
+                        this.attachNodes.Add(attachnode);
                     }
                     else
                     {
@@ -379,8 +428,9 @@
                 }
             }
 
-            foreach (Part p in this.part.fuelLookupTargets)
-            {
+            for (int i = 0; i < this.part.fuelLookupTargets.Count; i++)
+            {
+                Part p = this.part.fuelLookupTargets[i];
                 if (p != null)
                 {
                     PartSim targetSim;
@@ -446,18 +496,13 @@
                 return true;
             }
 
-            var modList = this.part.Modules.OfType<ModuleEngines>();
-            if (modList.Count() == 0)
+            if (!this.part.IsEngine())
             {
                 return false;
             }
 
-            if (modList.First().throttleLocked)
-            {
-                return true;
-            }
-
-            return false;
+
+            return this.part.IsSolidRocket();
         }
 
         public void ReleasePart()
@@ -468,7 +513,7 @@
         // All functions below this point must not rely on the part member (it may be null)
         //
 
-        public HashSet<PartSim> GetSourceSet(int type, List<PartSim> allParts, HashSet<PartSim> visited, LogMsg log, String indent)
+        public void GetSourceSet(int type, List<PartSim> allParts, HashSet<PartSim> visited, HashSet<PartSim> allSources, LogMsg log, String indent)
         {
             if (log != null)
             {
@@ -476,10 +521,7 @@
                 indent += "  ";
             }
 
-            HashSet<PartSim> allSources = new HashSet<PartSim>();
-            HashSet<PartSim> partSources = null;
-
-            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns empty list.
+            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
             if (visited.Contains(this))
             {
                 if (log != null)
@@ -487,7 +529,7 @@
                     log.buf.AppendLine(indent + "Returning empty set, already visited (" + this.name + ":" + this.partId + ")");
                 }
 
-                return allSources;
+                return;
             }
 
             //if (log != null)
@@ -499,8 +541,11 @@
             // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
             //MonoBehaviour.print("foreach fuel line");
 
-            foreach (PartSim partSim in this.fuelTargets)
-            {
+            int lastCount = allSources.Count;
+
+            for (int i = 0; i < this.fuelTargets.Count; i++)
+            {
+                PartSim partSim = this.fuelTargets[i];
                 if (visited.Contains(partSim))
                 {
                     //if (log != null)
@@ -511,24 +556,20 @@
                     //if (log != null)
                     //    log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
 
-                    partSources = partSim.GetSourceSet(type, allParts, visited, log, indent);
-                    if (partSources.Count > 0)
-                    {
-                        allSources.UnionWith(partSources);
-                        partSources.Clear();
-                    }
-                }
-            }
-
-            if (allSources.Count > 0)
+                    partSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
+                }
+            }
+
+            if (allSources.Count > lastCount)
             {
                 if (log != null)
                 {
-                    log.buf.AppendLine(indent + "Returning " + allSources.Count + " fuel target sources (" + this.name + ":" + this.partId + ")");
-                }
-
-                return allSources;
-            }
+                    log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
+                }
+
+                return;
+            }
+
 
             // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed
 
@@ -539,14 +580,18 @@
             //  The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment]
             if (this.fuelCrossFeed)
             {
+                lastCount = allSources.Count;
                 //MonoBehaviour.print("foreach attach node");
-                foreach (AttachNodeSim attachSim in this.attachNodes)
-                {
+                for (int i = 0; i < this.attachNodes.Count; i++)
+                {
+                    AttachNodeSim attachSim = this.attachNodes[i];
                     if (attachSim.attachedPartSim != null)
                     {
                         if (attachSim.nodeType == AttachNode.NodeType.Stack)
                         {
-                            if (!(this.noCrossFeedNodeKey != null && this.noCrossFeedNodeKey.Length > 0 && attachSim.id.Contains(this.noCrossFeedNodeKey)))
+                            if (
+                                !(this.noCrossFeedNodeKey != null && this.noCrossFeedNodeKey.Length > 0 &&
+                                  attachSim.id.Contains(this.noCrossFeedNodeKey)))
                             {
                                 if (visited.Contains(attachSim.attachedPartSim))
                                 {
@@ -558,26 +603,21 @@
                                     //if (log != null)
                                     //    log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
 
-                                    partSources = attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, log, indent);
-                                    if (partSources.Count > 0)
-                                    {
-                                        allSources.UnionWith(partSources);
-                                        partSources.Clear();
-                                    }
+                                    attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
                                 }
                             }
                         }
                     }
                 }
 
-                if (allSources.Count > 0)
+                if (allSources.Count > lastCount)
                 {
                     if (log != null)
                     {
-                        log.buf.AppendLine(indent + "Returning " + allSources.Count + " attached sources (" + this.name + ":" + this.partId + ")");
-                    }
-
-                    return allSources;
+                        log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
+                    }
+
+                    return;
                 }
             }
 
@@ -597,7 +637,7 @@
                     }
                 }
 
-                return allSources;
+                return;
             }
 
             // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its 
@@ -613,15 +653,16 @@
                     }
                     else
                     {
-                        allSources = this.parent.GetSourceSet(type, allParts, visited, log, indent);
-                        if (allSources.Count > 0)
+                        lastCount = allSources.Count;
+                        this.parent.GetSourceSet(type, allParts, visited, allSources, log, indent);
+                        if (allSources.Count > lastCount)
                         {
                             if (log != null)
                             {
-                                log.buf.AppendLine(indent + "Returning " + allSources.Count + " parent sources (" + this.name + ":" + this.partId + ")");
+                                log.buf.AppendLine(indent + "Returning " + (allSources.Count  - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
                             }
 
-                            return allSources;
+                            return;
                         }
                     }
                 }
@@ -631,14 +672,15 @@
             //if (log != null)
             //    log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
 
-            return allSources;
+            return;
         }
 
         public void RemoveAttachedParts(HashSet<PartSim> partSims)
         {
             // Loop through the attached parts
-            foreach (AttachNodeSim attachSim in this.attachNodes)
-            {
+            for (int i = 0; i < this.attachNodes.Count; i++)
+            {
+                AttachNodeSim attachSim = this.attachNodes[i];
                 // If the part is in the set then "remove" it by clearing the PartSim reference
                 if (partSims.Contains(attachSim.attachedPartSim))
                 {
@@ -650,8 +692,9 @@
         public void DrainResources(double time)
         {
             //MonoBehaviour.print("DrainResources(" + name + ":" + partId + ", " + time + ")");
-            foreach (int type in this.resourceDrains.Types)
-            {
+            for (int i = 0; i < this.resourceDrains.Types.Count; i++)
+            {
+                int type = this.resourceDrains.Types[i];
                 //MonoBehaviour.print("draining " + (time * resourceDrains[type]) + " " + ResourceContainer.GetResourceName(type));
                 this.resources.Add(type, -time * this.resourceDrains[type]);
                 //MonoBehaviour.print(ResourceContainer.GetResourceName(type) + " left = " + resources[type]);
@@ -663,8 +706,9 @@
             //MonoBehaviour.print("TimeToDrainResource(" + name + ":" + partId + ")");
             double time = double.MaxValue;
 
-            foreach (int type in this.resourceDrains.Types)
-            {
+            for (int i = 0; i < this.resourceDrains.Types.Count; i++)
+            {
+                int type = this.resourceDrains.Types[i];
                 if (this.resourceDrains[type] > 0)
                 {
                     time = Math.Min(time, this.resources[type] / this.resourceDrains[type]);
@@ -677,6 +721,19 @@
             return time;
         }
 
+        public bool EmptyOf(HashSet<int> types)
+        {
+            foreach (int type in types)
+            {
+                if (this.resources.HasType(type) && this.resourceFlowStates[type] != 0 && (double)this.resources[type] > SimManager.RESOURCE_MIN)
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
         public int DecouplerCount()
         {
             int count = 0;
@@ -702,8 +759,9 @@
         {
             double mass = this.baseMass;
 
-            foreach (int type in this.resources.Types)
-            {
+            for (int i = 0; i < this.resources.Types.Count; i++)
+            {
+                int type = this.resources.Types[i];
                 mass += this.resources.GetResourceMass(type);
             }
 
@@ -737,8 +795,9 @@
 
             buffer.AppendFormat(", isSep = {0}", this.isSepratron);
 
-            foreach (int type in this.resources.Types)
-            {
+            for (int i = 0; i < this.resources.Types.Count; i++)
+            {
+                int type = this.resources.Types[i];
                 buffer.AppendFormat(", {0} = {1:g6}", ResourceContainer.GetResourceName(type), this.resources[type]);
             }
 
@@ -761,8 +820,9 @@
             if (allParts != null)
             {
                 String newPrefix = prefix + " ";
-                foreach (PartSim partSim in allParts)
-                {
+                for (int i = 0; i < allParts.Count; i++)
+                {
+                    PartSim partSim = allParts[i];
                     if (partSim.parent == this)
                     {
                         partSim.DumpPartToBuffer(buffer, newPrefix, allParts);

--- a/KerbalEngineer/VesselSimulator/ResourceContainer.cs
+++ b/KerbalEngineer/VesselSimulator/ResourceContainer.cs
@@ -19,6 +19,7 @@
 
 #region Using Directives
 
+using System;
 using System.Collections;
 using System.Collections.Generic;
 
@@ -30,15 +31,17 @@
 {
     public class ResourceContainer
     {
-        private Hashtable resources = new Hashtable();
+        private Dictionary<int, double> resources = new Dictionary<int, double>();
+        private List<int> types = new List<int>();
 
         public double this[int type]
         {
             get
             {
-                if (this.resources.ContainsKey(type))
+                double value;
+                if (this.resources.TryGetValue(type, out value))
                 {
-                    return (double)this.resources[type];
+                    return value;
                 }
 
                 return 0d;
@@ -52,6 +55,7 @@
                 else
                 {
                     this.resources.Add(type, value);
+                    this.types.Add(type);
                 }
             }
         }
@@ -60,13 +64,6 @@
         {
             get
             {
-                List<int> types = new List<int>();
-
-                foreach (int key in this.resources.Keys)
-                {
-                    types.Add(key);
-                }
-
                 return types;
             }
         }
@@ -92,7 +89,7 @@
             {
                 foreach (int type in this.resources.Keys)
                 {
-                    if ((double)this.resources[type] > SimManager.RESOURCE_MIN)
+                    if (this.resources[type] > SimManager.RESOURCE_MIN)
                     {
                         return false;
                     }
@@ -111,7 +108,7 @@
         {
             foreach (int type in types)
             {
-                if (this.HasType(type) && (double)this.resources[type] > SimManager.RESOURCE_MIN)
+                if (this.HasType(type) && this.resources[type] > SimManager.RESOURCE_MIN)
                 {
                     return false;
                 }
@@ -124,17 +121,19 @@
         {
             if (this.resources.ContainsKey(type))
             {
-                this.resources[type] = (double)this.resources[type] + amount;
+                this.resources[type] = this.resources[type] + amount;
             }
             else
             {
                 this.resources.Add(type, amount);
+                this.types.Add(type);
             }
         }
 
         public void Reset()
         {
-            this.resources = new Hashtable();
+            this.resources.Clear();
+            this.types.Clear();
         }
 
         public void Debug()
@@ -148,7 +147,7 @@
         public double GetResourceMass(int type)
         {
             double density = GetResourceDensity(type);
-            return density == 0d ? 0d : (double)this.resources[type] * density;
+            return density == 0d ? 0d : this.resources[type] * density;
         }
 
         public static ResourceFlowMode GetResourceFlowMode(int type)
@@ -158,7 +157,7 @@
 
         public static ResourceTransferMode GetResourceTransferMode(int type)
         {
-            return PartResourceLibrary.Instance.GetDefinition(type).resourceTransferMode;
+            return PartResourceLibrary.Instance.GetDefinition(type).resourceTransferMode;;
         }
 
         public static float GetResourceDensity(int type)

--- a/KerbalEngineer/VesselSimulator/SimManager.cs
+++ b/KerbalEngineer/VesselSimulator/SimManager.cs
@@ -46,17 +46,20 @@
         private static readonly object locker = new object();
         private static readonly Stopwatch timer = new Stopwatch();
 
-        // Support for RealFuels using reflection to check localCorrectThrust without dependency
-
-        private static FieldInfo RF_ModuleEngineConfigs_locaCorrectThrust;
-        private static FieldInfo RF_ModuleHybridEngine_locaCorrectThrust;
-        private static FieldInfo RF_ModuleHybridEngines_locaCorrectThrust;
         private static bool bRequested;
         private static bool bRunning;
         private static TimeSpan delayBetweenSims;
-        private static bool hasCheckedForRealFuels;
+
+        // Support for RealFuels using reflection to check localCorrectThrust without dependency
+
+        private static bool hasCheckedForMods;
         private static bool hasInstalledRealFuels;
-
+        private static FieldInfo RF_ModuleEngineConfigs_localCorrectThrust;
+        private static FieldInfo RF_ModuleHybridEngine_localCorrectThrust;
+        private static FieldInfo RF_ModuleHybridEngines_localCorrectThrust;
+        private static bool hasInstalledKIDS;
+        private static MethodInfo KIDS_Utils_GetIspMultiplier;
+        private static bool bKIDSThrustISP = false;
         #endregion
 
         #region Delegates
@@ -89,54 +92,112 @@
 
         #region Methods
 
+        private static void CheckForMods()
+        {
+            hasCheckedForMods = true;
+
+            foreach (var assembly in AssemblyLoader.loadedAssemblies)
+            {
+                MonoBehaviour.print("Assembly:" + assembly.assembly);
+
+                var name = assembly.assembly.ToString().Split(',')[0];
+
+                if (name == "RealFuels")
+                {
+                    MonoBehaviour.print("Found RealFuels mod");
+
+                    var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
+                    if (RF_ModuleEngineConfigs_Type != null)
+                    {
+                        RF_ModuleEngineConfigs_localCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
+                    }
+
+                    var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
+                    if (RF_ModuleHybridEngine_Type != null)
+                    {
+                        RF_ModuleHybridEngine_localCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
+                    }
+
+                    var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
+                    if (RF_ModuleHybridEngines_Type != null)
+                    {
+                        RF_ModuleHybridEngines_localCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
+                    }
+
+                    hasInstalledRealFuels = true;
+                    break;
+                }
+                else if (name == "KerbalIspDifficultyScaler")
+                {
+                    var KIDS_Utils_Type = assembly.assembly.GetType("KerbalIspDifficultyScaler.KerbalIspDifficultyScalerUtils");
+                    if (KIDS_Utils_Type != null)
+                    {
+                        KIDS_Utils_GetIspMultiplier = KIDS_Utils_Type.GetMethod("GetIspMultiplier");
+                    }
+
+                    hasInstalledKIDS = true;
+                }
+            }
+        }
+
         public static bool DoesEngineUseCorrectedThrust(Part theEngine)
         {
-            if (!hasInstalledRealFuels /*|| HighLogic.LoadedSceneIsFlight*/)
-            {
-                return false;
-            }
-
-            // Look for any of the Real Fuels engine modules and call the relevant method to find out
-            if (RF_ModuleEngineConfigs_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
-            {
-                var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
-                if (modEngineConfigs != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleEngineConfigs_locaCorrectThrust.GetValue(modEngineConfigs))
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            if (RF_ModuleHybridEngine_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
-            {
-                var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
-                if (modHybridEngine != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleHybridEngine_locaCorrectThrust.GetValue(modHybridEngine))
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            if (RF_ModuleHybridEngines_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
-            {
-                var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
-                if (modHybridEngines != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleHybridEngines_locaCorrectThrust.GetValue(modHybridEngines))
-                    {
-                        return true;
-                    }
-                }
+            if (hasInstalledRealFuels)
+            {
+                // Look for any of the Real Fuels engine modules and call the relevant method to find out
+                if (RF_ModuleEngineConfigs_localCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
+                {
+                    var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
+                    if (modEngineConfigs != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleEngineConfigs_localCorrectThrust.GetValue(modEngineConfigs);
+                    }
+                }
+
+                if (RF_ModuleHybridEngine_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
+                {
+                    var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
+                    if (modHybridEngine != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleHybridEngine_localCorrectThrust.GetValue(modHybridEngine);
+                    }
+                }
+
+                if (RF_ModuleHybridEngines_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
+                {
+                    var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
+                    if (modHybridEngines != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleHybridEngines_localCorrectThrust.GetValue(modHybridEngines);
+                    }
+                }
+            }
+
+            if (hasInstalledKIDS && HighLogic.LoadedSceneIsEditor)
+            {
+                return bKIDSThrustISP;
             }
 
             return false;
+        }
+
+        public static void UpdateModSettings()
+        {
+            if (!hasCheckedForMods)
+            {
+                CheckForMods();
+            }
+
+            if (hasInstalledKIDS)
+            {
+                // (out ispMultiplierVac, out ispMultiplierAtm, out extendToZeroIsp, out thrustCorrection, out ispCutoff, out thrustCutoff);
+                object[] parameters = new object[6];
+                KIDS_Utils_GetIspMultiplier.Invoke(null, parameters);
+                bKIDSThrustISP = (bool)parameters[3];
+            }
         }
 
         public static String GetVesselTypeString(VesselType vesselType)
@@ -171,9 +232,9 @@
 
         public static void RequestSimulation()
         {
-            if (!hasCheckedForRealFuels)
-            {
-                GetRealFuelsTypes();
+            if (!hasCheckedForMods)
+            {
+                CheckForMods();
             }
 
             lock (locker)
@@ -215,42 +276,6 @@
             failMessage = "";
             Stages = null;
             LastStage = null;
-        }
-
-        private static void GetRealFuelsTypes()
-        {
-            hasCheckedForRealFuels = true;
-
-            foreach (var assembly in AssemblyLoader.loadedAssemblies)
-            {
-                MonoBehaviour.print("Assembly:" + assembly.assembly);
-
-                if (assembly.assembly.ToString().Split(',')[0] == "RealFuels")
-                {
-                    MonoBehaviour.print("Found RealFuels mod");
-
-                    var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
-                    if (RF_ModuleEngineConfigs_Type != null)
-                    {
-                        RF_ModuleEngineConfigs_locaCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
-                    }
-
-                    var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
-                    if (RF_ModuleHybridEngine_Type != null)
-                    {
-                        RF_ModuleHybridEngine_locaCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
-                    }
-
-                    var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
-                    if (RF_ModuleHybridEngines_Type != null)
-                    {
-                        RF_ModuleHybridEngines_locaCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
-                    }
-
-                    hasInstalledRealFuels = true;
-                    break;
-                }
-            }
         }
 
         private static void RunSimulation(object simObject)

--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -45,11 +45,14 @@
         private double atmosphere;
         private int currentStage;
         private double currentisp;
+        private HashSet<PartSim> decoupledParts = new HashSet<PartSim>();
         private bool doingCurrent;
         private List<PartSim> dontStageParts;
+        private List<List<PartSim>> dontStagePartsLists = new List<List<PartSim>>();
         private HashSet<PartSim> drainingParts;
         private HashSet<int> drainingResources;
         private double gravity;
+        private Dictionary<Part, PartSim> partSimLookup;
 
         private int lastStage;
         private List<Part> partList;
@@ -73,6 +76,17 @@
 
         public Simulation()
         {
+            this.allParts = new List<PartSim>();
+            this.allFuelLines = new List<PartSim>();
+            this.drainingParts = new HashSet<PartSim>();
+            this.allEngines = new List<EngineSim>();
+            this.activeEngines = new List<EngineSim>();
+            this.drainingResources = new HashSet<int>();
+            this.totalStageThrustForce = new ForceAccumulator();
+
+            // A dictionary for fast lookup of Part->PartSim during the preparation phase
+            partSimLookup = new Dictionary<Part, PartSim>();
+
             if (SimManager.logOutput)
             {
                 MonoBehaviour.print("Simulation created");
@@ -85,8 +99,9 @@
             {
                 double mass = 0d;
 
-                foreach (PartSim partSim in this.allParts)
-                {
+                for (int i = 0; i < this.allParts.Count; i++)
+                {
+                    PartSim partSim = this.allParts[i];
                     mass += partSim.GetMass();
                 }
 
@@ -100,8 +115,9 @@
             {
                 WeightedVectorAverager averager = new WeightedVectorAverager();
 
-                foreach (PartSim partSim in this.allParts)
-                {
+                for (int i = 0; i < this.allParts.Count; i++)
+                {
+                    PartSim partSim = this.allParts[i];
                     averager.Add(partSim.centerOfMass, partSim.GetMass());
                 }
 
@@ -132,27 +148,28 @@
             this.lastStage = Staging.lastStage;
             //MonoBehaviour.print("lastStage = " + lastStage);
 
-            // Create the lists for our simulation parts
-            this.allParts = new List<PartSim>();
-            this.allFuelLines = new List<PartSim>();
-            this.drainingParts = new HashSet<PartSim>();
-            this.allEngines = new List<EngineSim>();
-            this.activeEngines = new List<EngineSim>();
-            this.drainingResources = new HashSet<int>();
+            // Clear the lists for our simulation parts
+            this.allParts.Clear();
+            this.allFuelLines.Clear();
+            this.drainingParts.Clear();
+            this.allEngines.Clear();
+            this.activeEngines.Clear();
+            this.drainingResources.Clear();
 
             // A dictionary for fast lookup of Part->PartSim during the preparation phase
-            Dictionary<Part, PartSim> partSimLookup = new Dictionary<Part, PartSim>();
+            partSimLookup.Clear();
 
             if (this.partList.Count > 0 && this.partList[0].vessel != null)
             {
                 this.vesselName = this.partList[0].vessel.vesselName;
                 this.vesselType = this.partList[0].vessel.vesselType;
             }
-
+            //MonoBehaviour.print("PrepareSimulation pool size = " + PartSim.pool.Count());
             // First we create a PartSim for each Part (giving each a unique id)
             int partId = 1;
-            foreach (Part part in this.partList)
-            {
+            for (int i = 0; i < this.partList.Count; i++)
+            {
+                Part part = this.partList[i];
                 // If the part is already in the lookup dictionary then log it and skip to the next part
                 if (partSimLookup.ContainsKey(part))
                 {
@@ -164,7 +181,8 @@
                 }
 
                 // Create the PartSim
-                PartSim partSim = new PartSim(part, partId, this.atmosphere, log);
+                PartSim partSim = PartSim.pool.Borrow();
+                partSim.Set(part, partId, this.atmosphere, log);
 
                 // Add it to the Part lookup dictionary and the necessary lists
                 partSimLookup.Add(part, partSim);
@@ -185,16 +203,18 @@
 
             // Now that all the PartSims have been created we can do any set up that needs access to other parts
             // First we set up all the parent links
-            foreach (PartSim partSim in this.allParts)
-            {
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 partSim.SetupParent(partSimLookup, log);
             }
 
             // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets
             if (HighLogic.LoadedSceneIsEditor)
             {
-                foreach (PartSim partSim in this.allFuelLines)
-                {
+                for (int i = 0; i < this.allFuelLines.Count; i++)
+                {
+                    PartSim partSim = this.allFuelLines[i];
                     CModuleFuelLine fuelLine = partSim.part.GetModule<CModuleFuelLine>();
                     if (fuelLine.target != null)
                     {
@@ -227,8 +247,9 @@
             }
 
             //MonoBehaviour.print("SetupAttachNodes and count stages");
-            foreach (PartSim partSim in this.allParts)
-            {
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 partSim.SetupAttachNodes(partSimLookup, log);
                 if (partSim.decoupledInStage >= this.lastStage)
                 {
@@ -238,8 +259,9 @@
 
             // And finally release the Part references from all the PartSims
             //MonoBehaviour.print("ReleaseParts");
-            foreach (PartSim partSim in this.allParts)
-            {
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 partSim.ReleasePart();
             }
 
@@ -260,7 +282,7 @@
 
             return true;
         }
-
+        
         // This function runs the simulation and returns a newly created array of Stage objects
         public Stage[] RunSimulation()
         {
@@ -280,13 +302,13 @@
             // Start with the last stage to simulate
             // (this is in a member variable so it can be accessed by AllowedToStage and ActivateStage)
             this.currentStage = this.lastStage;
-
             // Work out which engines would be active if just doing the staging and if this is different to the 
             // currently active engines then generate an extra stage
             // Loop through all the engines
             bool anyActive = false;
-            foreach (EngineSim engine in this.allEngines)
-            {
+            for (int i = 0; i < this.allEngines.Count; i++)
+            {
+                EngineSim engine = this.allEngines[i];
                 if (log != null)
                 {
                     log.buf.AppendLine("Testing engine mod of " + engine.partSim.name + ":" + engine.partSim.partId);
@@ -341,7 +363,7 @@
             }
 
             // Create a list of lists of PartSims that prevent decoupling
-            List<List<PartSim>> dontStagePartsLists = this.BuildDontStageLists(log);
+            this.BuildDontStageLists(log);
 
             if (log != null)
             {
@@ -350,7 +372,6 @@
 
             // Create the array of stages that will be returned
             Stage[] stages = new Stage[this.currentStage + 1];
-
 
             // Loop through the stages
             while (this.currentStage >= 0)
@@ -414,8 +435,9 @@
 
                 // Calculate the cost and mass of this stage and add all engines and tanks that are decoupled
                 // in the next stage to the dontStageParts list
-                foreach (PartSim partSim in this.allParts)
-                {
+                for (int i = 0; i < this.allParts.Count; i++)
+                {
+                    PartSim partSim = this.allParts[i];
                     if (partSim.decoupledInStage == this.currentStage - 1)
                     {
                         stage.cost += partSim.cost;
@@ -432,8 +454,9 @@
                     if (this.dontStageParts.Count > 0)
                     {
                         log.buf.AppendLine("Parts preventing staging:");
-                        foreach (PartSim partSim in this.dontStageParts)
-                        {
+                        for (int i = 0; i < this.dontStageParts.Count; i++)
+                        {
+                            PartSim partSim = this.dontStageParts[i];
                             partSim.DumpPartToBuffer(log.buf, "");
                         }
                     }
@@ -444,6 +467,7 @@
 
                     log.Flush();
                 }
+
 
                 // Now we will loop until we are allowed to stage
                 int loopCounter = 0;
@@ -451,7 +475,6 @@
                 {
                     loopCounter++;
                     //MonoBehaviour.print("loop = " + loopCounter);
-
                     // Calculate how long each draining tank will take to drain and run for the minimum time
                     double resourceDrainTime = double.MaxValue;
                     PartSim partMinDrain = null;
@@ -469,7 +492,6 @@
                     {
                         MonoBehaviour.print("Drain time = " + resourceDrainTime + " (" + partMinDrain.name + ":" + partMinDrain.partId + ")");
                     }
-
                     foreach (PartSim partSim in this.drainingParts)
                     {
                         partSim.DrainResources(resourceDrainTime);
@@ -501,7 +523,7 @@
 
                     // Recalculate the current thrust and isp for the next step
                     this.CalculateThrustAndISP();
-
+                    
                     // Check if we actually changed anything
                     if (this.stepStartMass == this.stepEndMass)
                     {
@@ -527,11 +549,12 @@
                     this.stepStartMass = this.stepEndMass;
                 }
 
+
                 // Store more values in the Stage object and stick it in the array
 
                 // Store the magnitude of the deltaV vector
                 stage.deltaV = this.vecStageDeltaV.magnitude;
-                stage.resourceMass = this.stepStartMass - this.stepEndMass;
+                stage.resourceMass = this.stageStartMass - this.stepEndMass;
 
                 // Recalculate effective stage isp from the stage deltaV (flip the standard deltaV calculation around)
                 // Note: If the mass doesn't change then this is a divide by zero
@@ -606,29 +629,54 @@
                 this._timer.Stop();
                 MonoBehaviour.print("RunSimulation: " + this._timer.ElapsedMilliseconds + "ms");
             }
-
+            FreePooledObject();
+            
             return stages;
         }
 
-        private List<List<PartSim>> BuildDontStageLists(LogMsg log)
+        
+        // Make sure we free them all, even if they should all be free already at this point
+        public void FreePooledObject()
+        {
+            //MonoBehaviour.print("FreePooledObject pool size before = " + PartSim.pool.Count() + " for " + allParts.Count + " parts");
+            foreach (PartSim part in allParts)
+            {
+                PartSim.pool.Release(part);
+            }
+            //MonoBehaviour.print("FreePooledObject pool size after = " + PartSim.pool.Count());
+
+            //MonoBehaviour.print("FreePooledObject pool size before = " + EngineSim.pool.Count() + " for " + allEngines.Count + " engines");
+            foreach (EngineSim engine in allEngines)
+            {
+                EngineSim.pool.Release(engine);
+            }
+            //MonoBehaviour.print("FreePooledObject pool size after = " + EngineSim.pool.Count());
+        }
+
+        private void BuildDontStageLists(LogMsg log)
         {
             if (log != null)
             {
                 log.buf.AppendLine("Creating list with capacity of " + (this.currentStage + 1));
             }
-            List<List<PartSim>> lists = new List<List<PartSim>>();
+            
             for (int i = 0; i <= this.currentStage; i++)
             {
-                lists.Add(new List<PartSim>());
-            }
-
-            foreach (PartSim partSim in this.allParts)
-            {
+                if (i < dontStagePartsLists.Count)
+                    dontStagePartsLists[i].Clear();
+                else
+                    dontStagePartsLists.Add(new List<PartSim>());
+            }
+
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 if (partSim.isEngine || !partSim.Resources.Empty)
                 {
                     if (log != null)
                     {
-                        log.buf.AppendLine(partSim.name + ":" + partSim.partId + " is engine or tank, decoupled = " + partSim.decoupledInStage);
+                        log.buf.AppendLine(
+                            partSim.name + ":" + partSim.partId + " is engine or tank, decoupled = " + partSim.decoupledInStage);
                     }
 
                     if (partSim.decoupledInStage < -1 || partSim.decoupledInStage > this.currentStage - 1)
@@ -640,28 +688,27 @@
                     }
                     else
                     {
-                        lists[partSim.decoupledInStage + 1].Add(partSim);
+                        dontStagePartsLists[partSim.decoupledInStage + 1].Add(partSim);
                     }
                 }
             }
 
             for (int i = 1; i <= this.lastStage; i++)
             {
-                if (lists[i].Count == 0)
-                {
-                    lists[i] = lists[i - 1];
-                }
-            }
-
-            return lists;
+                if (dontStagePartsLists[i].Count == 0)
+                {
+                    dontStagePartsLists[i] = dontStagePartsLists[i - 1];
+                }
+            }
         }
 
         // This function simply rebuilds the active engines by testing the isActive flag of all the engines
         private void UpdateActiveEngines()
         {
             this.activeEngines.Clear();
-            foreach (EngineSim engine in this.allEngines)
-            {
+            for (int i = 0; i < this.allEngines.Count; i++)
+            {
+                EngineSim engine = this.allEngines[i];
                 if (engine.isActive)
                 {
                     this.activeEngines.Add(engine);
@@ -679,12 +726,12 @@
             this.totalStageActualThrust = 0d;
             this.totalStageFlowRate = 0d;
             this.totalStageIspFlowRate = 0d;
-            this.totalStageThrustForce = new ForceAccumulator();
-
+            this.totalStageThrustForce.Reset();
             // Loop through all the active engines totalling the thrust, actual thrust and mass flow rates
             // The thrust is totalled as vectors
-            foreach (EngineSim engine in this.activeEngines)
-            {
+            for (int i = 0; i < this.activeEngines.Count; i++)
+            {
+                EngineSim engine = this.activeEngines[i];
                 this.simpleTotalThrust += engine.thrust;
                 this.vecThrust += ((float)engine.thrust * engine.thrustVec);
                 this.vecActualThrust += ((float)engine.actualThrust * engine.thrustVec);
@@ -692,13 +739,13 @@
                 this.totalStageFlowRate += engine.ResourceConsumptions.Mass;
                 this.totalStageIspFlowRate += engine.ResourceConsumptions.Mass * engine.isp;
 
-                foreach (AppliedForce f in engine.appliedForces) {
+                for (int j = 0; j < engine.appliedForces.Count; j++)
+                {
+                    AppliedForce f = engine.appliedForces[j];
                     this.totalStageThrustForce.AddForce(f);
                 }
             }
-
             //MonoBehaviour.print("vecThrust = " + vecThrust.ToString() + "   magnitude = " + vecThrust.magnitude);
-
             this.totalStageThrust = this.vecThrust.magnitude;
             this.totalStageActualThrust = this.vecActualThrust.magnitude;
 
@@ -733,14 +780,16 @@
             this.drainingParts.Clear();
 
             // Loop through all the active engine modules
-            foreach (EngineSim engine in this.activeEngines)
-            {
+            for (int i = 0; i < this.activeEngines.Count; i++)
+            {
+                EngineSim engine = this.activeEngines[i];
                 // Set the resource drains for this engine
                 if (engine.SetResourceDrains(this.allParts, this.allFuelLines, this.drainingParts))
                 {
                     // If it is active then add the consumed resource types to the set
-                    foreach (int type in engine.ResourceConsumptions.Types)
-                    {
+                    for (int j = 0; j < engine.ResourceConsumptions.Types.Count; j++)
+                    {
+                        int type = engine.ResourceConsumptions.Types[j];
                         this.drainingResources.Add(type);
                     }
                 }
@@ -754,8 +803,9 @@
                 StringBuilder buffer = new StringBuilder(1024);
                 buffer.AppendFormat("Active engines = {0:d}\n", this.activeEngines.Count);
                 int i = 0;
-                foreach (EngineSim engine in this.activeEngines)
-                {
+                for (int j = 0; j < this.activeEngines.Count; j++)
+                {
+                    EngineSim engine = this.activeEngines[j];
                     engine.DumpEngineToBuffer(buffer, "Engine " + (i++) + ":");
                 }
                 MonoBehaviour.print(buffer);
@@ -775,15 +825,16 @@
 
             if (this.activeEngines.Count > 0)
             {
-                foreach (PartSim partSim in this.dontStageParts)
-                {
+                for (int i = 0; i < this.dontStageParts.Count; i++)
+                {
+                    PartSim partSim = this.dontStageParts[i];
                     if (SimManager.logOutput)
                     {
                         partSim.DumpPartToBuffer(buffer, "Testing: ");
                     }
                     //buffer.AppendFormat("isSepratron = {0}\n", partSim.isSepratron ? "true" : "false");
 
-                    if (!partSim.isSepratron && !partSim.Resources.EmptyOf(this.drainingResources))
+                    if (!partSim.isSepratron && !partSim.EmptyOf(this.drainingResources))
                     {
                         if (SimManager.logOutput)
                         {
@@ -795,8 +846,9 @@
 
                     if (partSim.isEngine)
                     {
-                        foreach (EngineSim engine in this.activeEngines)
-                        {
+                        for (int j = 0; j < this.activeEngines.Count; j++)
+                        {
+                            EngineSim engine = this.activeEngines[j];
                             if (engine.partSim == partSim)
                             {
                                 if (SimManager.logOutput)
@@ -834,9 +886,10 @@
         private void ActivateStage()
         {
             // Build a set of all the parts that will be decoupled
-            HashSet<PartSim> decoupledParts = new HashSet<PartSim>();
-            foreach (PartSim partSim in this.allParts)
-            {
+            decoupledParts.Clear();
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 if (partSim.decoupledInStage >= this.currentStage)
                 {
                     decoupledParts.Add(partSim);
@@ -847,14 +900,17 @@
             {
                 // Remove it from the all parts list
                 this.allParts.Remove(partSim);
+                PartSim.pool.Release(partSim);
                 if (partSim.isEngine)
                 {
                     // If it is an engine then loop through all the engine modules and remove all the ones from this engine part
                     for (int i = this.allEngines.Count - 1; i >= 0; i--)
                     {
-                        if (this.allEngines[i].partSim == partSim)
+                        EngineSim engine = this.allEngines[i];
+                        if (engine.partSim == partSim)
                         {
                             this.allEngines.RemoveAt(i);
+                            EngineSim.pool.Release(engine);
                         }
                     }
                 }
@@ -866,15 +922,17 @@
             }
 
             // Loop through all the (remaining) parts
-            foreach (PartSim partSim in this.allParts)
-            {
+            for (int i = 0; i < this.allParts.Count; i++)
+            {
+                PartSim partSim = this.allParts[i];
                 // Ask the part to remove all the parts that are decoupled
                 partSim.RemoveAttachedParts(decoupledParts);
             }
 
             // Now we loop through all the engines and activate those that are ignited in this stage
-            foreach (EngineSim engine in this.allEngines)
-            {
+            for (int i = 0; i < this.allEngines.Count; i++)
+            {
+                EngineSim engine = this.allEngines[i];
                 if (engine.partSim.inverseStage == this.currentStage)
                 {
                     engine.isActive = true;

--- a/KerbalEngineer/VesselSimulator/Stage.cs
+++ b/KerbalEngineer/VesselSimulator/Stage.cs
@@ -29,27 +29,28 @@
 {
     public class Stage
     {
-        public double actualThrust = 0f;
-        public double actualThrustToWeight = 0f;
-        public double cost = 0d;
-        public double deltaV = 0f;
-        public double inverseTotalDeltaV = 0f;
-        public double isp = 0f;
-        public double mass = 0f;
-        public double maxThrustToWeight = 0f;
+        public double actualThrust = 0.0;
+        public double actualThrustToWeight = 0.0;
+        public double cost = 0.0;
+        public double deltaV = 0.0;
+        public double inverseTotalDeltaV = 0.0;
+        public double isp = 0.0;
+        public double mass = 0.0;
+        public double rcsMass = 0.0;
+        public double maxThrustToWeight = 0.0;
         public int number = 0;
-        public double thrust = 0f;
-        public double thrustToWeight = 0f;
-        public double time = 0f;
-        public double totalCost = 0;
-        public double totalDeltaV = 0f;
-        public double totalMass = 0f;
-        public double totalTime = 0f;
+        public double thrust = 0.0;
+        public double thrustToWeight = 0.0;
+        public double time = 0.0;
+        public double totalCost = 0.0;
+        public double totalDeltaV = 0.0;
+        public double totalMass = 0.0;
+        public double totalTime = 0.0;
         public int totalPartCount = 0;
         public int partCount = 0;
         public double resourceMass = 0.0;
-        public double maxThrustTorque = 0f;
-        public double thrustOffsetAngle = 0f;
+        public double maxThrustTorque = 0.0;
+        public double thrustOffsetAngle = 0.0;
 
         public void Dump()
         {

 Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ
--- a/Output/KerbalEngineer/KerbalEngineer.version
+++ b/Output/KerbalEngineer/KerbalEngineer.version
@@ -5,8 +5,8 @@
 	{
 		"MAJOR":1,
 		"MINOR":0,
-		"PATCH":13,
-		"BUILD":0
+		"PATCH":15,
+		"BUILD":2
 	},
 	"KSP_VERSION":
 	{

 Binary files /dev/null and b/Output/KerbalEngineer/Parts/Engineer7500/model000.mbm differ
--- a/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
+++ b/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
@@ -7,7 +7,6 @@
 	
 	// --- asset parameters ---
 	mesh = model.mu
-	texture = model000.mbm
 	rescaleFactor = 0.8
 
 	PhysicsSignificance = 1

 Binary files a/Output/KerbalEngineer/Parts/Engineer7500/textures/model000.mbm and /dev/null differ