diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
index b18a86b854..09d9c8f9e5 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
@@ -53,6 +53,7 @@ import mage.client.remote.Session;
 import mage.client.table.TablePlayerPanel;
 import mage.client.util.Event;
 import mage.client.util.Listener;
+import mage.game.match.MatchOptions;
 import mage.sets.Sets;
 import mage.util.Logging;
 import mage.view.GameTypeView;
@@ -277,18 +278,16 @@ public class NewTableDialog extends MageDialog {
 
 	private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
 		GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
-		List<String> playerTypes = new ArrayList<String>();
-		playerTypes.add("Human");
+		MatchOptions options = new MatchOptions("Quick Start Game", gameType.getName());
+		options.getPlayerTypes().add("Human");
 		for (TablePlayerPanel player: players) {
-			playerTypes.add(player.getPlayerType());
+			options.getPlayerTypes().add(player.getPlayerType());
 		}
-		table = session.createTable(
-				roomId,
-				gameType.getName(),
-				(String)this.cbDeckType.getSelectedItem(),
-				playerTypes,
-				(MultiplayerAttackOption)this.cbAttackOption.getSelectedItem(), 
-				(RangeOfInfluence)this.cbRange.getSelectedItem());
+		options.setDeckType((String) this.cbDeckType.getSelectedItem());
+		options.setAttackOption((MultiplayerAttackOption) this.cbAttackOption.getSelectedItem());
+		options.setRange((RangeOfInfluence) this.cbRange.getSelectedItem());
+		options.setWinsNeeded(1);
+		table = session.createTable(roomId, options);
 		try {
 			if (session.joinTable(roomId, table.getTableId(), this.player1Panel.getPlayerName(), Sets.loadDeck(this.player1Panel.getDeckFile()))) {
 				for (TablePlayerPanel player: players) {
diff --git a/Mage.Client/src/main/java/mage/client/remote/Session.java b/Mage.Client/src/main/java/mage/client/remote/Session.java
index af7841411d..1093013070 100644
--- a/Mage.Client/src/main/java/mage/client/remote/Session.java
+++ b/Mage.Client/src/main/java/mage/client/remote/Session.java
@@ -49,7 +49,9 @@ import mage.client.components.MageUI;
 import mage.client.game.GamePanel;
 import mage.client.util.Config;
 import mage.game.GameException;
+import mage.game.match.MatchType;
 import mage.interfaces.MageException;
+import mage.game.match.MatchOptions;
 import mage.interfaces.Server;
 import mage.interfaces.ServerState;
 import mage.interfaces.callback.CallbackClientDaemon;
@@ -396,9 +398,9 @@ public class Session {
 		return false;
 	}
 
-	public TableView createTable(UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
+	public TableView createTable(UUID roomId, MatchOptions matchOptions) {
 		try {
-			return server.createTable(sessionId, roomId, gameType, deckType, playerTypes, attackOption, range);
+			return server.createTable(sessionId, roomId, matchOptions);
 		} catch (RemoteException ex) {
 			handleRemoteException(ex);
 		} catch (MageException ex) {
@@ -456,7 +458,7 @@ public class Session {
 
 	public boolean startGame(UUID roomId, UUID tableId) {
 		try {
-			server.startGame(sessionId, roomId, tableId);
+			server.startMatch(sessionId, roomId, tableId);
 			return true;
 		} catch (RemoteException ex) {
 			handleRemoteException(ex);
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
index 94f01af53e..929c0facab 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
@@ -37,9 +37,7 @@ package mage.client.table;
 import java.awt.Color;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Observable;
 import java.util.Observer;
@@ -53,8 +51,9 @@ import javax.swing.JComponent;
 import javax.swing.JOptionPane;
 import javax.swing.Timer;
 import javax.swing.table.AbstractTableModel;
+import mage.Constants.MultiplayerAttackOption;
+import mage.Constants.RangeOfInfluence;
 
-import mage.cards.decks.DeckCardLists;
 import mage.client.MageFrame;
 import mage.client.components.MageComponents;
 import mage.client.dialog.JoinTableDialog;
@@ -63,6 +62,7 @@ import mage.client.dialog.TableWaitingDialog;
 import mage.client.remote.MageRemoteException;
 import mage.client.remote.Session;
 import mage.client.util.ButtonColumn;
+import mage.game.match.MatchOptions;
 import mage.sets.Sets;
 import mage.util.Logging;
 import mage.view.TableView;
@@ -280,16 +280,14 @@ public class TablesPanel extends javax.swing.JPanel implements Observer {
 	private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed
 		TableView table;
 		try {
-			List<String> playerTypes = new ArrayList<String>();
-			playerTypes.add("Human");
-			playerTypes.add("Computer - default");
-			table = session.createTable(
-					roomId,
-					"Two Player Duel",
-					"Constructed",
-					playerTypes,
-					null, null
-			);
+			MatchOptions options = new MatchOptions("1", "Two Player Duel");
+			options.getPlayerTypes().add("Human");
+			options.getPlayerTypes().add("Computer - default");
+			options.setDeckType("Limited");
+			options.setAttackOption(MultiplayerAttackOption.LEFT);
+			options.setRange(RangeOfInfluence.ALL);
+			options.setWinsNeeded(1);
+			table = session.createTable(roomId,	options);
 			session.joinTable(
 					roomId,
 					table.getTableId(),
diff --git a/Mage.Common/src/mage/interfaces/Server.java b/Mage.Common/src/mage/interfaces/Server.java
index 5ce8de4b8a..18ba540d47 100644
--- a/Mage.Common/src/mage/interfaces/Server.java
+++ b/Mage.Common/src/mage/interfaces/Server.java
@@ -28,16 +28,14 @@
 
 package mage.interfaces;
 
+import mage.game.match.MatchOptions;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 import java.util.List;
 import java.util.UUID;
-import mage.Constants.MultiplayerAttackOption;
-import mage.Constants.RangeOfInfluence;
 import mage.cards.decks.DeckCardLists;
 import mage.game.GameException;
 import mage.interfaces.callback.CallbackServer;
-import mage.view.GameTypeView;
 import mage.view.TableView;
 import mage.view.GameView;
 
@@ -54,7 +52,7 @@ public interface Server extends Remote, CallbackServer {
 	public ServerState getServerState() throws RemoteException, MageException;
 
 	//table methods
-	public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) throws RemoteException, MageException;
+	public TableView createTable(UUID sessionId, UUID roomId, MatchOptions matchOptions) throws RemoteException, MageException;
 	public boolean joinTable(UUID sessionId, UUID roomId, UUID tableId, String name, DeckCardLists deckList) throws RemoteException, MageException, GameException;
 	public boolean watchTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
 	public boolean replayTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
@@ -77,7 +75,7 @@ public interface Server extends Remote, CallbackServer {
 	public UUID getMainRoomId() throws RemoteException, MageException;
 
 	//game methods
-	public void startGame(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
+	public void startMatch(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
 	public void joinGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
 	public void watchGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
 	public void stopWatching(UUID gameId, UUID sessionId) throws RemoteException, MageException;
diff --git a/Mage.Common/src/mage/view/GameTypeView.java b/Mage.Common/src/mage/view/GameTypeView.java
index 97426e47f9..310e405727 100644
--- a/Mage.Common/src/mage/view/GameTypeView.java
+++ b/Mage.Common/src/mage/view/GameTypeView.java
@@ -29,7 +29,7 @@
 package mage.view;
 
 import java.io.Serializable;
-import mage.game.GameType;
+import mage.game.match.MatchType;
 
 /**
  *
@@ -45,7 +45,7 @@ public class GameTypeView implements Serializable {
 	private boolean useRange;
 	private boolean useAttackOption;
 
-	public GameTypeView(GameType gameType) {
+	public GameTypeView(MatchType gameType) {
 		this.name = gameType.getName();
 		this.minPlayers = gameType.getMinPlayers();
 		this.maxPlayers = gameType.getMaxPlayers();
diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java
index 478dcb5b93..97c25e4c5f 100644
--- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java
+++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java
@@ -28,6 +28,7 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -59,7 +60,7 @@ public class FreeForAll extends GameImpl<FreeForAll> {
 	}
 
 	@Override
-	public GameType getGameType() {
+	public MatchType getGameType() {
 		return new FreeForAllType();
 	}
 
diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java
new file mode 100644
index 0000000000..613fcf6af7
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without modification, are
+ *  permitted provided that the following conditions are met:
+ * 
+ *     1. Redistributions of source code must retain the above copyright notice, this list of
+ *        conditions and the following disclaimer.
+ * 
+ *     2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *        of conditions and the following disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *  The views and conclusions contained in the software and documentation are those of the
+ *  authors and should not be interpreted as representing official policies, either expressed
+ *  or implied, of BetaSteward_at_googlemail.com.
+ */
+
+package mage.game;
+
+import mage.game.match.MatchImpl;
+import mage.game.match.MatchOptions;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class FreeForAllMatch extends MatchImpl<FreeForAll> {
+
+	public FreeForAllMatch(MatchOptions options) {
+		super(options);
+	}
+
+	@Override
+	public void startGame() throws GameException {
+		FreeForAll game = new FreeForAll(options.getAttackOption(), options.getRange());
+		initGame(game);
+		games.add(game);
+	}
+
+}
diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllType.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllType.java
index ee24d0675a..a7fabda172 100644
--- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllType.java
+++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllType.java
@@ -28,11 +28,13 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
+
 /**
  *
  * @author BetaSteward_at_googlemail.com
  */
-public class FreeForAllType extends GameType {
+public class FreeForAllType extends MatchType<FreeForAllType> {
 
 	public FreeForAllType() {
 		this.name = "Free For All";
@@ -42,4 +44,13 @@ public class FreeForAllType extends GameType {
 		this.useAttackOption = true;
 		this.useRange = true;
 	}
+
+	protected FreeForAllType(final FreeForAllType matchType) {
+		super(matchType);
+	}
+
+	@Override
+	public FreeForAllType copy() {
+		return new FreeForAllType(this);
+	}
 }
diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java
index fe3b9d76fe..7c53f6eab1 100644
--- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java
+++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java
@@ -28,6 +28,7 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.UUID;
@@ -39,7 +40,7 @@ import mage.game.turn.TurnMod;
 public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
 
 	public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) {
-		super(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL);
+		super(attackOption, range);
 	}
 
 	public TwoPlayerDuel(final TwoPlayerDuel game) {
@@ -47,7 +48,7 @@ public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
 	}
 
 	@Override
-	public GameType getGameType() {
+	public MatchType getGameType() {
 		return new TwoPlayerDuelType();
 	}
 
diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuelType.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuelType.java
index c25aaa8dc2..c15c12f1e4 100644
--- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuelType.java
+++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuelType.java
@@ -28,11 +28,13 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
+
 /**
  *
  * @author BetaSteward_at_googlemail.com
  */
-public class TwoPlayerDuelType extends GameType {
+public class TwoPlayerDuelType extends MatchType<TwoPlayerDuelType> {
 
 	public TwoPlayerDuelType() {
 		this.name = "Two Player Duel";
@@ -43,4 +45,13 @@ public class TwoPlayerDuelType extends GameType {
 		this.useRange = false;
 	}
 
+	protected TwoPlayerDuelType(final TwoPlayerDuelType matchType) {
+		super(matchType);
+	}
+
+	@Override
+	public TwoPlayerDuelType copy() {
+		return new TwoPlayerDuelType(this);
+	}
+
 }
diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java
new file mode 100644
index 0000000000..c3f7723146
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without modification, are
+ *  permitted provided that the following conditions are met:
+ * 
+ *     1. Redistributions of source code must retain the above copyright notice, this list of
+ *        conditions and the following disclaimer.
+ * 
+ *     2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *        of conditions and the following disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *  The views and conclusions contained in the software and documentation are those of the
+ *  authors and should not be interpreted as representing official policies, either expressed
+ *  or implied, of BetaSteward_at_googlemail.com.
+ */
+
+package mage.game;
+
+import mage.game.match.MatchImpl;
+import mage.game.match.MatchOptions;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class TwoPlayerMatch extends MatchImpl<TwoPlayerDuel> {
+
+	public TwoPlayerMatch(MatchOptions options) {
+		super(options);
+	}
+
+	@Override
+	public void startGame() throws GameException {
+		TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange());
+		initGame(game);
+		games.add(game);
+	}
+	
+}
diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml
index 9733c9db7e..df6998b9b9 100644
--- a/Mage.Server/config/config.xml
+++ b/Mage.Server/config/config.xml
@@ -9,8 +9,8 @@
 		<playerType name="Computer - minimax hybrid" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>
 	</playerTypes>
 	<gameTypes>
-		<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerDuel" typeName="mage.game.TwoPlayerDuelType"/>
-		<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAll" typeName="mage.game.FreeForAllType"/>
+		<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>
+		<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
 	</gameTypes>
 	<deckTypes>
 		<deckType name="Constructed" jar="mage-deck-constructed.jar" className="mage.deck.Constructed"/>
diff --git a/Mage.Server/plugins/mage-deck-constructed.jar b/Mage.Server/plugins/mage-deck-constructed.jar
index cdcc7affaa..5ce9f4b469 100644
Binary files a/Mage.Server/plugins/mage-deck-constructed.jar and b/Mage.Server/plugins/mage-deck-constructed.jar differ
diff --git a/Mage.Server/plugins/mage-deck-limited.jar b/Mage.Server/plugins/mage-deck-limited.jar
index 8e20dbdb8a..57ea157b7a 100644
Binary files a/Mage.Server/plugins/mage-deck-limited.jar and b/Mage.Server/plugins/mage-deck-limited.jar differ
diff --git a/Mage.Server/plugins/mage-game-freeforall.jar b/Mage.Server/plugins/mage-game-freeforall.jar
index 25f863f3df..170e2d6993 100644
Binary files a/Mage.Server/plugins/mage-game-freeforall.jar and b/Mage.Server/plugins/mage-game-freeforall.jar differ
diff --git a/Mage.Server/plugins/mage-game-twoplayerduel.jar b/Mage.Server/plugins/mage-game-twoplayerduel.jar
index 22b21ec61e..82888f63b1 100644
Binary files a/Mage.Server/plugins/mage-game-twoplayerduel.jar and b/Mage.Server/plugins/mage-game-twoplayerduel.jar differ
diff --git a/Mage.Server/plugins/mage-player-ai.jar b/Mage.Server/plugins/mage-player-ai.jar
index e7b4c9190c..da0274094b 100644
Binary files a/Mage.Server/plugins/mage-player-ai.jar and b/Mage.Server/plugins/mage-player-ai.jar differ
diff --git a/Mage.Server/plugins/mage-player-aiminimax.jar b/Mage.Server/plugins/mage-player-aiminimax.jar
index d2f5a8333b..c3a0c972fd 100644
Binary files a/Mage.Server/plugins/mage-player-aiminimax.jar and b/Mage.Server/plugins/mage-player-aiminimax.jar differ
diff --git a/Mage.Server/plugins/mage-player-human.jar b/Mage.Server/plugins/mage-player-human.jar
index 37aa8262f0..2f32a784d2 100644
Binary files a/Mage.Server/plugins/mage-player-human.jar and b/Mage.Server/plugins/mage-player-human.jar differ
diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java
index e8425dbc35..9cec754fa9 100644
--- a/Mage.Server/src/main/java/mage/server/Main.java
+++ b/Mage.Server/src/main/java/mage/server/Main.java
@@ -35,7 +35,7 @@ import java.io.FilenameFilter;
 import java.net.InetAddress;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import mage.game.GameType;
+import mage.game.match.MatchType;
 import mage.server.game.DeckValidatorFactory;
 import mage.server.game.GameFactory;
 import mage.server.game.PlayerFactory;
@@ -119,11 +119,11 @@ public class Main {
 		return null;
 	}
 
-	private static GameType loadGameType(GamePlugin plugin) {
+	private static MatchType loadGameType(GamePlugin plugin) {
 		try {
 			classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
 			logger.info("Loading game type: " + plugin.getClassName());
-			return (GameType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
+			return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
 		} catch (ClassNotFoundException ex) {
 			logger.log(Level.SEVERE, "Game type not found:" + plugin.getJar() + " - check plugin folder");
 		} catch (Exception ex) {
diff --git a/Mage.Server/src/main/java/mage/server/ServerImpl.java b/Mage.Server/src/main/java/mage/server/ServerImpl.java
index 9585c34595..42093e5511 100644
--- a/Mage.Server/src/main/java/mage/server/ServerImpl.java
+++ b/Mage.Server/src/main/java/mage/server/ServerImpl.java
@@ -43,7 +43,9 @@ import mage.Constants.MultiplayerAttackOption;
 import mage.Constants.RangeOfInfluence;
 import mage.cards.decks.DeckCardLists;
 import mage.game.GameException;
+import mage.game.match.MatchType;
 import mage.interfaces.MageException;
+import mage.game.match.MatchOptions;
 import mage.interfaces.Server;
 import mage.interfaces.ServerState;
 import mage.interfaces.callback.ClientCallback;
@@ -117,9 +119,9 @@ public class ServerImpl extends RemoteServer implements Server {
 	}
 
 	@Override
-	public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) throws MageException {
+	public TableView createTable(UUID sessionId, UUID roomId, MatchOptions options) throws MageException {
 		try {
-			TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, gameType, deckType, playerTypes, attackOption, range);
+			TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, options);
 			logger.info("Table " + table.getTableId() + " created");
 			return table;
 		}
@@ -202,13 +204,13 @@ public class ServerImpl extends RemoteServer implements Server {
 	}
 
 	@Override
-	public void startGame(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
+	public void startMatch(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
 		try {
 			rmiExecutor.execute(
 				new Runnable() {
 					@Override
 					public void run() {
-						TableManager.getInstance().startGame(sessionId, roomId, tableId);
+						TableManager.getInstance().startMatch(sessionId, roomId, tableId);
 					}
 				}
 			);
diff --git a/Mage.Server/src/main/java/mage/server/game/GameFactory.java b/Mage.Server/src/main/java/mage/server/game/GameFactory.java
index 6af3d534bd..e35ee4b9ca 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameFactory.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameFactory.java
@@ -30,17 +30,15 @@ package mage.server.game;
 
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import mage.Constants.MultiplayerAttackOption;
-import mage.Constants.RangeOfInfluence;
-import mage.game.Game;
+import mage.game.match.Match;
+import mage.game.match.MatchOptions;
 import mage.util.Logging;
-import mage.game.GameType;
+import mage.game.match.MatchType;
 import mage.view.GameTypeView;
 
 /**
@@ -52,8 +50,8 @@ public class GameFactory {
 	private final static GameFactory INSTANCE = new GameFactory();
 	private final static Logger logger = Logging.getLogger(GameFactory.class.getName());
 
-	private Map<String, Class<Game>> games = new HashMap<String, Class<Game>>();
-	private Map<String, GameType> gameTypes = new HashMap<String, GameType>();
+	private Map<String, Class<Match>> games = new HashMap<String, Class<Match>>();
+	private Map<String, MatchType> gameTypes = new HashMap<String, MatchType>();
 	private List<GameTypeView> gameTypeViews = new ArrayList<GameTypeView>();
 
 
@@ -63,31 +61,31 @@ public class GameFactory {
 
 	private GameFactory() {}
 
-	public Game createGame(String gameType, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
+	public Match createMatch(String gameType, MatchOptions options) {
 
-		Game game;
-		Constructor<Game> con;
+		Match match;
+		Constructor<Match> con;
 		try {
-			con = games.get(gameType).getConstructor(new Class[]{MultiplayerAttackOption.class, RangeOfInfluence.class});
-			game = con.newInstance(new Object[] {attackOption, range});
+			con = games.get(gameType).getConstructor(new Class[]{MatchOptions.class});
+			match = con.newInstance(new Object[] {options});
 		} catch (Exception ex) {
 			logger.log(Level.SEVERE, null, ex);
 			return null;
 		}
-		logger.info("Game created: " + game.getId().toString());
+		logger.info("Game created: " + gameType); // + game.getId().toString());
 
-		return game;
+		return match;
 	}
 
 	public List<GameTypeView> getGameTypes() {
 		return gameTypeViews;
 	}
 
-	public void addGameType(String name, GameType gameType, Class game) {
+	public void addGameType(String name, MatchType matchType, Class game) {
 		if (game != null) {
 			this.games.put(name, game);
-			this.gameTypes.put(name, gameType);
-			this.gameTypeViews.add(new GameTypeView(gameType));
+			this.gameTypes.put(name, matchType);
+			this.gameTypeViews.add(new GameTypeView(matchType));
 		}
 	}
 
diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java
index 3e72cdaa06..901a6f12fb 100644
--- a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java
+++ b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java
@@ -34,6 +34,8 @@ import mage.Constants.MultiplayerAttackOption;
 import mage.Constants.RangeOfInfluence;
 import mage.cards.decks.DeckCardLists;
 import mage.game.GameException;
+import mage.game.match.MatchType;
+import mage.game.match.MatchOptions;
 import mage.view.TableView;
 
 /**
@@ -44,7 +46,7 @@ public interface GamesRoom extends Room {
 
 	public List<TableView> getTables();
 	public boolean joinTable(UUID sessionId, UUID tableId, String name, DeckCardLists deckList) throws GameException;
-	public TableView createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range);
+	public TableView createTable(UUID sessionId, MatchOptions options);
 	public void removeTable(UUID sessionId, UUID tableId);
 	public TableView getTable(UUID tableId);
 	public void leaveTable(UUID sessionId, UUID tableId);
diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
index a4fc250fa5..f327c23306 100644
--- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
+++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
@@ -39,6 +39,8 @@ import mage.Constants.MultiplayerAttackOption;
 import mage.Constants.RangeOfInfluence;
 import mage.cards.decks.DeckCardLists;
 import mage.game.GameException;
+import mage.game.match.MatchType;
+import mage.game.match.MatchOptions;
 import mage.util.Logging;
 import mage.view.TableView;
 
@@ -71,8 +73,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
 	}
 
 	@Override
-	public TableView createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
-		Table table = TableManager.getInstance().createTable(sessionId, gameType, deckType, playerTypes, attackOption, range);
+	public TableView createTable(UUID sessionId, MatchOptions options) {
+		Table table = TableManager.getInstance().createTable(sessionId, options);
 		tables.put(table.getId(), table);
 		return new TableView(table);
 	}
diff --git a/Mage.Server/src/main/java/mage/server/game/TableController.java b/Mage.Server/src/main/java/mage/server/game/TableController.java
index 31ef031c3b..48da85e1ee 100644
--- a/Mage.Server/src/main/java/mage/server/game/TableController.java
+++ b/Mage.Server/src/main/java/mage/server/game/TableController.java
@@ -55,7 +55,10 @@ import mage.cards.decks.DeckCardLists;
 import mage.game.Game;
 import mage.game.GameException;
 import mage.game.GameStates;
+import mage.game.match.Match;
+import mage.game.match.MatchType;
 import mage.game.Seat;
+import mage.game.match.MatchOptions;
 import mage.players.Player;
 import mage.server.ChatManager;
 import mage.server.Main;
@@ -73,17 +76,19 @@ public class TableController {
 
 	private UUID sessionId;
 	private UUID chatId;
-	private UUID gameId;
+	//private UUID gameId;
 	private Table table;
-	private Game game;
+	private Match match;
+	private MatchOptions options;
 	private ConcurrentHashMap<UUID, UUID> sessionPlayerMap = new ConcurrentHashMap<UUID, UUID>();
 
-	public TableController(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
+	public TableController(UUID sessionId, MatchOptions options) {
 		this.sessionId = sessionId;
 		chatId = ChatManager.getInstance().createChatSession();
-		game = GameFactory.getInstance().createGame(gameType, attackOption, range);
-		gameId = game.getId();
-		table = new Table(gameType, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes);
+		this.options = options;
+		match = GameFactory.getInstance().createMatch(options.getGameType(), options);
+		//gameId = game.getId();
+		table = new Table(options.getGameType(), DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes());
 	}
 
 	public synchronized boolean joinTable(UUID sessionId, String name, DeckCardLists deckList) throws GameException {
@@ -100,8 +105,7 @@ public class TableController {
 		}
 		
 		Player player = createPlayer(name, deck, seat.getPlayerType());
-		game.loadCards(deck.getCards(), player.getId());
-		game.loadCards(deck.getSideboard(), player.getId());
+		match.addPlayer(player, deck);
 		table.joinTable(player, seat);
 		logger.info("player joined " + player.getId());
 		//only add human players to sessionPlayerMap
@@ -116,7 +120,7 @@ public class TableController {
 		if (table.getState() != TableState.DUELING) {
 			return false;
 		}
-		SessionManager.getInstance().getSession(sessionId).watchGame(game.getId());
+		SessionManager.getInstance().getSession(sessionId).watchGame(match.getGame().getId());
 		return true;
 	}
 
@@ -141,7 +145,7 @@ public class TableController {
 	}
 
 	private Player createPlayer(String name, Deck deck, String playerType) {
-		Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck, game.getRangeOfInfluence());
+		Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck, options.getRange());
 		logger.info("Player created " + player.getId());
 		return player;
 	}
@@ -151,26 +155,43 @@ public class TableController {
 			table.leaveTable(sessionPlayerMap.get(sessionId));
 	}
 
-	public synchronized void startGame(UUID sessionId) {
+	public synchronized void startMatch(UUID sessionId) {
 		if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) {
 			try {
-				table.initGame(game);
+				match.startMatch();
+				startGame();
 			} catch (GameException ex) {
 				logger.log(Level.SEVERE, null, ex);
 			}
-			GameManager.getInstance().createGameSession(game, sessionPlayerMap, table.getId());
-			SessionManager sessionManager = SessionManager.getInstance();
-			for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
-				sessionManager.getSession(entry.getKey()).gameStarted(game.getId(), entry.getValue());
-			}
+		}
+	}
+
+	private void startGame() throws GameException {
+		match.startGame();
+		GameManager.getInstance().createGameSession(match.getGame(), sessionPlayerMap, table.getId());
+		SessionManager sessionManager = SessionManager.getInstance();
+		for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
+			sessionManager.getSession(entry.getKey()).gameStarted(match.getGame().getId(), entry.getValue());
 		}
 	}
 
 	public void endGame() {
+		match.endGame();
 		table.endGame();
 		saveGame();
-		GameManager.getInstance().removeGame(game.getId());
-		game = null;
+		GameManager.getInstance().removeGame(match.getGame().getId());
+		try {
+			if (!match.isMatchOver()) {
+				startGame();
+			}
+		} catch (GameException ex) {
+			logger.log(Level.SEVERE, null, ex);
+		}
+		endMatch();
+	}
+
+	public void endMatch() {
+		match = null;
 	}
 
 	public void swapSeats(int seatNum1, int seatNum2) {
@@ -188,17 +209,17 @@ public class TableController {
 
 	private void saveGame() {
 		try {
-			OutputStream file = new FileOutputStream("saved/" + game.getId().toString() + ".game");
+			OutputStream file = new FileOutputStream("saved/" + match.getGame().getId().toString() + ".game");
 			OutputStream buffer = new BufferedOutputStream(file);
 			ObjectOutput output = new ObjectOutputStream(new GZIPOutputStream(buffer));
 			try {
-				output.writeObject(game);
-				output.writeObject(game.getGameStates());
+				output.writeObject(match.getGame());
+				output.writeObject(match.getGame().getGameStates());
 			}
 			finally {
 				output.close();
 			}
-			logger.log(Level.INFO, "Saved game:" + game.getId());
+			logger.log(Level.INFO, "Saved game:" + match.getGame().getId());
 		}
 		catch(IOException ex) {
 			logger.log(Level.SEVERE, "Cannot save game.", ex);
@@ -207,7 +228,7 @@ public class TableController {
 
 	private Game loadGame() {
 		try{
-			InputStream file = new FileInputStream("saved/" + gameId.toString() + ".game");
+			InputStream file = new FileInputStream("saved/" + match.getGame().toString() + ".game");
 			InputStream buffer = new BufferedInputStream(file);
 			ObjectInput input = new CopierObjectInputStream(Main.classLoader, new GZIPInputStream(buffer));
 			try {
@@ -224,7 +245,7 @@ public class TableController {
 			logger.log(Level.SEVERE, "Cannot load game. Class not found.", ex);
 		}
 		catch(IOException ex) {
-			logger.log(Level.SEVERE, "Cannot load game:" + game.getId(), ex);
+			logger.log(Level.SEVERE, "Cannot load game:" + match.getGame().getId(), ex);
 		}
 		return null;
 	}
diff --git a/Mage.Server/src/main/java/mage/server/game/TableManager.java b/Mage.Server/src/main/java/mage/server/game/TableManager.java
index 9369d13574..d0ffc29cc4 100644
--- a/Mage.Server/src/main/java/mage/server/game/TableManager.java
+++ b/Mage.Server/src/main/java/mage/server/game/TableManager.java
@@ -38,6 +38,8 @@ import mage.Constants.MultiplayerAttackOption;
 import mage.Constants.RangeOfInfluence;
 import mage.cards.decks.DeckCardLists;
 import mage.game.GameException;
+import mage.game.match.MatchType;
+import mage.game.match.MatchOptions;
 import mage.util.Logging;
 
 /**
@@ -56,8 +58,8 @@ public class TableManager {
 		return INSTANCE;
 	}
 
-	public Table createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
-		TableController tableController = new TableController(sessionId, gameType, deckType, playerTypes, attackOption, range);
+	public Table createTable(UUID sessionId, MatchOptions options) {
+		TableController tableController = new TableController(sessionId, options);
 		controllers.put(tableController.getTable().getId(), tableController);
 		tables.put(tableController.getTable().getId(), tableController.getTable());
 		return tableController.getTable();
@@ -100,8 +102,8 @@ public class TableManager {
 		return controllers.get(tableId).getChatId();
 	}
 
-	public void startGame(UUID sessionId, UUID roomId, UUID tableId) {
-		controllers.get(tableId).startGame(sessionId);
+	public void startMatch(UUID sessionId, UUID roomId, UUID tableId) {
+		controllers.get(tableId).startMatch(sessionId);
 	}
 
 	public boolean watchTable(UUID sessionId, UUID tableId) {
diff --git a/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java b/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java
index b174d9bbf1..6bda8ab0fc 100644
--- a/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java
+++ b/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java
@@ -21,6 +21,9 @@ import java.util.List;
 import java.util.UUID;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import mage.Constants.MultiplayerAttackOption;
+import mage.Constants.RangeOfInfluence;
+import mage.game.match.MatchOptions;
 
 /**
  * Base for starting Mage server.
@@ -64,14 +67,18 @@ public class MageBase {
             connect("player", "localhost", 17171);
             UUID roomId = server.getMainRoomId();
 
-            List<String> playerTypes = new ArrayList<String>();
-            playerTypes.add("Human");
-            playerTypes.add("Computer - default");
-            TableView table = server.createTable(sessionId, roomId, "Two Player Duel", "Limited", playerTypes, null, null);
+			MatchOptions options = new MatchOptions("1", "Two Player Duel");
+			options.getPlayerTypes().add("Human");
+			options.getPlayerTypes().add("Computer - default");
+			options.setDeckType("Limited");
+			options.setAttackOption(MultiplayerAttackOption.LEFT);
+			options.setRange(RangeOfInfluence.ALL);
+			options.setWinsNeeded(1);
+            TableView table = server.createTable(sessionId, roomId, options);
             System.out.println("Cards in the deck: " + Sets.loadDeck("UW Control.dck").getCards().size());
             server.joinTable(sessionId, roomId, table.getTableId(), "Human", Sets.loadDeck("UW Control.dck"));
             server.joinTable(sessionId, roomId, table.getTableId(), "Computer", Sets.loadDeck("UW Control.dck"));
-            server.startGame(sessionId, roomId, table.getTableId());
+            server.startMatch(sessionId, roomId, table.getTableId());
 
             synchronized (syncStart) {
                 int waitTime = 7000;
diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java
index 952c43e4cc..0bf3bc24f8 100644
--- a/Mage/src/mage/game/Game.java
+++ b/Mage/src/mage/game/Game.java
@@ -28,6 +28,7 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
 import mage.cards.Card;
 import mage.game.stack.SpellStack;
 import mage.MageObject;
@@ -64,7 +65,7 @@ import mage.players.Players;
 
 public interface Game extends MageItem, Serializable {
 
-	public GameType getGameType();
+	public MatchType getGameType();
 	public int getNumPlayers();
 	public int getLife();
 	public RangeOfInfluence getRangeOfInfluence();
diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java
index 280324324a..40b4ad16f0 100644
--- a/Mage/src/mage/game/GameImpl.java
+++ b/Mage/src/mage/game/GameImpl.java
@@ -28,6 +28,7 @@
 
 package mage.game;
 
+import mage.game.match.MatchType;
 import java.io.IOException;
 import mage.game.stack.SpellStack;
 import java.io.Serializable;
@@ -315,7 +316,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
 			player = players.getNext(this);
 		}
 
-		winnerId = findWinner();
+		winnerId = findWinnersAndLosers();
 
 		saveState();
 	}
@@ -380,13 +381,21 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
 		}
 	}
 
-	protected UUID findWinner() {
+	protected UUID findWinnersAndLosers() {
+		UUID winner = null;
 		for (Player player: state.getPlayers().values()) {
 			if (player.hasWon() || (!player.hasLost() && !player.hasLeft())) {
-				return player.getId();
+				player.won(this);
+				winner = player.getId();
+				break;
 			}
 		}
-		return null;
+		for (Player player: state.getPlayers().values()) {
+			if (winner != null && !player.getId().equals(winner)) {
+				player.lost(this);
+			}
+		}
+		return winner;
 	}
 
 	protected void endOfTurn() {
diff --git a/Mage/src/mage/game/Match.java b/Mage/src/mage/game/match/Match.java
similarity index 87%
rename from Mage/src/mage/game/Match.java
rename to Mage/src/mage/game/match/Match.java
index ad58ddd650..0c938da223 100644
--- a/Mage/src/mage/game/Match.java
+++ b/Mage/src/mage/game/match/Match.java
@@ -26,10 +26,13 @@
  *  or implied, of BetaSteward_at_googlemail.com.
  */
 
-package mage.game;
+package mage.game.match;
 
 import java.util.List;
+import java.util.UUID;
 import mage.cards.decks.Deck;
+import mage.game.Game;
+import mage.game.GameException;
 import mage.players.Player;
 
 /**
@@ -38,11 +41,13 @@ import mage.players.Player;
  */
 public interface Match {
 
+	public UUID getId();
 	public boolean isMatchOver();
 	public List<MatchPlayer> getPlayers();
 	public void addPlayer(Player player, Deck deck);
-	public int getMaxPlayers();
-	public int getMinPlayers();
-	public void startMatch();
+	public void startMatch() throws GameException;
+	public void startGame() throws GameException;
+	public void endGame();
+	public Game getGame();
 	
 }
diff --git a/Mage/src/mage/game/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java
similarity index 66%
rename from Mage/src/mage/game/MatchImpl.java
rename to Mage/src/mage/game/match/MatchImpl.java
index 96e6243d11..0dfa4e1d6d 100644
--- a/Mage/src/mage/game/MatchImpl.java
+++ b/Mage/src/mage/game/match/MatchImpl.java
@@ -26,27 +26,29 @@
  *  or implied, of BetaSteward_at_googlemail.com.
  */
 
-package mage.game;
+package mage.game.match;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 import mage.cards.decks.Deck;
+import mage.game.Game;
+import mage.game.GameException;
 import mage.players.Player;
 
 /**
  *
  * @author BetaSteward_at_googlemail.com
  */
-public class MatchImpl implements Match {
+public abstract class MatchImpl<T extends Game> implements Match {
 
+	protected UUID id = UUID.randomUUID();
 	protected List<MatchPlayer> players = new ArrayList<MatchPlayer>();
-	protected List<Game> games = new ArrayList<Game>();
-	protected int winsNeeded;
-	protected int maxPlayers;
-	protected int minPlayers;
+	protected List<T> games = new ArrayList<T>();
+	protected MatchOptions options;
 	
-	public MatchImpl(int winsNeeded) {
-		this.winsNeeded = winsNeeded;
+	public MatchImpl(MatchOptions options) {
+		this.options = options;
 	}
 
 	@Override
@@ -61,14 +63,19 @@ public class MatchImpl implements Match {
 	}
 
 	@Override
-	public void startMatch() {
+	public void startMatch() throws GameException {
 
 	}
 
+	@Override
+	public UUID getId() {
+		return id;
+	}
+
 	@Override
 	public boolean isMatchOver() {
 		for (MatchPlayer player: players) {
-			if (player.getWins() >= winsNeeded) {
+			if (player.getWins() >= options.getWinsNeeded()) {
 				return true;
 			}
 		}
@@ -76,13 +83,29 @@ public class MatchImpl implements Match {
 	}
 
 	@Override
-	public int getMaxPlayers() {
-		return this.maxPlayers;
+	public T getGame() {
+		return games.get(games.size() -1);
+	}
+
+	protected void initGame(Game game) throws GameException {
+		for (MatchPlayer matchPlayer: this.players) {
+			game.addPlayer(matchPlayer.getPlayer());
+			game.loadCards(matchPlayer.getDeck().getCards(), matchPlayer.getPlayer().getId());
+			game.loadCards(matchPlayer.getDeck().getSideboard(), matchPlayer.getPlayer().getId());
+		}
 	}
 
 	@Override
-	public int getMinPlayers() {
-		return this.minPlayers;
+	public void endGame() {
+		Game game = getGame();
+		for (MatchPlayer player: this.players) {
+			Player p = game.getPlayer(player.getPlayer().getId());
+			if (p != null) {
+				if (p.hasWon())
+					player.addWin();
+				if (p.hasLost())
+					player.addLose();
+			}
+		}
 	}
-
 }
diff --git a/Mage/src/mage/game/match/MatchOptions.java b/Mage/src/mage/game/match/MatchOptions.java
new file mode 100644
index 0000000000..5301c55e5b
--- /dev/null
+++ b/Mage/src/mage/game/match/MatchOptions.java
@@ -0,0 +1,104 @@
+/*
+ *  Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without modification, are
+ *  permitted provided that the following conditions are met:
+ * 
+ *     1. Redistributions of source code must retain the above copyright notice, this list of
+ *        conditions and the following disclaimer.
+ * 
+ *     2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *        of conditions and the following disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *  The views and conclusions contained in the software and documentation are those of the
+ *  authors and should not be interpreted as representing official policies, either expressed
+ *  or implied, of BetaSteward_at_googlemail.com.
+ */
+
+package mage.game.match;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import mage.Constants.MultiplayerAttackOption;
+import mage.Constants.RangeOfInfluence;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class MatchOptions implements Serializable {
+
+	protected String name;
+	protected MultiplayerAttackOption attackOption;
+	protected RangeOfInfluence range;
+	protected int winsNeeded;
+	protected String gameType;
+	protected String deckType;
+	protected List<String> playerTypes = new ArrayList<String>();
+
+	public MatchOptions(String name, String gameType) {
+		this.name = name;
+		this.gameType = gameType;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public MultiplayerAttackOption getAttackOption() {
+		return attackOption;
+	}
+
+	public void setAttackOption(MultiplayerAttackOption attackOption) {
+		this.attackOption = attackOption;
+	}
+
+	public RangeOfInfluence getRange() {
+		return range;
+	}
+
+	public void setRange(RangeOfInfluence range) {
+		this.range = range;
+	}
+
+	public int getWinsNeeded() {
+		return winsNeeded;
+	}
+
+	public void setWinsNeeded(int winsNeeded) {
+		this.winsNeeded = winsNeeded;
+	}
+
+	public String getGameType() {
+		return gameType;
+	}
+
+	public void setGameType(String gameType) {
+		this.gameType = gameType;
+	}
+
+	public String getDeckType() {
+		return deckType;
+	}
+
+	public void setDeckType(String deckType) {
+		this.deckType = deckType;
+	}
+
+	public List<String> getPlayerTypes() {
+		return playerTypes;
+	}
+
+}
diff --git a/Mage/src/mage/game/MatchPlayer.java b/Mage/src/mage/game/match/MatchPlayer.java
similarity index 98%
rename from Mage/src/mage/game/MatchPlayer.java
rename to Mage/src/mage/game/match/MatchPlayer.java
index 4402b85c50..cf013ded15 100644
--- a/Mage/src/mage/game/MatchPlayer.java
+++ b/Mage/src/mage/game/match/MatchPlayer.java
@@ -26,7 +26,7 @@
  *  or implied, of BetaSteward_at_googlemail.com.
  */
 
-package mage.game;
+package mage.game.match;
 
 import mage.cards.decks.Deck;
 import mage.players.Player;
diff --git a/Mage/src/mage/game/GameType.java b/Mage/src/mage/game/match/MatchType.java
similarity index 80%
rename from Mage/src/mage/game/GameType.java
rename to Mage/src/mage/game/match/MatchType.java
index 4670e3da2e..d3c58fece0 100644
--- a/Mage/src/mage/game/GameType.java
+++ b/Mage/src/mage/game/match/MatchType.java
@@ -26,15 +26,17 @@
  *  or implied, of BetaSteward_at_googlemail.com.
  */
 
-package mage.game;
+package mage.game.match;
 
 import java.io.Serializable;
+import mage.Constants.MultiplayerAttackOption;
+import mage.Constants.RangeOfInfluence;
 
 /**
  *
  * @author BetaSteward_at_googlemail.com
  */
-public abstract class GameType implements Serializable {
+public abstract class MatchType<T extends MatchType<T>> implements Serializable {
 
 	protected String name;
 	protected int minPlayers;
@@ -44,6 +46,20 @@ public abstract class GameType implements Serializable {
 	protected boolean useRange;
 	protected boolean useAttackOption;
 
+	protected MatchType() {}
+	
+	protected MatchType(final MatchType matchType) {
+		this.name = matchType.name;
+		this.maxPlayers = matchType.maxPlayers;
+		this.minPlayers = matchType.minPlayers;
+		this.numTeams = matchType.numTeams;
+		this.playersPerTeam = matchType.playersPerTeam;
+		this.useRange = matchType.useRange;
+		this.useAttackOption = matchType.useAttackOption;
+	}
+
+	public abstract T copy();
+
 	@Override
 	public String toString() {
 		return name;