diff --git a/src/action/action_move.cpp b/src/action/action_move.cpp
index 1f8b438db..97edd9744 100644
--- a/src/action/action_move.cpp
+++ b/src/action/action_move.cpp
@@ -125,8 +125,6 @@ static int ActionMoveGeneric(Unit* unit, const Animation* anim)
 		y = unit->Y + yd;
 		MoveUnitToXY(unit, x, y);
 
-		MustRedraw |= RedrawMinimap;
-
 		// Remove unit from the current selection
 		if (unit->Selected && !IsMapFieldVisible(ThisPlayer, x, y)) {
 			if (NumSelected == 1) { //  Remove building cursor
diff --git a/src/action/action_train.cpp b/src/action/action_train.cpp
index efae665ad..cd67fcae9 100644
--- a/src/action/action_train.cpp
+++ b/src/action/action_train.cpp
@@ -102,20 +102,18 @@ void HandleActionTrain(Unit* unit)
 	//
 	if (!unit->SubAction) {
 		unit->Data.Train.Ticks = 0;
-		unit->Data.Train.What[0] = unit->Orders[0].Type;
-		unit->Data.Train.Count = 1;
 		unit->SubAction = 1;
 	}
 	unit->Data.Train.Ticks += SpeedTrain;
 	// FIXME: Should count down
 	if (unit->Data.Train.Ticks >=
-		unit->Data.Train.What[0]->Stats[player->Player].Costs[TimeCost]) {
+		unit->Orders[0].Type->Stats[player->Player].Costs[TimeCost]) {
 		//
 		// Check if there are still unit slots.
 		//
 		if (NumUnits >= UnitMax) {
 			unit->Data.Train.Ticks =
-				unit->Data.Train.What[0]->Stats[player->Player].Costs[TimeCost];
+				unit->Orders[0].Type->Stats[player->Player].Costs[TimeCost];
 			unit->Reset = 1;
 			unit->Wait = CYCLES_PER_SECOND / 6;
 			return;
@@ -124,20 +122,20 @@ void HandleActionTrain(Unit* unit)
 		//
 		// Check if enough supply available.
 		//
-		food = PlayerCheckLimits(player, unit->Data.Train.What[0]);
+		food = PlayerCheckLimits(player, unit->Orders[0].Type);
 		if (food < 0) {
 			if (food == -3 && unit->Player->AiEnabled) {
 				AiNeedMoreSupply(unit, unit->Orders[0].Type);
 			}
 
 			unit->Data.Train.Ticks =
-				unit->Data.Train.What[0]->Stats[player->Player].Costs[TimeCost];
+				unit->Orders[0].Type->Stats[player->Player].Costs[TimeCost];
 			unit->Reset = 1;
 			unit->Wait = CYCLES_PER_SECOND / 6;
 			return;
 		}
 
-		nunit = MakeUnit(unit->Data.Train.What[0], player);
+		nunit = MakeUnit(unit->Orders[0].Type, player);
 		nunit->X = unit->X;
 		nunit->Y = unit->Y;
 		type = unit->Type;
@@ -166,16 +164,8 @@ void HandleActionTrain(Unit* unit)
 
 		unit->Reset = unit->Wait = 1;
 
-		if (--unit->Data.Train.Count) {
-			int z;
-			for (z = 0; z < unit->Data.Train.Count; ++z) {
-				unit->Data.Train.What[z] = unit->Data.Train.What[z + 1];
-			}
-			unit->Data.Train.Ticks = 0;
-		} else {
-			unit->Orders[0].Action = UnitActionStill;
-			unit->SubAction = 0;
-		}
+		unit->Orders[0].Action = UnitActionStill;
+		unit->SubAction = 0;
 
 		if (!CanHandleOrder(nunit, &unit->NewOrder)) {
 			DebugPrint("Wrong order for unit\n");
diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index c9a32d48b..e9dc9e267 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -555,7 +555,7 @@ void UnitActions(void)
 		fprintf(logf, "%d %s S%d/%d-%d P%d Refs %d: %X %d,%d %d,%d\n",
 			UnitNumber(unit), unit->Type ? unit->Type->Ident : "unit-killed",
 			unit->State, unit->SubAction,
-			unit->Orders[0].Action,
+			unit->Orders ? unit->Orders[0].Action : -1,
 			unit->Player ? unit->Player->Player : -1, unit->Refs,SyncRandSeed,
 			unit->X, unit->Y, unit->IX, unit->IY);
 
@@ -569,7 +569,7 @@ void UnitActions(void)
 		// Calculate some hash.
 		//
 		SyncHash = (SyncHash << 5) | (SyncHash >> 27);
-		SyncHash ^= unit->Orders[0].Action << 18;
+		SyncHash ^= unit->Orders ? unit->Orders[0].Action << 18 : 0;
 		SyncHash ^= unit->State << 12;
 		SyncHash ^= unit->SubAction << 6;
 		SyncHash ^= unit->Refs << 3;
diff --git a/src/action/command.cpp b/src/action/command.cpp
index 900a6e950..8fba311a6 100644
--- a/src/action/command.cpp
+++ b/src/action/command.cpp
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "stratagus.h"
 #include "unittype.h"
@@ -96,21 +97,57 @@ static void ReleaseOrders(Unit* unit)
 */
 static Order* GetNextOrder(Unit* unit, int flush)
 {
+	Order *OldOrders;
 	if (flush) {
 		// empty command queue
 		ReleaseOrders(unit);
-	} else if (unit->OrderCount == MAX_ORDERS) {
-		// FIXME: johns: wrong place for an error message.
-		// FIXME: johns: should be checked by AI or the user interface
-		// NOTE: But must still be checked here.
-		NotifyPlayer(unit->Player, NotifyYellow, unit->X, unit->Y,
-			"Unit order list is full");
-		return NULL;
+	} else if (unit->OrderCount == unit->TotalOrders) {
+		// Expand Order Queue if filled
+		OldOrders = unit->Orders;
+		unit->Orders = realloc(unit->Orders, sizeof(Order) * unit->TotalOrders * 2);
+		// Realloc failed, fail gracefully
+		if (!unit->Orders) {
+			unit->Orders = OldOrders;
+			NotifyPlayer(unit->Player, NotifyYellow, unit->X, unit->Y,
+				"Unable to add order to list");
+			return NULL;
+		}
+		memset(&unit->Orders[unit->TotalOrders], 0, sizeof(Order) * unit->TotalOrders);
+		unit->TotalOrders *= 2;
 	}
 
 	return &unit->Orders[(int)unit->OrderCount++];
 }
 
+/*
+**  Remove an order from the list of orders pending
+**
+**  @param unit   pointer to unit
+**  @param order  number of the order to remove
+*/
+static void RemoveOrder(Unit* unit, int order)
+{
+	int i;
+	
+	i = order;
+	while(i < unit->OrderCount - 1) {
+		unit->Orders[i] = unit->Orders[i + 1];
+		++i;
+	}
+
+	if (unit->OrderCount > 1) {
+		--unit->OrderCount;
+	} else {
+		unit->Orders[i].Action = UnitActionStill;
+		unit->Orders[i].X = unit->Orders[i].Y = -1;
+		unit->SubAction = 0;
+		unit->Orders[i].Type = NULL;
+		unit->Orders[i].Arg1 = NULL;
+	}
+
+	return;
+}
+
 /**
 **  Clear the saved action.
 **
@@ -839,6 +876,8 @@ void CommandReturnGoods(Unit* unit, Unit* goal, int flush)
 void CommandTrainUnit(Unit* unit, UnitType* type,
 	int flush __attribute__((unused)))
 {
+	Order* order;
+
 	//
 	// Check if unit is still valid? (NETWORK!)
 	//
@@ -855,32 +894,19 @@ void CommandTrainUnit(Unit* unit, UnitType* type,
 		//
 		// Not already training?
 		//
-		if (unit->Orders[0].Action != UnitActionTrain) {
-			if (unit->OrderCount == 2 && unit->Orders[1].Action == UnitActionTrain) {
-				DebugPrint("FIXME: not supported. Unit queue full!\n");
-				return;
-			} else {
-				ReleaseOrders(unit);
-				unit->Orders[1].Action = UnitActionTrain;
-			}
-			Assert(unit->OrderCount == 1 && unit->OrderFlush == 1);
-
-			unit->OrderCount = 2;
-			unit->Orders[1].Type = type;
-			unit->Orders[1].X = unit->Orders[1].Y = -1;
-			unit->Orders[1].Goal = NoUnitP;
-			unit->Orders[1].Arg1 = NULL;
-		} else {
-			//
-			// Training slots are all already full. (NETWORK!)
-			//
-			if (!EnableTrainingQueue || unit->Data.Train.Count >= MAX_UNIT_TRAIN) {
-				DebugPrint("Unit queue full!\n");
-				return;
-			}
-
-			unit->Data.Train.What[unit->Data.Train.Count++] = type;
+		if (!EnableTrainingQueue && unit->Orders[0].Action == UnitActionTrain) {
+			DebugPrint("Unit queue full!\n");
+			return;
 		}
+		if (!(order = GetNextOrder(unit, 0))) {
+			return;
+		}
+
+		order->Action = UnitActionTrain;
+		order->Type = type;
+		order->X = order->Y = -1;
+		order->Goal = NoUnitP;
+		order->Arg1 = NULL;
 		// FIXME: if you give quick an other order, the resources are lost!
 		PlayerSubUnitType(unit->Player, type);
 	}
@@ -896,8 +922,6 @@ void CommandTrainUnit(Unit* unit, UnitType* type,
 */
 void CommandCancelTraining(Unit* unit, int slot, const UnitType* type)
 {
-	int i;
-	int n;
 
 	DebugPrint("Cancel %d type: %s\n" _C_ slot _C_
 		type ? type->Ident : "-any-");
@@ -907,42 +931,45 @@ void CommandCancelTraining(Unit* unit, int slot, const UnitType* type)
 	//
 	// Check if unit is still training 'slot'? (NETWORK!)
 	//
-	if (unit->Orders[0].Action == UnitActionTrain) {
-		n = unit->Data.Train.Count;
-		Assert(n >= 1);
-		if (slot == -1) { // default last slot!
-			slot += n;
+
+	if (slot == -1) {
+		// Cancel All training
+		while(unit->Orders[0].Action == UnitActionTrain) {
+			PlayerAddCostsFactor(unit->Player,
+				unit->Orders[0].Type->Stats[unit->Player->Player].Costs,
+				CancelTrainingCostsFactor);
+			RemoveOrder(unit, 0);
+		}	
+		unit->Data.Train.Ticks = 0;
+		unit->Wait = unit->Reset = 1; // immediately start next training
+		if (unit->Player == ThisPlayer && unit->Selected) {
+			SelectedUnitChanged();
 		}
-		//
-		// Check if slot and unit-type is still trained? (NETWORK!)
-		//
-		if (slot >= n || (type && unit->Data.Train.What[slot] != type)) {
-			// FIXME: we can look if this is now in an earlier slot.
+	} else if (unit->OrderCount < slot) {
+		// Order has moved
+		return;
+	} else if (unit->Orders[slot].Action != UnitActionTrain) {
+		// Order has moved, we are not training
+		return;
+	} else if (unit->Orders[slot].Action == UnitActionTrain) {
+		// Still training this order, same unit?
+		if (type && unit->Orders[slot].Type != type) {
+			// Different unit being trained
 			return;
 		}
 
 		DebugPrint("Cancel training\n");
 
 		PlayerAddCostsFactor(unit->Player,
-			unit->Data.Train.What[slot]->Stats[unit->Player->Player].Costs,
+			unit->Orders[slot].Type->Stats[unit->Player->Player].Costs,
 			CancelTrainingCostsFactor);
 
-		if (--n) {
-			// Copy the other slots down
-			for (i = slot; i < n; ++i) {
-				unit->Data.Train.What[i] = unit->Data.Train.What[i + 1];
-			}
-			if (!slot) { // Canceled in work slot
-				unit->Data.Train.Ticks = 0;
-				unit->Wait = unit->Reset = 1; // immediately start next training
-			}
-			unit->Data.Train.Count = n;
-		} else {
-			DebugPrint("Last slot\n");
-			unit->Orders[0].Action = UnitActionStill;
-			unit->SubAction = 0;
-			unit->Wait = unit->Reset = 1;
+	
+		if (!slot) { // Canceled in work slot
+			unit->Data.Train.Ticks = 0;
+			unit->Wait = unit->Reset = 1; // immediately start next training
 		}
+		RemoveOrder(unit, slot);
 
 		//
 		// Update interface.
diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp
index 32e597280..8fe361631 100644
--- a/src/ai/ai.cpp
+++ b/src/ai/ai.cpp
@@ -1513,7 +1513,6 @@ static int FindTransporterOnZone(int waterzone, ZoneSet* destzones,
 		// If transporter is moving, check if it is moving on our coast
 		if (!unitok &&
 				unit->OrderCount + (unit->OrderFlush ? 1 : 0) >= 2 &&
-				unit->OrderCount < MAX_ORDERS - 1 &&
 				unit->Orders[unit->OrderFlush ? 1 : 0].Action == UnitActionFollow &&
 				unit->Orders[unit->OrderCount - 1].Action == UnitActionUnload &&
 				unit->BoardCount + unit->OrderCount - (unit->OrderFlush ? 1 : 0) <= unit->Type->MaxOnBoard) {
diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp
index a51451439..e5881364e 100644
--- a/src/editor/editloop.cpp
+++ b/src/editor/editloop.cpp
@@ -77,10 +77,10 @@ static int IconWidth;                       /// Icon width in panels
 static int IconHeight;                      /// Icon height in panels
 
 
-char EditorRunning;    /// True editor is running
 char EditorMapLoaded;  /// Map loaded in editor
 
-EditorStateType EditorState;  /// Current editor state.
+EditorStateType EditorState;                /// Current editor state.
+EditorRunningType EditorRunning;  /// Running State of editor.
 
 static char TileToolRandom;      /// Tile tool draws random
 static char TileToolDecoration;  /// Tile tool draws with decorations
@@ -201,7 +201,6 @@ void EditTile(int x, int y, int tile)
 
 	UpdateMinimapSeenXY(x, y);
 	UpdateMinimapXY(x, y);
-	MustRedraw |= RedrawMinimap;
 
 	EditorTileChanged(x, y);
 }
@@ -1168,7 +1167,6 @@ static void EditorCallbackButtonDown(unsigned button __attribute__ ((unused)))
 			if (TheMap.Info->PlayerType[CursorPlayer] != PlayerNobody) {
 				SelectedPlayer = CursorPlayer;
 				ThisPlayer = Players + SelectedPlayer;
-				MustRedraw |= RedrawMinimap;
 			}
 			return;
 		}
@@ -2025,7 +2023,7 @@ void EditorMainLoop(void)
 
 	while (1) {
 		EditorMapLoaded = 0;
-		EditorRunning = 1;
+		EditorRunning = EditorEditing;
 
 		CreateEditor();
 
diff --git a/src/include/editor.h b/src/include/editor.h
index 153c7d4ec..7295f86f5 100644
--- a/src/include/editor.h
+++ b/src/include/editor.h
@@ -38,7 +38,15 @@
 ----------------------------------------------------------------------------*/
 
 	/// Editor is running
-extern char EditorRunning;
+typedef enum _editor_running_state_ {
+	EditorNotRunning = 0,   ///< Not Running
+	EditorStarted = 1,      ///< Editor Enabled at all
+	EditorCommandLine = 2,  ///< Called from Command Line
+	EditorEditing = 4       ///< Editor is fully running
+} EditorRunningType;
+
+extern EditorRunningType EditorRunning;
+
 	/// Map loaded in editor
 extern char EditorMapLoaded;
 	/// Current editor state type.
diff --git a/src/include/stratagus.h b/src/include/stratagus.h
index 0462fde78..0698508f7 100644
--- a/src/include/stratagus.h
+++ b/src/include/stratagus.h
@@ -248,6 +248,7 @@ extern char NameLine[];
 	/// Game cycles per second to simulate (original 30-40)
 #define CYCLES_PER_SECOND  30  // 1/30s 0.33ms
 
+#define DEFAULT_START_ORDERS 4  // The number of Orders allocated on unit creation
 	/// Must redraw flags
 enum _must_redraw_flags_ {
 	RedrawNothing   = 1 << 0,           ///< Nothing to do
@@ -275,21 +276,6 @@ enum _must_redraw_flags_ {
 	RedrawEverything    = -1,           ///< Must redraw everything
 };
 
-	/// Must redraw all maps
-#define RedrawMaps        (RedrawMinimap | RedrawMap)
-	/// Must redraw all cursors
-#define RedrawCursors     (RedrawMinimapCursor | RedrawCursor)
-	/// Must redraw all panels
-#define RedrawPanels      (RedrawInfoPanel | RedrawButtonPanel)
-	/// Must redraw after color cycle
-#define RedrawColorCycle  (RedrawMap | RedrawInfoPanel | RedrawButtonPanel | RedrawResources)
-
-	/// Invalidated redraw flags
-extern int MustRedraw;
-
-	/// Enable redraw flags
-extern int EnableRedraw;
-
 /*----------------------------------------------------------------------------
 --  clone.c
 ----------------------------------------------------------------------------*/
diff --git a/src/include/unit.h b/src/include/unit.h
index 795ef657d..9cb37f6cc 100644
--- a/src/include/unit.h
+++ b/src/include/unit.h
@@ -331,18 +331,23 @@
 **  Unit::OrderCount
 **
 **  The number of the orders unit to process. An unit has atleast
-**  one order. Unit::OrderCount should be a number between 1 and
-**  ::MAX_ORDERS. The orders are in Unit::Orders[].
+**  one order. Unit::OrderCount should be a number at least 1.
+**  The orders are in Unit::Orders[].
 **
 **  Unit::OrderFlush
 **
 **  A flag, which tells the unit to stop with the current order
 **  and immediately start with the next order.
 **
+**  Unit::TotalOrders
+**
+**  The number of Orders allocated for this unit to use.
+**  Default is 4, but is dynamically updated if more orders are
+**  given.
+**
 **  Unit::Orders
 **
 **  Contains all orders of the unit. Slot 0 is always used.
-**  Up to ::MAX_ORDERS can be stored.
 **
 **  Unit::SavedOrder
 **
@@ -596,10 +601,10 @@ struct _unit_ {
 	unsigned Rs : 8;
 	unsigned char CurrentResource;
 
-#define MAX_ORDERS 16           ///< How many outstanding orders?
 	char OrderCount;            ///< how many orders in queue
 	char OrderFlush;            ///< cancel current order, take next
-	Order Orders[MAX_ORDERS];   ///< orders to process
+	int  TotalOrders;           ///< Total Number of orders available
+	Order* Orders;              ///< orders to process
 	Order SavedOrder;           ///< order to continue after current
 	Order NewOrder;             ///< order for new trained units
 	char* AutoCastSpell;        ///< spells to auto cast
@@ -632,10 +637,6 @@ struct _unit_ {
 	} UpgradeTo; ///< Upgrade to action
 	struct _order_train_ {
 		int Ticks;                      ///< Ticks to complete
-		int Count;                      ///< Units in training queue
-		// TODO: vladi: later we should train more units or automatic
-#define MAX_UNIT_TRAIN 6 ///< max number of units in queue
-		UnitType* What[MAX_UNIT_TRAIN]; ///< Unit trained
 	} Train; ///< Train units action
 	} Data; ///< Storage room for different commands
 
@@ -729,6 +730,9 @@ extern int    NumTeamSelected[PlayerMax];  ///< Number of Units a team member ha
 extern Unit* ReleasedHead;                 ///< Head of the released unit list.
 extern Unit* ReleasedTail;                 ///< Tail of the released unit list.
 
+extern Order* ReleasedOrderHead;           ///< Head of the released orders list.
+extern Order* ReleasedOrderTail;           ///< Tail of the released unit list.
+
 /*----------------------------------------------------------------------------
 -- Functions
 ----------------------------------------------------------------------------*/
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 7dfa0395a..a1d25711e 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -207,8 +207,6 @@ void ViewportSetViewpoint(Viewport* vp, int x, int y, int offsetx, int offsety)
 	vp->OffsetY = y % TileSizeY;
 	vp->MapWidth = ((vp->EndX - vp->X) + vp->OffsetX - 1) / TileSizeX + 1;
 	vp->MapHeight = ((vp->EndY - vp->Y) + vp->OffsetY - 1) / TileSizeY + 1;
-
-	MustRedraw |= RedrawMinimap | RedrawMinimapCursor;
 }
 
 /**
diff --git a/src/map/map_rock.cpp b/src/map/map_rock.cpp
index aa4a2187c..6dede6f02 100644
--- a/src/map/map_rock.cpp
+++ b/src/map/map_rock.cpp
@@ -178,7 +178,6 @@ void MapFixSeenRockTile(int x, int y)
 	// FIXME: can this only happen if seen?
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 }
 
@@ -317,7 +316,6 @@ void MapFixRockTile(int x, int y)
 		if (IsMapFieldVisible(ThisPlayer, x, y)) {
 			UpdateMinimapSeenXY(x, y);
 			MapMarkSeenTile(x, y);
-			MustRedraw |= RedrawMinimap;
 		}
 	}
 }
@@ -344,7 +342,6 @@ void MapRemoveRock(unsigned x, unsigned y)
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
 		MapMarkSeenTile(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 #ifdef MAP_REGIONS
 	MapSplitterTilesCleared(x, y, x, y);
diff --git a/src/map/map_wall.cpp b/src/map/map_wall.cpp
index af194631d..d2585767e 100644
--- a/src/map/map_wall.cpp
+++ b/src/map/map_wall.cpp
@@ -165,7 +165,6 @@ void MapFixSeenWallTile(int x, int y)
 		// FIXME: can this only happen if seen?
 		if (IsMapFieldVisible(ThisPlayer, x, y)) {
 			UpdateMinimapSeenXY(x, y);
-			MustRedraw |= RedrawMinimap;
 		}
 	}
 }
@@ -265,7 +264,6 @@ void MapFixWallTile(int x, int y)
 		if (IsMapFieldVisible(ThisPlayer, x, y)) {
 			UpdateMinimapSeenXY(x, y);
 			MapMarkSeenTile(x, y);
-			MustRedraw |= RedrawMinimap;
 		}
 	}
 }
@@ -305,7 +303,6 @@ void MapRemoveWall(unsigned x, unsigned y)
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
 		MapMarkSeenTile(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 #ifdef MAP_REGIONS
 	MapSplitterTilesCleared(x, y, x, y);
@@ -347,7 +344,6 @@ void MapSetWall(unsigned x, unsigned y, int humanwall)
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
 		MapMarkSeenTile(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 #ifdef MAP_REGIONS
 	MapSplitterTilesOccuped(x, y, x, y);
diff --git a/src/map/map_wood.cpp b/src/map/map_wood.cpp
index 01b4e57f7..65df1de80 100644
--- a/src/map/map_wood.cpp
+++ b/src/map/map_wood.cpp
@@ -176,7 +176,6 @@ void MapFixSeenWoodTile(int x, int y)
 	// FIXME: can this only happen if seen?
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 }
 
@@ -313,7 +312,6 @@ void MapFixWoodTile(int x, int y)
 		if (IsMapFieldVisible(ThisPlayer, x, y)) {
 			UpdateMinimapSeenXY(x, y);
 			MapMarkSeenTile(x, y);
-			MustRedraw |= RedrawMinimap;
 		}
 	}
 }
@@ -341,7 +339,6 @@ void MapRemoveWood(unsigned x, unsigned y)
 	if (IsMapFieldVisible(ThisPlayer, x, y)) {
 		UpdateMinimapSeenXY(x, y);
 		MapMarkSeenTile(x, y);
-		MustRedraw |= RedrawMinimap;
 	}
 #ifdef MAP_REGIONS
 	MapSplitterTilesCleared(x, y, x, y);
diff --git a/src/pathfinder/astar.cpp b/src/pathfinder/astar.cpp
index 802edc551..6ce0b276f 100644
--- a/src/pathfinder/astar.cpp
+++ b/src/pathfinder/astar.cpp
@@ -729,6 +729,10 @@ int AStarFindPath(Unit* unit, int gx, int gy, int gw, int gh, int minrange, int
 
 	// let's clean up the matrix now
 	AStarCleanUp(num_in_close);
+	if ((TheMap.Width*TheMap.Height) - counter > 500) {
+		DebugPrint("%s:%d Visited %d tiles\n" _C_ unit->Type->Name _C_ UnitNumber(unit) 
+			_C_ (TheMap.Width*TheMap.Height) - counter);
+	}
 	return path_length;
 }
 
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index c81dd8090..f82a2a540 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -67,6 +67,7 @@
 #include "commands.h"
 #include "cdaudio.h"
 #include "pathfinder.h"
+#include "editor.h"
 
 #ifdef USE_SDLCD
 #include "SDL.h"
@@ -336,7 +337,7 @@ void DrawMapArea(void)
 */
 void UpdateDisplay(void)
 {
-	if (EnableRedraw != RedrawMenu) {
+	if (GameRunning || EditorRunning == EditorEditing) {
 		int i;
 
 		DrawMapArea();
diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp
index 4ab71eba2..43f2d01fd 100644
--- a/src/stratagus/stratagus.cpp
+++ b/src/stratagus/stratagus.cpp
@@ -257,10 +257,6 @@ int SpeedResearch = 1;               ///< speed factor for researching
 ==  DISPLAY
 ============================================================================*/
 
-// FIXME: not the correct place
-int MustRedraw = RedrawEverything;   ///< Redraw flags
-int EnableRedraw = RedrawEverything; ///< Enable flags
-
 unsigned long GameCycle;             ///< Game simulation cycle counter
 unsigned long FastForwardCycle;      ///< Cycle to fastforward to in a replay
 
@@ -664,8 +660,6 @@ void MenuLoop(char* filename, WorldMap* map)
 				PlayMusic(MenuMusic);
 			}
 
-			EnableRedraw = RedrawMenu;
-
 			GuiGameStarted = 0;
 			while (GuiGameStarted == 0) {
 				int old_video_sync;
@@ -673,7 +667,7 @@ void MenuLoop(char* filename, WorldMap* map)
 				old_video_sync = VideoSyncSpeed;
 				VideoSyncSpeed = 100;
 				SetVideoSync();
-				if (EditorRunning == 2) {
+				if (EditorRunning == EditorCommandLine) {
 					SetupEditor();
 				}
 				if (EditorRunning) {
@@ -685,7 +679,6 @@ void MenuLoop(char* filename, WorldMap* map)
 				SetVideoSync();
 			}
 
-			EnableRedraw = RedrawEverything;
 			DebugPrint("Menu start: NetPlayers %d\n" _C_ NetPlayers);
 			filename = CurrentMapPath;
 		} else {
@@ -983,7 +976,7 @@ int main(int argc, char** argv)
 				}
 				continue;
 			case 'e':
-				EditorRunning = 2;
+				EditorRunning = EditorCommandLine;
 				continue;
 			case 'E':
 				EditorStartFile = optarg;
diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp
index d03172ac7..efccd6173 100644
--- a/src/ui/botpanel.cpp
+++ b/src/ui/botpanel.cpp
@@ -811,8 +811,7 @@ void DoButtonButtonClicked(int button)
 			break;
 
 		case ButtonCancelTrain:
-			Assert(Selected[0]->Orders[0].Action == UnitActionTrain &&
-				Selected[0]->Data.Train.Count);
+			Assert(Selected[0]->Orders[0].Action == UnitActionTrain);
 			SendCommandCancelTraining(Selected[0], -1, NULL);
 			ClearStatusLine();
 			ClearCosts();
@@ -848,8 +847,7 @@ void DoButtonButtonClicked(int button)
 			// FIXME: training queue full check is not correct for network.
 			// FIXME: this can be correct written, with a little more code.
 			if (Selected[0]->Orders[0].Action == UnitActionTrain &&
-					(Selected[0]->Data.Train.Count == MAX_UNIT_TRAIN ||
-						!EnableTrainingQueue)) {
+					!EnableTrainingQueue) {
 				NotifyPlayer(Selected[0]->Player, NotifyYellow, Selected[0]->X,
 					Selected[0]->Y, "Unit training queue is full");
 			} else if (PlayerCheckLimits(Selected[0]->Player, type) >= 0 &&
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 7d248e29c..be79ff7ef 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -461,8 +461,6 @@ static void UiToggleBigMap(void)
 
 		SetViewportMode(TheUI.ViewportMode);
 
-		EnableRedraw = RedrawMap | RedrawCursor | RedrawMessage | RedrawMenu |
-			RedrawTimer | RedrawAll;
 		SetStatusLine("Big map enabled");
 	} else {
 		TheUI.MapArea.X = mapx;
@@ -472,7 +470,6 @@ static void UiToggleBigMap(void)
 
 		SetViewportMode(TheUI.ViewportMode);
 
-		EnableRedraw = RedrawEverything;
 		SetStatusLine("Returning to old map");
 	}
 }
@@ -559,7 +556,6 @@ static void UiToggleTerrain(void)
 	} else {
 		SetStatusLine("Terrain hidden.");
 	}
-	MustRedraw |= RedrawMinimap;
 }
 
 /**
diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp
index 48b7ccc0a..c97cbee79 100644
--- a/src/ui/mainscr.cpp
+++ b/src/ui/mainscr.cpp
@@ -375,20 +375,20 @@ static void DrawUnitInfo(const Unit* unit)
 		//  Building training units.
 		//
 		if (unit->Orders[0].Action == UnitActionTrain) {
-			if (unit->Data.Train.Count == 1) {
+			if (unit->Orders[1].Action != UnitActionTrain) {
 				if (TheUI.SingleTrainingText) {
 					VideoDrawText(TheUI.SingleTrainingTextX, TheUI.SingleTrainingTextY,
 						TheUI.SingleTrainingFont, TheUI.SingleTrainingText);
 				}
 				if (TheUI.SingleTrainingButton) {
-					DrawUnitIcon(unit->Player, unit->Data.Train.What[0]->Icon.Icon,
+					DrawUnitIcon(unit->Player, unit->Orders[0].Type->Icon.Icon,
 						(ButtonAreaUnderCursor == ButtonAreaTraining &&
 							ButtonUnderCursor == 0) ?
 							(IconActive | (MouseButtons & LeftButton)) : 0,
 						TheUI.SingleTrainingButton->X, TheUI.SingleTrainingButton->Y);
 				}
 
-				UiDrawCompletedBar(unit->Data.Train.What[0]->Stats[
+				UiDrawCompletedBar(unit->Orders[0].Type->Stats[
 					unit->Player->Player].Costs[TimeCost],
 					unit->Data.Train.Ticks);
 			} else {
@@ -397,17 +397,19 @@ static void DrawUnitInfo(const Unit* unit)
 						TheUI.TrainingFont, TheUI.TrainingText);
 				}
 				if (TheUI.TrainingButtons) {
-					for (i = 0; i < unit->Data.Train.Count &&
+					for (i = 0; i < unit->OrderCount &&
 							i < TheUI.NumTrainingButtons; ++i) {
-						DrawUnitIcon(unit->Player, unit->Data.Train.What[i]->Icon.Icon,
-							(ButtonAreaUnderCursor == ButtonAreaTraining &&
-								ButtonUnderCursor == i) ?
-								(IconActive | (MouseButtons & LeftButton)) : 0,
-							TheUI.TrainingButtons[i].X, TheUI.TrainingButtons[i].Y);
+						if (unit->Orders[i].Action == UnitActionTrain) {
+							DrawUnitIcon(unit->Player, unit->Orders[i].Type->Icon.Icon,
+								(ButtonAreaUnderCursor == ButtonAreaTraining &&
+									ButtonUnderCursor == i) ?
+									(IconActive | (MouseButtons & LeftButton)) : 0,
+								TheUI.TrainingButtons[i].X, TheUI.TrainingButtons[i].Y);
+						}
 					}
 				}
 
-				UiDrawCompletedBar(unit->Data.Train.What[0]->Stats[
+				UiDrawCompletedBar(unit->Orders[0].Type->Stats[
 					unit->Player->Player].Costs[TimeCost],
 					unit->Data.Train.Ticks);
 			}
diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp
index 3a56d6b6f..c388a0701 100644
--- a/src/ui/menus.cpp
+++ b/src/ui/menus.cpp
@@ -1837,7 +1837,6 @@ static void SetFogOfWar(Menuitem *mi __attribute__((unused)))
 		UpdateFogOfWarChange();
 		CommandLog("input", NoUnitP, FlushCommands, -1, -1, NoUnitP, "fow on", -1);
 	}
-	MustRedraw &= ~RedrawMinimap;
 }
 
 /**
@@ -4718,7 +4717,7 @@ static void StartEditor(void)
 {
 	SetupEditor();
 
-	EditorRunning = 1;
+	EditorRunning = EditorStarted;
 	EndMenu();
 }
 
@@ -4763,7 +4762,7 @@ void SetupEditor(void)
 static void EditorSelectCancel(void)
 {
 	QuitToMenu = 1;
-	EditorRunning = 0;
+	EditorRunning = EditorNotRunning;
 	EndMenu();
 }
 
@@ -5349,7 +5348,7 @@ void EditorLoadMenu(void)
 	}
 
 	EditorMapLoaded = 1;
-	EditorRunning = 0;
+	EditorRunning = EditorNotRunning;
 	EndMenu();
 }
 
@@ -6193,7 +6192,7 @@ static void EditorSaveConfirmCancel(void)
 static void EditorQuitToMenu(void)
 {
 	QuitToMenu = 1;
-	EditorRunning = 0;
+	EditorRunning = EditorNotRunning;
 	EndMenu();
 }
 
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index 75475d855..32978d53f 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -445,7 +445,7 @@ static void HandleMouseOn(int x, int y)
 	}
 	if (NumSelected == 1 && Selected[0]->Type->Building && !BigMapMode) {
 		if (Selected[0]->Orders[0].Action == UnitActionTrain) {
-			if (Selected[0]->Data.Train.Count == 1) {
+			if (Selected[0]->OrderCount == 1) {
 				if (TheUI.SingleTrainingButton &&
 						x >= TheUI.SingleTrainingButton->X &&
 						x < TheUI.SingleTrainingButton->X + TheUI.SingleTrainingButton->Width + 7 &&
@@ -457,10 +457,10 @@ static void HandleMouseOn(int x, int y)
 					return;
 				}
 			} else {
-				i = (TheUI.NumTrainingButtons < Selected[0]->Data.Train.Count) ?
-					TheUI.NumTrainingButtons : Selected[0]->Data.Train.Count;
-				for (--i; i >= 0; --i) {
-					if (x >= TheUI.TrainingButtons[i].X &&
+				for (i = 0; i < Selected[0]->OrderCount &&
+					i < TheUI.NumTrainingButtons; ++i) {
+					if (Selected[0]->Orders[i].Action == UnitActionTrain &&
+							x >= TheUI.TrainingButtons[i].X &&
 							x < TheUI.TrainingButtons[i].X + TheUI.TrainingButtons[i].Width + 7 &&
 							y >= TheUI.TrainingButtons[i].Y &&
 							y < TheUI.TrainingButtons[i].Y + TheUI.TrainingButtons[i].Height + 7) {
@@ -1482,7 +1482,6 @@ void UIHandleButtonDown(unsigned button)
 			if (NumSelected && Selected[0]->Player == ThisPlayer &&
 					CursorState == CursorStatePoint) {
 				CursorState = CursorStatePieMenu;
-				MustRedraw |= RedrawCursor;
 			}
 		} else if (MouseButtons & LeftButton) { // enter select mode
 			CursorStartX = CursorX;
@@ -1587,13 +1586,14 @@ void UIHandleButtonDown(unsigned button)
 			} else if (ButtonAreaUnderCursor == ButtonAreaTraining) {
 				if (!GameObserve && !GamePaused &&
 					PlayersTeamed(ThisPlayer->Player, Selected[0]->Player->Player)) {
-					if (ButtonUnderCursor < Selected[0]->Data.Train.Count) {
+					if (ButtonUnderCursor < Selected[0]->OrderCount &&
+						Selected[0]->Orders[ButtonUnderCursor].Action == UnitActionTrain) {
 						DebugPrint("Cancel slot %d %s\n" _C_
 							ButtonUnderCursor _C_
-							Selected[0]->Data.Train.What[ButtonUnderCursor]->Ident);
+							Selected[0]->Orders[ButtonUnderCursor].Type->Ident);
 						SendCommandCancelTraining(Selected[0],
 							ButtonUnderCursor,
-							Selected[0]->Data.Train.What[ButtonUnderCursor]);
+							Selected[0]->Orders[ButtonUnderCursor].Type);
 					}
 				}
 			//
diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp
index bc8fa1792..cbdcd3dcb 100644
--- a/src/unit/script_unit.cpp
+++ b/src/unit/script_unit.cpp
@@ -348,12 +348,9 @@ void CclParseOrder(lua_State* l, Order* order)
 */
 static void CclParseOrders(lua_State* l, Unit* unit)
 {
-	int args;
 	int j;
 
-	args = luaL_getn(l, -1);
-	Assert(args == MAX_ORDERS);
-	for (j = 0; j < args; ++j) {
+	for (j = 0; j < unit->TotalOrders; ++j) {
 		lua_rawgeti(l, -1, j + 1);
 		CclParseOrder(l, &unit->Orders[j]);
 		lua_pop(l, 1);
@@ -514,7 +511,6 @@ static void CclParseUpgradeTo(lua_State* l, Unit* unit)
 static void CclParseTrain(lua_State* l, Unit* unit)
 {
 	const char* value;
-	int i;
 	int args;
 	int j;
 
@@ -531,30 +527,6 @@ static void CclParseTrain(lua_State* l, Unit* unit)
 			lua_rawgeti(l, -1, j + 1);
 			unit->Data.Train.Ticks = LuaToNumber(l, -1);
 			lua_pop(l, 1);
-		} else if (!strcmp(value, "count")) {
-			lua_rawgeti(l, -1, j + 1);
-			unit->Data.Train.Count = LuaToNumber(l, -1);
-			lua_pop(l, 1);
-		} else if (!strcmp(value, "queue")) {
-			int subargs;
-			int k;
-
-			lua_rawgeti(l, -1, j + 1);
-			if (!lua_istable(l, -1)) {
-				LuaError(l, "incorrect argument");
-			}
-			subargs = luaL_getn(l, -1);
-			for (i = 0, k = 0; i < MAX_UNIT_TRAIN && k < subargs; ++i, ++k) {
-				lua_rawgeti(l, -1, k + 1);
-				value = LuaToString(l, -1);
-				lua_pop(l, 1);
-				if (!strcmp(value, "unit-none")) {
-					unit->Data.Train.What[i] = NULL;
-				} else {
-					unit->Data.Train.What[i] = UnitTypeByIdent(value);
-				}
-			}
-			lua_pop(l, 1);
 		}
 	}
 }
@@ -859,6 +831,11 @@ static int CclUnit(lua_State* l)
 			unit->OrderCount = LuaToNumber(l, j + 1);
 		} else if (!strcmp(value, "order-flush")) {
 			unit->OrderFlush = LuaToNumber(l, j + 1);
+		} else if (!strcmp(value, "order-total")) {
+			unit->TotalOrders = LuaToNumber(l, j + 1);
+			free(unit->Orders);
+			// Allocate the space for orders
+			unit->Orders = calloc(unit->TotalOrders, sizeof(Order));
 		} else if (!strcmp(value, "orders")) {
 			int hp;
 
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index 54514d33c..7fcd5e759 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -74,6 +74,9 @@ Unit** UnitSlotFree;                      ///< First free unit slot
 Unit* ReleasedHead;                       ///< List of released units.
 Unit* ReleasedTail;                       ///< List tail of released units.
 
+Order* ReleasedOrderHead;                 ///< List of released Orders.
+Order* ReleasedOrderTail;                 ///< List tail of released orders.
+
 Unit* Units[MAX_UNIT_SLOTS];              ///< Array of used slots
 int NumUnits;                             ///< Number of slots used
 
@@ -225,6 +228,18 @@ void ReleaseUnit(Unit* unit)
 	unit->Refs = GameCycle + (NetworkMaxLag << 1); // could be reuse after this time
 	unit->Type = 0;  // for debugging.
 	free(unit->CacheLinks);
+
+	if (ReleasedOrderHead) {
+		ReleasedOrderTail->Arg1 = unit->Orders;
+		ReleasedOrderTail = unit->Orders;
+		unit->Orders->Arg1 = NULL;
+	} else {
+		ReleasedOrderHead = ReleasedOrderTail = unit->Orders;
+		unit->Orders->Arg1 = NULL;
+	}
+	unit->Orders->X = GameCycle + (NetworkMaxLag << 1); // could be reuse after this time
+	unit->Orders->Y = unit->TotalOrders; // store order count for when reused
+	unit->Orders = NULL;
 }
 
 /**
@@ -339,6 +354,18 @@ void InitUnit(Unit* unit, UnitType* type)
 
 	unit->Rs = MyRand() % 100; // used for fancy buildings and others
 
+	// Init Orders and Default to Still/None
+	if (ReleasedOrderHead && (unsigned)ReleasedOrderHead->X < GameCycle) {
+		unit->Orders = ReleasedOrderHead;
+		unit->TotalOrders = ReleasedOrderHead->Y;
+		ReleasedOrderHead = (Order*)ReleasedOrderHead->Arg1;
+	} else {
+		// No Available Orders in Memory, create new ones
+		unit->TotalOrders = DEFAULT_START_ORDERS;
+		unit->Orders = calloc(unit->TotalOrders, sizeof(Order));
+	}
+
+
 	unit->OrderCount = 1; // No orders
 	unit->Orders[0].Action = UnitActionStill;
 	unit->Orders[0].X = unit->Orders[0].Y = -1;
@@ -596,7 +623,6 @@ static void MarkUnitFieldFlags(const Unit* unit)
 		MapSplitterTilesOccuped(x, y, x + type->TileWidth - 1, y + type->TileHeight - 1);
 	}
 #endif
-
 }
 
 /**
@@ -761,7 +787,6 @@ void PlaceUnit(Unit* unit, int x, int y)
 	// Vision
 	MapMarkUnitSight(unit);
 
-	MustRedraw |= RedrawMinimap;
 	UnitCountSeen(unit);
 }
 
@@ -832,7 +857,6 @@ void RemoveUnit(Unit* unit, Unit* host)
 	if (unit == UnitUnderCursor) {
 		UnitUnderCursor = NULL;
 	}
-	MustRedraw |= RedrawMinimap;
 }
 
 /**
@@ -3576,8 +3600,9 @@ void SaveUnit(const Unit* unit, CLFile* file)
 	}
 	CLprintf(file, "\"order-count\", %d,\n  ", unit->OrderCount);
 	CLprintf(file, "\"order-flush\", %d,\n  ", unit->OrderFlush);
+	CLprintf(file, "\"order-total\", %d,\n	", unit->TotalOrders);
 	CLprintf(file, "\"orders\", {");
-	for (i = 0; i < MAX_ORDERS; ++i) {
+	for (i = 0; i < unit->TotalOrders; ++i) {
 		CLprintf(file, "\n ");
 		SaveOrder(&unit->Orders[i], file);
 		CLprintf(file, ",");
@@ -3643,17 +3668,7 @@ void SaveUnit(const Unit* unit, CLFile* file)
 		case UnitActionTrain:
 			CLprintf(file, ",\n  \"data-train\", {");
 			CLprintf(file, "\"ticks\", %d, ", unit->Data.Train.Ticks);
-			CLprintf(file, "\"count\", %d, ", unit->Data.Train.Count);
-			CLprintf(file, "\"queue\", {");
-			for (i = 0; i < MAX_UNIT_TRAIN; ++i) {
-				if (i < unit->Data.Train.Count) {
-					CLprintf(file, "\"%s\", ", unit->Data.Train.What[i]->Ident);
-				} else {
-					/* this slot is currently unused */
-					CLprintf(file, "\"unit-none\", ");
-				}
-			}
-			CLprintf(file, "}}");
+			CLprintf(file, "}");
 			break;
 		default:
 			CLprintf(file, ",\n  \"data-move\", {");
@@ -3791,6 +3806,7 @@ void CleanUnits(void)
 {
 	Unit** table;
 	Unit* unit;
+	Order* order;
 
 	//
 	//  Free memory for all units in unit table.
@@ -3809,6 +3825,14 @@ void CleanUnits(void)
 		ReleasedHead = unit->Next;
 		free(unit);
 	}
+
+	//
+	//  Release memory of Orders in the release queue.
+	while ((order = ReleasedOrderHead)) {
+		ReleasedOrderHead = order->Arg1;
+		free(order);
+	}
+
 	InitUnitsMemory();
 
 	XpDamage = 0;
diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp
index 031350545..6aafa52fe 100644
--- a/src/unit/unit_draw.cpp
+++ b/src/unit/unit_draw.cpp
@@ -1083,7 +1083,7 @@ static void DrawDecoration(const Unit* unit, const UnitType* type, int x, int y)
 	if (unit->Orders[0].Action == UnitActionTrain) {
 		unit->Variable[TRAINING_INDEX].Value = unit->Data.Train.Ticks;
 		unit->Variable[TRAINING_INDEX].Max =
-			unit->Data.Train.What[0]->Stats[unit->Player->Player].Costs[TimeCost];
+			unit->Orders[0].Type->Stats[unit->Player->Player].Costs[TimeCost];
 	}
 
 	// UpgradeTo
diff --git a/src/unit/upgrade.cpp b/src/unit/upgrade.cpp
index 8f6f1646e..46a04d139 100644
--- a/src/unit/upgrade.cpp
+++ b/src/unit/upgrade.cpp
@@ -1165,16 +1165,16 @@ static void ConvertUnitTypeTo(Player* player, const UnitType* src, UnitType* dst
 		//  FIXME: what about buildings?
 		//
 		} else {
-			if (unit->Orders[0].Action == UnitActionTrain) {
-				for (j = 0; j < unit->Data.Train.Count; ++j) {
-					if (unit->Data.Train.What[j] == src) {
-						unit->Data.Train.What[j] = dst;
-					}
-				}
-			}
-			for (j = 1; j < unit->OrderCount; ++j) {
+			for (j = 0; j < unit->OrderCount; ++j) {
 				if (unit->Orders[j].Action == UnitActionTrain &&
 						unit->Orders[j].Type == src) {
+						if (j == 0) {
+							// Must Adjust Ticks to the fraction that was trained
+							unit->Data.Train.Ticks = 
+								unit->Data.Train.Ticks *
+								dst->Stats[player->Player].Costs[TimeCost] /
+								src->Stats[player->Player].Costs[TimeCost];
+						}
 					unit->Orders[j].Type = dst;
 				}
 			}