diff --git a/Build/Setup/dxwebsetup.exe b/Build/Setup/dxwebsetup.exe
index c9e89a8a6e7d1803c58f73d862fa61563477caef..53d2415e8ac2b4c3972c2e2452b403ee7399a0cd 100644
Binary files a/Build/Setup/dxwebsetup.exe and b/Build/Setup/dxwebsetup.exe differ
diff --git a/Builder.sln b/Builder.sln
index e0e90cb9835041cb728c60b8451f0bbb540f4dc3..ccfb731c46e72d93aead46870d24230c0f717306 100644
--- a/Builder.sln
+++ b/Builder.sln
@@ -9,42 +9,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statistics", "Source\Plugin
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Debug|Mixed Platforms = Debug|Mixed Platforms
 		Debug|x86 = Debug|x86
-		Release|Any CPU = Release|Any CPU
-		Release|Mixed Platforms = Release|Mixed Platforms
 		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Debug|Mixed Platforms.Build.0 = Debug|x86
 		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Debug|x86.ActiveCfg = Debug|x86
 		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Debug|x86.Build.0 = Debug|x86
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Release|Any CPU.ActiveCfg = Release|x86
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Release|Mixed Platforms.Build.0 = Release|x86
 		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Release|x86.ActiveCfg = Release|x86
 		{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}.Release|x86.Build.0 = Release|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Debug|Mixed Platforms.Build.0 = Debug|x86
 		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Debug|x86.ActiveCfg = Debug|x86
 		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Debug|x86.Build.0 = Debug|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|Any CPU.ActiveCfg = Release|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|Mixed Platforms.Build.0 = Release|x86
 		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|x86.ActiveCfg = Release|x86
 		{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|x86.Build.0 = Release|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.Build.0 = Debug|x86
 		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|x86.ActiveCfg = Debug|x86
 		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|x86.Build.0 = Debug|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Any CPU.ActiveCfg = Release|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.Build.0 = Release|x86
 		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|x86.ActiveCfg = Release|x86
 		{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index 0860f39d43ed93052f1dba75c55ff4a6ab488155..3e7a7dbf20d82907bfd5b8909f2b635a1253064d 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -135,7 +135,6 @@
     <Compile Include="Editing\GridSetup.cs" />
     <Compile Include="Editing\NullThingsFilter.cs" />
     <Compile Include="Editing\ThingsFilter.cs" />
-    <Compile Include="Editing\UndoGroup.cs" />
     <Compile Include="Editing\UndoManager.cs" />
     <Compile Include="Editing\UndoSnapshot.cs" />
     <Compile Include="Editing\ClassicMode.cs" />
diff --git a/Source/Core/Editing/UndoManager.cs b/Source/Core/Editing/UndoManager.cs
index 2fa6cd74059b82f93212cbe954fc9128c09d97a0..391453779991d33d530f70868fb4bb7234744496 100644
--- a/Source/Core/Editing/UndoManager.cs
+++ b/Source/Core/Editing/UndoManager.cs
@@ -25,6 +25,7 @@ using System.Threading;
 using System.Windows.Forms;
 using System.IO;
 using System.Reflection;
+using CodeImp.DoomBuilder.Plugins;
 using CodeImp.DoomBuilder.Windows;
 using CodeImp.DoomBuilder.IO;
 using CodeImp.DoomBuilder.Map;
@@ -49,7 +50,8 @@ namespace CodeImp.DoomBuilder.Editing
 		private List<UndoSnapshot> redos;
 
 		// Grouping
-		private UndoGroup lastgroup;
+		private Plugin lastgroupplugin;
+		private int lastgroupid;
 		private int lastgrouptag;
 		
 		// Unique tickets
@@ -233,29 +235,47 @@ namespace CodeImp.DoomBuilder.Editing
 			ClearRedos();
 			General.MainWindow.UpdateInterface();
 		}
-		
-		// This makes an undo and returns the unique ticket id
-		// Also automatically indicates that the map is changed
+
+		/// <summary>
+		/// This makes an undo and returns the unique ticket id. Also automatically indicates that the map is changed.
+		/// </summary>
+		/// <param name="description">Any description you want the undo to be named. Should be something related to the changes you are about to make.</param>
+		/// <returns>Ticket ID that identifies the created undo level.</returns>
 		public int CreateUndo(string description)
 		{
-			return CreateUndo(description, UndoGroup.None, 0);
+			return CreateUndo(description, null, 0, 0);
 		}
 		
-		// This makes an undo and returns the unique ticket id
-		// Also automatically indicates that the map is changed
-		public int CreateUndo(string description, UndoGroup group, int grouptag)
+		/// <summary>
+		/// This makes an undo and returns the unique ticket id. Also automatically indicates that the map is changed.
+		/// </summary>
+		/// <param name="description">Any description you want the undo to be named. Should be something related to the changes you are about to make.</param>
+		/// <param name="groupsource">The object creating the undo. All objects from within the same plugin are equal, so it is safe to just use 'this' everywhere. This is only used for undo grouping and you can use 'null' if you don't want undo grouping.</param>
+		/// <param name="groupid">The undo group id you want this undo level to group with (undos only group together if the previous undo has the same source, id and tag). Group 0 indicates no grouping.</param>
+		/// <param name="grouptag">The undo group tag you want this undo level to group with (undos only group together if the previous undo has the same source, id and tag). Use at your own discretion.</param>
+		/// <returns>Ticket ID that identifies the created undo level. Returns -1 when no undo level was created.</returns>
+		public int CreateUndo(string description, object groupsource, int groupid, int grouptag)
 		{
 			UndoSnapshot u;
+			Plugin p = null;
+			string groupsourcename = "Null";
+			
+			// Figure out the source plugin
+			if(groupsource != null)
+			{
+				p = General.Plugins.FindPluginByAssembly(groupsource.GetType().Assembly);
+				if(p != null) groupsourcename = p.Name;
+			}
 
-			// Not the same as previous group?
-			if((group == UndoGroup.None) ||
-			   (group != lastgroup) ||
+			// Not the same as previous group, or no grouping desired...
+			if((p == null) || (lastgroupplugin == null) || (p != lastgroupplugin) ||
+			   (groupid == 0) || (lastgroupid == 0) || (groupid != lastgroupid) ||
 			   (grouptag != lastgrouptag))
 			{
 				// Next ticket id
 				if(++ticketid == int.MaxValue) ticketid = 1;
 
-				General.WriteLogLine("Creating undo snapshot \"" + description + "\", Group " + group + ", Tag " + grouptag + ", Ticket ID " + ticketid + "...");
+				General.WriteLogLine("Creating undo snapshot \"" + description + "\", Source " + groupsourcename + ", Group " + groupid + ", Tag " + grouptag + ", Ticket ID " + ticketid + "...");
 
 				// Make a snapshot
 				u = new UndoSnapshot(description, General.Map.Map.Serialize(), ticketid);
@@ -275,7 +295,8 @@ namespace CodeImp.DoomBuilder.Editing
 				ClearRedos();
 
 				// Keep grouping info
-				lastgroup = group;
+				lastgroupplugin = p;
+				lastgroupid = groupid;
 				lastgrouptag = grouptag;
 				
 				// Map changes!
@@ -323,42 +344,6 @@ namespace CodeImp.DoomBuilder.Editing
 			}
 		}
 
-		// This changes the description of previously made undo
-		public void SetUndoDescription(int ticket, string description)
-		{
-			// Anything to undo?
-			if(undos.Count > 0)
-			{
-				// Check if the ticket id matches
-				if(ticket == undos[0].TicketID)
-				{
-					lock(undos)
-					{
-						undos[0].Description = description;
-					}
-					
-					// Update
-					General.MainWindow.UpdateInterface();
-				}
-			}
-		}
-
-		// This changes the grouping settings
-		public void SetUndoGrouping(int ticket, UndoGroup group, int grouptag)
-		{
-			// Anything to undo?
-			if(undos.Count > 0)
-			{
-				// Check if the ticket id matches
-				if(ticket == undos[0].TicketID)
-				{
-					// Keep grouping info
-					lastgroup = group;
-					lastgrouptag = grouptag;
-				}
-			}
-		}
-
 		// This performs an undo
 		[BeginAction("undo")]
 		public void PerformUndo()
@@ -409,7 +394,7 @@ namespace CodeImp.DoomBuilder.Editing
 							}
 							
 							// Reset grouping
-							lastgroup = UndoGroup.None;
+							lastgroupplugin = null;
 
 							// Change map set
 							MemoryStream data = u.GetMapData();
@@ -486,7 +471,7 @@ namespace CodeImp.DoomBuilder.Editing
 						}
 						
 						// Reset grouping
-						lastgroup = UndoGroup.None;
+						lastgroupplugin = null;
 
 						// Change map set
 						MemoryStream data = r.GetMapData();
diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj
index 5e7e0e1ef364b7ef0cfa130d9597d3641d2689e4..84ed7522179eff6481be18368762a9e39a44e085 100644
--- a/Source/Plugins/BuilderModes/BuilderModes.csproj
+++ b/Source/Plugins/BuilderModes/BuilderModes.csproj
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
+    <ProductVersion>9.0.30729</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -247,6 +247,7 @@
     <Compile Include="FindReplace\FindThingThingRef.cs" />
     <Compile Include="FindReplace\FindThingType.cs" />
     <Compile Include="FindReplace\FindVertexNumber.cs" />
+    <Compile Include="General\UndoGroup.cs" />
     <Compile Include="VisualModes\VisualActionResult.cs" />
   </ItemGroup>
   <ItemGroup>
diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
index b2b86b73d8fe4ee2b6b30264cbb00e9f28b4d7d7..51bdd887d4eac964f9c1bda3a0faafb80b5bd01f 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
@@ -1210,7 +1210,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public void LowerFloors8()
 		{
 			General.Interface.DisplayStatus(StatusType.Action, "Lowered floor heights by 8mp.");
-			General.Map.UndoRedo.CreateUndo("Floor heights change", UndoGroup.FloorHeightChange, CreateSelectionCRC());
+			General.Map.UndoRedo.CreateUndo("Floor heights change", this, UndoGroup.FloorHeightChange, CreateSelectionCRC());
 
 			// Change heights
 			ICollection<Sector> selected = General.Map.Map.GetSelectedSectors(true);
@@ -1230,7 +1230,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public void RaiseFloors8()
 		{
 			General.Interface.DisplayStatus(StatusType.Action, "Raised floor heights by 8mp.");
-			General.Map.UndoRedo.CreateUndo("Floor heights change", UndoGroup.FloorHeightChange, CreateSelectionCRC());
+			General.Map.UndoRedo.CreateUndo("Floor heights change", this, UndoGroup.FloorHeightChange, CreateSelectionCRC());
 
 			// Change heights
 			ICollection<Sector> selected = General.Map.Map.GetSelectedSectors(true);
@@ -1250,7 +1250,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public void LowerCeilings8()
 		{
 			General.Interface.DisplayStatus(StatusType.Action, "Lowered ceiling heights by 8mp.");
-			General.Map.UndoRedo.CreateUndo("Ceiling heights change", UndoGroup.CeilingHeightChange, CreateSelectionCRC());
+			General.Map.UndoRedo.CreateUndo("Ceiling heights change", this, UndoGroup.CeilingHeightChange, CreateSelectionCRC());
 
 			// Change heights
 			ICollection<Sector> selected = General.Map.Map.GetSelectedSectors(true);
@@ -1270,7 +1270,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public void RaiseCeilings8()
 		{
 			General.Interface.DisplayStatus(StatusType.Action, "Raised ceiling heights by 8mp.");
-			General.Map.UndoRedo.CreateUndo("Ceiling heights change", UndoGroup.CeilingHeightChange, CreateSelectionCRC());
+			General.Map.UndoRedo.CreateUndo("Ceiling heights change", this, UndoGroup.CeilingHeightChange, CreateSelectionCRC());
 
 			// Change heights
 			ICollection<Sector> selected = General.Map.Map.GetSelectedSectors(true);
diff --git a/Source/Core/Editing/UndoGroup.cs b/Source/Plugins/BuilderModes/General/UndoGroup.cs
similarity index 67%
rename from Source/Core/Editing/UndoGroup.cs
rename to Source/Plugins/BuilderModes/General/UndoGroup.cs
index 2297b0df86d2d6225b0918e608205005a979fd3d..229cceb97067e6be601a7c8c9cd5dd608816e009 100644
--- a/Source/Core/Editing/UndoGroup.cs
+++ b/Source/Plugins/BuilderModes/General/UndoGroup.cs
@@ -28,13 +28,15 @@ using CodeImp.DoomBuilder.Map;
 
 #endregion
 
-namespace CodeImp.DoomBuilder.Editing
+namespace CodeImp.DoomBuilder.BuilderModes
 {
-	public enum UndoGroup : int
+	public class UndoGroup
 	{
-		None,
-		FloorHeightChange,
-		CeilingHeightChange,
-		SectorBrightnessChange
+		public const int None = 0;
+		public const int FloorHeightChange = 1;
+		public const int CeilingHeightChange = 2;
+		public const int SectorBrightnessChange = 3;
+		public const int TextureOffsetChange = 4;
+		public const int SectorHeightChange = 5;
 	}
 }
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
index b3c2ea9bc7f650dad43bb99b3007854a84a592e5..23a38acae48eb0a6b2da3056135f4e5400e78e72 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
@@ -470,6 +470,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		// Select button pressed
 		public virtual void OnSelectBegin()
 		{
+			mode.LockTarget();
 			dragstartanglexy = General.Map.VisualCamera.AngleXY;
 			dragstartanglez = General.Map.VisualCamera.AngleZ;
 			dragorigin = pickintersect;
@@ -482,11 +483,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		// Select button released
 		public virtual void OnSelectEnd()
 		{
+			mode.UnlockTarget();
+			
 			// Was dragging?
 			if(uvdragging)
 			{
 				// Dragging stops now
-				mode.UnlockTarget();
 				uvdragging = false;
 			}
 			else
@@ -548,11 +550,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					float deltaz = General.Map.VisualCamera.AngleZ - dragstartanglez;
 					if((Math.Abs(deltaxy) + Math.Abs(deltaz)) > DRAG_ANGLE_TOLERANCE)
 					{
+						mode.PreAction(UndoGroup.TextureOffsetChange);
 						mode.CreateUndo("Change texture offsets");
 
 						// Start drag now
 						uvdragging = true;
-						mode.LockTarget();
 						UpdateDragUV();
 					}
 				}
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
index b08e5e203b300bc9f4475c928b3d5733b1c1f243..1081a1229131cbd7d4f001e804e6d65cd139b2fb 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
@@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		
 		// We keep these to determine if we need to make a new undo level
 		private bool selectionchanged;
-		private Actions.Action lastaction;
+		private int lastundogroup;
 		private VisualActionResult actionresult;
 		private bool undocreated;
 
@@ -125,7 +125,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		#region ================== Methods
 		
 		// This is called before an action is performed
-		private void PreAction(bool groupmultiselectionundo)
+		public void PreAction(int multiselectionundogroup)
 		{
 			actionresult = new VisualActionResult();
 			
@@ -148,9 +148,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				// Check if we should make a new undo level
 				// We don't want to do this if this is the same action with the same
 				// selection and the action wants to group the undo levels
-				if((lastaction != General.Actions.Current) || selectionchanged || !groupmultiselectionundo)
+				if((lastundogroup != multiselectionundogroup) || (lastundogroup == UndoGroup.None) ||
+				   (multiselectionundogroup == UndoGroup.None) || selectionchanged)
 				{
 					// We want to create a new undo level, but not just yet
+					lastundogroup = multiselectionundogroup;
 					undocreated = false;
 				}
 				else
@@ -186,7 +188,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				bvs.Ceiling.Changed = false;
 			}
 
-			lastaction = General.Actions.Current;
 			selectionchanged = false;
 			
 			if(singleselection)
@@ -211,16 +212,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		
 		// This creates an undo, when only a single selection is made
 		// When a multi-selection is made, the undo is created by the PreAction function
-		public int CreateUndo(string description, UndoGroup group, int grouptag)
+		public int CreateUndo(string description, int group, int grouptag)
 		{
 			if(!undocreated)
 			{
 				undocreated = true;
 
 				if(singleselection)
-					return General.Map.UndoRedo.CreateUndo(description, group, grouptag);
+					return General.Map.UndoRedo.CreateUndo(description, this, group, grouptag);
 				else
-					return General.Map.UndoRedo.CreateUndo(description, UndoGroup.None, 0);
+					return General.Map.UndoRedo.CreateUndo(description, this, UndoGroup.None, 0);
 			}
 			else
 			{
@@ -489,6 +490,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnMouseMove(e);
 		}
 		
+		// Undo performed
+		public override void OnUndoEnd()
+		{
+			base.OnUndoEnd();
+
+			// We can't group with this undo level anymore
+			lastundogroup = UndoGroup.None;
+		}
+		
 		#endregion
 
 		#region ================== Action Assist
@@ -641,7 +651,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("visualedit", BaseAction = true)]
 		public void BeginEdit()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnEditBegin();
 			PostAction();
 		}
@@ -649,7 +659,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[EndAction("visualedit", BaseAction = true)]
 		public void EndEdit()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnEditEnd();
 			PostAction();
 		}
@@ -657,7 +667,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("raisesector8")]
 		public void RaiseSector8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorHeightChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetHeight(8);
 			PostAction();
 		}
@@ -665,7 +675,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("lowersector8")]
 		public void LowerSector8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorHeightChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetHeight(-8);
 			PostAction();
 		}
@@ -673,7 +683,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("raisesector1")]
 		public void RaiseSector1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorHeightChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetHeight(1);
 			PostAction();
 		}
@@ -681,7 +691,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("lowersector1")]
 		public void LowerSector1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorHeightChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetHeight(-1);
 			PostAction();
 		}
@@ -696,7 +706,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("raisebrightness8")]
 		public void RaiseBrightness8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorBrightnessChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetBrightness(true);
 			PostAction();
 		}
@@ -704,7 +714,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("lowerbrightness8")]
 		public void LowerBrightness8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.SectorBrightnessChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTargetBrightness(false);
 			PostAction();
 		}
@@ -712,7 +722,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureleft")]
 		public void MoveTextureLeft1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(-1, 0);
 			PostAction();
 		}
@@ -720,7 +730,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureright")]
 		public void MoveTextureRight1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(1, 0);
 			PostAction();
 		}
@@ -728,7 +738,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureup")]
 		public void MoveTextureUp1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(0, -1);
 			PostAction();
 		}
@@ -736,7 +746,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetexturedown")]
 		public void MoveTextureDown1()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(0, 1);
 			PostAction();
 		}
@@ -744,7 +754,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureleft8")]
 		public void MoveTextureLeft8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(-8, 0);
 			PostAction();
 		}
@@ -752,7 +762,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureright8")]
 		public void MoveTextureRight8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(8, 0);
 			PostAction();
 		}
@@ -760,7 +770,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetextureup8")]
 		public void MoveTextureUp8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(0, -8);
 			PostAction();
 		}
@@ -768,7 +778,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("movetexturedown8")]
 		public void MoveTextureDown8()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.TextureOffsetChange);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnChangeTextureOffset(0, 8);
 			PostAction();
 		}
@@ -776,7 +786,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("textureselect")]
 		public void TextureSelect()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			renderer.SetCrosshairBusy(true);
 			General.Interface.RedrawDisplay();
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnSelectTexture();
@@ -796,7 +806,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("texturepaste")]
 		public void TexturePaste()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnPasteTexture();
 			PostAction();
 		}
@@ -804,7 +814,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("visualautoalignx")]
 		public void TextureAutoAlignX()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			renderer.SetCrosshairBusy(true);
 			General.Interface.RedrawDisplay();
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnTextureAlign(true, false);
@@ -816,7 +826,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("visualautoaligny")]
 		public void TextureAutoAlignY()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			renderer.SetCrosshairBusy(true);
 			General.Interface.RedrawDisplay();
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnTextureAlign(false, true);
@@ -828,7 +838,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("toggleupperunpegged")]
 		public void ToggleUpperUnpegged()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnToggleUpperUnpegged();
 			PostAction();
 		}
@@ -836,7 +846,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("togglelowerunpegged")]
 		public void ToggleLowerUnpegged()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnToggleLowerUnpegged();
 			PostAction();
 		}
@@ -860,7 +870,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("resettexture")]
 		public void ResetTexture()
 		{
-			PreAction(true);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnResetTextureOffset();
 			PostAction();
 		}
@@ -868,7 +878,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("floodfilltextures")]
 		public void FloodfillTextures()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			if(target.picked != null) (target.picked as IVisualEventReceiver).OnTextureFloodfill();
 			PostAction();
 		}
@@ -884,7 +894,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("texturepasteoffsets")]
 		public void TexturePasteOffsets()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnPasteTextureOffsets();
 			PostAction();
 		}
@@ -900,7 +910,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("pasteproperties")]
 		public void PasteProperties()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnPasteProperties();
 			PostAction();
 		}
@@ -908,7 +918,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("insertitem", BaseAction = true)]
 		public void Insert()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnInsert();
 			PostAction();
 		}
@@ -916,7 +926,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		[BeginAction("deleteitem", BaseAction = true)]
 		public void Delete()
 		{
-			PreAction(false);
+			PreAction(UndoGroup.None);
 			foreach(IVisualEventReceiver i in selectedobjects) i.OnDelete();
 			PostAction();
 		}