PartInfoItem objects are now pooled.
PartInfoItem objects are now pooled.

--- a/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
+++ b/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
@@ -128,6 +128,8 @@
                         return;
                     }
 
+                    PartInfoItem.ReleaseAll();
+
                     this.SetCostInfo();
                     this.SetMassItems();
                     this.SetResourceItems();
@@ -186,16 +188,16 @@
             }
 
             var alternator = this.selectedPart.GetModule<ModuleAlternator>();
-            this.infoItems.Add(new PartInfoItem("Alternator"));
+            this.infoItems.Add(PartInfoItem.Create("Alternator"));
             foreach (var resource in alternator.outputResources)
             {
-                this.infoItems.Add(new PartInfoItem("\t" + resource.name, resource.rate.ToRate()));
+                this.infoItems.Add(PartInfoItem.Create("\t" + resource.name, resource.rate.ToRate()));
             }
         }
 
         private void SetCostInfo()
         {
-            this.infoItems.Add(new PartInfoItem("Cost", Units.ConcatF(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
+            this.infoItems.Add(PartInfoItem.Create("Cost", Units.ConcatF(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
         }
 
         private void SetDecouplerInfo()
@@ -206,10 +208,10 @@
             }
 
             var decoupler = this.selectedPart.GetProtoModuleDecoupler();
-            this.infoItems.Add(new PartInfoItem("Ejection Force", decoupler.EjectionForce.ToForce()));
+            this.infoItems.Add(PartInfoItem.Create("Ejection Force", decoupler.EjectionForce.ToForce()));
             if (decoupler.IsOmniDecoupler)
             {
-                this.infoItems.Add(new PartInfoItem("Omni-directional"));
+                this.infoItems.Add(PartInfoItem.Create("Omni-directional"));
             }
         }
 
@@ -221,15 +223,15 @@
             }
 
             var engine = this.selectedPart.GetProtoModuleEngine();
-            this.infoItems.Add(new PartInfoItem("Thrust", Units.ToForce(engine.MinimumThrust, engine.MaximumThrust)));
-            this.infoItems.Add(new PartInfoItem("Isp", Units.ConcatF(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
+            this.infoItems.Add(PartInfoItem.Create("Thrust", Units.ToForce(engine.MinimumThrust, engine.MaximumThrust)));
+            this.infoItems.Add(PartInfoItem.Create("Isp", Units.ConcatF(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
             if (engine.Propellants.Count > 0)
             {
-                this.infoItems.Add(new PartInfoItem("Propellants"));
+                this.infoItems.Add(PartInfoItem.Create("Propellants"));
                 var totalRatio = engine.Propellants.Sum(p => p.ratio);
                 foreach (var propellant in engine.Propellants)
                 {
-                    this.infoItems.Add(new PartInfoItem("\t" + propellant.name, (propellant.ratio / totalRatio).ToPercent()));
+                    this.infoItems.Add(PartInfoItem.Create("\t" + propellant.name, (propellant.ratio / totalRatio).ToPercent()));
                 }
             }
         }
@@ -244,23 +246,23 @@
             var generator = this.selectedPart.GetModule<ModuleGenerator>();
             if (generator.inputList.Count > 0)
             {
-                this.infoItems.Add(new PartInfoItem("Generator Input"));
+                this.infoItems.Add(PartInfoItem.Create("Generator Input"));
                 foreach (var resource in generator.inputList)
                 {
-                    this.infoItems.Add(new PartInfoItem("\t" + resource.name, resource.rate.ToRate()));
+                    this.infoItems.Add(PartInfoItem.Create("\t" + resource.name, resource.rate.ToRate()));
                 }
             }
             if (generator.outputList.Count > 0)
             {
-                this.infoItems.Add(new PartInfoItem("Generator Output"));
+                this.infoItems.Add(PartInfoItem.Create("Generator Output"));
                 foreach (var resource in generator.outputList)
                 {
-                    this.infoItems.Add(new PartInfoItem("\t" + resource.name, resource.rate.ToRate()));
+                    this.infoItems.Add(PartInfoItem.Create("\t" + resource.name, resource.rate.ToRate()));
                 }
             }
             if (generator.isAlwaysActive)
             {
-                this.infoItems.Add(new PartInfoItem("Generator is Always Active"));
+                this.infoItems.Add(PartInfoItem.Create("Generator is Always Active"));
             }
         }
 
@@ -272,14 +274,14 @@
             }
 
             var gimbal = this.selectedPart.GetModule<ModuleGimbal>();
-            this.infoItems.Add(new PartInfoItem("Thrust Vectoring", gimbal.gimbalRange.ToString("F2")));
+            this.infoItems.Add(PartInfoItem.Create("Thrust Vectoring", gimbal.gimbalRange.ToString("F2")));
         }
 
         private void SetMassItems()
         {
             if (this.selectedPart.physicalSignificance == Part.PhysicalSignificance.FULL)
             {
-                this.infoItems.Add(new PartInfoItem("Mass", Units.ToMass(this.selectedPart.GetDryMass(), this.selectedPart.GetWetMass())));
+                this.infoItems.Add(PartInfoItem.Create("Mass", Units.ToMass(this.selectedPart.GetDryMass(), this.selectedPart.GetWetMass())));
             }
         }
 
@@ -291,9 +293,9 @@
             }
 
             var parachute = this.selectedPart.GetModule<ModuleParachute>();
-            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")));
+            this.infoItems.Add(PartInfoItem.Create("Deployed Drag", Units.ConcatF(parachute.semiDeployedDrag, parachute.fullyDeployedDrag)));
+            this.infoItems.Add(PartInfoItem.Create("Deployment Altitude", parachute.deployAltitude.ToDistance()));
+            this.infoItems.Add(PartInfoItem.Create("Deployment Pressure", parachute.minAirPressureToOpen.ToString("F2")));
         }
 
         private void SetRcsInfo()
@@ -304,8 +306,8 @@
             }
 
             var rcs = this.selectedPart.GetModule<ModuleRCS>();
-            this.infoItems.Add(new PartInfoItem("Thruster Power", rcs.thrusterPower.ToForce()));
-            this.infoItems.Add(new PartInfoItem("Specific Impulse", Units.ConcatF(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
+            this.infoItems.Add(PartInfoItem.Create("Thruster Power", rcs.thrusterPower.ToForce()));
+            this.infoItems.Add(PartInfoItem.Create("Specific Impulse", Units.ConcatF(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
         }
 
         private void SetReactionWheelInfo()
@@ -316,13 +318,13 @@
             }
 
             var reactionWheel = this.selectedPart.GetModule<ModuleReactionWheel>();
-            this.infoItems.Add(new PartInfoItem("Reaction Wheel Torque"));
-            this.infoItems.Add(new PartInfoItem("\tPitch", reactionWheel.PitchTorque.ToTorque()));
-            this.infoItems.Add(new PartInfoItem("\tRoll", reactionWheel.RollTorque.ToTorque()));
-            this.infoItems.Add(new PartInfoItem("\tYaw", reactionWheel.YawTorque.ToTorque()));
+            this.infoItems.Add(PartInfoItem.Create("Reaction Wheel Torque"));
+            this.infoItems.Add(PartInfoItem.Create("\tPitch", reactionWheel.PitchTorque.ToTorque()));
+            this.infoItems.Add(PartInfoItem.Create("\tRoll", reactionWheel.RollTorque.ToTorque()));
+            this.infoItems.Add(PartInfoItem.Create("\tYaw", reactionWheel.YawTorque.ToTorque()));
             foreach (var resource in reactionWheel.inputResources)
             {
-                this.infoItems.Add(new PartInfoItem("\t" + resource.name, resource.rate.ToRate()));
+                this.infoItems.Add(PartInfoItem.Create("\t" + resource.name, resource.rate.ToRate()));
             }
         }
 
@@ -330,12 +332,12 @@
         {
             if (this.selectedPart.Resources.list.Any(r => !r.hideFlow))
             {
-                this.infoItems.Add(new PartInfoItem("Resources"));
+                this.infoItems.Add(PartInfoItem.Create("Resources"));
                 foreach (var resource in this.selectedPart.Resources.list.Where(r => !r.hideFlow))
                 {
                     this.infoItems.Add(resource.GetDensity() > 0
-                        ? new PartInfoItem("\t" + resource.info.name, "(" + resource.GetMass().ToMass() + ") " + resource.amount.ToString("F1"))
-                        : new PartInfoItem("\t" + resource.info.name, resource.amount.ToString("F1")));
+                        ? PartInfoItem.Create("\t" + resource.info.name, "(" + resource.GetMass().ToMass() + ") " + resource.amount.ToString("F1"))
+                        : PartInfoItem.Create("\t" + resource.info.name, resource.amount.ToString("F1")));
                 }
             }
         }
@@ -344,7 +346,7 @@
         {
             if (this.selectedPart.HasModule<ModuleSAS>())
             {
-                this.infoItems.Add(new PartInfoItem("SAS Equiped"));
+                this.infoItems.Add(PartInfoItem.Create("SAS Equiped"));
             }
         }
 
@@ -352,7 +354,7 @@
         {
             if (this.selectedPart.HasModule<ModuleScienceContainer>())
             {
-                this.infoItems.Add(new PartInfoItem("Science Container"));
+                this.infoItems.Add(PartInfoItem.Create("Science Container"));
             }
         }
 
@@ -364,11 +366,11 @@
             }
 
             var experiment = this.selectedPart.GetModule<ModuleScienceExperiment>();
-            this.infoItems.Add(new PartInfoItem("Science Experiment", experiment.experimentActionName));
-            this.infoItems.Add(new PartInfoItem("\tTransmit Efficiency", experiment.xmitDataScalar.ToPercent()));
+            this.infoItems.Add(PartInfoItem.Create("Science Experiment", experiment.experimentActionName));
+            this.infoItems.Add(PartInfoItem.Create("\tTransmit Efficiency", experiment.xmitDataScalar.ToPercent()));
             if (!experiment.rerunnable)
             {
-                this.infoItems.Add(new PartInfoItem("\tSingle Usage"));
+                this.infoItems.Add(PartInfoItem.Create("\tSingle Usage"));
             }
         }
 
@@ -376,7 +378,7 @@
         {
             if (this.selectedPart.HasModule<ModuleAnimateGeneric>(m => m.isOneShot))
             {
-                this.infoItems.Add(new PartInfoItem("Single Activation"));
+                this.infoItems.Add(PartInfoItem.Create("Single Activation"));
             }
         }
 
@@ -388,14 +390,14 @@
             }
 
             var solarPanel = this.selectedPart.GetModule<ModuleDeployableSolarPanel>();
-            this.infoItems.Add(new PartInfoItem("Charge Rate", solarPanel.chargeRate.ToRate()));
+            this.infoItems.Add(PartInfoItem.Create("Charge Rate", solarPanel.chargeRate.ToRate()));
             if (solarPanel.isBreakable)
             {
-                this.infoItems.Add(new PartInfoItem("Breakable"));
+                this.infoItems.Add(PartInfoItem.Create("Breakable"));
             }
             if (solarPanel.sunTracking)
             {
-                this.infoItems.Add(new PartInfoItem("Sun Tracking"));
+                this.infoItems.Add(PartInfoItem.Create("Sun Tracking"));
             }
         }
 
@@ -407,9 +409,9 @@
             }
 
             var transmitter = this.selectedPart.GetModule<ModuleDataTransmitter>();
-            this.infoItems.Add(new PartInfoItem("Packet Size", transmitter.packetSize.ToString("F2") + " Mits"));
-            this.infoItems.Add(new PartInfoItem("Bandwidth", (transmitter.packetInterval * transmitter.packetSize).ToString("F2") + "Mits/sec"));
-            this.infoItems.Add(new PartInfoItem(transmitter.requiredResource, transmitter.packetResourceCost.ToString("F2") + "/Packet"));
+            this.infoItems.Add(PartInfoItem.Create("Packet Size", transmitter.packetSize.ToString("F2") + " Mits"));
+            this.infoItems.Add(PartInfoItem.Create("Bandwidth", (transmitter.packetInterval * transmitter.packetSize).ToString("F2") + "Mits/sec"));
+            this.infoItems.Add(PartInfoItem.Create(transmitter.requiredResource, transmitter.packetResourceCost.ToString("F2") + "/Packet"));
         }
 
         private void Window(int windowId)

--- a/KerbalEngineer/Editor/BuildOverlayVessel.cs
+++ b/KerbalEngineer/Editor/BuildOverlayVessel.cs
@@ -200,11 +200,12 @@
 
             if (this.lastStage != null)
             {
+                PartInfoItem.ReleaseAll();
                 this.infoItems.Clear();
-                this.infoItems.Add(new PartInfoItem("Delta-V", this.lastStage.deltaV.ToString("N0") + " / " + this.lastStage.totalDeltaV.ToString("N0") + "m/s"));
-                this.infoItems.Add(new PartInfoItem("Mass", Units.ToMass(this.lastStage.mass, this.lastStage.totalMass)));
-                this.infoItems.Add(new PartInfoItem("TWR", this.lastStage.thrustToWeight.ToString("F2") + " (" + this.lastStage.maxThrustToWeight.ToString("F2") + ")"));
-                this.infoItems.Add(new PartInfoItem("Parts", this.lastStage.partCount + " / " + this.lastStage.totalPartCount));
+                this.infoItems.Add(PartInfoItem.Create("Delta-V", this.lastStage.deltaV.ToString("N0") + " / " + this.lastStage.totalDeltaV.ToString("N0") + "m/s"));
+                this.infoItems.Add(PartInfoItem.Create("Mass", Units.ToMass(this.lastStage.mass, this.lastStage.totalMass)));
+                this.infoItems.Add(PartInfoItem.Create("TWR", this.lastStage.thrustToWeight.ToString("F2") + " (" + this.lastStage.maxThrustToWeight.ToString("F2") + ")"));
+                this.infoItems.Add(PartInfoItem.Create("Parts", this.lastStage.partCount + " / " + this.lastStage.totalPartCount));
             }
         }
 

--- a/KerbalEngineer/Editor/PartInfoItem.cs
+++ b/KerbalEngineer/Editor/PartInfoItem.cs
@@ -19,29 +19,38 @@
 
 namespace KerbalEngineer.Editor
 {
-    public class PartInfoItem
+    using VesselSimulator;
+
+    public class PartInfoItem : Pool<PartInfoItem>
     {
-        #region Constructors
-
-        public PartInfoItem(string name)
-        {
-            this.Name = name;
-        }
-
-        public PartInfoItem(string name, string value)
-        {
-            this.Name = name;
-            this.Value = value;
-        }
-
-        #endregion
-
-        #region Properties
-
         public string Name { get; set; }
 
         public string Value { get; set; }
 
-        #endregion
+        public static PartInfoItem Create(string name)
+        {
+            return GetPoolObject().Initialise(name);
+        }
+
+        public static PartInfoItem Create(string name, string value)
+        {
+            return GetPoolObject().Initialise(name, value);
+        }
+
+        public PartInfoItem Initialise(string name)
+        {
+            Name = name;
+            Value = string.Empty;
+
+            return this;
+        }
+
+        public PartInfoItem Initialise(string name, string value)
+        {
+            Name = name;
+            Value = value;
+
+            return this;
+        }
     }
 }

--- a/KerbalEngineer/Extensions/PartExtensions.cs
+++ b/KerbalEngineer/Extensions/PartExtensions.cs
@@ -17,21 +17,17 @@
 //     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 
 
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-#endregion
-
 namespace KerbalEngineer.Extensions
 {
+    using System;
+    using System.Collections.Generic;
     using CompoundParts;
 
     public static class PartExtensions
     {
-        #region Methods: public
+        private static Part cachePart;
+        private static PartModule cachePartModule;
+        private static PartResource cachePartResource;
 
         /// <summary>
         ///     Gets whether the part contains a specific resource.
@@ -46,7 +42,14 @@
         /// </summary>
         public static bool ContainsResources(this Part part)
         {
-            return part.Resources.list.Count(p => p.amount > 0d) > 0;
+            for (int i = 0; i < part.Resources.list.Count; ++i)
+            {
+                if (part.Resources.list[i].amount > 0.0)
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         /// <summary>
@@ -54,13 +57,16 @@
         /// </summary>
         public static bool EngineHasFuel(this Part part)
         {
-            if (part.HasModule<ModuleEngines>())
-            {
-                return part.GetModuleEngines().getFlameoutState;
-            }
-            if (part.HasModule<MultiModeEngine>())
-            {
-                return part.GetModuleMultiModeEngine().getFlameoutState;
+            cachePartModule = GetModule<ModuleEngines>(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEngines).getFlameoutState;
+            }
+
+            cachePartModule = GetModuleMultiModeEngine(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEnginesFX).getFlameoutState;
             }
 
             return false;
@@ -103,20 +109,19 @@
         /// </summary>
         public static double GetMaxThrust(this Part part)
         {
-            if (part.HasModule<ModuleEngines>())
-            {
-                return part.GetModuleEngines().maxThrust;
-            }
-            if (part.HasModule<MultiModeEngine>())
-            {
-                return part.GetModuleMultiModeEngine().maxThrust;
-            }
-            if (part.HasModule<ModuleEnginesFX>())
-            {
-                return part.GetModuleEnginesFx().maxThrust;
-            }
-
-            return 0d;
+            cachePartModule = GetModule<ModuleEngines>(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEngines).maxThrust;
+            }
+
+            cachePartModule = GetModuleMultiModeEngine(part) ?? GetModule<ModuleEnginesFX>(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEnginesFX).maxThrust;
+            }
+
+            return 0.0;
         }
 
         /// <summary>
@@ -124,7 +129,16 @@
         /// </summary>
         public static T GetModule<T>(this Part part) where T : PartModule
         {
-            return part.Modules.OfType<T>().FirstOrDefault();
+            PartModule partModule;
+            for (int i = 0; i < part.Modules.Count; ++i)
+            {
+                partModule = part.Modules[i];
+                if (partModule is T)
+                {
+                    return partModule as T;
+                }
+            }
+            return null;
         }
 
         /// <summary>
@@ -132,7 +146,7 @@
         /// </summary>
         public static T GetModule<T>(this Part part, string className) where T : PartModule
         {
-            return (T)Convert.ChangeType(part.Modules[className], typeof(T));
+            return part.Modules[className] as T;
         }
 
         /// <summary>
@@ -140,7 +154,7 @@
         /// </summary>
         public static T GetModule<T>(this Part part, int classId) where T : PartModule
         {
-            return (T)Convert.ChangeType(part.Modules[classId], typeof(T));
+            return part.Modules[classId] as T;
         }
 
         /// <summary>
@@ -148,7 +162,7 @@
         /// </summary>
         public static ModuleAlternator GetModuleAlternator(this Part part)
         {
-            return part.GetModule<ModuleAlternator>();
+            return GetModule<ModuleAlternator>(part);
         }
 
         /// <summary>
@@ -156,7 +170,7 @@
         /// </summary>
         public static ModuleDeployableSolarPanel GetModuleDeployableSolarPanel(this Part part)
         {
-            return part.GetModule<ModuleDeployableSolarPanel>();
+            return GetModule<ModuleDeployableSolarPanel>(part);
         }
 
         /// <summary>
@@ -164,12 +178,12 @@
         /// </summary>
         public static ModuleEngines GetModuleEngines(this Part part)
         {
-            return part.GetModule<ModuleEngines>();
+            return GetModule<ModuleEngines>(part);
         }
 
         public static ModuleEnginesFX GetModuleEnginesFx(this Part part)
         {
-            return part.GetModule<ModuleEnginesFX>();
+            return GetModule<ModuleEnginesFX>(part);
         }
 
         /// <summary>
@@ -177,7 +191,7 @@
         /// </summary>
         public static ModuleGenerator GetModuleGenerator(this Part part)
         {
-            return part.GetModule<ModuleGenerator>();
+            return GetModule<ModuleGenerator>(part);
         }
 
         /// <summary>
@@ -185,7 +199,7 @@
         /// </summary>
         public static ModuleGimbal GetModuleGimbal(this Part part)
         {
-            return part.GetModule<ModuleGimbal>();
+            return GetModule<ModuleGimbal>(part);
         }
 
         /// <summary>
@@ -193,8 +207,17 @@
         /// </summary>
         public static ModuleEnginesFX GetModuleMultiModeEngine(this Part part)
         {
-            var mode = part.GetModule<MultiModeEngine>().mode;
-            return part.Modules.OfType<ModuleEnginesFX>().FirstOrDefault(engine => engine.engineID == mode);
+            ModuleEnginesFX moduleEngineFx;
+            string mode = GetModule<MultiModeEngine>(part).mode;
+            for (int i = 0; i < part.Modules.Count; ++i)
+            {
+                moduleEngineFx = part.Modules[i] as ModuleEnginesFX;
+                if (moduleEngineFx != null && moduleEngineFx.engineID == mode)
+                {
+                    return moduleEngineFx;
+                }
+            }
+            return null;
         }
 
         /// <summary>
@@ -202,12 +225,12 @@
         /// </summary>
         public static ModuleParachute GetModuleParachute(this Part part)
         {
-            return part.GetModule<ModuleParachute>();
+            return GetModule<ModuleParachute>(part);
         }
 
         public static ModuleRCS GetModuleRcs(this Part part)
         {
-            return part.GetModule<ModuleRCS>();
+            return GetModule<ModuleRCS>(part);
         }
 
         /// <summary>
@@ -215,19 +238,30 @@
         /// </summary>
         public static List<T> GetModules<T>(this Part part) where T : PartModule
         {
-            return part.Modules.OfType<T>().ToList();
+            List<T> list = new List<T>();
+            for (int i = 0; i < part.Modules.Count; ++i)
+            {
+                T module = part.Modules[i] as T;
+                if (module != null)
+                {
+                    list.Add(module);
+                }
+            }
+            return list;
         }
 
         public static ProtoModuleDecoupler GetProtoModuleDecoupler(this Part part)
         {
-            if (HasModule<ModuleDecouple>(part))
-            {
-                return new ProtoModuleDecoupler(GetModule<ModuleDecouple>(part));
-            }
-            if (HasModule<ModuleAnchoredDecoupler>(part))
-            {
-                return new ProtoModuleDecoupler(GetModule<ModuleAnchoredDecoupler>(part));
-            }
+            cachePartModule = GetModule<ModuleDecouple>(part);
+            if (cachePartModule == null)
+            {
+                cachePartModule = GetModule<ModuleAnchoredDecoupler>(part);
+            }
+            if (cachePartModule != null)
+            {
+                return new ProtoModuleDecoupler(cachePartModule);
+            }
+
             return null;
         }
 
@@ -236,18 +270,18 @@
         /// </summary>
         public static ProtoModuleEngine GetProtoModuleEngine(this Part part)
         {
-            if (HasModule<ModuleEngines>(part))
-            {
-                return new ProtoModuleEngine(GetModule<ModuleEngines>(part));
-            }
-            if (HasModule<MultiModeEngine>(part))
-            {
-                return new ProtoModuleEngine(GetModuleMultiModeEngine(part));
-            }
-            if (HasModule<ModuleEnginesFX>(part))
-            {
-                return new ProtoModuleEngine(GetModule<ModuleEnginesFX>(part));
-            }
+            cachePartModule = GetModule<ModuleEngines>(part);
+            if (cachePartModule != null)
+            {
+                return new ProtoModuleEngine(cachePartModule);
+            }
+
+            cachePartModule = GetModuleMultiModeEngine(part) ?? GetModule<ModuleEnginesFX>(part);
+            if (cachePartModule != null)
+            {
+                return new ProtoModuleEngine(cachePartModule);
+            }
+
             return null;
         }
 
@@ -256,7 +290,13 @@
         /// </summary>
         public static double GetResourceCost(this Part part)
         {
-            return part.Resources.list.Sum(r => r.amount * r.info.unitCost);
+            double cost = 0.0;
+            for (int i = 0; i < part.Resources.list.Count; ++i)
+            {
+                cachePartResource = part.Resources.list[i];
+                cost = cost + (cachePartResource.amount * cachePartResource.info.unitCost);
+            }
+            return cost;
         }
 
         /// <summary>
@@ -264,7 +304,13 @@
         /// </summary>
         public static double GetResourceCostInverted(this Part part)
         {
-            return part.Resources.list.Sum(r => (r.maxAmount - r.amount) * r.info.unitCost);
+            double cost = 0.0;
+            for (int i = 0; i < part.Resources.list.Count; ++i)
+            {
+                cachePartResource = part.Resources.list[i];
+                cost = cost + ((cachePartResource.maxAmount - cachePartResource.amount) * cachePartResource.info.unitCost);
+            }
+            return cost;
         }
 
         /// <summary>
@@ -272,7 +318,13 @@
         /// </summary>
         public static double GetResourceCostMax(this Part part)
         {
-            return part.Resources.list.Sum(r => r.maxAmount * r.info.unitCost);
+            double cost = 0.0;
+            for (int i = 0; i < part.Resources.list.Count; ++i)
+            {
+                cachePartResource = part.Resources.list[i];
+                cost = cost + (cachePartResource.maxAmount * cachePartResource.info.unitCost);
+            }
+            return cost;
         }
 
         /// <summary>
@@ -280,20 +332,19 @@
         /// </summary>
         public static double GetSpecificImpulse(this Part part, float atmosphere)
         {
-            if (part.HasModule<ModuleEngines>())
-            {
-                return part.GetModuleEngines().atmosphereCurve.Evaluate(atmosphere);
-            }
-            if (part.HasModule<MultiModeEngine>())
-            {
-                return part.GetModuleMultiModeEngine().atmosphereCurve.Evaluate(atmosphere);
-            }
-            if (part.HasModule<ModuleEnginesFX>())
-            {
-                return part.GetModuleEnginesFx().atmosphereCurve.Evaluate(atmosphere);
-            }
-
-            return 0d;
+            cachePartModule = GetModule<ModuleEngines>(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEngines).atmosphereCurve.Evaluate(atmosphere);
+            }
+
+            cachePartModule = GetModuleMultiModeEngine(part) ?? GetModule<ModuleEnginesFX>(part);
+            if (cachePartModule != null)
+            {
+                return (cachePartModule as ModuleEnginesFX).atmosphereCurve.Evaluate(atmosphere);
+            }
+
+            return 0.0;
         }
 
         /// <summary>
@@ -309,7 +360,14 @@
         /// </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 +375,15 @@
         /// </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)
+            {
+                cachePartModule = part.Modules[i] as T;
+                if (cachePartModule != null && predicate(cachePartModule as T))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         /// <summary>
@@ -341,7 +407,8 @@
         /// </summary>
         public static bool HasOneShotAnimation(this Part part)
         {
-            return part.HasModule<ModuleAnimateGeneric>() && part.GetModule<ModuleAnimateGeneric>().isOneShot;
+            cachePartModule = GetModule<ModuleAnimateGeneric>(part);
+            return cachePartModule != null && (cachePartModule as ModuleAnimateGeneric).isOneShot;
         }
 
         /// <summary>
@@ -349,7 +416,7 @@
         /// </summary>
         public static bool IsCommandModule(this Part part)
         {
-            return part.HasModule<ModuleCommand>();
+            return HasModule<ModuleCommand>(part);
         }
 
         /// <summary>
@@ -357,7 +424,7 @@
         /// </summary>
         public static bool IsDecoupledInStage(this Part part, int stage)
         {
-            if ((part.IsDecoupler() || part.IsLaunchClamp()) && part.inverseStage == stage)
+            if ((IsDecoupler(part) || IsLaunchClamp(part)) && part.inverseStage == stage)
             {
                 return true;
             }
@@ -365,7 +432,7 @@
             {
                 return false;
             }
-            return part.parent.IsDecoupledInStage(stage);
+            return IsDecoupledInStage(part.parent, stage);
         }
 
         /// <summary>
@@ -373,7 +440,7 @@
         /// </summary>
         public static bool IsDecoupler(this Part part)
         {
-            return part.HasModule<ModuleDecouple>() || part.HasModule<ModuleAnchoredDecoupler>();
+            return HasModule<ModuleDecouple>(part) || HasModule<ModuleAnchoredDecoupler>(part);
         }
 
         /// <summary>
@@ -381,7 +448,7 @@
         /// </summary>
         public static bool IsEngine(this Part part)
         {
-            return part.HasModule<ModuleEngines>() || part.HasModule<ModuleEnginesFX>();
+            return HasModule<ModuleEngines>(part) || HasModule<ModuleEnginesFX>(part);
         }
 
         /// <summary>
@@ -389,7 +456,7 @@
         /// </summary>
         public static bool IsFuelLine(this Part part)
         {
-            return (HasModule<CModuleFuelLine>(part));
+            return HasModule<CModuleFuelLine>(part);
         }
 
         /// <summary>
@@ -397,7 +464,7 @@
         /// </summary>
         public static bool IsGenerator(this Part part)
         {
-            return part.HasModule<ModuleGenerator>();
+            return HasModule<ModuleGenerator>(part);
         }
 
         /// <summary>
@@ -405,7 +472,7 @@
         /// </summary>
         public static bool IsLaunchClamp(this Part part)
         {
-            return part.HasModule<LaunchClamp>();
+            return HasModule<LaunchClamp>(part);
         }
 
         /// <summary>
@@ -413,7 +480,7 @@
         /// </summary>
         public static bool IsParachute(this Part part)
         {
-            return part.HasModule<ModuleParachute>();
+            return HasModule<ModuleParachute>(part);
         }
 
         /// <summary>
@@ -421,14 +488,15 @@
         /// </summary>
         public static bool IsPrimary(this Part part, List<Part> partsList, PartModule module)
         {
-            foreach (var vesselPart in partsList)
-            {
-                if (!vesselPart.HasModule(module.ClassID))
+            for (int i = 0; i < partsList.Count; ++i)
+            {
+                cachePart = partsList[i];
+
+                if (HasModule(cachePart, module.ClassID) == false)
                 {
                     continue;
                 }
-
-                if (vesselPart == part)
+                if (cachePart == part)
                 {
                     return true;
                 }
@@ -440,7 +508,7 @@
 
         public static bool IsRcsModule(this Part part)
         {
-            return part.HasModule<ModuleRCS>();
+            return HasModule<ModuleRCS>(part);
         }
 
         /// <summary>
@@ -448,7 +516,7 @@
         /// </summary>
         public static bool IsSepratron(this Part part)
         {
-            return (part.IsSolidRocket() && part.ActivatesEvenIfDisconnected && part.IsDecoupledInStage(part.inverseStage));
+            return IsSolidRocket(part) && part.ActivatesEvenIfDisconnected && IsDecoupledInStage(part, part.inverseStage);
         }
 
         /// <summary>
@@ -456,7 +524,7 @@
         /// </summary>
         public static bool IsSolarPanel(this Part part)
         {
-            return part.HasModule<ModuleDeployableSolarPanel>();
+            return HasModule<ModuleDeployableSolarPanel>(part);
         }
 
         /// <summary>
@@ -464,160 +532,106 @@
         /// </summary>
         public static bool IsSolidRocket(this Part part)
         {
-            return (part.HasModule<ModuleEngines>() && part.GetModuleEngines().throttleLocked) || (part.HasModule<ModuleEnginesFX>() && part.GetModuleEnginesFx().throttleLocked);
-        }
-
-        #endregion
-
-        #region Nested Type: ProtoModuleDecoupler
+            return (HasModule<ModuleEngines>(part) && GetModuleEngines(part).throttleLocked) || (HasModule<ModuleEnginesFX>(part) && GetModuleEnginesFx(part).throttleLocked);
+        }
 
         public class ProtoModuleDecoupler
         {
-            #region Fields
-
             private readonly PartModule module;
 
-            #endregion
-
-            #region Constructors
-
             public ProtoModuleDecoupler(PartModule module)
             {
                 this.module = module;
 
                 if (this.module is ModuleDecouple)
                 {
-                    this.SetModuleDecouple();
+                    SetModuleDecouple();
                 }
                 else if (this.module is ModuleAnchoredDecoupler)
                 {
-                    this.SetModuleAnchoredDecoupler();
-                }
-            }
-
-            #endregion
-
-            #region Properties
+                    SetModuleAnchoredDecoupler();
+                }
+            }
 
             public double EjectionForce { get; private set; }
             public bool IsOmniDecoupler { get; private set; }
 
-            #endregion
-
-            #region Methods: private
-
             private void SetModuleAnchoredDecoupler()
             {
-                var decoupler = this.module as ModuleAnchoredDecoupler;
+                ModuleAnchoredDecoupler decoupler = module as ModuleAnchoredDecoupler;
                 if (decoupler == null)
                 {
                     return;
                 }
 
-                this.EjectionForce = decoupler.ejectionForce;
+                EjectionForce = decoupler.ejectionForce;
             }
 
             private void SetModuleDecouple()
             {
-                var decoupler = this.module as ModuleDecouple;
+                ModuleDecouple decoupler = module as ModuleDecouple;
                 if (decoupler == null)
                 {
                     return;
                 }
 
-                this.EjectionForce = decoupler.ejectionForce;
-                this.IsOmniDecoupler = decoupler.isOmniDecoupler;
-            }
-
-            #endregion
-        }
-
-        #endregion
-
-        #region Nested Type: ProtoModuleEngine
+                EjectionForce = decoupler.ejectionForce;
+                IsOmniDecoupler = decoupler.isOmniDecoupler;
+            }
+        }
 
         public class ProtoModuleEngine
         {
-            #region Fields
-
             private readonly PartModule module;
 
-            #endregion
-
-            #region Constructors
-
             public ProtoModuleEngine(PartModule module)
             {
                 this.module = module;
 
                 if (module is ModuleEngines)
                 {
-                    this.SetModuleEngines();
-                }
-                else if (module is ModuleEnginesFX)
-                {
-                    this.SetModuleEnginesFx();
-                }
-            }
-
-            #endregion
-
-            #region Properties
+                    SetModuleEngines();
+                }
+            }
 
             public double MaximumThrust { get; private set; }
             public double MinimumThrust { get; private set; }
             public List<Propellant> Propellants { get; private set; }
 
-            #endregion
-
-            #region Methods: public
-
             public float GetSpecificImpulse(float atmosphere)
             {
-                if (this.module is ModuleEngines)
-                {
-                    return (this.module as ModuleEngines).atmosphereCurve.Evaluate(atmosphere);
-                }
-                if (this.module is ModuleEnginesFX)
-                {
-                    return (this.module as ModuleEnginesFX).atmosphereCurve.Evaluate(atmosphere);
+                if (module is ModuleEngines)
+                {
+                    return (module as ModuleEngines).atmosphereCurve.Evaluate(atmosphere);
                 }
                 return 0.0f;
             }
 
-            #endregion
-
-            #region Methods: private
-
             private void SetModuleEngines()
             {
-                var engine = this.module as ModuleEngines;
+                ModuleEngines engine = module as ModuleEngines;
                 if (engine == null)
                 {
                     return;
                 }
 
-                this.MaximumThrust = engine.maxThrust * (engine.thrustPercentage * 0.01);
-                this.MinimumThrust = engine.minThrust;
-                this.Propellants = engine.propellants;
+                MaximumThrust = engine.maxThrust * (engine.thrustPercentage * 0.01);
+                MinimumThrust = engine.minThrust;
+                Propellants = engine.propellants;
             }
 
             private void SetModuleEnginesFx()
             {
-                var engine = this.module as ModuleEnginesFX;
+                ModuleEnginesFX engine = module as ModuleEnginesFX;
                 if (engine == null)
                 {
                     return;
                 }
 
-                this.MaximumThrust = engine.maxThrust * (engine.thrustPercentage * 0.01);
-                this.MinimumThrust = engine.minThrust;
-                this.Propellants = engine.propellants;
-            }
-
-            #endregion
-        }
-
-        #endregion
+                MaximumThrust = engine.maxThrust * (engine.thrustPercentage * 0.01);
+                MinimumThrust = engine.minThrust;
+                Propellants = engine.propellants;
+            }
+        }
     }
 }

 Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ