Added required parts of Smooth library
Added required parts of Smooth library

--- 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.15.2";
 
         #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/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" />

--- /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/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -243,7 +243,7 @@
                 switch (ResourceContainer.GetResourceFlowMode(type))
                 {
                     case ResourceFlowMode.NO_FLOW:
-                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN)
+                        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");
@@ -254,7 +254,7 @@
                     case ResourceFlowMode.ALL_VESSEL:
                         foreach (PartSim aPartSim in allParts)
                         {
-                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN)
+                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                             {
                                 if (sourcePartSet == null)
                                 {
@@ -270,10 +270,10 @@
                         var stagePartSets = new Dictionary<int, HashSet<PartSim>>();
                         var maxStage = -1;
 
-                        Logger.Log(type);
+                        //Logger.Log(type);
                         foreach (var aPartSim in allParts)
                         {
-                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN) continue;
+                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0) continue;
 
                             var stage = aPartSim.DecouplerCount();
                             if (stage > maxStage)

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -677,6 +677,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;

--- 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
@@ -531,7 +531,7 @@
 
                 // 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
@@ -783,7 +783,7 @@
                     }
                     //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)
                         {

--- 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