diff --git a/Build/Updater.exe b/Build/Updater.exe
index 91fe2604f6976aea493100eb10e4134ba817b626..95fe67fafcb583f926cf43b55dcd843fef247466 100644
Binary files a/Build/Updater.exe and b/Build/Updater.exe differ
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index d468f3252da335caa937faec1415c99dbcffb04c..d8cd54f2a7e7d8af25a4a5bb4a17316f13ca88ea 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -522,7 +522,9 @@
     <Compile Include="Rendering\WorldVertex.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="JetBrains.Profiler.Core.Api, Version=1.3.1661.20096, Culture=neutral, PublicKeyToken=1010a0d8d6380325" Condition=" '$(Configuration)|$(Platform)' == 'Debug + Profiler|x86' Or '$(Configuration)|$(Platform)' == 'Release + Profiler|x86' " />
+    <Reference Include="JetBrains.Profiler.Core.Api, Version=1.3.1661.20096, Culture=neutral, PublicKeyToken=1010a0d8d6380325" Condition=" '$(Configuration)|$(Platform)' == 'Debug + Profiler|x86' Or '$(Configuration)|$(Platform)' == 'Release + Profiler|x86' ">
+      <SpecificVersion>False</SpecificVersion>
+    </Reference>
     <Reference Include="ScintillaNET.3.5, Version=3.5.8.0, Culture=neutral, processorArchitecture=x86">
       <Private>False</Private>
     </Reference>
diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs
index 355f1a370404360f5e0a13f0c4177693e67db39a..d1b32f5cfc06cbdf25d613fdb0659b875d9cc523 100644
--- a/Source/Core/Geometry/Tools.cs
+++ b/Source/Core/Geometry/Tools.cs
@@ -223,8 +223,13 @@ namespace CodeImp.DoomBuilder.Geometry
 						LinedefTracePath tracepath = new LinedefTracePath(innerlines);
 						EarClipPolygon innerpoly = tracepath.MakePolygon(true);
 
+						//mxd. Check bbox first...
+						Vector2D foundsidepoint = foundline.GetSidePoint(foundlinefront);
+						RectangleF innerbbox = innerpoly.CreateBBox();
+						bool outsidebbox = (foundsidepoint.x < innerbbox.Left || foundsidepoint.x > innerbbox.Right || foundsidepoint.y < innerbbox.Top || foundsidepoint.y > innerbbox.Bottom);
+
 						// Check if the front of the line is outside the polygon
-						if(!innerpoly.Intersect(foundline.GetSidePoint(foundlinefront)))
+						if(outsidebbox || !innerpoly.Intersect(foundsidepoint))
 						{
 							// Valid hole found!
 							alllines.AddRange(innerlines);
@@ -244,6 +249,7 @@ namespace CodeImp.DoomBuilder.Geometry
 		{
 			Linedef scanline = line;
 			bool scanfront = front;
+			Vector2D sidepoint = line.GetSidePoint(front); //mxd
 
 			do
 			{
@@ -255,8 +261,12 @@ namespace CodeImp.DoomBuilder.Geometry
 					LinedefTracePath tracepath = new LinedefTracePath(pathlines);
 					EarClipPolygon poly = tracepath.MakePolygon(true);
 
+					//mxd. Check bbox first...
+					RectangleF bbox = poly.CreateBBox();
+					bool outsidebbox = (sidepoint.x < bbox.Left || sidepoint.x > bbox.Right || sidepoint.y < bbox.Top || sidepoint.y > bbox.Bottom);
+
 					// Check if the front of the line is inside the polygon
-					if(poly.Intersect(line.GetSidePoint(front)))
+					if(!outsidebbox && poly.Intersect(sidepoint))
 					{
 						// Outer lines found!
 						alllines.AddRange(pathlines);
@@ -921,6 +931,11 @@ namespace CodeImp.DoomBuilder.Geometry
 			List<Vertex> nonmergeverts = new List<Vertex>(General.Map.Map.Vertices);
 			MapSet map = General.Map.Map;
 
+			//mxd. Let's use a blockmap...
+			RectangleF area = MapSet.CreateArea(oldlines);
+			BlockMap<BlockEntry> oldlinesmap = new BlockMap<BlockEntry>(area);
+			oldlinesmap.AddLinedefsSet(oldlines);
+
 			General.Map.Map.ClearAllMarks(false);
 			
 			// Any points to do?
@@ -1065,7 +1080,7 @@ namespace CodeImp.DoomBuilder.Geometry
 						foreach(Linedef ld in newlines)
 						{
 							Vector2D ldcp = ld.GetCenterPoint();
-							Linedef nld = MapSet.NearestLinedef(oldlines, ldcp);
+							Linedef nld = MapSet.NearestLinedef(oldlinesmap, ldcp); //mxd. Lines collection -> Blockmap
 							if(nld != null)
 							{
 								float ldside = nld.SideOfLine(ldcp);
@@ -1102,7 +1117,7 @@ namespace CodeImp.DoomBuilder.Geometry
 								List<LinedefSide> endpoints = new List<LinedefSide>();
 
 								// Find out where the start will stitch and create test points
-								Linedef l1 = MapSet.NearestLinedefRange(oldlines, firstline.Start.Position, MapSet.STITCH_DISTANCE);
+								Linedef l1 = MapSet.NearestLinedefRange(oldlinesmap, firstline.Start.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
 								Vertex vv1 = null;
 								if(l1 != null)
 								{
@@ -1127,7 +1142,7 @@ namespace CodeImp.DoomBuilder.Geometry
 								}
 
 								// Find out where the end will stitch and create test points
-								Linedef l2 = MapSet.NearestLinedefRange(oldlines, lastline.End.Position, MapSet.STITCH_DISTANCE);
+								Linedef l2 = MapSet.NearestLinedefRange(oldlinesmap, lastline.End.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
 								Vertex vv2 = null;
 								if(l2 != null)
 								{
@@ -2187,15 +2202,23 @@ namespace CodeImp.DoomBuilder.Geometry
 			{
 				if(l.Front != null && (l.Front.Sector != null && !SectorWasInvalid(l.Front.Sector)))
 				{
-					if(!sectorsidesref.ContainsKey(l.Front.Sector)) sectorsidesref.Add(l.Front.Sector, new HashSet<Sidedef>());
-					sectorsidesref[l.Front.Sector].Add(l.Front);
+					// Add only multipart sectors
+					if(l.Front.Sector.Triangles.IslandVertices.Count > 1)
+					{
+						if(!sectorsidesref.ContainsKey(l.Front.Sector)) sectorsidesref[l.Front.Sector] = new HashSet<Sidedef>();
+						sectorsidesref[l.Front.Sector].Add(l.Front);
+					}
 					drawnsides.Add(l.Front);
 				}
 
 				if(l.Back != null && (l.Back.Sector != null && !SectorWasInvalid(l.Back.Sector)))
 				{
-					if(!sectorsidesref.ContainsKey(l.Back.Sector)) sectorsidesref.Add(l.Back.Sector, new HashSet<Sidedef>());
-					sectorsidesref[l.Back.Sector].Add(l.Back);
+					// Add only multipart sectors
+					if(l.Back.Sector.Triangles.IslandVertices.Count > 1)
+					{
+						if(!sectorsidesref.ContainsKey(l.Back.Sector)) sectorsidesref[l.Back.Sector] = new HashSet<Sidedef>();
+						sectorsidesref[l.Back.Sector].Add(l.Back);
+					}
 					drawnsides.Add(l.Back);
 				}
 			}
@@ -2389,28 +2412,6 @@ namespace CodeImp.DoomBuilder.Geometry
 			return 0;
 		}
 
-		//mxd
-		public static Sector FindSectorContaining(Linedef line, bool front)
-		{
-			List<LinedefSide> sectorsides = FindPotentialSectorAt(line, front);
-			if(sectorsides == null) return null;
-
-			// Check potential sectors
-			foreach(LinedefSide sectorside in sectorsides)
-			{
-				Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back);
-				if(target != null && target.Sector != null)
-				{
-					// Check if target line is inside the found sector
-					if(target.Sector.Intersect(line.Start.Position, false) && target.Sector.Intersect(line.End.Position, false))
-						return target.Sector;
-				}
-			}
-
-			// No dice...
-			return null;
-		}
-
 		#endregion
 
 		#region ================== Misc Exported Functions
diff --git a/Source/Core/Map/BlockMap.cs b/Source/Core/Map/BlockMap.cs
index be3c02d538fbf4809ca0695f33dd1d2f0e9fbc6c..c1a727f8b90b21b411b000c16a555a857e0568f8 100644
--- a/Source/Core/Map/BlockMap.cs
+++ b/Source/Core/Map/BlockMap.cs
@@ -105,7 +105,7 @@ namespace CodeImp.DoomBuilder.Map
 		#region ================== Methods
 		
 		// This returns the block coordinates
-		protected Point GetBlockCoordinates(Vector2D v)
+		internal Point GetBlockCoordinates(Vector2D v)
 		{
 			return new Point((int)(v.x - range.Left) >> blocksizeshift,
 							 (int)(v.y - range.Top) >> blocksizeshift);
@@ -119,7 +119,7 @@ namespace CodeImp.DoomBuilder.Map
 		}
 		
 		// This returns true when the given block is inside range
-		protected bool IsInRange(Point p)
+		internal bool IsInRange(Point p)
 		{
 			return (p.X >= 0) && (p.X < size.Width) && (p.Y >= 0) && (p.Y < size.Height);
 		}
@@ -356,6 +356,9 @@ namespace CodeImp.DoomBuilder.Map
 		// This puts a sector in the blockmap
 		public virtual void AddSector(Sector s)
 		{
+			//mxd. Check range. Sector can be bigger than blockmap range
+			if(!range.IntersectsWith(s.BBox)) return;
+			
 			Point p1 = GetBlockCoordinates(new Vector2D(s.BBox.Left, s.BBox.Top));
 			Point p2 = GetBlockCoordinates(new Vector2D(s.BBox.Right, s.BBox.Bottom));
 			p1 = CropToRange(p1);
diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs
index 0640ad05a8631a20a2592863cee70efc602f695b..b7e69bc9c3f18b85cac9f404fe559014e513ed9f 100644
--- a/Source/Core/Map/MapSet.cs
+++ b/Source/Core/Map/MapSet.cs
@@ -1987,6 +1987,32 @@ namespace CodeImp.DoomBuilder.Map
 			return new RectangleF(l, t, r - l, b - t);
 		}
 
+		/// <summary>This increases and existing area with the given linedefs.</summary>
+		public static RectangleF IncreaseArea(RectangleF area, ICollection<Linedef> lines) //mxd
+		{
+			float l = area.Left;
+			float t = area.Top;
+			float r = area.Right;
+			float b = area.Bottom;
+
+			// Go for all vertices
+			foreach(Linedef ld in lines)
+			{
+				// Adjust boundaries by vertices
+				if(ld.Start.Position.x < l) l = ld.Start.Position.x;
+				if(ld.Start.Position.x > r) r = ld.Start.Position.x;
+				if(ld.Start.Position.y < t) t = ld.Start.Position.y;
+				if(ld.Start.Position.y > b) b = ld.Start.Position.y;
+				if(ld.End.Position.x < l) l = ld.End.Position.x;
+				if(ld.End.Position.x > r) r = ld.End.Position.x;
+				if(ld.End.Position.y < t) t = ld.End.Position.y;
+				if(ld.End.Position.y > b) b = ld.End.Position.y;
+			}
+
+			// Return a rect
+			return new RectangleF(l, t, r - l, b - t);
+		}
+
 		/// <summary>This filters lines by a rectangular area.</summary>
 		public static HashSet<Linedef> FilterByArea(ICollection<Linedef> lines, ref RectangleF area)
 		{
@@ -2435,12 +2461,21 @@ namespace CodeImp.DoomBuilder.Map
 				if(line.Front == null) linesmissingfront.Add(line);
 			}
 
+			// Anything to do?
+			if(linesmissingfront.Count == 0 && linesmissingback.Count == 0) return;
+
+			// Let's use a blockmap...
+			RectangleF area = CreateArea(linesmissingfront);
+			area = IncreaseArea(area, linesmissingback);
+			BlockMap<BlockEntry> blockmap = new BlockMap<BlockEntry>(area);
+			blockmap.AddSectorsSet(General.Map.Map.Sectors);
+
 			// Find sectors to join singlesided lines
 			Dictionary<Linedef, Sector> linefrontsectorref = new Dictionary<Linedef, Sector>();
 			foreach(Linedef line in linesmissingfront)
 			{
-				// Line is now inside a sector? (check from the missing side!)
-				Sector nearest = Tools.FindSectorContaining(line, true);
+				// Line is now inside a sector?
+				Sector nearest = FindSectorContaining(blockmap, line);
 
 				// We can reattach our line!
 				if(nearest != null) linefrontsectorref[line] = nearest;
@@ -2449,8 +2484,8 @@ namespace CodeImp.DoomBuilder.Map
 			Dictionary<Linedef, Sector> linebacksectorref = new Dictionary<Linedef, Sector>();
 			foreach(Linedef line in linesmissingback)
 			{
-				// Line is now inside a sector? (check from the missing side!)
-				Sector nearest = Tools.FindSectorContaining(line, false);
+				// Line is now inside a sector?
+				Sector nearest = FindSectorContaining(blockmap, line);
 
 				// We can reattach our line!
 				if(nearest != null) linebacksectorref[line] = nearest;
@@ -2511,6 +2546,28 @@ namespace CodeImp.DoomBuilder.Map
 			}
 		}
 
+		//mxd
+		private static Sector FindSectorContaining(BlockMap<BlockEntry> sectorsmap, Linedef line)
+		{
+			HashSet<BlockEntry> blocks = new HashSet<BlockEntry>
+			{
+				sectorsmap.GetBlockAt(line.Start.Position),
+				sectorsmap.GetBlockAt(line.End.Position),
+			};
+
+			foreach(BlockEntry be in blocks)
+			{
+				foreach(Sector sector in be.Sectors)
+				{
+					// Check if target line is inside the found sector
+					if(sector.Intersect(line.Start.Position, false) && sector.Intersect(line.End.Position, false))
+						return sector;
+				}
+			}
+
+			return null;
+		}
+
 		//mxd
 		private static string GetAdjacentMiddleTexture(Vertex v)
 		{
@@ -2726,46 +2783,78 @@ namespace CodeImp.DoomBuilder.Map
 
 			do
 			{
+				//mxd. Create blockmap
+				ICollection<Vertex> biggerset, smallerset;
+				bool keepsmaller;
+				if(set1.Count > set2.Count)
+				{
+					biggerset = set1;
+					smallerset = set2;
+					keepsmaller = !keepsecond;
+				}
+				else
+				{
+					biggerset = set2;
+					smallerset = set1;
+					keepsmaller = keepsecond;
+				}
+				
+				RectangleF area = CreateArea(biggerset);
+				BlockMap<BlockEntry> blockmap = new BlockMap<BlockEntry>(area);
+				blockmap.AddVerticesSet(biggerset);
+				
 				// No joins yet
 				joined = false;
 
-				// Go for all vertices in the first set
-				foreach(Vertex v1 in set1)
+				// Go for all vertices in the smaller set
+				foreach(Vertex v1 in smallerset)
 				{
-					// Go for all vertices in the second set
-					foreach(Vertex v2 in set2)
+					HashSet<BlockEntry> blocks = new HashSet<BlockEntry>
 					{
-						// Check if vertices are close enough
-						if(v1.DistanceToSq(v2.Position) <= joindist2)
+						blockmap.GetBlockAt(v1.Position), 
+						blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y + joindist)), 
+						blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y - joindist)), 
+						blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y + joindist)), 
+						blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y - joindist))
+					};
+
+					foreach(BlockEntry be in blocks)
+					{
+						if(be == null) continue;
+						foreach(Vertex v2 in be.Vertices)
 						{
-							// Check if not the same vertex
-							if(v1 != v2)
+							// Check if vertices are close enough
+							if(v1.DistanceToSq(v2.Position) <= joindist2)
 							{
-								// Move the second vertex to match the first
-								v2.Move(v1.Position);
-								
-								// Check which one to keep
-								if(keepsecond)
+								// Check if not the same vertex
+								if(v1 != v2)
 								{
-									// Join the first into the second
-									// Second is kept, first is removed
-									v1.Join(v2);
-									set1.Remove(v1);
-									set2.Remove(v1);
-								}
-								else
-								{
-									// Join the second into the first
-									// First is kept, second is removed
-									v2.Join(v1);
-									set1.Remove(v2);
-									set2.Remove(v2);
+									// Move the second vertex to match the first
+									v2.Move(v1.Position);
+
+									// Check which one to keep
+									if(keepsmaller)
+									{
+										// Join the first into the second
+										// Second is kept, first is removed
+										v1.Join(v2);
+										biggerset.Remove(v1);
+										smallerset.Remove(v1);
+									}
+									else
+									{
+										// Join the second into the first
+										// First is kept, second is removed
+										v2.Join(v1);
+										biggerset.Remove(v2);
+										smallerset.Remove(v2);
+									}
+
+									// Count the join
+									joinsdone++;
+									joined = true;
+									break;
 								}
-								
-								// Count the join
-								joinsdone++;
-								joined = true;
-								break;
 							}
 						}
 					}
@@ -3177,6 +3266,62 @@ namespace CodeImp.DoomBuilder.Map
 			return closest;
 		}
 
+		/// <summary>This finds the line closest to the specified position.</summary>
+		public static Linedef NearestLinedef(BlockMap<BlockEntry> selectionmap, Vector2D pos) //mxd
+		{
+			Linedef closest = null;
+			float distance = float.MaxValue;
+
+			Point p = selectionmap.GetBlockCoordinates(pos);
+			int minx = p.X;
+			int maxx = p.X;
+			int miny = p.Y;
+			int maxy = p.Y;
+			int step = 0;
+
+			// Check square block ranges around pos...
+			while(true)
+			{
+				bool noblocksfound = true;
+				for(int x = minx; x < maxx + 1; x++)
+				{
+					for(int y = miny; y < maxy + 1; y++)
+					{
+						// Skip inner blocks...
+						if(x > minx && x < maxx && y > miny && y < maxy) continue;
+						if(!selectionmap.IsInRange(new Point(x, y))) continue;
+
+						// Go for all linedefs in block
+						BlockEntry be = selectionmap.Map[x, y];
+						foreach(Linedef l in be.Lines)
+						{
+							// Calculate distance and check if closer than previous find
+							float d = l.SafeDistanceToSq(pos, true);
+							if(d < distance)
+							{
+								// This one is closer
+								closest = l;
+								distance = d;
+							}
+						}
+
+						noblocksfound = false;
+					}
+				}
+
+				// Abort if line was found or when outside of blockmap range...
+				// Check at least 3x3 blocks, because there's a possibility that a line closer to pos exists in a nearby block than in the first block
+				if(noblocksfound || (closest != null && step > 0)) return closest;
+
+				// Increase search range...
+				minx--;
+				maxx++;
+				miny--;
+				maxy++;
+				step++;
+			}
+		}
+
 		/// <summary>This finds the line closest to the specified position.</summary>
 		public static Linedef NearestLinedef(ICollection<Linedef> selection, Vector2D pos)
 		{
@@ -3224,6 +3369,48 @@ namespace CodeImp.DoomBuilder.Map
 			return closest;
 		}
 
+		/// <summary>This finds the line closest to the specified position.</summary>
+		public static Linedef NearestLinedefRange(BlockMap<BlockEntry> selectionmap, Vector2D pos, float maxrange) //mxd
+		{
+			Linedef closest = null;
+			float distance = float.MaxValue;
+			float maxrangesq = maxrange * maxrange;
+			HashSet<Linedef> processed = new HashSet<Linedef>();
+			
+			HashSet<BlockEntry> blocks = new HashSet<BlockEntry>
+			{
+				selectionmap.GetBlockAt(pos), 
+				selectionmap.GetBlockAt(new Vector2D(pos.x + maxrange, pos.y + maxrange)), 
+				selectionmap.GetBlockAt(new Vector2D(pos.x + maxrange, pos.y - maxrange)), 
+				selectionmap.GetBlockAt(new Vector2D(pos.x - maxrange, pos.y + maxrange)), 
+				selectionmap.GetBlockAt(new Vector2D(pos.x - maxrange, pos.y - maxrange))
+			};
+
+			foreach(BlockEntry be in blocks)
+			{
+				if(be == null) continue;
+
+				foreach(Linedef l in be.Lines)
+				{
+					if(processed.Contains(l)) continue;
+					
+					// Calculate distance and check if closer than previous find
+					float d = l.SafeDistanceToSq(pos, true);
+					if(d < distance && d <= maxrangesq)
+					{
+						// This one is closer
+						closest = l;
+						distance = d;
+					}
+
+					processed.Add(l);
+				}
+			}
+
+			// Return result
+			return closest;
+		}
+
 		/// <summary>mxd. This finds the line closest to the specified position excluding given list of linedefs.</summary>
 		public Linedef NearestLinedef(Vector2D pos, HashSet<Linedef> linesToExclude) 
 		{
diff --git a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
index b0780624c473a8e4cf3b58b51b87c88a535141d9..8d6edd5a0893b050e1ad513a0e186fc1f4842617 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
@@ -398,6 +398,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			else if(editpressed && prevoffset != 0)
 			{
 				int diff = (int)Math.Round((offset - prevoffset) * renderer.Scale);
+				if(panel.FixedCurve) diff *= Math.Sign(panel.Distance); // Special cases...
 				if(panel.Angle + diff > 0) panel.Angle += diff;
 			}
 
diff --git a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs
index d45dd1f681551a1c06dd07c411fb1a6489a28e74..9c028b1b8a3ac91c93b5276acb2e405aca8dead8 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs
@@ -1586,6 +1586,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
 
 					// Go for all sidedes in the new geometry
 					List<Sidedef> newsides = General.Map.Map.GetMarkedSidedefs(true);
+					List<Linedef> oldlines = General.Map.Map.GetMarkedLinedefs(false); //mxd
+
+					//mxd. Let's use a blockmap...
+					RectangleF area = MapSet.CreateArea(oldlines);
+					BlockMap<BlockEntry> blockmap = new BlockMap<BlockEntry>(area);
+					blockmap.AddLinedefsSet(oldlines);
+
 					foreach(Sidedef s in newsides) 
 					{
 						// Connected to a virtual sector?
@@ -1604,7 +1611,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 							{
 								// Find out in which sector this was pasted
 								Vector2D testpoint = s.Line.GetSidePoint(!s.IsFront);
-								Linedef nl = MapSet.NearestLinedef(General.Map.Map.GetMarkedLinedefs(false), testpoint);
+								Linedef nl = MapSet.NearestLinedef(blockmap, testpoint); //mxd
 								if(nl != null) 
 								{
 									Sidedef joinsidedef = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index 5973cf70eca43c04a641fcad72782f69ce73d640..093c7a828c5fb806c79fb22c7d51b41899f2a80a 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -263,7 +263,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 
 			if(lines.Count == 0) 
 			{
-				General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection");
+				General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!");
 				return;
 			}
 
@@ -1565,6 +1565,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				// Go into curve linedefs mode
 				General.Editing.ChangeMode(new CurveLinedefsMode());
 			}
+			else
+			{
+				//mxd
+				General.Interface.DisplayStatus(StatusType.Warning, "This action requres a selection!");
+			}
 		}
 		
 		[BeginAction("fliplinedefs")]
diff --git a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs
index 1e7449ccd502708405286703b06dbcc664cdc560..4e6d6a71df45eac08a61689e72097b5fa6f98116 100644
--- a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs
@@ -35,12 +35,13 @@
 			this.distance = new CodeImp.DoomBuilder.Controls.ToolStripNumericUpDown();
 			this.anglelabel = new System.Windows.Forms.ToolStripLabel();
 			this.angle = new CodeImp.DoomBuilder.Controls.ToolStripNumericUpDown();
+			this.reset = new System.Windows.Forms.ToolStripButton();
 			this.separator1 = new System.Windows.Forms.ToolStripSeparator();
 			this.fixedcurve = new System.Windows.Forms.ToolStripButton();
 			this.separator2 = new System.Windows.Forms.ToolStripSeparator();
 			this.apply = new System.Windows.Forms.ToolStripButton();
 			this.cancel = new System.Windows.Forms.ToolStripButton();
-			this.reset = new System.Windows.Forms.ToolStripButton();
+			this.flip = new System.Windows.Forms.ToolStripButton();
 			this.toolstrip.SuspendLayout();
 			this.SuspendLayout();
 			// 
@@ -53,6 +54,7 @@
             this.distance,
             this.anglelabel,
             this.angle,
+            this.flip,
             this.reset,
             this.separator1,
             this.fixedcurve,
@@ -61,7 +63,7 @@
             this.cancel});
 			this.toolstrip.Location = new System.Drawing.Point(0, 0);
 			this.toolstrip.Name = "toolstrip";
-			this.toolstrip.Size = new System.Drawing.Size(620, 25);
+			this.toolstrip.Size = new System.Drawing.Size(760, 25);
 			this.toolstrip.TabIndex = 0;
 			this.toolstrip.Text = "toolStrip1";
 			// 
@@ -170,6 +172,17 @@
             0});
 			this.angle.ValueChanged += new System.EventHandler(this.OnUIValuesChanged);
 			// 
+			// reset
+			// 
+			this.reset.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+			this.reset.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset;
+			this.reset.ImageTransparentColor = System.Drawing.Color.Magenta;
+			this.reset.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2);
+			this.reset.Name = "reset";
+			this.reset.Size = new System.Drawing.Size(23, 22);
+			this.reset.Text = "Reset";
+			this.reset.Click += new System.EventHandler(this.reset_Click);
+			// 
 			// separator1
 			// 
 			this.separator1.Name = "separator1";
@@ -212,16 +225,15 @@
 			this.cancel.Text = "Cancel";
 			this.cancel.Click += new System.EventHandler(this.cancel_Click);
 			// 
-			// reset
+			// flip
 			// 
-			this.reset.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-			this.reset.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset;
-			this.reset.ImageTransparentColor = System.Drawing.Color.Magenta;
-			this.reset.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2);
-			this.reset.Name = "reset";
-			this.reset.Size = new System.Drawing.Size(23, 22);
-			this.reset.Text = "Reset";
-			this.reset.Click += new System.EventHandler(this.reset_Click);
+			this.flip.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+			this.flip.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Flip;
+			this.flip.ImageTransparentColor = System.Drawing.Color.Magenta;
+			this.flip.Name = "flip";
+			this.flip.Size = new System.Drawing.Size(23, 22);
+			this.flip.Text = "Flip Curve";
+			this.flip.Click += new System.EventHandler(this.flip_Click);
 			// 
 			// CurveLinedefsOptionsPanel
 			// 
@@ -229,7 +241,7 @@
 			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
 			this.Controls.Add(this.toolstrip);
 			this.Name = "CurveLinedefsOptionsPanel";
-			this.Size = new System.Drawing.Size(620, 60);
+			this.Size = new System.Drawing.Size(760, 60);
 			this.toolstrip.ResumeLayout(false);
 			this.toolstrip.PerformLayout();
 			this.ResumeLayout(false);
@@ -252,5 +264,6 @@
 		private System.Windows.Forms.ToolStripButton apply;
 		private System.Windows.Forms.ToolStripButton cancel;
 		private System.Windows.Forms.ToolStripButton reset;
+		private System.Windows.Forms.ToolStripButton flip;
 	}
 }
diff --git a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs
index f6b13ce62d2532e3034e8e036833b37439fb89a7..b687dcd54de624c76c6348cce6021e925b03cdc1 100644
--- a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs
+++ b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs
@@ -60,6 +60,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			General.Interface.AddButton(distance);
 			General.Interface.AddButton(anglelabel);
 			General.Interface.AddButton(angle);
+			General.Interface.AddButton(flip);
 			General.Interface.AddButton(reset);
 			General.Interface.AddButton(separator1);
 			General.Interface.AddButton(fixedcurve);
@@ -77,6 +78,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			General.Interface.RemoveButton(fixedcurve);
 			General.Interface.RemoveButton(separator1);
 			General.Interface.RemoveButton(reset);
+			General.Interface.RemoveButton(flip);
 			General.Interface.RemoveButton(angle);
 			General.Interface.RemoveButton(anglelabel);
 			General.Interface.RemoveButton(distance);
@@ -115,6 +117,11 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			if(!blockevents && OnValueChanged != null) OnValueChanged(this, EventArgs.Empty);
 		}
 
+		private void flip_Click(object sender, EventArgs e)
+		{
+			distance.Value = -distance.Value;
+		}
+
 		private void reset_Click(object sender, EventArgs e)
 		{
 			SetValues(CurveLinedefsMode.DEFAULT_VERTICES_COUNT, CurveLinedefsMode.DEFAULT_DISTANCE, CurveLinedefsMode.DEFAULT_ANGLE, false);
diff --git a/Source/Tools/Updater/Helpers/TaskbarProgress.cs b/Source/Tools/Updater/Helpers/TaskbarProgress.cs
index e4f58f968efc1e25fdf52791173130b9bb175c84..0a9c56d3488a0ba6d39a92c44bb43f06a0828632 100644
--- a/Source/Tools/Updater/Helpers/TaskbarProgress.cs
+++ b/Source/Tools/Updater/Helpers/TaskbarProgress.cs
@@ -64,6 +64,7 @@ namespace mxd.GZDBUpdater
 
 		private static ITaskbarList3 taskbarinstance;
 		private static bool taskbarsupported; //mxd. Environment.OSVersion.Version won't save us here...
+		private static bool checkperformed;
 
 		#endregion
 
@@ -82,8 +83,9 @@ namespace mxd.GZDBUpdater
 		//mxd
 		private static bool TaskBarSupported()
 		{
-			if(taskbarinstance == null)
+			if(!checkperformed)
 			{
+				checkperformed = true;
 				taskbarsupported = true;
 				try { taskbarinstance = (ITaskbarList3)new TaskbarInstance(); }
 				catch { taskbarsupported = false; }