diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs
index 4c8a716ed5ed5edf350d68069373c0cf04d1eb91..b36cc5494e2d4af7a65e1aea1b0531ae3976672d 100644
--- a/Source/Core/General/General.cs
+++ b/Source/Core/General/General.cs
@@ -1048,9 +1048,9 @@ namespace CodeImp.DoomBuilder
 				// Clean up
 				if(map != null) { map.Dispose(); map = null; }
 				if(editing != null) { editing.Dispose(); editing = null; }
+				if(plugins != null) { plugins.Dispose(); plugins = null; }
 				if(mainwindow != null) { mainwindow.Dispose(); mainwindow = null; }
 				if(actions != null) { actions.Dispose(); actions = null; }
-				if(plugins != null) { plugins.Dispose(); plugins = null; }
 				if(types != null) { types.Dispose(); types = null; }
 				try { D3DDevice.Terminate(); } catch(Exception) { }
 
diff --git a/Source/Core/General/MurmurHash2.cs b/Source/Core/General/MurmurHash2.cs
index da5e7e48d129c7e0457bcae5a626477e995df985..98c1e560741e7f5ecbcc4fb02911ce96835c65ba 100644
--- a/Source/Core/General/MurmurHash2.cs
+++ b/Source/Core/General/MurmurHash2.cs
@@ -44,7 +44,7 @@ using System.Text;
 
 namespace CodeImp.DoomBuilder
 {
-	internal static class MurmurHash2
+	public static class MurmurHash2
 	{
 		private const UInt32 m = 0x5bd1e995;
 		private const Int32 r = 24;
diff --git a/Source/Core/Plugins/Plugin.cs b/Source/Core/Plugins/Plugin.cs
index 6c7d58a5e386dc74270ba36ddf6fe6545c73eb2e..02934e344d1a38e816a445780fafb4fbaf051399 100644
--- a/Source/Core/Plugins/Plugin.cs
+++ b/Source/Core/Plugins/Plugin.cs
@@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.Plugins
 		private Plug plug;
 		
 		// Unique name used to refer to this assembly
-		private string name;
+		private readonly string name;
 		
 		// Disposing
 		private bool isdisposed;
@@ -122,6 +122,8 @@ namespace CodeImp.DoomBuilder.Plugins
 			if(!isdisposed)
 			{
 				// Clean up
+				plug.Dispose(); //mxd
+				plug = null; //mxd
 				asm = null;
 				
 				// Done
diff --git a/Source/Core/Plugins/PluginManager.cs b/Source/Core/Plugins/PluginManager.cs
index 440507b8a1131f2088c70e40b500acf5564cdc87..cfc6a2776099862e38c54487fe332fd70ac3fbb4 100644
--- a/Source/Core/Plugins/PluginManager.cs
+++ b/Source/Core/Plugins/PluginManager.cs
@@ -217,7 +217,7 @@ namespace CodeImp.DoomBuilder.Plugins
 			// Go for all plugins the find the one with matching assembly
 			foreach(Plugin p in plugins)
 			{
-				if(p.Assembly == assembly) return p;
+				if(Equals(p.Assembly, assembly)) return p;
 			}
 
 			// Nothing found
diff --git a/Source/Core/Properties/AssemblyInfo.cs b/Source/Core/Properties/AssemblyInfo.cs
index ba444623bfff97074cf69e66a6bf5982e56dee3b..ce6ac15f3944b0239a213f9bde28e789b2008216 100644
--- a/Source/Core/Properties/AssemblyInfo.cs
+++ b/Source/Core/Properties/AssemblyInfo.cs
@@ -28,4 +28,4 @@ using System.Runtime.InteropServices;
 //      Build Number
 //      Revision
 //
-[assembly: AssemblyVersion("2.3.0.2201")]
\ No newline at end of file
+[assembly: AssemblyVersion("2.3.0.2411")]
\ No newline at end of file
diff --git a/Source/Core/VisualModes/VisualCamera.cs b/Source/Core/VisualModes/VisualCamera.cs
index 66af0f51853be3d947ae75374171486384c8d70e..cdd649b4f822ddda72347ed64ebd8cdafc00b241 100644
--- a/Source/Core/VisualModes/VisualCamera.cs
+++ b/Source/Core/VisualModes/VisualCamera.cs
@@ -30,7 +30,6 @@ namespace CodeImp.DoomBuilder.VisualModes
 		private float anglexy, anglez;
 		private Sector sector;
 		private float gravity = 1.0f; //mxd
-		private bool udmf; //mxd
 		
 		#endregion
 
@@ -56,7 +55,6 @@ namespace CodeImp.DoomBuilder.VisualModes
 			anglexy = 0.0f;
 			anglez = Angle2D.PI;
 			sector = null;
-			udmf = General.Map.UDMF; //mxd
 			
 			PositionAtThing();
 		}
@@ -101,12 +99,18 @@ namespace CodeImp.DoomBuilder.VisualModes
 		// Returns false when it couldn't find a 3D Camera Thing
 		public virtual bool PositionAtThing()
 		{
+			if(General.Settings.GZSynchCameras) return true; //mxd
 			Thing modething = null;
-			Vector3D delta;
-			
+
 			// Find a 3D Mode thing
 			foreach(Thing t in General.Map.Map.Things)
-				if(t.Type == General.Map.Config.Start3DModeThingType) modething = t;
+			{
+				if(t.Type == General.Map.Config.Start3DModeThingType)
+				{
+					modething = t;
+					break; //mxd
+				}
+			}
 
 			// Found one?
 			if(modething != null)
@@ -118,7 +122,7 @@ namespace CodeImp.DoomBuilder.VisualModes
 				
 				// Position camera here
 				Vector3D wantedposition = new Vector3D(modething.Position.x, modething.Position.y, z + THING_Z_OFFSET);
-				delta = position - wantedposition;
+				Vector3D delta = position - wantedposition;
 				if(delta.GetLength() > 1.0f) position = wantedposition;
 				
 				// Change angle
@@ -138,11 +142,18 @@ namespace CodeImp.DoomBuilder.VisualModes
 		// Returns false when it couldn't find a 3D Camera Thing
 		public virtual bool ApplyToThing()
 		{
+			if(General.Settings.GZSynchCameras) return true; //mxd
 			Thing modething = null;
 			
 			// Find a 3D Mode thing
 			foreach(Thing t in General.Map.Map.Things)
-				if(t.Type == General.Map.Config.Start3DModeThingType) modething = t;
+			{
+				if(t.Type == General.Map.Config.Start3DModeThingType)
+				{
+					modething = t;
+					break; //mxd
+				}
+			}
 
 			// Found one?
 			if(modething != null)
@@ -162,7 +173,7 @@ namespace CodeImp.DoomBuilder.VisualModes
 		//mxd
 		private void UpdateGravity() 
 		{
-			if(!udmf || sector == null) return;
+			if(!General.Map.UDMF || sector == null) return;
 			gravity = sector.Fields.GetValue("gravity", 1.0f);
 		}
 		
diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs
index d2d89fde67e19c9fc70637629aea976a3a624462..6873d3293d65d9bd77cbde0989d968bca894f69f 100644
--- a/Source/Core/VisualModes/VisualThing.cs
+++ b/Source/Core/VisualModes/VisualThing.cs
@@ -227,11 +227,85 @@ namespace CodeImp.DoomBuilder.VisualModes
 		}
 
 		/// <summary>
-		/// Sets the color of the cage around the thing geometry.
+		/// Sets the color of the cage around the thing geometry and rebuilds the thing cage.
 		/// </summary>
-		protected void SetCageColor(PixelColor color)
+		protected void UpdateThingCage(PixelColor color)
 		{
 			cagecolor = color.ToColorValue();
+
+			// Trash cage buffer
+			if(cagebuffer != null) cagebuffer.Dispose();
+			cagebuffer = null;
+
+			// Make a new cage
+			List<WorldVertex> cageverts;
+			if(sizeless)
+			{
+				WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z);
+				WorldVertex v1 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z);
+				WorldVertex v2 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z);
+				WorldVertex v3 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z);
+				WorldVertex v4 = new WorldVertex(position_v3.X, position_v3.Y, info.Radius + position_v3.Z);
+				WorldVertex v5 = new WorldVertex(position_v3.X, position_v3.Y, -info.Radius + position_v3.Z);
+
+				cageverts = new List<WorldVertex>(new[] { v0, v1, v2, v3, v4, v5 });
+			}
+			else
+			{
+				float top = position_v3.Z + info.Height;
+				float bottom = position_v3.Z;
+
+				WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom);
+				WorldVertex v1 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom);
+				WorldVertex v2 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom);
+				WorldVertex v3 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom);
+
+				WorldVertex v4 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, top);
+				WorldVertex v5 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, top);
+				WorldVertex v6 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, top);
+				WorldVertex v7 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, top);
+
+				cageverts = new List<WorldVertex>(new[] { v0, v1,
+														  v1, v2,
+														  v2, v3,
+														  v3, v0,
+														  v4, v5, 
+														  v5, v6,
+														  v6, v7,
+														  v7, v4,
+														  v0, v4,
+														  v1, v5,
+														  v2, v6,
+														  v3, v7 });
+			}
+
+			// Make new arrow
+			if(Thing.IsDirectional)
+			{
+				Matrix transform = Matrix.Scaling(info.Radius, info.Radius, info.Radius)
+					* (Matrix.RotationY(-Thing.RollRad) * Matrix.RotationX(-Thing.PitchRad) * Matrix.RotationZ(Thing.Angle))
+					* (sizeless ? position : position * Matrix.Translation(0.0f, 0.0f, thingheight / 2f));
+
+				WorldVertex a0 = new WorldVertex(Vector3D.Transform(0.0f, 0.0f, 0.0f, transform)); //start
+				WorldVertex a1 = new WorldVertex(Vector3D.Transform(0.0f, -1.5f, 0.0f, transform)); //end
+				WorldVertex a2 = new WorldVertex(Vector3D.Transform(0.2f, -1.1f, 0.2f, transform));
+				WorldVertex a3 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, 0.2f, transform));
+				WorldVertex a4 = new WorldVertex(Vector3D.Transform(0.2f, -1.1f, -0.2f, transform));
+				WorldVertex a5 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, -0.2f, transform));
+
+				cageverts.AddRange(new[] { a0, a1,
+										   a1, a2,
+										   a1, a3,
+										   a1, a4,
+										   a1, a5 });
+			}
+
+			// Create buffer
+			WorldVertex[] cv = cageverts.ToArray();
+			cagelength = cv.Length / 2;
+			cagebuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * cv.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
+			cagebuffer.Lock(0, WorldVertex.Stride * cv.Length, LockFlags.None).WriteRange(cv);
+			cagebuffer.Unlock();
 		}
 
 		/// <summary>
@@ -387,7 +461,7 @@ namespace CodeImp.DoomBuilder.VisualModes
 			if(updategeo)
 			{
 				// Trash geometry buffer
-				if (geobuffer != null) geobuffer.Dispose();
+				if(geobuffer != null) geobuffer.Dispose();
 				geobuffer = null;
 
 				// Any vertics?
@@ -403,80 +477,6 @@ namespace CodeImp.DoomBuilder.VisualModes
 					geobuffer.Unlock();
 					bufferstream.Dispose();
 				}
-
-				// Trash cage buffer
-				if(cagebuffer != null) cagebuffer.Dispose();
-				cagebuffer = null;
-
-				// Make a new cage
-				List<WorldVertex> cageverts;
-				if(sizeless)
-				{
-					WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z);
-					WorldVertex v1 = new WorldVertex( info.Radius + position_v3.X,  info.Radius + position_v3.Y, position_v3.Z);
-					WorldVertex v2 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z);
-					WorldVertex v3 = new WorldVertex(-info.Radius + position_v3.X,  info.Radius + position_v3.Y, position_v3.Z);
-					WorldVertex v4 = new WorldVertex(position_v3.X, position_v3.Y,  info.Radius + position_v3.Z);
-					WorldVertex v5 = new WorldVertex(position_v3.X, position_v3.Y, -info.Radius + position_v3.Z);
-
-					cageverts = new List<WorldVertex>(new[] { v0, v1, v2, v3, v4, v5 });
-				}
-				else
-				{
-					float top = position_v3.Z + info.Height;
-					float bottom = position_v3.Z;
-
-					WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom);
-					WorldVertex v1 = new WorldVertex(-info.Radius + position_v3.X,  info.Radius + position_v3.Y, bottom);
-					WorldVertex v2 = new WorldVertex( info.Radius + position_v3.X,  info.Radius + position_v3.Y, bottom);
-					WorldVertex v3 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom);
-
-					WorldVertex v4 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, top);
-					WorldVertex v5 = new WorldVertex(-info.Radius + position_v3.X,  info.Radius + position_v3.Y, top);
-					WorldVertex v6 = new WorldVertex( info.Radius + position_v3.X,  info.Radius + position_v3.Y, top);
-					WorldVertex v7 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, top);
-
-					cageverts = new List<WorldVertex>(new[] { v0, v1,
-															  v1, v2,
-															  v2, v3,
-															  v3, v0,
-															  v4, v5, 
-															  v5, v6,
-															  v6, v7,
-															  v7, v4,
-															  v0, v4,
-															  v1, v5,
-															  v2, v6,
-															  v3, v7 });
-				}
-				
-				// Make new arrow
-				if(Thing.IsDirectional)
-				{
-					Matrix transform = Matrix.Scaling(info.Radius, info.Radius, info.Radius)
-						* (Matrix.RotationY(-Thing.RollRad) * Matrix.RotationX(-Thing.PitchRad) * Matrix.RotationZ(Thing.Angle))
-						* (sizeless ? position : position * Matrix.Translation(0.0f, 0.0f, thingheight / 2f));
-					
-					WorldVertex a0 = new WorldVertex(Vector3D.Transform( 0.0f,  0.0f,  0.0f, transform)); //start
-					WorldVertex a1 = new WorldVertex(Vector3D.Transform( 0.0f, -1.5f,  0.0f, transform)); //end
-					WorldVertex a2 = new WorldVertex(Vector3D.Transform( 0.2f, -1.1f,  0.2f, transform));
-					WorldVertex a3 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f,  0.2f, transform));
-					WorldVertex a4 = new WorldVertex(Vector3D.Transform( 0.2f, -1.1f, -0.2f, transform));
-					WorldVertex a5 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, -0.2f, transform));
-
-					cageverts.AddRange(new[] {a0, a1,
-											  a1, a2,
-											  a1, a3,
-											  a1, a4,
-											  a1, a5});
-				}
-
-				// Create buffer
-				WorldVertex[] cv = cageverts.ToArray();
-				cagelength = cv.Length / 2;
-				cagebuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * cv.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
-				cagebuffer.Lock(0, WorldVertex.Stride * cv.Length, LockFlags.None).WriteRange(cv);
-				cagebuffer.Unlock();
 				
 				//mxd. Check if thing is light
 				CheckLightState();
diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs
index d78d2e0ce34fcaeb5d6d4ba6e3efb70b4bc742d4..0a58b8b24095fddc5fa7c9af31d7a8a19876732b 100644
--- a/Source/Core/Windows/MainForm.cs
+++ b/Source/Core/Windows/MainForm.cs
@@ -4018,6 +4018,7 @@ namespace CodeImp.DoomBuilder.Windows
 		#endregion
 
 		#region ================== Dockers
+		
 		// This adds a docker
 		public void AddDocker(Docker d)
 		{
@@ -4033,9 +4034,11 @@ namespace CodeImp.DoomBuilder.Windows
 		// This removes a docker
 		public bool RemoveDocker(Docker d)
 		{
+			if(!dockerspanel.Contains(d)) return true; //mxd. Already removed/never added
+			
 			// Make sure the full name is set with the plugin name as prefix
-			Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly());
-			d.MakeFullName(plugin.Name.ToLowerInvariant());
+			//Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly());
+			//d.MakeFullName(plugin.Name.ToLowerInvariant());
 			
 			// We must release all keys because the focus may be stolen when
 			// this was the selected docker (the previous docker is automatically selected)
@@ -4047,6 +4050,8 @@ namespace CodeImp.DoomBuilder.Windows
 		// This selects a docker
 		public bool SelectDocker(Docker d)
 		{
+			if(!dockerspanel.Contains(d)) return false; //mxd
+			
 			// Make sure the full name is set with the plugin name as prefix
 			Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly());
 			d.MakeFullName(plugin.Name.ToLowerInvariant());
diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
index a505f693a53b6909e873c2b9d7a831058974aa20..cfd9f3103d6e6f7f0a0607c4a97c83ebe42dd477 100644
--- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs
+++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
@@ -220,12 +220,23 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				menusform.Unregister();
 				menusform.Dispose();
 				menusform = null;
-				curvelinedefsform.Dispose();
-				curvelinedefsform = null;
-				findreplaceform.Dispose();
-				findreplaceform = null;
-				errorcheckform.Dispose();
-				errorcheckform = null;
+
+				//mxd. These are created on demand, so they may be nulls.
+				if(curvelinedefsform != null)
+				{
+					curvelinedefsform.Dispose();
+					curvelinedefsform = null;
+				}
+				if(findreplaceform != null)
+				{
+					findreplaceform.Dispose();
+					findreplaceform = null;
+				}
+				if(errorcheckform != null)
+				{
+					errorcheckform.Dispose();
+					errorcheckform = null;
+				}
 				
 				// Done
 				me = null;
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
index c2e61ae7511f313d73f033ad73e0cd3bb003ca13..ab92a700355d6e6ea307066ad0762475bbd74b5d 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
@@ -414,7 +414,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			
 			// Apply settings
 			SetPosition(pos);
-			SetCageColor(Thing.Color);
+			UpdateThingCage(Thing.Color);
 
 			// Keep info for object picking
 			cageradius2 = thingradius * Angle2D.SQRT2;
diff --git a/Source/Plugins/VisplaneExplorer/BuilderPlug.cs b/Source/Plugins/VisplaneExplorer/BuilderPlug.cs
index 5c7cb56aaba8f91f7b565769deb4650fe0b7535b..bdc6f28c4262e450b9bb1b1a547e0cafcd86fd9f 100644
--- a/Source/Plugins/VisplaneExplorer/BuilderPlug.cs
+++ b/Source/Plugins/VisplaneExplorer/BuilderPlug.cs
@@ -17,6 +17,7 @@
 #region ================== Namespaces
 
 using System;
+using System.Globalization;
 using System.IO;
 using CodeImp.DoomBuilder.Plugins.VisplaneExplorer.Properties;
 using CodeImp.DoomBuilder.Windows;
@@ -33,6 +34,7 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
 		private static BuilderPlug me;
 		private VPOManager vpo;
 		private InterfaceForm interfaceform;
+		private bool enabled; //mxd
 
 		// Palettes
 		private Palette[] palettes;
@@ -42,55 +44,31 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
 		#region ================== Properties
 		
 		// Properties
-		public static BuilderPlug Me { get { return me; } }
 		public override string Name { get { return "VisplaneExplorer"; } }
 		internal static VPOManager VPO { get { return me.vpo; } }
 		internal static InterfaceForm InterfaceForm { get { return me.interfaceform; } }
-		internal static Palette[] Palettes { get { return me.palettes; } }
-		public override int MinimumRevision { get { return 1545; } }
+		internal static Palette[] Palettes { get { return me.GetPalettes(); } }
+		public override int MinimumRevision { get { return 2411; } }
 		
 		#endregion
 
 		#region ================== Initialize / Dispose
 
-		// This event is called when the plugin is initialized
-		public override void OnInitialize()
+		//mxd. Initialize when we can check the map format
+		public override void OnMapNewEnd() { OnMapOpenEnd(); }
+		public override void OnMapOpenEnd()
 		{
-			base.OnInitialize();
-			
-			//General.Actions.BindMethods(this); //mxd. But... we have no methods to bind!
-			
-			// Load interface controls
-			interfaceform = new InterfaceForm();
-
-			// Load VPO manager (manages multithreading and communication with vpo.dll)
-			vpo = new VPOManager();
-
-			// Keep a static reference
-			me = this;
-		}
+			enabled = (General.Map.DOOM || General.Map.HEXEN);
+			if(enabled)
+			{
+				// Load interface controls
+				interfaceform = new InterfaceForm();
 
-        //mxd. This, actually, can also happen
-        public override void OnMapNewBegin() 
-		{
-            OnMapOpenBegin();
-        }
+				// Load VPO manager (manages multithreading and communication with vpo.dll)
+				vpo = new VPOManager();
 
-		// Some things cannot be initialized at plugin start, so we do them here
-		public override void OnMapOpenBegin()
-		{
-			base.OnMapOpenBegin();
-
-            if (palettes == null)
-			{
-				// Load palettes
-				palettes = new Palette[(int)ViewStats.NumStats];
-				palettes[(int)ViewStats.Visplanes] = new Palette(Resources.Visplanes_pal);
-				palettes[(int)ViewStats.Drawsegs] = new Palette(Resources.Drawsegs_pal);
-				palettes[(int)ViewStats.Solidsegs] = new Palette(Resources.Solidsegs_pal);
-				palettes[(int)ViewStats.Openings] = new Palette(Resources.Openings_pal);
-				palettes[(int)ViewStats.Heatmap] = new Palette(Resources.Heatmap_pal); //mxd
-				ApplyUserColors();
+				// Keep a static reference
+				me = this;
 			}
 		}
 
@@ -104,45 +82,69 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
 		// This is called when the plugin is terminated
 		public override void Dispose()
 		{
-			// Clean up
-			interfaceform.Dispose();
-			interfaceform = null;
-			vpo.Dispose();
-			vpo = null;
-			base.Dispose();
+			//mxd. Active and not already disposed?
+			if(!IsDisposed)
+			{
+				if(enabled)
+				{
+					// Clean up
+					interfaceform.Dispose();
+					interfaceform = null;
+					vpo.Dispose();
+					vpo = null;
+
+					// Done
+					me = null;
+				}
+
+				base.Dispose();
+			}
 		}
 
 		#endregion
 
 		#region ================== Methods
 
+		//mxd
+		private Palette[] GetPalettes()
+		{
+			if(palettes == null)
+			{
+				// Load palettes
+				palettes = new Palette[(int)ViewStats.NumStats];
+				palettes[(int)ViewStats.Visplanes] = new Palette(Resources.Visplanes_pal);
+				palettes[(int)ViewStats.Drawsegs] = new Palette(Resources.Drawsegs_pal);
+				palettes[(int)ViewStats.Solidsegs] = new Palette(Resources.Solidsegs_pal);
+				palettes[(int)ViewStats.Openings] = new Palette(Resources.Openings_pal);
+				palettes[(int)ViewStats.Heatmap] = new Palette(Resources.Heatmap_pal); //mxd
+				ApplyUserColors();
+			}
+			return palettes;
+		}
+
 		// This applies user-defined appearance colors to the palettes
 		private void ApplyUserColors()
 		{
-            if(palettes != null)
+			//mxd
+			if(palettes == null)
 			{
-				// Override special palette indices with user-defined colors
-				for(int i = 0; i < palettes.Length; i++)
-				{
-					palettes[i].SetColor(Tile.POINT_VOID_B, General.Colors.Background.WithAlpha(0).ToInt());
-				}
+				GetPalettes();
+				return;
 			}
+			
+			// Override special palette indices with user-defined colors
+			foreach(Palette p in palettes) p.SetColor(Tile.POINT_VOID_B, General.Colors.Background.WithAlpha(0).ToInt());
 		}
 
 		// This returns a unique temp filename
 		public static string MakeTempFilename(string extension)
 		{
 			string filename;
-			string chars = "abcdefghijklmnopqrstuvwxyz1234567890";
-			Random rnd = new Random();
-			int i;
 
 			do
 			{
-				// Generate a filename
-				filename = "";
-				for(i = 0; i < 8; i++) filename += chars[rnd.Next(chars.Length)];
-				filename = Path.Combine(General.TempPath, filename + extension);
+				//mxd. Generate a filename
+				filename = Path.Combine(General.TempPath, MurmurHash2.Hash(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture)) + extension);
 			}
 			// Continue while file is not unique
 			while(File.Exists(filename) || Directory.Exists(filename));