From 499a6fb0dfbb865a24e975ceb45a65e60e3d4af5 Mon Sep 17 00:00:00 2001
From: BetaSteward <betasteward@gmail>
Date: Thu, 6 Jan 2011 23:19:24 -0500
Subject: [PATCH] adding Architect Ramp deck + plus necessary cards (taking a
 break from coding drafts)

---
 .../release/sample-decks/Architect Ramp.dck   |  19 ++
 .../mage/sets/magic2011/AncientHellkite.java  |  10 +-
 .../mage/sets/magic2011/CyclopsGladiator.java |  14 +-
 .../riseoftheeldrazi/EnclaveCryptologist.java |  85 +++++++++
 .../LighthouseChronologist.java               | 136 ++++++++++++++
 .../sets/scarsofmirrodin/GrandArchitect.java  | 134 ++++++++++++++
 .../sets/scarsofmirrodin/MyrBattlesphere.java | 169 ++++++++++++++++++
 .../mage/sets/worldwake/HalimarDepths.java    | 124 +++++++++++++
 .../src/mage/sets/zendikar/GoblinGuide.java   |   9 +-
 .../mage/sets/zendikar/KrakenHatchling.java   |  62 +++++++
 ...ingOfControllerUpkeepTriggeredAbility.java |   2 +-
 .../costs/common/TapVariableTargetCost.java   | 100 +++++++++++
 .../common/BoostPowerXSourceEffect.java       |   2 +-
 .../effects/common/DamageXTargetEffect.java   |   2 +-
 .../common/DrawDiscardControllerEffect.java   |  73 ++++++++
 Mage/src/mage/game/GameImpl.java              |  10 ++
 Mage/src/mage/game/combat/Combat.java         |  11 ++
 17 files changed, 934 insertions(+), 28 deletions(-)
 create mode 100644 Mage.Client/release/sample-decks/Architect Ramp.dck
 create mode 100644 Mage.Sets/src/mage/sets/riseoftheeldrazi/EnclaveCryptologist.java
 create mode 100644 Mage.Sets/src/mage/sets/riseoftheeldrazi/LighthouseChronologist.java
 create mode 100644 Mage.Sets/src/mage/sets/scarsofmirrodin/GrandArchitect.java
 create mode 100644 Mage.Sets/src/mage/sets/scarsofmirrodin/MyrBattlesphere.java
 create mode 100644 Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java
 create mode 100644 Mage.Sets/src/mage/sets/zendikar/KrakenHatchling.java
 create mode 100644 Mage/src/mage/abilities/costs/common/TapVariableTargetCost.java
 create mode 100644 Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java

diff --git a/Mage.Client/release/sample-decks/Architect Ramp.dck b/Mage.Client/release/sample-decks/Architect Ramp.dck
new file mode 100644
index 0000000000..f8867be804
--- /dev/null
+++ b/Mage.Client/release/sample-decks/Architect Ramp.dck	
@@ -0,0 +1,19 @@
+NAME:Architect Ramp
+2 [SOM:180] Myr Battlesphere
+3 [ZEN:234] Island
+3 [ZEN:236] Island
+2 [ZEN:223] Scalding Tarn
+3 [M11:70] Preordain
+3 [ZEN:235] Island
+3 [ZEN:237] Island
+4 [ROE:66] Enclave Cryptologist
+4 [ROE:85] Sea Gate Oracle
+3 [WWK:137] Halimar Depths
+4 [ZEN:50] Kraken Hatchling
+4 [SOM:33] Grand Architect
+3 [SOM:177] Molten-Tail Masticore
+4 [ROE:75] Lighthouse Chronologist
+4 [WWK:145] Tectonic Edge
+4 [ZEN:220] Misty Rainforest
+3 [WWK:31] Jace, the Mind Sculptor
+4 [SOM:223] Wurmcoil Engine
diff --git a/Mage.Sets/src/mage/sets/magic2011/AncientHellkite.java b/Mage.Sets/src/mage/sets/magic2011/AncientHellkite.java
index f7c403552b..7d53ef8b37 100644
--- a/Mage.Sets/src/mage/sets/magic2011/AncientHellkite.java
+++ b/Mage.Sets/src/mage/sets/magic2011/AncientHellkite.java
@@ -83,7 +83,7 @@ public class AncientHellkite extends CardImpl<AncientHellkite> {
 
 class AncientHellkiteAbility extends ActivatedAbilityImpl<AncientHellkiteAbility> {
 
-	private FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defender player controls");
+	private FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls");
 
 	public AncientHellkiteAbility() {
 		super(Zone.BATTLEFIELD, new DamageTargetEffect(1));
@@ -104,13 +104,7 @@ class AncientHellkiteAbility extends ActivatedAbilityImpl<AncientHellkiteAbility
 
 	@Override
 	public boolean activate(Game game, boolean noMana) {
-		UUID defenderId = null;
-		for (CombatGroup group: game.getCombat().getGroups()) {
-			if (group.getAttackers().contains(this.sourceId)) {
-				defenderId = group.getDefenderId();
-				break;
-			}
-		}
+		UUID defenderId = game.getCombat().getDefendingPlayer(sourceId);
 		if (defenderId != null) {
 			filter.getControllerId().clear();
 			filter.getControllerId().add(defenderId);
diff --git a/Mage.Sets/src/mage/sets/magic2011/CyclopsGladiator.java b/Mage.Sets/src/mage/sets/magic2011/CyclopsGladiator.java
index 6cdf2eb217..603b640014 100644
--- a/Mage.Sets/src/mage/sets/magic2011/CyclopsGladiator.java
+++ b/Mage.Sets/src/mage/sets/magic2011/CyclopsGladiator.java
@@ -91,16 +91,10 @@ class CyclopsGladiatorEffect extends OneShotEffect<CyclopsGladiatorEffect> {
 
 	@Override
 	public boolean apply(Game game, Ability source) {
-		Player defender = null;
-		for (CombatGroup group: game.getCombat().getGroups()) {
-			if (group.getAttackers().contains(source.getSourceId())) {
-				defender = game.getPlayer(group.getDefenderId());
-				break;
-			}
-		}
-		if (defender != null) {
-			FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player owns");
-			filter.getControllerId().add(defender.getId());
+		UUID defenderId = game.getCombat().getDefendingPlayer(source.getSourceId());
+		if (defenderId != null) {
+			FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls");
+			filter.getControllerId().add(defenderId);
 			TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
 			Player player = game.getPlayer(source.getControllerId());
 			player.choose(Outcome.Damage, target, game);
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/EnclaveCryptologist.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/EnclaveCryptologist.java
new file mode 100644
index 0000000000..9aacf44900
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/EnclaveCryptologist.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 2011 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.sets.riseoftheeldrazi;
+
+import java.util.UUID;
+import mage.Constants.CardType;
+import mage.Constants.Rarity;
+import mage.Constants.Zone;
+import mage.MageInt;
+import mage.abilities.Abilities;
+import mage.abilities.AbilitiesImpl;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardControllerEffect;
+import mage.abilities.effects.common.DrawDiscardControllerEffect;
+import mage.abilities.keyword.LevelAbility;
+import mage.abilities.keyword.LevelUpAbility;
+import mage.cards.LevelerCard;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class EnclaveCryptologist extends LevelerCard<EnclaveCryptologist> {
+
+    public EnclaveCryptologist (UUID ownerId) {
+        super(ownerId, 66, "Enclave Cryptologist", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{U}");
+        this.expansionSetCode = "ROE";
+        this.subtype.add("Merfolk");
+        this.subtype.add("Wizard");
+        this.color.setBlue(true);
+        this.power = new MageInt(0);
+        this.toughness = new MageInt(1);
+
+        this.addAbility(new LevelUpAbility(new ManaCostsImpl("{1}{U}")));
+        Abilities<Ability> abilities1 = new AbilitiesImpl<Ability>();
+        Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardControllerEffect(), new TapSourceCost());
+        abilities1.add(ability);
+        this.getLevels().add(new LevelAbility(1, 2, abilities1, 0, 1));
+
+        Abilities<Ability> abilities2 = new AbilitiesImpl<Ability>();
+        ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardControllerEffect(1), new TapSourceCost());
+        abilities2.add(ability);
+        this.getLevels().add(new LevelAbility(3, -1, abilities2, 0, 1));
+
+    }
+
+    public EnclaveCryptologist (final EnclaveCryptologist card) {
+        super(card);
+    }
+
+    @Override
+    public EnclaveCryptologist copy() {
+        return new EnclaveCryptologist(this);
+    }
+
+}
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/LighthouseChronologist.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/LighthouseChronologist.java
new file mode 100644
index 0000000000..99670e7488
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/LighthouseChronologist.java
@@ -0,0 +1,136 @@
+/*
+ *  Copyright 2011 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.sets.riseoftheeldrazi;
+
+import java.util.UUID;
+import mage.Constants;
+import mage.Constants.CardType;
+import mage.Constants.Outcome;
+import mage.Constants.Rarity;
+import mage.MageInt;
+import mage.abilities.Abilities;
+import mage.abilities.AbilitiesImpl;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.LevelAbility;
+import mage.abilities.keyword.LevelUpAbility;
+import mage.cards.LevelerCard;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.turn.TurnMod;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class LighthouseChronologist extends LevelerCard<LighthouseChronologist> {
+
+    public LighthouseChronologist (UUID ownerId) {
+        super(ownerId, 75, "Lighthouse Chronologist", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{1}{U}");
+        this.expansionSetCode = "ROE";
+        this.subtype.add("Human");
+        this.subtype.add("Wizard");
+        this.color.setBlue(true);
+        this.power = new MageInt(1);
+        this.toughness = new MageInt(3);
+
+        this.addAbility(new LevelUpAbility(new ManaCostsImpl("{U}")));
+        Abilities<Ability> abilities1 = new AbilitiesImpl<Ability>();
+        this.getLevels().add(new LevelAbility(4, 6, abilities1, 2, 4));
+
+        Abilities<Ability> abilities2 = new AbilitiesImpl<Ability>();
+        abilities2.add(new LighthouseChronologistAbility());
+        this.getLevels().add(new LevelAbility(7, -1, abilities2, 3, 5));
+
+    }
+
+    public LighthouseChronologist (final LighthouseChronologist card) {
+        super(card);
+    }
+
+    @Override
+    public LighthouseChronologist copy() {
+        return new LighthouseChronologist(this);
+    }
+
+}
+
+class LighthouseChronologistAbility extends TriggeredAbilityImpl<LighthouseChronologistAbility> {
+
+    public LighthouseChronologistAbility() {
+        super(Constants.Zone.BATTLEFIELD, new LighthouseChronologistEffect(), false);
+    }
+
+    public LighthouseChronologistAbility(final LighthouseChronologistAbility ability) {
+        super(ability);
+    }
+
+    @Override
+    public LighthouseChronologistAbility copy() {
+        return new LighthouseChronologistAbility(this);
+    }
+
+    @Override
+    public boolean checkTrigger(GameEvent event, Game game) {
+        if (event.getType() == GameEvent.EventType.END_TURN_STEP_PRE && !game.getActivePlayerId().equals(this.controllerId)) {
+			return true;
+		}
+		return false;
+    }
+
+    @Override
+    public String getRule() {
+        return "At the beginning of each end step, if it's not your turn, take an extra turn after this one.";
+    }
+}
+
+class LighthouseChronologistEffect extends OneShotEffect<LighthouseChronologistEffect> {
+
+	public LighthouseChronologistEffect() {
+		super(Outcome.ExtraTurn);
+	}
+
+	public LighthouseChronologistEffect(final LighthouseChronologistEffect effect) {
+		super(effect);
+	}
+
+	@Override
+	public LighthouseChronologistEffect copy() {
+		return new LighthouseChronologistEffect(this);
+	}
+
+	@Override
+	public boolean apply(Game game, Ability source) {
+		game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false));
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/GrandArchitect.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/GrandArchitect.java
new file mode 100644
index 0000000000..ff51f94203
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/GrandArchitect.java
@@ -0,0 +1,134 @@
+/*
+ *  Copyright 2011 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.sets.scarsofmirrodin;
+
+import java.util.UUID;
+import mage.Constants.CardType;
+import mage.Constants.Duration;
+import mage.Constants.Layer;
+import mage.Constants.Outcome;
+import mage.Constants.Rarity;
+import mage.Constants.SubLayer;
+import mage.Constants.Zone;
+import mage.MageInt;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.BoostControlledEffect;
+import mage.abilities.effects.common.ManaEffect;
+import mage.abilities.mana.SimpleManaAbility;
+import mage.cards.CardImpl;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class GrandArchitect extends CardImpl<GrandArchitect> {
+
+	private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue creatures");
+	private static final FilterControlledCreaturePermanent filter2 = new FilterControlledCreaturePermanent("untapped blue creature");
+
+	static {
+		filter.getColor().setBlue(true);
+		filter.setUseColor(true);
+		filter2.getColor().setBlue(true);
+		filter2.setUseColor(true);
+		filter2.setTapped(false);
+		filter2.setUseTapped(true);
+	}
+
+	public GrandArchitect(UUID ownerId) {
+		super(ownerId, 33, "Grand Architect", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
+		this.expansionSetCode = "SOM";
+		this.subtype.add("Vedalken");
+		this.subtype.add("Artificer");
+		this.color.setBlue(true);
+		this.power = new MageInt(1);
+		this.toughness = new MageInt(3);
+
+		this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true)));
+		this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GrandArchitectEffect(), new ManaCostsImpl("{U}")));
+		this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new ManaEffect(Mana.ColorlessMana(2)), new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter2, true))));
+		//TODO: add filter to mana
+	}
+
+	public GrandArchitect(final GrandArchitect card) {
+		super(card);
+	}
+
+	@Override
+	public GrandArchitect copy() {
+		return new GrandArchitect(this);
+	}
+
+}
+
+class GrandArchitectEffect extends ContinuousEffectImpl<GrandArchitectEffect> {
+
+	public GrandArchitectEffect() {
+		super(Duration.EndOfTurn, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Detriment);
+	}
+
+	public GrandArchitectEffect(final GrandArchitectEffect effect) {
+		super(effect);
+	}
+
+	@Override
+	public GrandArchitectEffect copy() {
+		return new GrandArchitectEffect(this);
+	}
+
+	@Override
+	public boolean apply(Game game, Ability source) {
+		Permanent permanent = game.getPermanent(source.getFirstTarget());
+		if (permanent != null) {
+			permanent.getColor().setRed(true);
+			permanent.getColor().setWhite(false);
+			permanent.getColor().setGreen(false);
+			permanent.getColor().setBlue(false);
+			permanent.getColor().setBlack(false);
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public String getText(Ability source) {
+		return "Target artifact creature becomes blue until end of turn";
+	}
+}
diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/MyrBattlesphere.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/MyrBattlesphere.java
new file mode 100644
index 0000000000..899a9d7d4f
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/MyrBattlesphere.java
@@ -0,0 +1,169 @@
+/*
+ *  Copyright 2011 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.sets.scarsofmirrodin;
+
+import java.util.UUID;
+import mage.Constants.CardType;
+import mage.Constants.Duration;
+import mage.Constants.Outcome;
+import mage.Constants.Rarity;
+import mage.Constants.Zone;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.costs.common.TapVariableTargetCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.BoostPowerXSourceEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
+import mage.game.permanent.token.Token;
+import mage.players.Player;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class MyrBattlesphere extends CardImpl<MyrBattlesphere> {
+
+	public MyrBattlesphere(UUID ownerId) {
+		super(ownerId, 180, "Myr Battlesphere", Rarity.RARE, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
+		this.expansionSetCode = "SOM";
+		this.subtype.add("Myr");
+		this.subtype.add("Construct");
+		this.power = new MageInt(4);
+		this.toughness = new MageInt(7);
+
+		this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MyrToken(), 4), false));
+		this.addAbility(new MyrBattlesphereAbility());
+	}
+
+	public MyrBattlesphere(final MyrBattlesphere card) {
+		super(card);
+	}
+
+	@Override
+	public MyrBattlesphere copy() {
+		return new MyrBattlesphere(this);
+	}
+
+}
+
+class MyrToken extends Token {
+
+	public MyrToken() {
+		super("Myr", "1/1 colorless Myr artifact creature");
+		cardType.add(CardType.CREATURE);
+		cardType.add(CardType.ARTIFACT);
+		subtype.add("Myr");
+		power = new MageInt(1);
+		toughness = new MageInt(1);
+	}
+}
+
+class MyrBattlesphereAbility extends TriggeredAbilityImpl<MyrBattlesphereAbility> {
+
+	private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Myr");
+
+	static {
+		filter.getSubtype().add("Myr");
+		filter.setTapped(false);
+		filter.setUseTapped(true);
+	}
+
+	public MyrBattlesphereAbility() {
+		super(Zone.BATTLEFIELD, new BoostPowerXSourceEffect(Duration.EndOfTurn), true);
+		this.addEffect(new MyrBattlesphereEffect());
+		this.addCost(new TapVariableTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false)));
+	}
+
+	public MyrBattlesphereAbility(final MyrBattlesphereAbility ability) {
+		super(ability);
+	}
+
+	@Override
+	public boolean checkInterveningIfClause(Game game) {
+		if (costs.isPaid())
+			return true;
+		return costs.pay(game, this.getId(), this.getControllerId(), false);
+	}
+
+	@Override
+	public boolean checkTrigger(GameEvent event, Game game) {
+		if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId()) ) {
+			costs.clearPaid();
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public String getRule() {
+		return "When Myr Battlesphere attacks, " + super.getRule();
+	}
+
+	@Override
+	public MyrBattlesphereAbility copy() {
+		return new MyrBattlesphereAbility(this);
+	}
+
+}
+
+class MyrBattlesphereEffect extends OneShotEffect<MyrBattlesphereEffect> {
+
+	public MyrBattlesphereEffect() {
+		super(Outcome.Damage);
+	}
+
+	public MyrBattlesphereEffect(final MyrBattlesphereEffect effect) {
+		super(effect);
+	}
+
+	@Override
+	public boolean apply(Game game, Ability source) {
+		UUID defenderId = game.getCombat().getDefendingPlayer(source.getSourceId());
+		Player defender = game.getPlayer(defenderId);
+		if (defender != null) {
+			defender.damage(source.getCosts().getVariableCosts().get(0).getAmount(), source.getSourceId(), game, false, false);
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public MyrBattlesphereEffect copy() {
+		return new MyrBattlesphereEffect(this);
+	}
+
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java b/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java
new file mode 100644
index 0000000000..d5aa551cfc
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java
@@ -0,0 +1,124 @@
+/*
+ *  Copyright 2011 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.sets.worldwake;
+
+import java.util.UUID;
+import mage.Constants.CardType;
+import mage.Constants.Outcome;
+import mage.Constants.Rarity;
+import mage.Constants.Zone;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.mana.BlueManaAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.filter.FilterCard;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class HalimarDepths extends CardImpl<HalimarDepths> {
+
+	public HalimarDepths(UUID ownerId) {
+		super(ownerId, 137, "Halimar Depths", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
+		this.expansionSetCode = "WWK";
+        this.addAbility(new EntersBattlefieldTappedAbility());
+		this.addAbility(new EntersBattlefieldTriggeredAbility(new HalimarDepthsEffect()));
+		this.addAbility(new BlueManaAbility());
+	}
+
+	public HalimarDepths(final HalimarDepths card) {
+		super(card);
+	}
+
+	@Override
+	public HalimarDepths copy() {
+		return new HalimarDepths(this);
+	}
+
+}
+
+class HalimarDepthsEffect extends OneShotEffect<HalimarDepthsEffect> {
+
+	protected static FilterCard filter2 = new FilterCard("card to put on the top of your library");
+
+	public HalimarDepthsEffect() {
+		super(Outcome.Benefit);
+	}
+
+	public HalimarDepthsEffect(final HalimarDepthsEffect effect) {
+		super(effect);
+	}
+
+	@Override
+	public boolean apply(Game game, Ability source) {
+		Player player = game.getPlayer(source.getControllerId());
+		Cards cards = new CardsImpl(Zone.PICK);
+		for (int i = 0; i < 3; i++) {
+			Card card = player.getLibrary().removeFromTop(game);
+			cards.add(card);
+			game.setZone(card.getId(), Zone.PICK);
+		}
+		if (cards.size() > 1) {
+			TargetCard target2 = new TargetCard(Zone.PICK, filter2);
+			target2.setRequired(true);
+			while (cards.size() > 1) {
+				player.choose(cards, target2, game);
+				Card card = cards.get(target2.getFirstTarget(), game);
+				cards.remove(card);
+				card.moveToZone(Zone.LIBRARY, source.getId(), game, true);
+				target2.clearChosen();
+			}
+		}
+		if (cards.size() == 1) {
+			Card card = cards.get(cards.iterator().next(), game);
+			card.moveToZone(Zone.LIBRARY, source.getId(), game, true);
+		}
+		return true;
+	}
+
+	@Override
+	public HalimarDepthsEffect copy() {
+		return new HalimarDepthsEffect(this);
+	}
+
+	@Override
+	public String getText(Ability source) {
+		return "look at the top three cards of your library, then put them back in any order";
+	}
+
+}
diff --git a/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java b/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java
index ad8d74be95..fdc6378a8a 100644
--- a/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java
+++ b/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java
@@ -97,13 +97,8 @@ class GoblinGuideEffect extends OneShotEffect<GoblinGuideEffect> {
 
 	@Override
 	public boolean apply(Game game, Ability source) {
-		Player defender = null;
-		for (CombatGroup group: game.getCombat().getGroups()) {
-			if (group.getAttackers().contains(source.getSourceId())) {
-				defender = game.getPlayer(group.getDefenderId());
-				break;
-			}
-		}
+		UUID defenderId = game.getCombat().getDefendingPlayer(source.getSourceId());
+		Player defender = game.getPlayer(defenderId);
 		if (defender != null) {
 			Cards cards = new CardsImpl();
 			Card card = defender.getLibrary().getFromTop(game);
diff --git a/Mage.Sets/src/mage/sets/zendikar/KrakenHatchling.java b/Mage.Sets/src/mage/sets/zendikar/KrakenHatchling.java
new file mode 100644
index 0000000000..02234f6052
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/zendikar/KrakenHatchling.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 2011 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.sets.zendikar;
+
+import java.util.UUID;
+import mage.Constants.CardType;
+import mage.Constants.Rarity;
+import mage.MageInt;
+import mage.cards.CardImpl;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class KrakenHatchling extends CardImpl<KrakenHatchling> {
+
+	public KrakenHatchling(UUID ownerId) {
+		super(ownerId, 50, "Kraken Hatchling", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{U}");
+		this.expansionSetCode = "ZEN";
+		this.subtype.add("Kraken");
+		this.color.setBlue(true);
+		this.power = new MageInt(0);
+		this.toughness = new MageInt(4);
+
+	}
+
+	public KrakenHatchling(final KrakenHatchling card) {
+		super(card);
+	}
+
+	@Override
+	public KrakenHatchling copy() {
+		return new KrakenHatchling(this);
+	}
+
+}
diff --git a/Mage/src/mage/abilities/common/BeginningOfControllerUpkeepTriggeredAbility.java b/Mage/src/mage/abilities/common/BeginningOfControllerUpkeepTriggeredAbility.java
index 446d1f786c..6f5c1e78fd 100644
--- a/Mage/src/mage/abilities/common/BeginningOfControllerUpkeepTriggeredAbility.java
+++ b/Mage/src/mage/abilities/common/BeginningOfControllerUpkeepTriggeredAbility.java
@@ -31,6 +31,6 @@ public class BeginningOfControllerUpkeepTriggeredAbility extends TriggeredAbilit
 
     @Override
     public String getRule() {
-        return "At the beginning of your upkeep, " + effects.getText(this);
+        return "At the beginning of your upkeep, " + effects.getText(this) + ".";
     }
 }
diff --git a/Mage/src/mage/abilities/costs/common/TapVariableTargetCost.java b/Mage/src/mage/abilities/costs/common/TapVariableTargetCost.java
new file mode 100644
index 0000000000..7695183715
--- /dev/null
+++ b/Mage/src/mage/abilities/costs/common/TapVariableTargetCost.java
@@ -0,0 +1,100 @@
+/*
+ *  Copyright 2011 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.abilities.costs.common;
+
+import java.util.List;
+import java.util.UUID;
+import mage.Constants.Outcome;
+import mage.abilities.costs.CostImpl;
+import mage.abilities.costs.VariableCost;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetControlledPermanent;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class TapVariableTargetCost extends CostImpl<TapVariableTargetCost> implements VariableCost {
+
+	protected int amountPaid = 0;
+	protected TargetControlledPermanent target;
+
+	public TapVariableTargetCost(TargetControlledPermanent target) {
+		this.target = target;
+		this.text = "tap X " + target.getTargetName() + " you control";
+	}
+
+	public TapVariableTargetCost(final TapVariableTargetCost cost) {
+		super(cost);
+		this.target = cost.target.copy();
+		this.amountPaid = cost.amountPaid;
+	}
+
+	@Override
+	public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
+		return target.canChoose(controllerId, game);
+	}
+
+	@Override
+	public boolean pay(Game game, UUID sourceId, UUID controllerId, boolean noMana) {
+		amountPaid = 0;
+		while (true) {
+			target.clearChosen();
+			if (target.choose(Outcome.Tap, controllerId, game)) {
+				Permanent permanent = game.getPermanent(target.getFirstTarget());
+				if (permanent != null && permanent.tap(game)) {
+					amountPaid++;
+				}
+			}
+			else {
+				break;
+			}
+		}
+		paid = true;
+		return true;
+	}
+
+	@Override
+	public void clearPaid() {
+		paid = false;
+		amountPaid = 0;
+	}
+
+	@Override
+	public int getAmount() {
+		return amountPaid;
+	}
+
+	@Override
+	public TapVariableTargetCost copy() {
+		return new TapVariableTargetCost(this);
+	}
+
+}
diff --git a/Mage/src/mage/abilities/effects/common/BoostPowerXSourceEffect.java b/Mage/src/mage/abilities/effects/common/BoostPowerXSourceEffect.java
index 77be209ebf..fc04fe1e64 100644
--- a/Mage/src/mage/abilities/effects/common/BoostPowerXSourceEffect.java
+++ b/Mage/src/mage/abilities/effects/common/BoostPowerXSourceEffect.java
@@ -58,7 +58,7 @@ public class BoostPowerXSourceEffect extends ContinuousEffectImpl<BoostPowerXSou
 
 	@Override
 	public boolean apply(Game game, Ability source) {
-		int amount = source.getManaCosts().getVariableCosts().get(0).getAmount();
+		int amount = source.getCosts().getVariableCosts().get(0).getAmount();
 		Permanent target = (Permanent) game.getPermanent(source.getSourceId());
 		if (target != null) {
 			target.addPower(amount);
diff --git a/Mage/src/mage/abilities/effects/common/DamageXTargetEffect.java b/Mage/src/mage/abilities/effects/common/DamageXTargetEffect.java
index d3e0e016ba..6cce41d658 100644
--- a/Mage/src/mage/abilities/effects/common/DamageXTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/DamageXTargetEffect.java
@@ -56,7 +56,7 @@ public class DamageXTargetEffect extends OneShotEffect<DamageXTargetEffect> {
 
 	@Override
 	public boolean apply(Game game, Ability source) {
-		int amount = source.getManaCosts().getVariableCosts().get(0).getAmount();
+		int amount = source.getCosts().getVariableCosts().get(0).getAmount();
 		Permanent permanent = game.getPermanent(source.getFirstTarget());
 		if (permanent != null) {
 			permanent.damage(amount, source.getId(), game, true, false);
diff --git a/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java b/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java
new file mode 100644
index 0000000000..53b3f9ea20
--- /dev/null
+++ b/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 2011 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.abilities.effects.common;
+
+import mage.Constants.Outcome;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class DrawDiscardControllerEffect extends OneShotEffect<DrawDiscardControllerEffect> {
+
+	public DrawDiscardControllerEffect() {
+		super(Outcome.DrawCard);
+	}
+
+	public DrawDiscardControllerEffect(final DrawDiscardControllerEffect effect) {
+		super(effect);
+	}
+
+	@Override
+	public DrawDiscardControllerEffect copy() {
+		return new DrawDiscardControllerEffect(this);
+	}
+
+	@Override
+	public boolean apply(Game game, Ability source) {
+		Player player = game.getPlayer(source.getControllerId());
+		if (player != null) {
+			player.drawCards(1, game);
+			player.discard(1, source, game);
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public String getText(Ability source) {
+		return "Draw a card, then discard a card";
+	}
+
+
+}
diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java
index 12e7ca05eb..7ecc3c62eb 100644
--- a/Mage/src/mage/game/GameImpl.java
+++ b/Mage/src/mage/game/GameImpl.java
@@ -191,11 +191,15 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
 
 	@Override
 	public Player getPlayer(UUID playerId) {
+		if (playerId == null)
+			return null;
 		return state.getPlayer(playerId);
 	}
 
 	@Override
 	public MageObject getObject(UUID objectId) {
+		if (objectId == null)
+			return null;
 		MageObject object;
 		if (state.getBattlefield().containsPermanent(objectId)) {
 			object = state.getBattlefield().getPermanent(objectId);
@@ -217,16 +221,22 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
 
 	@Override
 	public Permanent getPermanent(UUID permanentId) {
+		if (permanentId == null)
+			return null;
 		return state.getPermanent(permanentId);
 	}
 
 	@Override
 	public Card getCard(UUID cardId) {
+		if (cardId == null)
+			return null;
 		return gameCards.get(cardId);
 	}
 
 	@Override
 	public Zone getZone(UUID objectId) {
+		if (objectId == null)
+			return null;
 		return state.getZone(objectId);
 	}
 
diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java
index a359f77648..1cdc5d345c 100644
--- a/Mage/src/mage/game/combat/Combat.java
+++ b/Mage/src/mage/game/combat/Combat.java
@@ -318,6 +318,17 @@ public class Combat implements Serializable, Copyable<Combat> {
 		return false;
 	}
 
+	public UUID getDefendingPlayer(UUID attackerId) {
+		UUID defenderId = null;
+		for (CombatGroup group: groups) {
+			if (group.getAttackers().contains(attackerId)) {
+				defenderId = group.getDefenderId();
+				break;
+			}
+		}
+		return defenderId;
+	}
+
 	private Set<UUID> getPlayerDefenders(Game game) {
 		Set<UUID> playerDefenders = new HashSet<UUID>();
 		for (CombatGroup group: groups) {