From 1739bcab56382f00ff377f704dd271ffd5fd1386 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Fri, 9 Oct 2015 16:29:51 +0200
Subject: [PATCH 01/13] * Added missing override of getAllEffects.

---
 Mage/src/mage/game/stack/StackAbility.java | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java
index aa8d58de40..157dace466 100644
--- a/Mage/src/mage/game/stack/StackAbility.java
+++ b/Mage/src/mage/game/stack/StackAbility.java
@@ -237,6 +237,11 @@ public class StackAbility extends StackObjImpl implements Ability {
         return ability.getEffects();
     }
 
+    @Override
+    public Effects getAllEffects() {
+        return ability.getAllEffects();
+    }
+
     @Override
     public Effects getEffects(Game game, EffectType effectType) {
         return ability.getEffects(game, effectType);

From abc6b11c32e4350e8846963b454ebe3adfe00cc9 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Fri, 9 Oct 2015 16:30:28 +0200
Subject: [PATCH 02/13] * Mizzium Meddler - Fixed target change handling

---
 .../sets/magicorigins/MizziumMeddler.java     | 106 +-------------
 .../src/mage/sets/newphyrexia/Spellskite.java | 120 +---------------
 ...getOfTargetSpellAbilityToSourceEffect.java | 130 ++++++++++++++++++
 3 files changed, 136 insertions(+), 220 deletions(-)
 create mode 100644 Mage/src/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java

diff --git a/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java b/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java
index c0a7dc19ae..a59cd456d3 100644
--- a/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java
+++ b/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java
@@ -29,23 +29,14 @@ package mage.sets.magicorigins;
 
 import java.util.UUID;
 import mage.MageInt;
-import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ChangeATargetOfTargetSpellAbilityToSourceEffect;
 import mage.abilities.keyword.FlashAbility;
 import mage.cards.CardImpl;
 import mage.constants.CardType;
-import mage.constants.Outcome;
 import mage.constants.Rarity;
-import mage.game.Game;
-import mage.game.stack.Spell;
-import mage.game.stack.StackAbility;
-import mage.game.stack.StackObject;
-import mage.players.Player;
-import mage.target.Target;
 import mage.target.TargetStackObject;
-import mage.target.Targets;
 
 /**
  *
@@ -63,9 +54,9 @@ public class MizziumMeddler extends CardImpl {
 
         // Flash
         this.addAbility(FlashAbility.getInstance());
-        
-        // When Mizzium Meddler enters the battlefield, change a target of target spell or ability to Mizzium Meddler.
-        Ability ability = new EntersBattlefieldTriggeredAbility(new MizziumMeddlerEffect());
+
+        // When Mizzium Meddler enters the battlefield, you may change a target of target spell or ability to Mizzium Meddler.
+        Ability ability = new EntersBattlefieldTriggeredAbility(new ChangeATargetOfTargetSpellAbilityToSourceEffect(), true);
         ability.addTarget(new TargetStackObject());
         this.addAbility(ability);
     }
@@ -79,92 +70,3 @@ public class MizziumMeddler extends CardImpl {
         return new MizziumMeddler(this);
     }
 }
-
-class MizziumMeddlerEffect extends OneShotEffect {
-
-    public MizziumMeddlerEffect() {
-        super(Outcome.Neutral);
-        staticText = "Change a target of target spell or ability to {this}";
-    }
-
-    public MizziumMeddlerEffect(final MizziumMeddlerEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
-        MageObject sourceObject = game.getObject(source.getSourceId());
-        if (stackObject != null && sourceObject != null) {
-            Targets targets;
-            Ability sourceAbility;
-            MageObject oldTarget = null;
-            if (stackObject instanceof Spell) {
-                Spell spell = (Spell)stackObject;
-                sourceAbility = spell.getSpellAbility();
-                targets = spell.getSpellAbility().getTargets();
-            } else if (stackObject instanceof StackAbility) {
-                StackAbility stackAbility = (StackAbility)stackObject;
-                sourceAbility = stackAbility;
-                targets = stackAbility.getTargets();
-            } else {
-                return false;
-            }
-            boolean twoTimesTarget = false;
-            if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
-                Target target = targets.get(0);
-                if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
-                    oldTarget = game.getObject(targets.getFirstTarget());
-                    target.clearChosen();
-                    // The source is still the spell on the stack
-                    target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
-                }                
-            } else {
-                Player player = game.getPlayer(source.getControllerId());
-                for (Target target: targets) {
-                    for (UUID targetId: target.getTargets()) {
-                        MageObject object = game.getObject(targetId);
-                        String name;
-                        if (object == null) {
-                            Player targetPlayer = game.getPlayer(targetId);
-                            name = targetPlayer.getLogName();
-                        } else {
-                            name = object.getName();
-                        }
-                        if (!targetId.equals(source.getSourceId()) && target.getTargets().contains(source.getSourceId())) {
-                            // you can't change this target to MizziumMeddler because MizziumMeddler is already another targetId of that target.
-                            twoTimesTarget = true;
-                            continue;
-                        }
-                        if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), source, game)) {
-                            if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
-                                oldTarget = game.getObject(targets.getFirstTarget());
-                                target.remove(targetId);
-                                // The source is still the spell on the stack
-                                target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-            if (oldTarget != null) {
-                game.informPlayers(sourceObject.getLogName() + ": Changed target of " +stackObject.getLogName() + " from " + oldTarget.getLogName() + " to " + sourceObject.getLogName());
-            } else {
-                if (twoTimesTarget) {
-                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getName());
-                } else {
-                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getName());
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public MizziumMeddlerEffect copy() {
-        return new MizziumMeddlerEffect(this);
-    }
-
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java b/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java
index ca7cfbd7e8..4e12742197 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java
@@ -29,24 +29,15 @@ package mage.sets.newphyrexia;
 
 import java.util.UUID;
 import mage.MageInt;
-import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleActivatedAbility;
 import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ChangeATargetOfTargetSpellAbilityToSourceEffect;
 import mage.cards.CardImpl;
 import mage.constants.CardType;
-import mage.constants.Outcome;
 import mage.constants.Rarity;
 import mage.constants.Zone;
-import mage.game.Game;
-import mage.game.stack.Spell;
-import mage.game.stack.StackAbility;
-import mage.game.stack.StackObject;
-import mage.players.Player;
-import mage.target.Target;
 import mage.target.TargetStackObject;
-import mage.target.Targets;
 
 /**
  *
@@ -62,7 +53,7 @@ public class Spellskite extends CardImpl {
         this.toughness = new MageInt(4);
 
         // {UP}: Change a target of target spell or ability to Spellskite.
-        Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SpellskiteEffect(), new ManaCostsImpl("{UP}"));
+        Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChangeATargetOfTargetSpellAbilityToSourceEffect(), new ManaCostsImpl("{UP}"));
         ability.addTarget(new TargetStackObject());
         this.addAbility(ability);
     }
@@ -76,110 +67,3 @@ public class Spellskite extends CardImpl {
         return new Spellskite(this);
     }
 }
-
-class SpellskiteEffect extends OneShotEffect {
-
-    public SpellskiteEffect() {
-        super(Outcome.Neutral);
-        staticText = "Change a target of target spell or ability to {this}";
-    }
-
-    public SpellskiteEffect(final SpellskiteEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
-        MageObject sourceObject = game.getObject(source.getSourceId());
-        if (stackObject != null && sourceObject != null) {
-            Targets targets = new Targets();
-            Ability sourceAbility;
-            String oldTargetName = null;
-            if (stackObject instanceof Spell) {
-                Spell spell = (Spell) stackObject;
-                sourceAbility = spell.getSpellAbility();
-            } else if (stackObject instanceof StackAbility) {
-                StackAbility stackAbility = (StackAbility) stackObject;
-                sourceAbility = stackAbility;
-            } else {
-                return false;
-            }
-            for (UUID modeId : sourceAbility.getModes().getSelectedModes()) {
-                sourceAbility.getModes().setActiveMode(modeId);
-                targets.addAll(sourceAbility.getTargets());
-            }
-
-            boolean twoTimesTarget = false;
-            if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
-                Target target = targets.get(0);
-                if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
-                    oldTargetName = getTargetName(targets.getFirstTarget(), game);
-                    target.clearChosen();
-                    // The source is still the spell on the stack
-                    target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
-                }
-            } else {
-                Player controller = game.getPlayer(source.getControllerId());
-                boolean validTargets = false;
-                do {
-                    for (Target target : targets) {
-                        for (UUID targetId : target.getTargets()) {
-                            String name = getTargetName(targets.getFirstTarget(), game);
-                            if (!targetId.equals(source.getSourceId()) && target.getTargets().contains(source.getSourceId())) {
-                                // you can't change this target to Spellskite because Spellskite is already another targetId of that target.
-                                twoTimesTarget = true;
-                                continue;
-                            }
-                            if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
-                                validTargets = true;
-                                if (name != null
-                                        && controller.chooseUse(Outcome.Neutral, "Change target from " + name + " to " + sourceObject.getLogName() + "?", source, game)) {
-                                    oldTargetName = getTargetName(targetId, game);
-                                    target.remove(targetId);
-                                    // The source is still the spell on the stack
-                                    target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
-                                    break;
-                                }
-                            }
-                        }
-                        if (oldTargetName != null) {
-                            break;
-                        }
-                    }
-                    if (oldTargetName == null) {
-                        game.informPlayer(controller, "You have to select at least one target to change to spellskite!");
-                    }
-                } while (validTargets && oldTargetName == null);
-            }
-            if (oldTargetName != null) {
-                game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTargetName + " to " + sourceObject.getLogName());
-            } else {
-                if (twoTimesTarget) {
-                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName());
-                } else {
-                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName());
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public SpellskiteEffect copy() {
-        return new SpellskiteEffect(this);
-    }
-
-    private String getTargetName(UUID objectId, Game game) {
-        MageObject object = game.getObject(objectId);
-        if (object != null) {
-            return object.getLogName();
-        }
-        Player player = game.getPlayer(objectId);
-        if (player != null) {
-            return player.getLogName();
-        }
-        return null;
-    }
-}
diff --git a/Mage/src/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java b/Mage/src/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java
new file mode 100644
index 0000000000..e660cd1967
--- /dev/null
+++ b/Mage/src/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java
@@ -0,0 +1,130 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mage.abilities.effects.common;
+
+import java.util.UUID;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.stack.Spell;
+import mage.game.stack.StackAbility;
+import mage.game.stack.StackObject;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.Targets;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ChangeATargetOfTargetSpellAbilityToSourceEffect extends OneShotEffect {
+
+    public ChangeATargetOfTargetSpellAbilityToSourceEffect() {
+        super(Outcome.Neutral);
+        staticText = "Change a target of target spell or ability to {this}";
+    }
+
+    public ChangeATargetOfTargetSpellAbilityToSourceEffect(final ChangeATargetOfTargetSpellAbilityToSourceEffect effect) {
+        super(effect);
+    }
+
+    @Override
+    public boolean apply(Game game, Ability source) {
+        StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (stackObject != null && sourceObject != null) {
+            Targets targets = new Targets();
+            Ability sourceAbility;
+            String oldTargetName = null;
+            if (stackObject instanceof Spell) {
+                Spell spell = (Spell) stackObject;
+                sourceAbility = spell.getSpellAbility();
+            } else if (stackObject instanceof StackAbility) {
+                StackAbility stackAbility = (StackAbility) stackObject;
+                sourceAbility = stackAbility;
+            } else {
+                return false;
+            }
+            for (UUID modeId : sourceAbility.getModes().getSelectedModes()) {
+                sourceAbility.getModes().setActiveMode(modeId);
+                targets.addAll(sourceAbility.getTargets());
+            }
+
+            boolean twoTimesTarget = false;
+            if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
+                Target target = targets.get(0);
+                if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
+                    oldTargetName = getTargetName(targets.getFirstTarget(), game);
+                    target.clearChosen();
+                    // The source is still the spell on the stack
+                    target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
+                }
+            } else {
+                Player controller = game.getPlayer(source.getControllerId());
+                boolean validTargets = false;
+                do {
+                    for (Target target : targets) {
+                        for (UUID targetId : target.getTargets()) {
+                            String name = getTargetName(targets.getFirstTarget(), game);
+                            if (!targetId.equals(source.getSourceId()) && target.getTargets().contains(source.getSourceId())) {
+                                // you can't change this target to source because the source is already another targetId of that target.
+                                twoTimesTarget = true;
+                                continue;
+                            }
+                            if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
+                                validTargets = true;
+                                if (name != null
+                                        && controller.chooseUse(Outcome.Neutral, "Change target from " + name + " to " + sourceObject.getLogName() + "?", source, game)) {
+                                    oldTargetName = getTargetName(targetId, game);
+                                    target.remove(targetId);
+                                    // The source is still the spell on the stack
+                                    target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
+                                    break;
+                                }
+                            }
+                        }
+                        if (oldTargetName != null) {
+                            break;
+                        }
+                    }
+                    if (oldTargetName == null) {
+                        game.informPlayer(controller, "You have to select at least one target to change to " + sourceObject.getIdName() + "!");
+                    }
+                } while (validTargets && oldTargetName == null);
+            }
+            if (oldTargetName != null) {
+                game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTargetName + " to " + sourceObject.getLogName());
+            } else {
+                if (twoTimesTarget) {
+                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName());
+                } else {
+                    game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName());
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public ChangeATargetOfTargetSpellAbilityToSourceEffect copy() {
+        return new ChangeATargetOfTargetSpellAbilityToSourceEffect(this);
+    }
+
+    private String getTargetName(UUID objectId, Game game) {
+        MageObject object = game.getObject(objectId);
+        if (object != null) {
+            return object.getLogName();
+        }
+        Player player = game.getPlayer(objectId);
+        if (player != null) {
+            return player.getLogName();
+        }
+        return null;
+    }
+}

From bdbfe633d58b66156de7c4e978e178caca061bf9 Mon Sep 17 00:00:00 2001
From: Jeff <Jeff@PCB1000.delmarus.com>
Date: Fri, 9 Oct 2015 14:13:59 -0500
Subject: [PATCH 03/13] - Fixed text Nim Abomination.

---
 .../mage/sets/darksteel/NimAbomination.java   | 33 ++++++++++++++++---
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/darksteel/NimAbomination.java b/Mage.Sets/src/mage/sets/darksteel/NimAbomination.java
index d13bc0e250..23c0aa159e 100644
--- a/Mage.Sets/src/mage/sets/darksteel/NimAbomination.java
+++ b/Mage.Sets/src/mage/sets/darksteel/NimAbomination.java
@@ -29,20 +29,22 @@ package mage.sets.darksteel;
 
 import java.util.UUID;
 import mage.MageInt;
+import mage.abilities.Ability;
 import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
-import mage.abilities.condition.InvertCondition;
-import mage.abilities.condition.common.SourceTappedCondition;
+import mage.abilities.condition.Condition;
 import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
 import mage.cards.CardImpl;
 import mage.constants.CardType;
 import mage.constants.Rarity;
 import mage.constants.TargetController;
 import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
 
 /**
  *
  * @author LoneFox
-
+ *
  */
 public class NimAbomination extends CardImpl {
 
@@ -55,7 +57,7 @@ public class NimAbomination extends CardImpl {
 
         // At the beginning of your end step, if Nim Abomination is untapped, you lose 3 life.
         this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new LoseLifeSourceControllerEffect(3),
-            TargetController.YOU, new InvertCondition(new SourceTappedCondition()), false));
+                TargetController.YOU, new SourceUntappedCondition(), false));
     }
 
     public NimAbomination(final NimAbomination card) {
@@ -67,3 +69,26 @@ public class NimAbomination extends CardImpl {
         return new NimAbomination(this);
     }
 }
+
+class SourceUntappedCondition implements Condition {
+
+    private static final SourceUntappedCondition fInstance = new SourceUntappedCondition();
+
+    public static SourceUntappedCondition getInstance() {
+        return fInstance;
+    }
+
+    @Override
+    public boolean apply(Game game, Ability source) {
+        Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
+        if (permanent != null) {
+            return !permanent.isTapped();
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "if {this} is untapped";
+    }
+}

From 62ab3758e9e37041855fd341cf9d2c67914f4a21 Mon Sep 17 00:00:00 2001
From: LoneFox <lonefox@kapsi.fi>
Date: Fri, 9 Oct 2015 22:15:53 +0300
Subject: [PATCH 04/13] Fix Land Cap's card number

---
 Mage.Sets/src/mage/sets/iceage/LandCap.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Mage.Sets/src/mage/sets/iceage/LandCap.java b/Mage.Sets/src/mage/sets/iceage/LandCap.java
index ebb3dcb35f..c430a5be24 100644
--- a/Mage.Sets/src/mage/sets/iceage/LandCap.java
+++ b/Mage.Sets/src/mage/sets/iceage/LandCap.java
@@ -55,7 +55,7 @@ import mage.counters.CounterType;
 public class LandCap extends CardImpl {
 
     public LandCap(UUID ownerId) {
-        super(ownerId, 319, "Land Cap", Rarity.RARE, new CardType[]{CardType.LAND}, "");
+        super(ownerId, 338, "Land Cap", Rarity.RARE, new CardType[]{CardType.LAND}, "");
         this.expansionSetCode = "ICE";
 
         // Land Cap doesn't untap during your untap step if it has a depletion counter on it.

From 8b8097878cb1234a27c90cb8c619e310747dfae3 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 03:52:38 +0200
Subject: [PATCH 05/13] * Reworked/Cleaned card movement handling.

---
 .../src/mage/player/ai/ComputerPlayer6.java   |  21 +-
 .../avacynrestored/InfiniteReflection.java    |  24 +-
 .../sets/dragonsmaze/PossibilityStorm.java    |   1 -
 .../mage/sets/fifthdawn/MycosynthGolem.java   |  36 ++-
 .../mage/sets/gatecrash/ThespiansStage.java   |  11 +-
 .../sets/guildpact/MizziumTransreliquat.java  |  14 +-
 .../sets/journeyintonyx/PolymorphousRush.java |  15 +-
 .../mage/sets/judgment/WorldgorgerDragon.java |   4 +-
 .../mage/sets/limitedalpha/CopyArtifact.java  |   6 +-
 .../src/mage/sets/lorwyn/Shapesharer.java     |  14 +-
 Mage.Sets/src/mage/sets/magic2012/Flight.java |  15 +-
 .../mage/sets/magic2012/PhantasmalImage.java  |   6 +-
 .../sets/magic2015/MercurialPretender.java    |   7 +-
 .../sets/mirrodinbesieged/KnowledgePool.java  |   7 +-
 .../sets/newphyrexia/PhyrexianMetamorph.java  |   2 +-
 .../sets/planeshift/SkyshipWeatherlight.java  |   2 +-
 .../RenegadeDoppelganger.java                 |   3 +-
 .../SakashimaTheImpostor.java                 |   6 +-
 .../mage/sets/shadowmoor/CemeteryPuca.java    |   2 +-
 .../sets/shadowmoor/LureboundScarecrow.java   |  42 +---
 .../src/mage/sets/shadowmoor/Mirrorweave.java |   3 +-
 .../sets/shardsofalara/TidehollowSculler.java |   2 +-
 .../mage/sets/tempest/RootwaterMatriarch.java |  12 +-
 .../sets/theros/AshiokNightmareWeaver.java    |  21 +-
 .../unlimitededition/VesuvanDoppelganger.java |   2 +-
 .../abilities/enters/ProteanHydraTest.java    |   5 +-
 .../abilities/other/MycosynthGolemTest.java   |   4 +-
 .../other/SoulfireGrandMasterTest.java        |   6 +-
 .../conditional/RootwaterMatriarchTest.java   |  46 ++--
 .../test/cards/copy/PhantasmalImageTest.java  | 107 ++++-----
 .../cards/copy/PhyrexianMetamorphTest.java    | 117 +++++++---
 .../java/org/mage/test/player/TestPlayer.java |   7 +-
 .../base/impl/CardTestPlayerAPIImpl.java      |   2 +-
 .../common/DiesAttachedTriggeredAbility.java  |   2 +-
 .../common/EnchantedTargetCondition.java      |   6 +-
 .../effects/AuraReplacementEffect.java        |  98 ++++----
 .../abilities/effects/ContinuousEffects.java  |   6 +-
 .../effects/ContinuousEffectsList.java        |  81 +++----
 .../effects/EntersBattlefieldEffect.java      |  68 +++---
 .../effects/common/CopyPermanentEffect.java   |  18 +-
 .../CounterTargetWithReplacementEffect.java   |  31 +--
 Mage/src/mage/cards/Card.java                 |   5 +
 Mage/src/mage/cards/CardImpl.java             | 214 ++++++------------
 Mage/src/mage/game/CardState.java             |  35 +--
 Mage/src/mage/game/Game.java                  |   6 +-
 Mage/src/mage/game/GameImpl.java              |  27 ++-
 Mage/src/mage/game/GameState.java             |   2 +-
 .../mage/game/permanent/PermanentCard.java    |  79 ++++---
 Mage/src/mage/game/stack/Spell.java           |  20 +-
 Mage/src/mage/game/stack/SpellStack.java      |  14 +-
 Mage/src/mage/game/stack/StackAbility.java    |   5 +-
 Mage/src/mage/players/Player.java             |  14 ++
 Mage/src/mage/players/PlayerImpl.java         |  81 ++++++-
 Mage/src/mage/util/CardUtil.java              |  17 --
 54 files changed, 714 insertions(+), 687 deletions(-)

diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
index 66fc062f4d..022e7f9ee3 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
@@ -436,29 +436,32 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
     }
 
     protected void resolve(SimulationNode2 node, int depth, Game game) {
-        StackObject ability = game.getStack().pop();
-        if (ability instanceof StackAbility) {
-            SearchEffect effect = getSearchEffect((StackAbility) ability);
-            if (effect != null && ability.getControllerId().equals(playerId)) {
+        StackObject stackObject = game.getStack().getFirst();
+        if (stackObject instanceof StackAbility) {
+            SearchEffect effect = getSearchEffect((StackAbility) stackObject);
+            if (effect != null && stackObject.getControllerId().equals(playerId)) {
                 Target target = effect.getTarget();
                 if (!target.doneChosing()) {
-                    for (UUID targetId : target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game)) {
+                    for (UUID targetId : target.possibleTargets(stackObject.getSourceId(), stackObject.getControllerId(), game)) {
                         Game sim = game.copy();
-                        StackAbility newAbility = (StackAbility) ability.copy();
+                        StackAbility newAbility = (StackAbility) stackObject.copy();
                         SearchEffect newEffect = getSearchEffect(newAbility);
                         newEffect.getTarget().addTarget(targetId, newAbility, sim);
                         sim.getStack().push(newAbility);
-                        SimulationNode2 newNode = new SimulationNode2(node, sim, depth, ability.getControllerId());
+                        SimulationNode2 newNode = new SimulationNode2(node, sim, depth, stackObject.getControllerId());
                         node.children.add(newNode);
                         newNode.getTargets().add(targetId);
-                        logger.trace("Sim search -- node#: " + SimulationNode2.getCount() + " for player: " + sim.getPlayer(ability.getControllerId()).getName());
+                        logger.trace("Sim search -- node#: " + SimulationNode2.getCount() + " for player: " + sim.getPlayer(stackObject.getControllerId()).getName());
                     }
                     return;
                 }
             }
         }
         //logger.info("simulating resolve ");
-        ability.resolve(game);
+        stackObject.resolve(game);
+        if (stackObject instanceof StackAbility) {
+            game.getStack().remove(stackObject);
+        }
         game.applyEffects();
         game.getPlayers().resetPassed();
         game.getPlayerList().setCurrent(game.getActivePlayerId());
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/InfiniteReflection.java b/Mage.Sets/src/mage/sets/avacynrestored/InfiniteReflection.java
index 3f79caf503..1744100e91 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/InfiniteReflection.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/InfiniteReflection.java
@@ -27,7 +27,8 @@
  */
 package mage.sets.avacynrestored;
 
-import mage.constants.*;
+import java.util.UUID;
+import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.Mode;
 import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -37,6 +38,11 @@ import mage.abilities.effects.ReplacementEffectImpl;
 import mage.abilities.effects.common.AttachEffect;
 import mage.abilities.keyword.EnchantAbility;
 import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
 import mage.filter.FilterPermanent;
 import mage.filter.common.FilterControlledCreaturePermanent;
 import mage.game.Game;
@@ -47,8 +53,6 @@ import mage.target.TargetPermanent;
 import mage.target.common.TargetCreaturePermanent;
 import mage.util.functions.EmptyApplyToPermanent;
 
-import java.util.UUID;
-
 /**
  *
  * @author noxx
@@ -60,7 +64,6 @@ public class InfiniteReflection extends CardImpl {
         this.expansionSetCode = "AVR";
         this.subtype.add("Aura");
 
-
         // Enchant creature
         TargetPermanent auraTarget = new TargetCreaturePermanent();
         this.getSpellAbility().addTarget(auraTarget);
@@ -109,9 +112,9 @@ class InfiniteReflectionTriggeredEffect extends OneShotEffect {
         if (sourcePermanent != null && sourcePermanent.getAttachedTo() != null) {
             Permanent toCopyFromPermanent = game.getPermanent(sourcePermanent.getAttachedTo());
             if (toCopyFromPermanent != null) {
-                for (Permanent toCopyToPermanent: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
+                for (Permanent toCopyToPermanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
                     if (!toCopyToPermanent.equals(toCopyFromPermanent) && !(toCopyToPermanent instanceof PermanentToken)) {
-                        game.copyPermanent(toCopyFromPermanent, toCopyToPermanent, source, new EmptyApplyToPermanent());
+                        game.copyPermanent(toCopyFromPermanent, toCopyToPermanent.getId(), source, new EmptyApplyToPermanent());
                     }
                 }
                 return true;
@@ -135,7 +138,7 @@ class InfiniteReflectionEntersBattlefieldEffect extends ReplacementEffectImpl {
     public boolean checksEventType(GameEvent event, Game game) {
         return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
     }
-    
+
     @Override
     public boolean applies(GameEvent event, Ability source, Game game) {
         Permanent permanent = game.getPermanent(event.getTargetId());
@@ -144,15 +147,14 @@ class InfiniteReflectionEntersBattlefieldEffect extends ReplacementEffectImpl {
                 && !(permanent instanceof PermanentToken);
     }
 
-
     @Override
     public boolean replaceEvent(GameEvent event, Ability source, Game game) {
-        Permanent toCopyToPermanent = game.getPermanent(event.getTargetId());
+        MageObject toCopyToObject = game.getObject(event.getTargetId());
         Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (sourcePermanent != null && toCopyToPermanent != null && sourcePermanent.getAttachedTo() != null) {
+        if (sourcePermanent != null && toCopyToObject != null && sourcePermanent.getAttachedTo() != null) {
             Permanent toCopyFromPermanent = game.getPermanent(sourcePermanent.getAttachedTo());
             if (toCopyFromPermanent != null) {
-                game.copyPermanent(toCopyFromPermanent, toCopyToPermanent, source, new EmptyApplyToPermanent());
+                game.copyPermanent(toCopyFromPermanent, toCopyToObject.getId(), source, new EmptyApplyToPermanent());
             }
         }
         return false;
diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java b/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java
index 1c6e13edb2..392679db64 100644
--- a/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java
+++ b/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java
@@ -157,7 +157,6 @@ class PossibilityStormEffect extends OneShotEffect {
                     if (exile != null) {
                         while (exile.size() > 0) {
                             card = exile.getRandom(game);
-                            exile.remove(card.getId());
                             spellController.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, false, false);
                         }
                     }
diff --git a/Mage.Sets/src/mage/sets/fifthdawn/MycosynthGolem.java b/Mage.Sets/src/mage/sets/fifthdawn/MycosynthGolem.java
index 084fbf7fc3..ea343a1c7c 100644
--- a/Mage.Sets/src/mage/sets/fifthdawn/MycosynthGolem.java
+++ b/Mage.Sets/src/mage/sets/fifthdawn/MycosynthGolem.java
@@ -54,14 +54,7 @@ import mage.players.Player;
  * @author jeffwadsworth
  */
 public class MycosynthGolem extends CardImpl {
-    
-    private static final FilterSpell filter = new FilterSpell("Artifact creature spells you cast");
 
-    static {
-        filter.add(new CardTypePredicate(CardType.ARTIFACT));
-        filter.add(new CardTypePredicate(CardType.CREATURE));
-    }
-    
     public MycosynthGolem(UUID ownerId) {
         super(ownerId, 137, "Mycosynth Golem", Rarity.RARE, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{11}");
         this.expansionSetCode = "5DN";
@@ -75,8 +68,8 @@ public class MycosynthGolem extends CardImpl {
 
         // Artifact creature spells you cast have affinity for artifacts.
         this.addAbility(new SimpleStaticAbility(
-            Zone.BATTLEFIELD, new MycosynthGolemGainAbilitySpellsEffect(new AffinityForArtifactsAbility(), filter)));        
-        
+                Zone.BATTLEFIELD, new MycosynthGolemGainAbilitySpellsEffect()));
+
     }
 
     public MycosynthGolem(final MycosynthGolem card) {
@@ -91,20 +84,21 @@ public class MycosynthGolem extends CardImpl {
 
 class MycosynthGolemGainAbilitySpellsEffect extends ContinuousEffectImpl {
 
-    private final Ability ability;
-    private final FilterSpell filter;
+    private static final FilterSpell filter = new FilterSpell("Artifact creature spells you cast");
+    private static final Ability ability = new AffinityForArtifactsAbility();
 
-    public MycosynthGolemGainAbilitySpellsEffect(Ability ability, FilterSpell filter) {
+    static {
+        filter.add(new CardTypePredicate(CardType.ARTIFACT));
+        filter.add(new CardTypePredicate(CardType.CREATURE));
+    }
+
+    public MycosynthGolemGainAbilitySpellsEffect() {
         super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
-        this.ability = ability;
-        this.filter = filter;
-        staticText = filter.getMessage() + " have " + ability.getRule();
+        staticText = "Artifact creature spells you cast have affinity for artifacts";
     }
 
     public MycosynthGolemGainAbilitySpellsEffect(final MycosynthGolemGainAbilitySpellsEffect effect) {
         super(effect);
-        this.ability = effect.ability;
-        this.filter = effect.filter;
     }
 
     @Override
@@ -114,17 +108,15 @@ class MycosynthGolemGainAbilitySpellsEffect extends ContinuousEffectImpl {
 
     @Override
     public boolean apply(Game game, Ability source) {
-        Player player = game.getPlayer(source.getControllerId());
+        Player controller = game.getPlayer(source.getControllerId());
         Permanent permanent = game.getPermanent(source.getSourceId());
-        if (player != null && permanent != null) {
+        if (controller != null && permanent != null) {
             for (StackObject stackObject : game.getStack()) {
                 // only spells cast, so no copies of spells
                 if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) {
                     Spell spell = (Spell) stackObject;
                     if (filter.match(spell, game)) {
-                        if (!spell.getAbilities().contains(ability)) {
-                            game.getState().addOtherAbility(spell.getCard(), ability);
-                        }
+                        game.getState().addOtherAbility(spell.getCard(), ability);
                     }
                 }
             }
diff --git a/Mage.Sets/src/mage/sets/gatecrash/ThespiansStage.java b/Mage.Sets/src/mage/sets/gatecrash/ThespiansStage.java
index fa629410a6..8fc75c855c 100644
--- a/Mage.Sets/src/mage/sets/gatecrash/ThespiansStage.java
+++ b/Mage.Sets/src/mage/sets/gatecrash/ThespiansStage.java
@@ -28,10 +28,6 @@
 package mage.sets.gatecrash;
 
 import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleActivatedAbility;
 import mage.abilities.costs.common.TapSourceCost;
@@ -39,6 +35,9 @@ import mage.abilities.costs.mana.GenericManaCost;
 import mage.abilities.effects.OneShotEffect;
 import mage.abilities.mana.ColorlessManaAbility;
 import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
 import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.permanent.Permanent;
@@ -80,7 +79,7 @@ class ThespiansStageCopyEffect extends OneShotEffect {
 
     public ThespiansStageCopyEffect() {
         super(Outcome.Benefit);
-        this.staticText = "Thespian's Stage becomes a copy of target land and gains this ability";
+        this.staticText = "{this} becomes a copy of target land and gains this ability";
     }
 
     public ThespiansStageCopyEffect(final ThespiansStageCopyEffect effect) {
@@ -97,7 +96,7 @@ class ThespiansStageCopyEffect extends OneShotEffect {
         Permanent sourcePermanent = game.getPermanent(source.getSourceId());
         Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
         if (sourcePermanent != null && copyFromPermanent != null) {
-            Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent, source, new EmptyApplyToPermanent());
+            Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent());
             Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThespiansStageCopyEffect(), new GenericManaCost(2));
             ability.addCost(new TapSourceCost());
             ability.addTarget(new TargetLandPermanent());
diff --git a/Mage.Sets/src/mage/sets/guildpact/MizziumTransreliquat.java b/Mage.Sets/src/mage/sets/guildpact/MizziumTransreliquat.java
index c1c75827a9..36802080cd 100644
--- a/Mage.Sets/src/mage/sets/guildpact/MizziumTransreliquat.java
+++ b/Mage.Sets/src/mage/sets/guildpact/MizziumTransreliquat.java
@@ -57,7 +57,7 @@ public class MizziumTransreliquat extends CardImpl {
         Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MizziumTransreliquatCopyEffect(), new ManaCostsImpl("{3}"));
         ability.addTarget(new TargetArtifactPermanent());
         this.addAbility(ability);
-        
+
         // {1}{U}{R}: Mizzium Transreliquat becomes a copy of target artifact and gains this ability.
         ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MizziumTransreliquatCopyAndGainAbilityEffect(), new ManaCostsImpl("{1}{U}{R}"));
         ability.addTarget(new TargetArtifactPermanent());
@@ -74,12 +74,11 @@ public class MizziumTransreliquat extends CardImpl {
     }
 }
 
-
 class MizziumTransreliquatCopyEffect extends OneShotEffect {
 
     public MizziumTransreliquatCopyEffect() {
         super(Outcome.Copy);
-        this.staticText = "Mizzium Transreliquat becomes a copy of target artifact until end of turn";
+        this.staticText = "{this} becomes a copy of target artifact until end of turn";
     }
 
     public MizziumTransreliquatCopyEffect(final MizziumTransreliquatCopyEffect effect) {
@@ -96,17 +95,18 @@ class MizziumTransreliquatCopyEffect extends OneShotEffect {
         Permanent sourcePermanent = game.getPermanent(source.getSourceId());
         Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
         if (sourcePermanent != null && copyFromPermanent != null) {
-            game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent, source, new EmptyApplyToPermanent());
+            game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent());
             return true;
         }
         return false;
     }
 }
+
 class MizziumTransreliquatCopyAndGainAbilityEffect extends OneShotEffect {
 
     public MizziumTransreliquatCopyAndGainAbilityEffect() {
         super(Outcome.Benefit);
-        this.staticText = "Mizzium Transreliquat becomes a copy of target artifact and gains this ability";
+        this.staticText = "{this} becomes a copy of target artifact and gains this ability";
     }
 
     public MizziumTransreliquatCopyAndGainAbilityEffect(final MizziumTransreliquatCopyAndGainAbilityEffect effect) {
@@ -123,7 +123,7 @@ class MizziumTransreliquatCopyAndGainAbilityEffect extends OneShotEffect {
         Permanent sourcePermanent = game.getPermanent(source.getSourceId());
         Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
         if (sourcePermanent != null && copyFromPermanent != null) {
-            Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent, source, new EmptyApplyToPermanent());
+            Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent());
             Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MizziumTransreliquatCopyAndGainAbilityEffect(), new ManaCostsImpl("{1}{U}{R}"));
             ability.addTarget(new TargetArtifactPermanent());
             newPermanent.addAbility(ability, source.getSourceId(), game);
@@ -131,4 +131,4 @@ class MizziumTransreliquatCopyAndGainAbilityEffect extends OneShotEffect {
         }
         return false;
     }
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/PolymorphousRush.java b/Mage.Sets/src/mage/sets/journeyintonyx/PolymorphousRush.java
index fe4506ed66..333cbdde27 100644
--- a/Mage.Sets/src/mage/sets/journeyintonyx/PolymorphousRush.java
+++ b/Mage.Sets/src/mage/sets/journeyintonyx/PolymorphousRush.java
@@ -64,7 +64,7 @@ public class PolymorphousRush extends CardImpl {
 
         // Strive - Polymorphous Rush costs {1}{U} more to cast for each target beyond the first.
         this.addAbility(new StriveAbility("{1}{U}"));
-        
+
         // Choose a creature on the battlefield. Any number of target creatures you control each become a copy of that creature until end of turn.
         this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, false));
         this.getSpellAbility().addEffect(new PolymorphousRushCopyEffect());
@@ -82,21 +82,21 @@ public class PolymorphousRush extends CardImpl {
 }
 
 class PolymorphousRushCopyEffect extends OneShotEffect {
-    
+
     public PolymorphousRushCopyEffect() {
         super(Outcome.Copy);
         this.staticText = "Choose a creature on the battlefield. Any number of target creatures you control each become a copy of that creature until end of turn";
     }
-    
+
     public PolymorphousRushCopyEffect(final PolymorphousRushCopyEffect effect) {
         super(effect);
     }
-    
+
     @Override
     public PolymorphousRushCopyEffect copy() {
         return new PolymorphousRushCopyEffect(this);
     }
-    
+
     @Override
     public boolean apply(Game game, Ability source) {
         Player controller = game.getPlayer(source.getControllerId());
@@ -107,10 +107,10 @@ class PolymorphousRushCopyEffect extends OneShotEffect {
             if (target.canChoose(source.getId(), controller.getId(), game) && controller.chooseTarget(outcome, target, source, game)) {
                 Permanent copyFromCreature = game.getPermanent(target.getFirstTarget());
                 if (copyFromCreature != null) {
-                    for (UUID copyToId: getTargetPointer().getTargets(game, source)) {
+                    for (UUID copyToId : getTargetPointer().getTargets(game, source)) {
                         Permanent copyToCreature = game.getPermanent(copyToId);
                         if (copyToCreature != null) {
-                            game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature, source, new EmptyApplyToPermanent());
+                            game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToId, source, new EmptyApplyToPermanent());
                         }
                     }
                 }
@@ -119,4 +119,5 @@ class PolymorphousRushCopyEffect extends OneShotEffect {
         }
         return false;
     }
+
 }
diff --git a/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java b/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java
index 03ba405c9d..ea74b1f892 100644
--- a/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java
+++ b/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java
@@ -110,7 +110,7 @@ class WorldgorgerDragonEntersEffect extends OneShotEffect {
         Player controller = game.getPlayer(source.getControllerId());
         MageObject sourceObject = source.getSourceObject(game);
         if (controller != null) {
-            UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject);
+            UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
             if (exileId != null) {
                 for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
                     if (!permanent.getId().equals(source.getSourceId())) { // Another
@@ -145,7 +145,7 @@ class WorldgorgerDragonLeavesEffect extends OneShotEffect {
         Player controller = game.getPlayer(source.getControllerId());
         MageObject sourceObject = source.getSourceObject(game);
         if (controller != null && sourceObject != null) {
-            int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1;
+            int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1;
             ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter));
             if (exile != null) {
                 exile = exile.copy();
diff --git a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java
index ec4ca9b5e0..b1a99b0e24 100644
--- a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java
+++ b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java
@@ -114,15 +114,15 @@ class CopyArtifactEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player player = game.getPlayer(source.getControllerId());
-        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourcePermanent != null) {
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (player != null && sourceObject != null) {
             Target target = new TargetPermanent(filter);
             target.setNotTarget(true);
             if (target.canChoose(source.getControllerId(), game)) {
                 player.choose(Outcome.Copy, target, source.getSourceId(), game);
                 Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
                 if (copyFromPermanent != null) {
-                    game.copyPermanent(copyFromPermanent, sourcePermanent, source, applier);
+                    game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, applier);
                     return true;
                 }
             }
diff --git a/Mage.Sets/src/mage/sets/lorwyn/Shapesharer.java b/Mage.Sets/src/mage/sets/lorwyn/Shapesharer.java
index 8cd1d57057..8f49981b4a 100644
--- a/Mage.Sets/src/mage/sets/lorwyn/Shapesharer.java
+++ b/Mage.Sets/src/mage/sets/lorwyn/Shapesharer.java
@@ -48,7 +48,6 @@ import mage.target.TargetPermanent;
 import mage.target.common.TargetCreaturePermanent;
 import mage.util.functions.EmptyApplyToPermanent;
 
-
 /**
  * @author duncant
  */
@@ -68,11 +67,11 @@ public class Shapesharer extends CardImpl {
         this.power = new MageInt(1);
         this.toughness = new MageInt(1);
         this.addAbility(ChangelingAbility.getInstance());
-        
+
         // {2}{U}: Target Shapeshifter becomes a copy of target creature until your next turn.
         Ability copyAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD,
-                                                         new ShapesharerEffect(),
-                                                         new ManaCostsImpl("{2}{U}"));
+                new ShapesharerEffect(),
+                new ManaCostsImpl("{2}{U}"));
         copyAbility.addTarget(new TargetPermanent(filterShapeshifter));
         copyAbility.addTarget(new TargetCreaturePermanent());
         this.addAbility(copyAbility);
@@ -89,6 +88,7 @@ public class Shapesharer extends CardImpl {
 }
 
 class ShapesharerEffect extends OneShotEffect {
+
     public ShapesharerEffect() {
         super(Outcome.Copy);
         this.staticText = "Target Shapeshifter becomes a copy of target creature until your next turn.";
@@ -105,10 +105,12 @@ class ShapesharerEffect extends OneShotEffect {
 
     @Override
     public boolean apply(Game game, Ability ability) {
-        Permanent copyTo = game.getPermanent(ability.getFirstTarget());
+        Permanent copyTo = game.getPermanent(getTargetPointer().getFirst(game, ability));
         if (copyTo != null) {
             Permanent copyFrom = game.getPermanentOrLKIBattlefield(ability.getTargets().get(1).getFirstTarget());
-            game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo, ability, new EmptyApplyToPermanent());
+            if (copyFrom != null) {
+                game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo.getId(), ability, new EmptyApplyToPermanent());
+            }
         }
         return true;
     }
diff --git a/Mage.Sets/src/mage/sets/magic2012/Flight.java b/Mage.Sets/src/mage/sets/magic2012/Flight.java
index 198a3e6a8a..0848e527c9 100644
--- a/Mage.Sets/src/mage/sets/magic2012/Flight.java
+++ b/Mage.Sets/src/mage/sets/magic2012/Flight.java
@@ -25,12 +25,9 @@
  *  authors and should not be interpreted as representing official policies, either expressed
  *  or implied, of BetaSteward_at_googlemail.com.
  */
-
 package mage.sets.magic2012;
 
 import java.util.UUID;
-
-import mage.constants.*;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleStaticAbility;
 import mage.abilities.effects.common.AttachEffect;
@@ -38,6 +35,11 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
 import mage.abilities.keyword.EnchantAbility;
 import mage.abilities.keyword.FlyingAbility;
 import mage.cards.CardImpl;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
 import mage.target.TargetPermanent;
 import mage.target.common.TargetCreaturePermanent;
 
@@ -47,20 +49,23 @@ import mage.target.common.TargetCreaturePermanent;
  */
 public class Flight extends CardImpl {
 
-    public Flight (UUID ownerId) {
+    public Flight(UUID ownerId) {
         super(ownerId, 53, "Flight", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{U}");
         this.expansionSetCode = "M12";
         this.subtype.add("Aura");
 
+        // Enchant creature
         TargetPermanent auraTarget = new TargetCreaturePermanent();
         this.getSpellAbility().addTarget(auraTarget);
         this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
         Ability ability = new EnchantAbility(auraTarget.getTargetName());
         this.addAbility(ability);
+
+        // Enchanted creature has flying.
         this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA)));
     }
 
-    public Flight (final Flight card) {
+    public Flight(final Flight card) {
         super(card);
     }
 
diff --git a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java
index 54d717c7b3..82de7d6d4e 100644
--- a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java
+++ b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java
@@ -97,15 +97,15 @@ class PhantasmalImageCopyEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player player = game.getPlayer(source.getControllerId());
-        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourcePermanent != null) {
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (player != null && sourceObject != null) {
             Target target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)"));
             target.setNotTarget(true);
             if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
                 player.choose(Outcome.Copy, target, source.getSourceId(), game);
                 Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
                 if (copyFromPermanent != null) {
-                    game.copyPermanent(copyFromPermanent, sourcePermanent, source, new ApplyToPermanent() {
+                    game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() {
                         @Override
                         public Boolean apply(Game game, Permanent permanent) {
                             if (!permanent.getSubtype().contains("Illusion")) {
diff --git a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java
index 6196ee8db7..1aa0cb0c7c 100644
--- a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java
+++ b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java
@@ -29,6 +29,7 @@ package mage.sets.magic2015;
 
 import java.util.UUID;
 import mage.MageInt;
+import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleActivatedAbility;
 import mage.abilities.common.SimpleStaticAbility;
@@ -96,15 +97,15 @@ class MercurialPretenderCopyEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player player = game.getPlayer(source.getControllerId());
-        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourcePermanent != null) {
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (player != null && sourceObject != null) {
             Target target = new TargetPermanent(new FilterControlledCreaturePermanent());
             target.setNotTarget(true);
             if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
                 player.choose(Outcome.Copy, target, source.getSourceId(), game);
                 Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
                 if (copyFromPermanent != null) {
-                    game.copyPermanent(copyFromPermanent, sourcePermanent, source,
+                    game.copyPermanent(copyFromPermanent, sourceObject.getId(), source,
                             // {2}{U}{U}: Return this creature to its owner's hand.
                             new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}")))
                     );
diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java
index 98c1aa29be..606fe4a93a 100644
--- a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java
+++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java
@@ -44,6 +44,7 @@ import mage.filter.common.FilterNonlandCard;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 import mage.game.events.GameEvent.EventType;
+import mage.game.permanent.PermanentToken;
 import mage.game.stack.Spell;
 import mage.players.Player;
 import mage.target.common.TargetCardInExile;
@@ -100,7 +101,8 @@ class KnowledgePoolEffect1 extends OneShotEffect {
             Player player = game.getPlayer(playerId);
             if (player != null) {
                 player.moveCardsToExile(player.getLibrary().getTopCards(game, 3), source, game, true,
-                        CardUtil.getObjectExileZoneId(game, sourceObject), sourceObject.getIdName() + " (" + sourceObject.getZoneChangeCounter(game) + ")");
+                        CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()),
+                        sourceObject.getIdName() + " (" + sourceObject.getZoneChangeCounter(game) + ")");
             }
         }
         return true;
@@ -168,7 +170,8 @@ class KnowledgePoolEffect2 extends OneShotEffect {
         MageObject sourceObject = game.getObject(source.getSourceId());
         Player controller = game.getPlayer(source.getControllerId());
         if (controller != null && spell != null && sourceObject != null) {
-            UUID exileZoneId = CardUtil.getObjectExileZoneId(game, sourceObject);
+            int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1;
+            UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter);
             if (controller.moveCardsToExile(spell, source, game, true, exileZoneId, sourceObject.getIdName())) {
                 Player player = game.getPlayer(spell.getControllerId());
                 if (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with " + sourceObject.getLogName() + " without paying that card's mana cost?", source, game)) {
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianMetamorph.java b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianMetamorph.java
index 25a6c37427..b6a7057dda 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianMetamorph.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianMetamorph.java
@@ -88,7 +88,7 @@ public class PhyrexianMetamorph extends CardImpl {
         // You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
         Effect effect = new CopyPermanentEffect(filter, phyrexianMetamorphApplier);
         effect.setText("You may have {this} enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types");
-        Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(effect));
+        Ability ability = new SimpleStaticAbility(Zone.ALL, new EntersBattlefieldEffect(effect));
         this.addAbility(ability);
     }
 
diff --git a/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java b/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java
index 22a1c755e1..06d9fb2a02 100644
--- a/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java
+++ b/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java
@@ -92,7 +92,7 @@ class SkyshipWeatherlightEffect extends SearchEffect {
         MageObject sourceObject = source.getSourceObject(game);
         if (sourceObject != null && controller != null) {
             if (controller.searchLibrary(target, game)) {
-                UUID exileZone = CardUtil.getObjectExileZoneId(game, sourceObject);
+                UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
                 if (target.getTargets().size() > 0) {
                     for (UUID cardID : target.getTargets()) {
                         Card card = controller.getLibrary().getCard(cardID, game);
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/RenegadeDoppelganger.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/RenegadeDoppelganger.java
index 2f8202380d..07b9a9ac94 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/RenegadeDoppelganger.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/RenegadeDoppelganger.java
@@ -46,7 +46,6 @@ import mage.game.permanent.Permanent;
 import mage.target.targetpointer.FixedTarget;
 import mage.util.functions.EmptyApplyToPermanent;
 
-
 /**
  *
  * @author North
@@ -142,7 +141,7 @@ class RenegadeDoppelgangerEffect extends OneShotEffect {
             return false;
         }
 
-        game.copyPermanent(Duration.EndOfTurn, targetCreature, permanent, source, new EmptyApplyToPermanent());
+        game.copyPermanent(Duration.EndOfTurn, targetCreature, permanent.getId(), source, new EmptyApplyToPermanent());
         return false;
     }
 }
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java
index b902d364f2..3a4232607b 100644
--- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java
@@ -98,15 +98,15 @@ class SakashimaTheImpostorCopyEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player player = game.getPlayer(source.getControllerId());
-        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourcePermanent != null) {
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (player != null && sourceObject != null) {
             Target target = new TargetPermanent(new FilterCreaturePermanent());
             target.setNotTarget(true);
             if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
                 player.choose(Outcome.Copy, target, source.getSourceId(), game);
                 Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
                 if (copyFromPermanent != null) {
-                    game.copyPermanent(copyFromPermanent, sourcePermanent, source, new ApplyToPermanent() {
+                    game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() {
                         @Override
                         public Boolean apply(Game game, Permanent permanent) {
                             if (!permanent.getSupertype().contains("Legendary")) {
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/CemeteryPuca.java b/Mage.Sets/src/mage/sets/shadowmoor/CemeteryPuca.java
index e3bc6c3365..f97b818c75 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/CemeteryPuca.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/CemeteryPuca.java
@@ -99,7 +99,7 @@ class CemeteryPucaEffect extends OneShotEffect {
         if (copyToCreature != null) {
             Permanent copyFromCreature = (Permanent) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.BATTLEFIELD);
             if (copyFromCreature != null) {
-                game.copyPermanent(Duration.WhileOnBattlefield, copyFromCreature, copyToCreature, source, new EmptyApplyToPermanent());
+                game.copyPermanent(Duration.WhileOnBattlefield, copyFromCreature, copyToCreature.getId(), source, new EmptyApplyToPermanent());
                 ContinuousEffect effect = new GainAbilityTargetEffect(new DiesCreatureTriggeredAbility(new DoIfCostPaid(new CemeteryPucaEffect(), new ManaCostsImpl("{1}")), false, new FilterCreaturePermanent("a creature"), true), Duration.WhileOnBattlefield);
                 effect.setTargetPointer(new FixedTarget(copyToCreature.getId()));
                 game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java
index 9ab3c91bb7..1964cd1cc4 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java
@@ -30,22 +30,16 @@ package mage.sets.shadowmoor;
 import java.util.UUID;
 import mage.MageInt;
 import mage.ObjectColor;
-import mage.abilities.Ability;
 import mage.abilities.StateTriggeredAbility;
 import mage.abilities.common.AsEntersBattlefieldAbility;
-import mage.abilities.effects.OneShotEffect;
 import mage.abilities.effects.common.SacrificeSourceEffect;
 import mage.cards.CardImpl;
-import mage.choices.ChoiceColor;
 import mage.constants.CardType;
-import mage.constants.Outcome;
 import mage.constants.Rarity;
 import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 import mage.game.permanent.Permanent;
-import mage.game.stack.StackObject;
-import mage.players.Player;
 
 /**
  *
@@ -62,7 +56,7 @@ public class LureboundScarecrow extends CardImpl {
         this.toughness = new MageInt(4);
 
         // As Lurebound Scarecrow enters the battlefield, choose a color.
-        this.addAbility(new AsEntersBattlefieldAbility(new LureboundScarecrowChooseColorEffect()));
+        this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect()));
 
         // When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow.
         this.addAbility(new LureboundScarecrowTriggeredAbility());
@@ -78,40 +72,6 @@ public class LureboundScarecrow extends CardImpl {
     }
 }
 
-class LureboundScarecrowChooseColorEffect extends OneShotEffect {
-
-    public LureboundScarecrowChooseColorEffect() {
-        super(Outcome.BoostCreature);
-        staticText = "choose a color";
-    }
-
-    public LureboundScarecrowChooseColorEffect(final LureboundScarecrowChooseColorEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        Player player = game.getPlayer(source.getControllerId());
-        StackObject sourceStackObject = game.getStack().getStackObject(source.getSourceId());
-        Permanent permanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourceStackObject != null && permanent != null) {
-            ChoiceColor colorChoice = new ChoiceColor();
-            if (player.choose(Outcome.BoostCreature, colorChoice, game)) {
-                game.informPlayers(sourceStackObject.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice());
-                game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
-                permanent.addInfo("chosen color", new StringBuilder("<font color='blue'>Chosen color: ").append(colorChoice.getColor().getDescription()).append("</font>").toString(), game);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public LureboundScarecrowChooseColorEffect copy() {
-        return new LureboundScarecrowChooseColorEffect(this);
-    }
-
-}
-
 class LureboundScarecrowTriggeredAbility extends StateTriggeredAbility {
 
     private static final String staticText = "When you control no permanents of the chosen color, sacrifice {this}.";
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/Mirrorweave.java b/Mage.Sets/src/mage/sets/shadowmoor/Mirrorweave.java
index fa2ecb5d7c..571cf64174 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/Mirrorweave.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/Mirrorweave.java
@@ -61,7 +61,6 @@ public class Mirrorweave extends CardImpl {
         super(ownerId, 143, "Mirrorweave", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{W/U}{W/U}");
         this.expansionSetCode = "SHM";
 
-
         // Each other creature becomes a copy of target nonlegendary creature until end of turn.
         this.getSpellAbility().addEffect(new MirrorWeaveEffect());
         this.getSpellAbility().addTarget(new TargetPermanent(filter));
@@ -105,7 +104,7 @@ class MirrorWeaveEffect extends OneShotEffect {
                 filter.add(Predicates.not(new PermanentIdPredicate(copyFromCreature.getId())));
                 for (Permanent copyToCreature : game.getBattlefield().getAllActivePermanents(filter, game)) {
                     if (copyToCreature != null) {
-                        game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature, source, new EmptyApplyToPermanent());
+                        game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature.getId(), source, new EmptyApplyToPermanent());
                     }
                 }
             }
diff --git a/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java b/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java
index e667e1d7cd..3f72887226 100644
--- a/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java
+++ b/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java
@@ -114,7 +114,7 @@ class TidehollowScullerExileEffect extends OneShotEffect {
             if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
                 Card card = opponent.getHand().get(target.getFirstTarget(), game);
                 if (card != null) {
-                    controller.moveCardToExileWithInfo(card, CardUtil.getObjectExileZoneId(game, sourcePermanent), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true);
+                    controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true);
                 }
             }
 
diff --git a/Mage.Sets/src/mage/sets/tempest/RootwaterMatriarch.java b/Mage.Sets/src/mage/sets/tempest/RootwaterMatriarch.java
index 39d3449e1f..88a5d98685 100644
--- a/Mage.Sets/src/mage/sets/tempest/RootwaterMatriarch.java
+++ b/Mage.Sets/src/mage/sets/tempest/RootwaterMatriarch.java
@@ -28,9 +28,6 @@
 package mage.sets.tempest;
 
 import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
 import mage.MageInt;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleActivatedAbility;
@@ -39,7 +36,9 @@ import mage.abilities.costs.common.TapSourceCost;
 import mage.abilities.decorator.ConditionalContinuousEffect;
 import mage.abilities.effects.common.continuous.GainControlTargetEffect;
 import mage.cards.CardImpl;
+import mage.constants.CardType;
 import mage.constants.Duration;
+import mage.constants.Rarity;
 import mage.constants.Zone;
 import mage.target.common.TargetCreaturePermanent;
 
@@ -56,9 +55,10 @@ public class RootwaterMatriarch extends CardImpl {
 
         this.power = new MageInt(2);
         this.toughness = new MageInt(3);
-        
-        // {TAP}: Gain control of target creature for as long as that creature is enchanted
-        ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.OneUse), EnchantedTargetCondition.getInstance(), "Gain control of target creature for as long as that creature is enchanted");
+
+        // {T}: Gain control of target creature for as long as that creature is enchanted
+        ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), EnchantedTargetCondition.getInstance(),
+                "Gain control of target creature for as long as that creature is enchanted");
         Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
         ability.addTarget(new TargetCreaturePermanent());
         this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java
index f742e0790f..25c3342c95 100644
--- a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java
+++ b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java
@@ -73,7 +73,6 @@ public class AshiokNightmareWeaver extends CardImpl {
         this.expansionSetCode = "THS";
         this.subtype.add("Ashiok");
 
-
         this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false));
 
         // +2: Exile the top three cards of target opponent's library.
@@ -121,14 +120,9 @@ class AshiokNightmareWeaverExileEffect extends OneShotEffect {
         Player controller = game.getPlayer(source.getControllerId());
         MageObject sourceObject = source.getSourceObject(game);
         if (sourceObject != null && opponent != null && controller != null) {
-            UUID exileZone = CardUtil.getObjectExileZoneId(game, sourceObject);
+            UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
             if (exileZone != null) {
-                for (int i = 0; i < 3; i++) {
-                    Card card = opponent.getLibrary().getFromTop(game);
-                    if (card != null) {
-                        controller.moveCardToExileWithInfo(card, exileZone, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
-                    }
-                }
+                controller.moveCardsToExile(opponent.getLibrary().getTopCards(game, 3), source, game, true, exileZone, sourceObject.getIdName());
                 return true;
             }
         }
@@ -167,11 +161,10 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
             }
         }
 
-        FilterCard filter = new FilterCreatureCard(new StringBuilder("creature card with converted mana cost {").append(cmc).append("} exiled with Ashiok, Nightmare Weaver").toString());
+        FilterCard filter = new FilterCreatureCard("creature card with converted mana cost {" + cmc + "} exiled with " + sourceObject.getIdName());
         filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, cmc));
-        
-        Target target = new TargetCardInExile(filter, CardUtil.getObjectExileZoneId(game, sourceObject));
 
+        Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()));
 
         if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
             if (controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) {
@@ -182,7 +175,7 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
                     if (permanent != null) {
                         permanent.changeControllerId(source.getControllerId(), game);
                     }
-                    
+
                     ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect();
                     effect.setTargetPointer(new FixedTarget(card.getId()));
                     game.addEffect(effect, source);
@@ -267,7 +260,7 @@ class AshiokNightmareWeaverExileAllEffect extends OneShotEffect {
         if (exileId == null) {
             return false;
         }
-        for (UUID opponentId: game.getOpponents(source.getControllerId())) {
+        for (UUID opponentId : game.getOpponents(source.getControllerId())) {
             Player opponent = game.getPlayer(opponentId);
             if (opponent != null) {
                 Cards cards = new CardsImpl();
@@ -280,7 +273,7 @@ class AshiokNightmareWeaverExileAllEffect extends OneShotEffect {
                 }
                 cards.clear();
                 cards.addAll(opponent.getGraveyard());
-                for (UUID cardId :cards) {
+                for (UUID cardId : cards) {
                     Card card = game.getCard(cardId);
                     if (card != null) {
                         controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true);
diff --git a/Mage.Sets/src/mage/sets/unlimitededition/VesuvanDoppelganger.java b/Mage.Sets/src/mage/sets/unlimitededition/VesuvanDoppelganger.java
index 09cc3484c9..8dd32a04b9 100644
--- a/Mage.Sets/src/mage/sets/unlimitededition/VesuvanDoppelganger.java
+++ b/Mage.Sets/src/mage/sets/unlimitededition/VesuvanDoppelganger.java
@@ -108,7 +108,7 @@ class VesuvanDoppelgangerCopyEffect extends OneShotEffect {
                 controller.choose(Outcome.Copy, target, source.getSourceId(), game);
                 Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
                 if (copyFromPermanent != null) {
-                    game.copyPermanent(copyFromPermanent, sourcePermanent, source, new ApplyToPermanent() {
+                    game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new ApplyToPermanent() {
                         @Override
                         public Boolean apply(Game game, Permanent permanent) {
                             permanent.getColor(game).setColor(sourcePermanent.getColor(game));
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ProteanHydraTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ProteanHydraTest.java
index 6b3a732531..4fd8c979fa 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ProteanHydraTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ProteanHydraTest.java
@@ -16,7 +16,10 @@ public class ProteanHydraTest extends CardTestPlayerBase {
     @Test
     public void testEnteringWithCounters() {
         addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
-        addCard(Zone.HAND, playerA, "Protean Hydra");
+        // Protean Hydra enters the battlefield with X +1/+1 counters on it.
+        // If damage would be dealt to Protean Hydra, prevent that damage and remove that many +1/+1 counters from it.
+        // Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.
+        addCard(Zone.HAND, playerA, "Protean Hydra"); // CREATURE - {X}{G}
 
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Protean Hydra");
 
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java
index f7172974d0..f77f9d097a 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java
@@ -51,8 +51,10 @@ public class MycosynthGolemTest extends CardTestPlayerBase {
     public void testSpellsAffinity() {
         addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
         addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
+        // Affinity for artifacts
+        // Artifact creature spells you cast have affinity for artifacts.
         addCard(Zone.BATTLEFIELD, playerA, "Mycosynth Golem");
-        addCard(Zone.HAND, playerA, "Alpha Myr");
+        addCard(Zone.HAND, playerA, "Alpha Myr"); // Creature - Myr  2/1
 
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alpha Myr");
 
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java
index bce6619569..32387a9896 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java
@@ -66,6 +66,9 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
     @Test
     public void testSpellsReturnToHand() {
         addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
+        // Lifelink
+        // Instant and sorcery spells you control have lifelink.
+        // {2}{U/R}{U/R}: The next time you cast an instant or sorcery spell from your hand this turn, put that card into your hand instead of your graveyard as it resolves.
         addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master");
         addCard(Zone.HAND, playerA, "Lightning Bolt");
 
@@ -199,7 +202,6 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
      * Test that if Soulfire Grand Master has left the battlefield spell has no
      * longer lifelink
      */
-
     @Test
     public void testSoulfireLeft() {
         addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
@@ -231,7 +233,6 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
      * the elemental, so stoke didnt resolve, but i still got the life from
      * lifelink.
      */
-
     @Test
     public void testSoulfireStokeTheFlames() {
         addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8);
@@ -296,7 +297,6 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
      * Constructed.
      *
      */
-
     @Test
     public void testWithDeflectingPalm() {
         addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/RootwaterMatriarchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/RootwaterMatriarchTest.java
index 7f74e56381..79a8b99666 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/RootwaterMatriarchTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/RootwaterMatriarchTest.java
@@ -1,7 +1,3 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
 package org.mage.test.cards.conditional;
 
 import mage.constants.PhaseStep;
@@ -14,10 +10,10 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
  * @author jeff
  */
 public class RootwaterMatriarchTest extends CardTestPlayerBase {
-    
+
     @Test
     public void testTargetFail() {
-        
+
         addCard(Zone.BATTLEFIELD, playerA, "Rootwater Matriarch");
         addCard(Zone.BATTLEFIELD, playerB, "Memnite");
 
@@ -25,73 +21,73 @@ public class RootwaterMatriarchTest extends CardTestPlayerBase {
 
         setStopAt(1, PhaseStep.BEGIN_COMBAT);
         execute();
-        
+
         assertPermanentCount(playerA, "Rootwater Matriarch", 1);
         assertPermanentCount(playerB, "Memnite", 1);
     }
-    
+
     @Test
     public void testTargetSuccess() {
-        
+        // {T}: Gain control of target creature for as long as that creature is enchanted
         addCard(Zone.BATTLEFIELD, playerA, "Rootwater Matriarch");
         addCard(Zone.BATTLEFIELD, playerA, "Island");
         addCard(Zone.BATTLEFIELD, playerB, "Memnite");
-        
+
         addCard(Zone.HAND, playerA, "Flight");
-        
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flight", "Memnite");
 
         activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{T}: Gain control of target creature for as long as that creature is enchanted.", "Memnite");
 
         setStopAt(1, PhaseStep.END_COMBAT);
         execute();
-        
+
         assertPermanentCount(playerA, "Rootwater Matriarch", 1);
         assertPermanentCount(playerA, "Memnite", 1);
-        
+
     }
-    
+
     @Test
     public void testGainControlEnchantedTargetAndRWLeavesPlay() {
-        
+
         addCard(Zone.BATTLEFIELD, playerA, "Rootwater Matriarch");
         addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
         addCard(Zone.BATTLEFIELD, playerB, "Memnite");
         addCard(Zone.HAND, playerA, "Unsummon");
         addCard(Zone.HAND, playerA, "Flight");
-        
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flight", "Memnite");
 
         activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{T}: Gain control of target creature for as long as that creature is enchanted.", "Memnite");
-        
+
         castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Unsummon", "Rootwater Matriarch");
-        
+
         setStopAt(1, PhaseStep.END_TURN);
         execute();
-        
+
         assertPermanentCount(playerA, "Rootwater Matriarch", 0);
         assertPermanentCount(playerA, "Memnite", 1);
     }
-    
+
     @Test
     public void testGainControlEnchantedTargetAndAuraIsDisenchanted() {
-        
+
         addCard(Zone.BATTLEFIELD, playerA, "Rootwater Matriarch");
         addCard(Zone.BATTLEFIELD, playerA, "Island");
         addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
         addCard(Zone.BATTLEFIELD, playerB, "Memnite");
         addCard(Zone.HAND, playerA, "Disenchant");
         addCard(Zone.HAND, playerA, "Flight");
-        
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flight", "Memnite");
 
         activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{T}: Gain control of target creature for as long as that creature is enchanted.", "Memnite");
-        
+
         castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Disenchant", "Flight");
-        
+
         setStopAt(1, PhaseStep.END_TURN);
         execute();
-        
+
         assertPermanentCount(playerA, "Rootwater Matriarch", 1);
         assertPermanentCount(playerB, "Memnite", 1);
     }
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java
index 7b1ecd66b1..7326f3ec5c 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java
@@ -202,6 +202,9 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
         addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
         addCard(Zone.HAND, playerA, "Phantasmal Image");
+
+        // As Lurebound Scarecrow enters the battlefield, choose a color.
+        // When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow.
         addCard(Zone.HAND, playerA, "Lurebound Scarecrow");
 
         setChoice(playerA, "Green");
@@ -324,7 +327,7 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         addCard(Zone.HAND, playerB, "Phantasmal Image");
 
         castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
-        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Veil of Secrecy", "Frost Titan"); // so it's no longer targetable 
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Veil of Secrecy", "Frost Titan"); // so it's no longer targetable
         setChoice(playerB, "Frost Titan");
 
         castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Terror", "Frost Titan"); // of player Bs Phantasmal Image copying Frost Titan
@@ -346,7 +349,7 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
     }
 
     // I've casted a Phantasmal Image targeting opponent's Wurmcoil Engine
-    // When my Phantasmal Image died, it didn't triggered the Wurmcoil Engine's last ability 
+    // When my Phantasmal Image died, it didn't triggered the Wurmcoil Engine's last ability
     // (When Wurmcoil Engine dies, put a 3/3 colorless Wurm artifact creature token with deathtouch and
     // a 3/3 colorless Wurm artifact creature token with lifelink onto the battlefield.)
     @Test
@@ -418,31 +421,39 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
     }
 
     /**
-     *                    Action
-     *      Game State 1 -----------------> Game State 2
-     *      (On 'field)     (Move to GY)    (In graveyard)
-     *      
-     *  LTB abilities such as Persist are expceptional in that they trigger based on their existence and 
-     *  state of objects before the event (Game State 1, when the card is on the battlefield) rather than 
-     *  after (Game State 2, when the card is in the graveyard). It doesn't matter that the LTB ability
-     *  doesn't exist in Game State 2. [CR 603.6d]
-     * 
-     *  603.6d Normally, objects that exist immediately after an event are checked to see if the event matched any trigger conditions. 
-     *  Continuous effects that exist at that time are used to determine what the trigger conditions are and what the objects involved 
-     *  in the event look like. However, some triggered abilities must be treated specially. Leaves-the-battlefield abilities, abilities
-     *  that trigger when a permanent phases out, abilities that trigger when an object that all players can see is put into a hand or 
-     *  library, abilities that trigger specifically when an object becomes unattached, abilities that trigger when a player loses control 
-     *  of an object, and abilities that trigger when a player planeswalks away from a plane will trigger based on their existence, and 
-     *  the appearance of objects, prior to the event rather than afterward. The game has to “look back in time” to determine if these abilities trigger.
-     * 
-     *  Example: Two creatures are on the battlefield along with an artifact that has the ability “Whenever a creature dies, you gain 1 life.” 
-     *  Someone plays a spell that destroys all artifacts, creatures, and enchantments. The artifact’s ability triggers twice, even though 
-     *  the artifact goes to its owner’s graveyard at the same time as the creatures.
-     * 
+     * Action Game State 1 -----------------> Game State 2 (On 'field) (Move to
+     * GY) (In graveyard)
+     *
+     * LTB abilities such as Persist are expceptional in that they trigger based
+     * on their existence and state of objects before the event (Game State 1,
+     * when the card is on the battlefield) rather than after (Game State 2,
+     * when the card is in the graveyard). It doesn't matter that the LTB
+     * ability doesn't exist in Game State 2. [CR 603.6d]
+     *
+     * 603.6d Normally, objects that exist immediately after an event are
+     * checked to see if the event matched any trigger conditions. Continuous
+     * effects that exist at that time are used to determine what the trigger
+     * conditions are and what the objects involved in the event look like.
+     * However, some triggered abilities must be treated specially.
+     * Leaves-the-battlefield abilities, abilities that trigger when a permanent
+     * phases out, abilities that trigger when an object that all players can
+     * see is put into a hand or library, abilities that trigger specifically
+     * when an object becomes unattached, abilities that trigger when a player
+     * loses control of an object, and abilities that trigger when a player
+     * planeswalks away from a plane will trigger based on their existence, and
+     * the appearance of objects, prior to the event rather than afterward. The
+     * game has to “look back in time” to determine if these abilities trigger.
+     *
+     * Example: Two creatures are on the battlefield along with an artifact that
+     * has the ability “Whenever a creature dies, you gain 1 life.” Someone
+     * plays a spell that destroys all artifacts, creatures, and enchantments.
+     * The artifact’s ability triggers twice, even though the artifact goes to
+     * its owner’s graveyard at the same time as the creatures.
+     *
      */
     @Test
     public void testPersist() {
-        addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);        
+        addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
         // When Kitchen Finks enters the battlefield, you gain 2 life.
         // Persist (When this creature dies, if it had no -1/-1 counters on it, return it to the battlefield under its owner's control with a -1/-1 counter on it.)
         addCard(Zone.HAND, playerA, "Kitchen Finks");
@@ -452,21 +463,20 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
 
         addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
-        
+
         // You may have Phantasmal Image enter the battlefield as a copy of any creature
         // on the battlefield, except it's an Illusion in addition to its other types and
-        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."        
+        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."
         addCard(Zone.HAND, playerB, "Phantasmal Image");
 
-        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitchen Finks"); 
-        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitchen Finks");
+
         castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
         setChoice(playerB, "Kitchen Finks");
-        
 
         castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Kitchen Finks");
         setChoice(playerB, "Kitchen Finks");
-        
+
         setStopAt(2, PhaseStep.END_TURN);
         execute();
 
@@ -480,13 +490,13 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         assertHandCount(playerB, "Phantasmal Image", 0);
         assertGraveyardCount(playerB, "Phantasmal Image", 0);
         assertPermanentCount(playerB, "Kitchen Finks", 1);
-        assertPowerToughness(playerB,  "Kitchen Finks", 2, 1);
+        assertPowerToughness(playerB, "Kitchen Finks", 2, 1);
 
     }
- 
+
     @Test
     public void testUndying() {
-        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);        
+        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
         // Undying (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.)
         addCard(Zone.HAND, playerA, "Butcher Ghoul");
 
@@ -495,21 +505,20 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
 
         addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
-        
+
         // You may have Phantasmal Image enter the battlefield as a copy of any creature
         // on the battlefield, except it's an Illusion in addition to its other types and
-        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."        
+        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."
         addCard(Zone.HAND, playerB, "Phantasmal Image");
 
-        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Butcher Ghoul"); 
-        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Butcher Ghoul");
+
         castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
         setChoice(playerB, "Butcher Ghoul");
-        
 
         castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Butcher Ghoul");
         setChoice(playerB, "Butcher Ghoul");
-        
+
         setStopAt(2, PhaseStep.END_TURN);
         execute();
 
@@ -523,29 +532,25 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         assertHandCount(playerB, "Phantasmal Image", 0);
         assertGraveyardCount(playerB, "Phantasmal Image", 0);
         assertPermanentCount(playerB, "Butcher Ghoul", 1);
-        assertPowerToughness(playerB,  "Butcher Ghoul", 2, 2);
+        assertPowerToughness(playerB, "Butcher Ghoul", 2, 2);
 
     }
 
     /**
      * 12:29: Attacker: Wurmcoil Engine [466] (6/6) blocked by Wurmcoil Engine
-     * [4ed] (6/6) 
-     * 12:29: yespair gains 6 life 
-     * 12:29: HipSomHap gains 6 life
-     * 12:29: Wurmcoil Engine [4ed] died 
-     * 12:29: Ability triggers: Wurmcoil Engine [4ed] - When Wurmcoil Engine [4ed] dies, put a a 3/3 colorless
+     * [4ed] (6/6) 12:29: yespair gains 6 life 12:29: HipSomHap gains 6 life
+     * 12:29: Wurmcoil Engine [4ed] died 12:29: Ability triggers: Wurmcoil
+     * Engine [4ed] - When Wurmcoil Engine [4ed] dies, put a a 3/3 colorless
      * Wurm artifact creature token with deathtouch onto the battlefield. Put a
      * a 3/3 colorless Wurm artifact creature token with lifelink onto the
-     * battlefield. 
-     * 12:29: Phantasmal Image [466] died 
-     * 12:29: HipSomHap puts a Wurm [7d0] token onto the battlefield 
-     * 12:29: HipSomHap puts a Wurm [186] token onto the battlefield
+     * battlefield. 12:29: Phantasmal Image [466] died 12:29: HipSomHap puts a
+     * Wurm [7d0] token onto the battlefield 12:29: HipSomHap puts a Wurm [186]
+     * token onto the battlefield
      *
      * To the best of my knowledge, the Phantasmal Image [466], which entered
      * the battlefield as a Wurmcoil Engine, should grant tokens through the
      * Dies-trigger as well, right?
      */
-
     @Test
     public void testDiesTriggered2() {
         addCard(Zone.BATTLEFIELD, playerB, "Wurmcoil Engine");
@@ -570,5 +575,5 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
         assertPermanentCount(playerA, "Wurm", 2);
         assertPermanentCount(playerB, "Wurm", 2);
 
-    }    
+    }
 }
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhyrexianMetamorphTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhyrexianMetamorphTest.java
index 460ac83b82..1f3ac8a324 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhyrexianMetamorphTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhyrexianMetamorphTest.java
@@ -36,10 +36,8 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
  *
  * @author LevelX2
  */
-
 public class PhyrexianMetamorphTest extends CardTestPlayerBase {
 
-
     @Test
     public void testCopyCreature() {
         addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
@@ -48,7 +46,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
         // You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
         addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
         addCard(Zone.HAND, playerA, "Cloudshift");
-        
+
         //Flying
         // Vanishing 3 (This permanent enters the battlefield with three time counters on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it.)
         // When Aven Riftwatcher enters the battlefield or leaves the battlefield, you gain 2 life.
@@ -68,13 +66,13 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
 
         assertLife(playerA, 24);
         assertLife(playerB, 20);
-        
+
         assertGraveyardCount(playerA, "Cloudshift", 1);
-        
+
         assertPermanentCount(playerA, "Ponyback Brigade", 1);
         assertPermanentCount(playerA, "Goblin", 3);
 
-    }  
+    }
 
     /**
      * An opponent cast Phyrexian Metamorph and cloned another opponent's
@@ -84,7 +82,6 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
      * to choose a new creature to clone when the Phyrexian Metamorph re-entered
      * the battlefield.
      */
-
     @Test
     public void testFlickerWithBrago() {
         addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
@@ -93,9 +90,9 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
         addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
 
         // Flying
-        // When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.        
+        // When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
         addCard(Zone.BATTLEFIELD, playerA, "Brago, King Eternal"); // 2/4
-        
+
         // Creatures you control have haste.
         // Cascade, cascade
         addCard(Zone.BATTLEFIELD, playerB, "Maelstrom Wanderer");  // 7/5
@@ -106,19 +103,19 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
         setChoice(playerA, "Maelstrom Wanderer");
 
         attack(3, playerA, "Brago, King Eternal");
-        addTarget(playerA, "Maelstrom Wanderer");        
+        addTarget(playerA, "Maelstrom Wanderer");
         setChoice(playerA, "Ponyback Brigade");
-        
+
         setStopAt(3, PhaseStep.END_COMBAT);
         execute();
 
         assertLife(playerA, 20);
         assertLife(playerB, 18);
-               
+
         assertPermanentCount(playerA, "Ponyback Brigade", 1);
         assertPermanentCount(playerA, "Goblin", 3);
 
-    }  
+    }
 
     /**
      * I had a Harmonic Sliver, my opponent played Phyrexian Metamorph copying
@@ -126,7 +123,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
      * destroying ability, where it should have had two of them and triggered
      * twice (the Metamorph might have nothing to do with this)
      */
-   @Test
+    @Test
     public void testHarmonicSliver() {
         addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
 
@@ -137,7 +134,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
         addCard(Zone.BATTLEFIELD, playerB, "Kitesail", 1);
         // All Slivers have "When this permanent enters the battlefield, destroy target artifact or enchantment."
         addCard(Zone.BATTLEFIELD, playerB, "Harmonic Sliver"); // 2/4
-        
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph");
         setChoice(playerA, "Harmonic Sliver");
         addTarget(playerA, "Alloy Myr");
@@ -145,66 +142,116 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
 
         setStopAt(1, PhaseStep.END_COMBAT);
         execute();
-               
+
         assertPermanentCount(playerA, "Harmonic Sliver", 1);
 
         assertGraveyardCount(playerB, "Alloy Myr", 1);
         assertGraveyardCount(playerB, "Kitesail", 1);
 
-    }  
-    
+    }
+
     /**
-     * If a Harmonic Sliver enters the battlefield 
-     * the controller has to destroy one artifacts or enchantments
+     * If a Harmonic Sliver enters the battlefield the controller has to destroy
+     * one artifacts or enchantments
      */
     @Test
     public void testHarmonicSliverNative1() {
         addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
         addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
-        
-        // All Slivers have "When this permanent enters the battlefield, destroy target artifact or enchantment."
-        addCard(Zone.HAND, playerA, "Harmonic Sliver"); 
 
-        addCard(Zone.BATTLEFIELD, playerB, "Alloy Myr", 2); // 2/2        
-        
+        // All Slivers have "When this permanent enters the battlefield, destroy target artifact or enchantment."
+        addCard(Zone.HAND, playerA, "Harmonic Sliver");
+
+        addCard(Zone.BATTLEFIELD, playerB, "Alloy Myr", 2); // 2/2
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Harmonic Sliver");
 
         setStopAt(1, PhaseStep.END_COMBAT);
         execute();
-               
+
         assertPermanentCount(playerA, "Harmonic Sliver", 1);
 
         assertGraveyardCount(playerB, "Alloy Myr", 1);
 
-    }      
-    
+    }
+
     /**
-     * If a Harmonic Sliver enters the battlefield and there is already one on the battlefield
-     * the controller has to destroy two artifacts or enchantments
+     * If a Harmonic Sliver enters the battlefield and there is already one on
+     * the battlefield the controller has to destroy two artifacts or
+     * enchantments
      */
     @Test
     public void testHarmonicSliverNative2() {
         addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
         addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
-        
-        addCard(Zone.HAND, playerA, "Harmonic Sliver"); 
+
+        addCard(Zone.HAND, playerA, "Harmonic Sliver");
 
         addCard(Zone.BATTLEFIELD, playerB, "Alloy Myr", 1);
         addCard(Zone.BATTLEFIELD, playerB, "Kitesail", 1);
         // All Slivers have "When this permanent enters the battlefield, destroy target artifact or enchantment."
         addCard(Zone.BATTLEFIELD, playerB, "Harmonic Sliver"); // 2/4
-        
+
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Harmonic Sliver");
         addTarget(playerA, "Alloy Myr");
         addTarget(playerA, "Kitesail");
 
         setStopAt(1, PhaseStep.END_COMBAT);
         execute();
-               
+
         assertPermanentCount(playerA, "Harmonic Sliver", 1);
 
         assertGraveyardCount(playerB, "Alloy Myr", 1);
         assertGraveyardCount(playerB, "Kitesail", 1);
 
-    }       
+    }
+
+    /**
+     * I cast Show and Tell, and put Sheoldred, Whispering One into play and my
+     * opponent put Phyrexian Metamorph into play and he was able to clone my
+     * Sheoldred, Whispering One.
+     *
+     * 6/1/2011 If Phyrexian Metamorph somehow enters the battlefield at the
+     * same time as another permanent (due to Mass Polymorph or Liliana Vess's
+     * third ability, for example), Phyrexian Metamorph can't become a copy of
+     * that permanent. You may only choose a permanent that's already on the
+     * battlefield.
+     *
+     * 400.6. If an object would move from one zone to another, determine what
+     * event is moving the object. If the object is moving to a public zone, all
+     * players look at it to see if it has any abilities that would affect the
+     * move. Then any appropriate replacement effects, whether they come from
+     * that object or from elsewhere, are applied to that event. If any effects
+     * or rules try to do two or more contradictory or mutually exclusive things
+     * to a particular object, that object's controller -- or its owner if it
+     * has no controller -- chooses which effect to apply, and what that effect
+     * does. (Note that multiple instances of the same thing may be mutually
+     * exclusive; for example, two simultaneous "destroy" effects.) Then the
+     * event moves the object.
+     */
+    @Test
+    public void testShowAndTell() {
+        addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+
+        // Each player may put an artifact, creature, enchantment, or land card from his or her hand onto the battlefield.
+        addCard(Zone.HAND, playerA, "Show and Tell"); // SORCERY {2}{U}
+
+        // Swampwalk
+        // At the beginning of your upkeep, return target creature card from your graveyard to the battlefield.
+        // At the beginning of each opponent's upkeep, that player sacrifices a creature.
+        addCard(Zone.HAND, playerA, "Sheoldred, Whispering One");
+
+        addCard(Zone.HAND, playerB, "Phyrexian Metamorph");
+
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Show and Tell");
+
+        setStopAt(1, PhaseStep.BEGIN_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "Sheoldred, Whispering One", 1);
+        assertPermanentCount(playerB, "Sheoldred, Whispering One", 0);
+
+        assertGraveyardCount(playerB, "Phyrexian Metamorph", 1);
+
+    }
 }
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index f168cd1c3d..fe231aa0a3 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -554,7 +554,7 @@ public class TestPlayer implements Player {
         if (!choices.isEmpty()) {
             for (String choice : choices) {
                 for (int index = 0; index < rEffects.size(); index++) {
-                    if (choice.equals(rEffects.get(index))) {
+                    if (choice.equals(rEffects.get(Integer.toString(index)))) {
                         choices.remove(choice);
                         return index;
                     }
@@ -1951,6 +1951,11 @@ public class TestPlayer implements Player {
         return computerPlayer.scry(value, source, game);
     }
 
+    @Override
+    public boolean moveCards(Set<Card> cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList<UUID> appliedEffects) {
+        return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects);
+    }
+
     public void setAIPlayer(boolean AIPlayer) {
         this.AIPlayer = AIPlayer;
     }
diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
index bc7f74a40f..77d726faea 100644
--- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
+++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
@@ -283,7 +283,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
                 if (card == null) {
                     throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
                 }
-                PermanentCard p = new PermanentCard(card, null, currentGame);
+                PermanentCard p = new PermanentCard(card, player.getId(), currentGame);
                 p.setTapped(tapped);
                 getBattlefieldCards(player).add(p);
             }
diff --git a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java
index 83adbea699..e22e9c5674 100644
--- a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java
+++ b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java
@@ -60,7 +60,7 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
                 // So check here with the LKI of the enchantment
                 Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
                 if (attachment != null && attachment.getAttachedTo().equals(zEvent.getTargetId())
-                        && attachment.getAttachedToZoneChangeCounter() == zEvent.getTarget().getZoneChangeCounter(game)) {
+                        && attachment.getAttachedToZoneChangeCounter() == zEvent.getTarget().getZoneChangeCounter(game) - 1) {
                     triggered = true;
                 }
             }
diff --git a/Mage/src/mage/abilities/condition/common/EnchantedTargetCondition.java b/Mage/src/mage/abilities/condition/common/EnchantedTargetCondition.java
index ccdc65b27a..98cd263290 100644
--- a/Mage/src/mage/abilities/condition/common/EnchantedTargetCondition.java
+++ b/Mage/src/mage/abilities/condition/common/EnchantedTargetCondition.java
@@ -1,8 +1,6 @@
-
 package mage.abilities.condition.common;
 
 import java.util.UUID;
-
 import mage.abilities.Ability;
 import mage.abilities.condition.Condition;
 import mage.constants.CardType;
@@ -15,8 +13,8 @@ import mage.target.Target;
  * @author Jeff
  */
 public class EnchantedTargetCondition implements Condition {
-    
-    private static EnchantedTargetCondition fInstance = new EnchantedTargetCondition();
+
+    private static final EnchantedTargetCondition fInstance = new EnchantedTargetCondition();
 
     public static Condition getInstance() {
         return fInstance;
diff --git a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java
index eabe831a80..116930ba28 100644
--- a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java
+++ b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java
@@ -36,13 +36,13 @@ import mage.cards.Card;
 import mage.constants.CardType;
 import mage.constants.Duration;
 import mage.constants.Outcome;
+import mage.constants.SpellAbilityType;
 import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 import mage.game.events.ZoneChangeEvent;
 import mage.game.permanent.Permanent;
 import mage.game.permanent.PermanentCard;
-import mage.game.stack.Spell;
 import mage.game.stack.StackAbility;
 import mage.players.Player;
 import mage.target.Target;
@@ -103,12 +103,12 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
         UUID targetId = null;
         MageObject sourceObject = game.getObject(sourceId);
         boolean enchantCardInGraveyard = false;
-        if (sourceObject instanceof Spell) {
-            if (fromZone.equals(Zone.EXILED)) {
-                // cast from exile (e.g. Neightveil Spector) -> no replacement
-                return false;
-            }
-        }
+//        if (sourceObject instanceof Spell) {
+//            if (fromZone.equals(Zone.EXILED)) {
+//                // cast from exile (e.g. Neightveil Spector) -> no replacement
+//                return false;
+//            }
+//        }
         if (sourceObject instanceof StackAbility) {
             StackAbility stackAbility = (StackAbility) sourceObject;
             if (!stackAbility.getEffects().isEmpty()) {
@@ -118,25 +118,34 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
 
         game.applyEffects(); // So continuousEffects are removed if previous effect of the same ability did move objects that cuase continuous effects
         if (targetId == null) {
-            Target target = card.getSpellAbility().getTargets().get(0).copy();
+            SpellAbility spellAbility = card.getSpellAbility();
+            if (spellAbility.getTargets().isEmpty()) {
+                for (Ability ability : card.getAbilities(game)) {
+                    if ((ability instanceof SpellAbility)
+                            && SpellAbilityType.BASE_ALTERNATE.equals(((SpellAbility) ability).getSpellAbilityType())
+                            && !ability.getTargets().isEmpty()) {
+                        spellAbility = (SpellAbility) ability;
+                        break;
+                    }
+                }
+            }
+            if (spellAbility.getTargets().isEmpty()) {
+                return false;
+            }
+            Target target = spellAbility.getTargets().get(0).copy();
+            Outcome auraOutcome = Outcome.BoostCreature;
+            for (Effect effect : spellAbility.getEffects()) {
+                if (effect instanceof AttachEffect) {
+                    auraOutcome = effect.getOutcome();
+                    break;
+                }
+            }
             enchantCardInGraveyard = target instanceof TargetCardInGraveyard;
             if (target != null) {
                 target.setNotTarget(true); // always not target because this way it's not handled targeted
                 target.clearChosen(); // neccessary if e.g. aura is blinked multiple times
             }
             Player player = game.getPlayer(card.getOwnerId());
-            Outcome auraOutcome = Outcome.BoostCreature;
-            Ability:
-            for (Ability ability : card.getAbilities()) {
-                if (ability instanceof SpellAbility) {
-                    for (Effect effect : ability.getEffects()) {
-                        if (effect instanceof AttachEffect) {
-                            auraOutcome = effect.getOutcome();
-                            break Ability;
-                        }
-                    }
-                }
-            }
             if (target != null && player != null && player.choose(auraOutcome, target, card.getId(), game)) {
                 targetId = target.getFirstTarget();
             }
@@ -151,44 +160,27 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
         }
         Player targetPlayer = game.getPlayer(targetId);
         if (targetCard != null || targetPermanent != null || targetPlayer != null) {
-            switch (fromZone) {
-                case EXILED:
-                    game.getExile().removeCard(card, game);
-                    break;
-                case GRAVEYARD:
-                    game.getPlayer(card.getOwnerId()).removeFromGraveyard(card, game);
-                    break;
-                case HAND:
-                    game.getPlayer(card.getOwnerId()).removeFromHand(card, game);
-                    break;
-                case LIBRARY:
-                    game.getPlayer(card.getOwnerId()).removeFromLibrary(card, game);
-                    break;
-                default:
-            }
-            game.rememberLKI(card.getId(), fromZone, card);
-
+            card.removeFromZone(game, fromZone, sourceId);
+            card.updateZoneChangeCounter(game);
             PermanentCard permanent = new PermanentCard(card, card.getOwnerId(), game);
             game.getBattlefield().addPermanent(permanent);
             card.setZone(Zone.BATTLEFIELD, game);
-            boolean entered = permanent.entersBattlefield(event.getSourceId(), game, fromZone, true);
-            game.applyEffects();
-            if (!entered) {
-                return false;
-            }
-            game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
+            if (permanent.entersBattlefield(event.getSourceId(), game, fromZone, true)) {
+                if (targetCard != null) {
+                    permanent.attachTo(targetCard.getId(), game);
+                } else if (targetPermanent != null) {
+                    targetPermanent.addAttachment(permanent.getId(), game);
+                } else if (targetPlayer != null) {
+                    targetPlayer.addAttachment(permanent.getId(), game);
+                }
+                game.applyEffects();
 
-            if (targetCard != null) {
-                permanent.attachTo(targetCard.getId(), game);
-            }
-            if (targetPermanent != null) {
-                targetPermanent.addAttachment(permanent.getId(), game);
-            }
-            if (targetPlayer != null) {
-                targetPlayer.addAttachment(permanent.getId(), game);
+                game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
+                return true;
             }
+
         }
-        return true;
+        return false;
     }
 
     @Override
@@ -199,7 +191,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
     @Override
     public boolean applies(GameEvent event, Ability source, Game game) {
         if (((ZoneChangeEvent) event).getToZone().equals(Zone.BATTLEFIELD)
-                && !(((ZoneChangeEvent) event).getFromZone().equals(Zone.HAND))) {
+                && !(((ZoneChangeEvent) event).getFromZone().equals(Zone.STACK))) {
             Card card = game.getCard(event.getTargetId());
             if (card != null && card.getCardType().contains(CardType.ENCHANTMENT) && card.hasSubtype("Aura")) {
                 return true;
diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java
index 3477010296..241c3de528 100644
--- a/Mage/src/mage/abilities/effects/ContinuousEffects.java
+++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java
@@ -1147,18 +1147,18 @@ public class ContinuousEffects implements Serializable {
         }
     }
 
-    private void setControllerForEffect(ContinuousEffectsList<?> effects, UUID cardId, UUID controllerId) {
+    private void setControllerForEffect(ContinuousEffectsList<?> effects, UUID sourceId, UUID controllerId) {
         for (Effect effect : effects) {
             HashSet<Ability> abilities = effects.getAbility(effect.getId());
             if (abilities != null) {
                 for (Ability ability : abilities) {
                     if (ability.getSourceId() != null) {
-                        if (ability.getSourceId().equals(cardId)) {
+                        if (ability.getSourceId().equals(sourceId)) {
                             ability.setControllerId(controllerId);
                         }
                     } else {
                         if (!ability.getZone().equals(Zone.COMMAND)) {
-                            logger.fatal(new StringBuilder("No sourceId Ability: ").append(ability));
+                            logger.fatal("Continuous effect for ability with no sourceId Ability: " + ability);
                         }
                     }
                 }
diff --git a/Mage/src/mage/abilities/effects/ContinuousEffectsList.java b/Mage/src/mage/abilities/effects/ContinuousEffectsList.java
index cbad22a927..234a30e456 100644
--- a/Mage/src/mage/abilities/effects/ContinuousEffectsList.java
+++ b/Mage/src/mage/abilities/effects/ContinuousEffectsList.java
@@ -1,30 +1,30 @@
 /*
-* Copyright 2012 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.
-*/
+ * Copyright 2012 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;
 
 import java.util.ArrayList;
@@ -46,18 +46,19 @@ import org.apache.log4j.Logger;
  * @param <T>
  */
 public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList<T> {
-    
+
     private static final Logger logger = Logger.getLogger(ContinuousEffectsList.class);
 
     // the effectAbilityMap holds for each effect all abilities that are connected (used) with this effect
     private final Map<UUID, HashSet<Ability>> effectAbilityMap = new HashMap<>();
 
-    public ContinuousEffectsList() { }
+    public ContinuousEffectsList() {
+    }
 
     public ContinuousEffectsList(final ContinuousEffectsList<T> effects) {
         this.ensureCapacity(effects.size());
-        for (ContinuousEffect cost: effects) {
-            this.add((T)cost.copy());
+        for (ContinuousEffect cost : effects) {
+            this.add((T) cost.copy());
         }
         for (Map.Entry<UUID, HashSet<Ability>> entry : effects.effectAbilityMap.entrySet()) {
             HashSet<Ability> newSet = new HashSet<>();
@@ -113,12 +114,12 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
             Ability ability = it.next();
             if (ability == null) {
                 it.remove();
-            } else  if (ability instanceof MageSingleton) {
+            } else if (ability instanceof MageSingleton) {
                 return false;
-            } else  if (effect.isDiscarded()) {
+            } else if (effect.isDiscarded()) {
                 it.remove();
             } else {
-                switch(effect.getDuration()) {
+                switch (effect.getDuration()) {
                     case WhileOnBattlefield:
                     case WhileInGraveyard:
                     case WhileOnStack:
@@ -133,8 +134,8 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
                         break;
                     case Custom:
                     case UntilYourNextTurn:
-                        if (effect.isInactive(ability , game)) {
-                               it.remove();
+                        if (effect.isInactive(ability, game)) {
+                            it.remove();
                         }
                 }
             }
@@ -143,9 +144,9 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
     }
 
     /**
-     * Adds an effect and its connected ability to the list.
-     * For each effect will be stored, which abilities are connected to the effect.
-     * So an effect can be connected to multiple abilities.
+     * Adds an effect and its connected ability to the list. For each effect
+     * will be stored, which abilities are connected to the effect. So an effect
+     * can be connected to multiple abilities.
      *
      * @param effect - effect to add
      * @param source - connected ability
@@ -153,8 +154,8 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
     public void addEffect(T effect, Ability source) {
         if (effectAbilityMap.containsKey(effect.getId())) {
             HashSet<Ability> set = effectAbilityMap.get(effect.getId());
-            for (Ability ability: set) {
-                if (ability.getId().equals(source.getId()) && ability.getSourceId().equals(source.getSourceId()) ) {
+            for (Ability ability : set) {
+                if (ability.getId().equals(source.getId()) && ability.getSourceId().equals(source.getSourceId())) {
                     return;
                 }
             }
diff --git a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java
index 90bdfaf14c..5a03cbcf33 100644
--- a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java
+++ b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java
@@ -1,42 +1,43 @@
 /*
-* 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.
-*/
-
+ * 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.abilities.effects;
 
-import mage.constants.Duration;
 import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.Mode;
 import mage.abilities.condition.Condition;
+import mage.constants.Duration;
+import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 import mage.game.events.GameEvent.EventType;
 import mage.game.stack.Spell;
+import mage.game.stack.StackObject;
 import mage.players.Player;
 
 /**
@@ -116,12 +117,17 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl {
             }
         }
         Spell spell = game.getStack().getSpell(event.getSourceId());
-        for (Effect effect: baseEffects) {
+        if (spell == null) {
+            StackObject stackObject = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK);
+            if (stackObject instanceof Spell) {
+                spell = (Spell) stackObject;
+            }
+        }
+        for (Effect effect : baseEffects) {
             if (source.activate(game, false)) {
                 if (effect instanceof ContinuousEffect) {
                     game.addEffect((ContinuousEffect) effect, source);
-                }
-                else {
+                } else {
                     if (spell != null) {
                         effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility());
                     }
diff --git a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java
index 7860911a2d..f6318632ac 100644
--- a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java
+++ b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,13 +20,14 @@
  *  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.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.effects.OneShotEffect;
 import mage.constants.Outcome;
@@ -66,6 +67,7 @@ public class CopyPermanentEffect extends OneShotEffect {
     public CopyPermanentEffect(FilterPermanent filter, ApplyToPermanent applier) {
         this(filter, applier, false);
     }
+
     public CopyPermanentEffect(FilterPermanent filter, ApplyToPermanent applier, boolean useTarget) {
         super(Outcome.Copy);
         this.applier = applier;
@@ -85,8 +87,8 @@ public class CopyPermanentEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player player = game.getPlayer(source.getControllerId());
-        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
-        if (player != null && sourcePermanent != null) {
+        MageObject sourceObject = game.getObject(source.getSourceId());
+        if (player != null && sourceObject != null) {
             Permanent copyFromPermanent = null;
             if (useTargetOfAbility) {
                 copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
@@ -99,7 +101,7 @@ public class CopyPermanentEffect extends OneShotEffect {
                 }
             }
             if (copyFromPermanent != null) {
-                bluePrintPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent, source, applier);
+                bluePrintPermanent = game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, applier);
             }
             return true;
         }
diff --git a/Mage/src/mage/abilities/effects/common/CounterTargetWithReplacementEffect.java b/Mage/src/mage/abilities/effects/common/CounterTargetWithReplacementEffect.java
index d23e2c8f2f..01e36d989b 100644
--- a/Mage/src/mage/abilities/effects/common/CounterTargetWithReplacementEffect.java
+++ b/Mage/src/mage/abilities/effects/common/CounterTargetWithReplacementEffect.java
@@ -28,7 +28,6 @@
 package mage.abilities.effects.common;
 
 import java.util.UUID;
-import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.Mode;
 import mage.abilities.effects.OneShotEffect;
@@ -56,7 +55,8 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
     /**
      *
      * @param targetZone
-     * @param flag use to specify when moving card to library <ul><li>true = put on top</li><li>false = put on bottom</li></ul>
+     * @param flag use to specify when moving card to library <ul><li>true = put
+     * on top</li><li>false = put on bottom</li></ul>
      */
     public CounterTargetWithReplacementEffect(Zone targetZone, boolean flag) {
         super(Outcome.Detriment);
@@ -83,33 +83,14 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
         if (controller != null) {
             StackObject stackObject = game.getStack().getStackObject(objectId);
             if (stackObject != null && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
-                boolean spell = false;
                 if (stackObject instanceof Spell) {
-                    game.rememberLKI(objectId, Zone.STACK, stackObject);
-                    spell = true;
-                }
-                game.getStack().remove(stackObject);
-                if (spell && !((Spell) stackObject).isCopiedSpell()) {
-                    MageObject mageObject = game.getObject(stackObject.getSourceId());
-                    if (mageObject instanceof Card) {
-                        Card card = (Card) mageObject;
-                        switch (targetZone) {
-                            case LIBRARY:
-                                controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true);
-                                break;
-                            case EXILED:
-                                controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK, true);
-                                break;
-                            default:
-                                controller.moveCards(card, Zone.STACK, targetZone, source, game);
-                        }                        
-                    } else {
-                        return false;
-                    }
+                    controller.moveCards((Card) stackObject, null, targetZone, source, game);
+                } else {
+                    game.getStack().remove(stackObject);
                 }
                 game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
                 return true;
-            }            
+            }
         }
         return false;
     }
diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java
index 6e5ec8c1d3..5befb3d3a5 100644
--- a/Mage/src/mage/cards/Card.java
+++ b/Mage/src/mage/cards/Card.java
@@ -40,6 +40,7 @@ import mage.constants.Zone;
 import mage.counters.Counter;
 import mage.counters.Counters;
 import mage.game.Game;
+import mage.game.permanent.Permanent;
 
 public interface Card extends MageObject {
 
@@ -65,6 +66,8 @@ public interface Card extends MageObject {
 
     String getTokenSetCode();
 
+    void checkForCountersToAdd(Permanent permanent, Game game);
+
     void setFaceDown(boolean value, Game game);
 
     boolean isFaceDown(Game game);
@@ -125,6 +128,8 @@ public interface Card extends MageObject {
 
     boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId);
 
+    boolean removeFromZone(Game game, Zone fromZone, UUID sourceId);
+
     boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId);
 
     boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped);
diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java
index ee05eb447b..d6dc1f58c7 100644
--- a/Mage/src/mage/cards/CardImpl.java
+++ b/Mage/src/mage/cards/CardImpl.java
@@ -54,8 +54,6 @@ import static mage.constants.Zone.EXILED;
 import static mage.constants.Zone.GRAVEYARD;
 import static mage.constants.Zone.HAND;
 import static mage.constants.Zone.LIBRARY;
-import static mage.constants.Zone.OUTSIDE;
-import static mage.constants.Zone.PICK;
 import static mage.constants.Zone.STACK;
 import mage.counters.Counter;
 import mage.counters.Counters;
@@ -65,6 +63,7 @@ import mage.game.Game;
 import mage.game.command.Commander;
 import mage.game.events.GameEvent;
 import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
 import mage.game.permanent.PermanentCard;
 import mage.game.stack.Spell;
 import mage.game.stack.StackObject;
@@ -342,55 +341,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
         Zone fromZone = game.getState().getZone(objectId);
         ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, ownerId, fromZone, toZone, appliedEffects);
         if (!game.replaceEvent(event)) {
-            if (event.getFromZone() != null) {
-                switch (event.getFromZone()) {
-                    case GRAVEYARD:
-                        game.getPlayer(ownerId).removeFromGraveyard(this, game);
-                        break;
-                    case HAND:
-                        game.getPlayer(ownerId).removeFromHand(this, game);
-                        break;
-                    case LIBRARY:
-                        game.getPlayer(ownerId).removeFromLibrary(this, game);
-                        break;
-                    case EXILED:
-                        game.getExile().removeCard(this, game);
-                        break;
-                    case OUTSIDE:
-                        game.getPlayer(ownerId).getSideboard().remove(this);
-                        break;
-                    case COMMAND:
-                        game.getState().getCommand().remove((Commander) game.getObject(objectId));
-                        break;
-                    case STACK:
-                        StackObject stackObject = game.getStack().getSpell(getSpellAbility().getId());
-                        if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack
-                            stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId());
-                            if (stackObject == null) {
-                                stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId());
-                            }
-                        }
-                        if (stackObject == null) {
-                            stackObject = game.getStack().getSpell(getId());
-                        }
-                        if (stackObject != null) {
-                            game.getStack().remove(stackObject);
-                        }
-                        break;
-                    case PICK:
-                    case BATTLEFIELD: // for sacrificing permanents or putting to library
-                        break;
-                    default:
-                        Card sourceCard = game.getCard(sourceId);
-                        logger.fatal(new StringBuilder("Invalid from zone [").append(fromZone)
-                                .append("] for card [").append(this.getName())
-                                .append("] to zone [").append(toZone)
-                                .append("] source [").append(sourceCard != null ? sourceCard.getName() : "null").append("]").toString());
-                        break;
-                }
-                game.rememberLKI(objectId, event.getFromZone(), this);
-            }
-
+            removeFromZone(game, fromZone, sourceId);
             setFaceDown(false, game);
             updateZoneChangeCounter(game);
             switch (event.getToZone()) {
@@ -454,32 +405,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
         Card mainCard = getMainCard();
         ZoneChangeEvent event = new ZoneChangeEvent(mainCard.getId(), ability.getId(), controllerId, fromZone, Zone.STACK);
         if (!game.replaceEvent(event)) {
-            if (event.getFromZone() != null) {
-                switch (event.getFromZone()) {
-                    case GRAVEYARD:
-                        game.getPlayer(ownerId).removeFromGraveyard(mainCard, game);
-                        break;
-                    case HAND:
-                        game.getPlayer(ownerId).removeFromHand(mainCard, game);
-                        break;
-                    case LIBRARY:
-                        game.getPlayer(ownerId).removeFromLibrary(mainCard, game);
-                        break;
-                    case EXILED:
-                        game.getExile().removeCard(mainCard, game);
-                        break;
-                    case OUTSIDE:
-                        game.getPlayer(ownerId).getSideboard().remove(mainCard);
-                        break;
-
-                    case COMMAND:
-                        game.getState().getCommand().remove((Commander) game.getObject(mainCard.getId()));
-                        break;
-                    default:
-                    //logger.warning("moveToZone, not fully implemented: from="+event.getFromZone() + ", to="+event.getToZone());
-                }
-                game.rememberLKI(mainCard.getId(), event.getFromZone(), this);
-            }
+            mainCard.removeFromZone(game, fromZone, ability.getSourceId());
             game.getStack().push(new Spell(this, ability.copy(), controllerId, event.getFromZone()));
             updateZoneChangeCounter(game);
             setZone(event.getToZone(), game);
@@ -499,36 +425,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
         Zone fromZone = game.getState().getZone(objectId);
         ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, ownerId, fromZone, Zone.EXILED, appliedEffects);
         if (!game.replaceEvent(event)) {
-            if (fromZone != null) {
-                switch (fromZone) {
-                    case GRAVEYARD:
-                        game.getPlayer(ownerId).removeFromGraveyard(this, game);
-                        break;
-                    case HAND:
-                        game.getPlayer(ownerId).removeFromHand(this, game);
-                        break;
-                    case LIBRARY:
-                        game.getPlayer(ownerId).removeFromLibrary(this, game);
-                        break;
-                    case EXILED:
-                        game.getExile().removeCard(this, game);
-                        break;
-                    case STACK:
-                        StackObject stackObject = game.getStack().getSpell(getId());
-                        if (stackObject != null) {
-                            game.getStack().remove(stackObject);
-                        }
-                        break;
-                    case PICK:
-                        // nothing to do
-                        break;
-                    default:
-                        MageObject object = game.getObject(sourceId);
-                        logger.warn(new StringBuilder("moveToExile, not fully implemented: from = ").append(fromZone).append(" - ").append(object != null ? object.getName() : "null"));
-                }
-                game.rememberLKI(objectId, event.getFromZone(), this);
-            }
-
+            removeFromZone(game, fromZone, sourceId);
             if (exileId == null) {
                 game.getExile().getPermanentExile().add(this);
             } else {
@@ -568,37 +465,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
             if (facedown) {
                 this.setFaceDown(false, game);
             }
-            if (fromZone != null) {
-                boolean removed = false;
-                switch (fromZone) {
-                    case GRAVEYARD:
-                        removed = game.getPlayer(ownerId).removeFromGraveyard(this, game);
-                        break;
-                    case HAND:
-                        removed = game.getPlayer(ownerId).removeFromHand(this, game);
-                        break;
-                    case LIBRARY:
-                        removed = game.getPlayer(ownerId).removeFromLibrary(this, game);
-                        break;
-                    case EXILED:
-                        game.getExile().removeCard(this, game);
-                        removed = true;
-                        break;
-                    case COMMAND:
-                        // command object (commander) is only on the stack, so no removing neccessary here
-                        removed = true;
-                        break;
-                    case PICK:
-                        removed = true;
-                        break;
-                    default:
-                        logger.warn("putOntoBattlefield, not fully implemented: fromZone=" + fromZone);
-                }
-                game.rememberLKI(objectId, event.getFromZone(), this);
-                if (!removed) {
-                    logger.warn("Couldn't find card in fromZone, card=" + getName() + ", fromZone=" + fromZone);
-                }
-            }
+            removeFromZone(game, fromZone, sourceId);
             updateZoneChangeCounter(game);
             PermanentCard permanent = new PermanentCard(this, event.getPlayerId(), game);
             // make sure the controller of all continuous effects of this card are switched to the current controller
@@ -624,7 +491,76 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
         return false;
     }
 
-    private void checkForCountersToAdd(PermanentCard permanent, Game game) {
+    @Override
+    public boolean removeFromZone(Game game, Zone fromZone, UUID sourceId) {
+        boolean removed = false;
+        MageObject lkiObject = null;
+        switch (fromZone) {
+            case GRAVEYARD:
+                removed = game.getPlayer(ownerId).removeFromGraveyard(this, game);
+                break;
+            case HAND:
+                removed = game.getPlayer(ownerId).removeFromHand(this, game);
+                break;
+            case LIBRARY:
+                removed = game.getPlayer(ownerId).removeFromLibrary(this, game);
+                break;
+            case EXILED:
+                if (game.getExile().getCard(getId(), game) != null) {
+                    game.getExile().removeCard(this, game);
+                    removed = true;
+                }
+                break;
+            case STACK:
+                StackObject stackObject = game.getStack().getSpell(getSpellAbility().getId());
+                if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack
+                    stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId());
+                    if (stackObject == null) {
+                        stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId());
+                    }
+                }
+                if (stackObject == null) {
+                    stackObject = game.getStack().getSpell(getId());
+                }
+                if (stackObject != null) {
+                    removed = game.getStack().remove(stackObject);
+                    lkiObject = stackObject;
+                }
+                break;
+            case COMMAND:
+                lkiObject = (Commander) game.getObject(objectId);
+                if (lkiObject != null) {
+                    removed = game.getState().getCommand().remove((Commander) game.getObject(objectId));
+                }
+                break;
+            case OUTSIDE:
+                if (isCopy()) { // copied cards have no need to be removed from a previous zone
+                    removed = true;
+                } else if (game.getPlayer(ownerId).getSideboard().contains(this.getId())) {
+                    game.getPlayer(ownerId).getSideboard().remove(this.getId());
+                    removed = true;
+                }
+                break;
+
+            case PICK: // Pick should no longer be used
+            case BATTLEFIELD: // for sacrificing permanents or putting to library
+                removed = true;
+                break;
+            default:
+                MageObject sourceObject = game.getObject(sourceId);
+                logger.fatal("Invalid from zone [" + fromZone + "] for card [" + this.getIdName()
+                        + "] source [" + (sourceObject != null ? sourceObject.getName() : "null") + "]");
+                break;
+        }
+        game.rememberLKI(objectId, fromZone, lkiObject != null ? lkiObject : this);
+        if (!removed) {
+            logger.warn("Couldn't find card in fromZone, card=" + getIdName() + ", fromZone=" + fromZone);
+        }
+        return removed;
+    }
+
+    @Override
+    public void checkForCountersToAdd(Permanent permanent, Game game) {
         Counters countersToAdd = game.getEnterWithCounters(permanent.getId());
         if (countersToAdd != null) {
             for (Counter counter : countersToAdd.values()) {
diff --git a/Mage/src/mage/game/CardState.java b/Mage/src/mage/game/CardState.java
index 1f471370f0..cf63e960bb 100644
--- a/Mage/src/mage/game/CardState.java
+++ b/Mage/src/mage/game/CardState.java
@@ -7,24 +7,25 @@ import mage.abilities.Abilities;
 import mage.abilities.AbilitiesImpl;
 import mage.abilities.Ability;
 import mage.counters.Counters;
+
 /**
  *
  * @author BetaSteward
  */
 public class CardState implements Serializable {
-    
+
     protected boolean faceDown;
     protected Map<String, String> info;
     protected Counters counters;
     protected Abilities<Ability> abilities;
-    
+
     private static final Map<String, String> emptyInfo = new HashMap<>();
     private static final Abilities<Ability> emptyAbilities = new AbilitiesImpl<>();
-    
+
     public CardState() {
         counters = new Counters();
     }
-    
+
     public CardState(final CardState state) {
         this.faceDown = state.faceDown;
         if (state.info != null) {
@@ -34,7 +35,7 @@ public class CardState implements Serializable {
         counters = state.counters.copy();
         if (state.abilities != null) {
             abilities = new AbilitiesImpl<>();
-            for (Ability ability: state.abilities) {
+            for (Ability ability : state.abilities) {
                 abilities.add(ability.copy());
             }
         }
@@ -43,7 +44,7 @@ public class CardState implements Serializable {
     public CardState copy() {
         return new CardState(this);
     }
-    
+
     public void setFaceDown(boolean value) {
         faceDown = value;
     }
@@ -66,45 +67,45 @@ public class CardState implements Serializable {
             info.put(key, value);
         }
     }
-    
+
     public Map<String, String> getInfo() {
         if (info == null) {
             return emptyInfo;
         }
         return info;
     }
-    
+
     public Abilities<Ability> getAbilities() {
         if (abilities == null) {
             return emptyAbilities;
         }
         return abilities;
     }
-    
+
     public void addAbility(Ability ability) {
         if (abilities == null) {
             abilities = new AbilitiesImpl<>();
         }
         abilities.add(ability);
-        for (Ability sub: ability.getSubAbilities()) {
+        for (Ability sub : ability.getSubAbilities()) {
             abilities.add(sub);
         }
     }
-    
+
     public void clearAbilities() {
         if (abilities != null) {
-            for (Ability ability: abilities) {
-                ability.setSourceId(null);
-                ability.setControllerId(null);
-            }
+//            for (Ability ability: abilities) { // Causes problems if temporary (gained) continuous effects are removed
+//                ability.setSourceId(null);
+//                ability.setControllerId(null);
+//            }
             abilities = null;
         }
     }
-    
+
     public void clear() {
         counters.clear();
         info = null;
         clearAbilities();
     }
-    
+
 }
diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java
index 1b19e9d30c..b75ea6a76e 100644
--- a/Mage/src/mage/game/Game.java
+++ b/Mage/src/mage/game/Game.java
@@ -364,14 +364,14 @@ public interface Game extends MageItem, Serializable {
      * This version supports copying of copies of any depth.
      *
      * @param copyFromPermanent
-     * @param copyToPermanent
+     * @param copyToPermanentId
      * @param source
      * @param applier
      * @return
      */
-    Permanent copyPermanent(Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier);
+    Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier);
 
-    Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier);
+    Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier);
 
     Card copyCard(Card cardToCopy, Ability source, UUID newController);
 
diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java
index a0b1c22579..27abfa58db 100644
--- a/Mage/src/mage/game/GameImpl.java
+++ b/Mage/src/mage/game/GameImpl.java
@@ -49,6 +49,7 @@ import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.ActivatedAbility;
 import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.SpellAbility;
 import mage.abilities.TriggeredAbility;
 import mage.abilities.common.ChancellorAbility;
 import mage.abilities.common.GemstoneCavernsAbility;
@@ -77,6 +78,7 @@ import mage.constants.Outcome;
 import mage.constants.PhaseStep;
 import mage.constants.PlayerAction;
 import mage.constants.RangeOfInfluence;
+import mage.constants.SpellAbilityType;
 import mage.constants.Zone;
 import mage.counters.CounterType;
 import mage.counters.Counters;
@@ -1402,12 +1404,12 @@ public abstract class GameImpl implements Game, Serializable {
     }
 
     @Override
-    public Permanent copyPermanent(Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier) {
-        return copyPermanent(Duration.Custom, copyFromPermanent, copyToPermanent, source, applier);
+    public Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier) {
+        return copyPermanent(Duration.Custom, copyFromPermanent, copyToPermanentId, source, applier);
     }
 
     @Override
-    public Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier) {
+    public Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier) {
         Permanent newBluePrint = null;
         // handle copies of copies
         for (Effect effect : getState().getContinuousEffects().getLayeredEffects(this)) {
@@ -1440,7 +1442,7 @@ public abstract class GameImpl implements Game, Serializable {
             applier.apply(this, newBluePrint);
         }
 
-        CopyEffect newEffect = new CopyEffect(duration, newBluePrint, copyToPermanent.getId());
+        CopyEffect newEffect = new CopyEffect(duration, newBluePrint, copyToPermanentId);
         newEffect.newId();
         newEffect.setApplier(applier);
         Ability newAbility = source.copy();
@@ -1686,11 +1688,22 @@ public abstract class GameImpl implements Game, Serializable {
                         }
                     }
                 } else {
+                    SpellAbility spellAbility = perm.getSpellAbility();
                     if (perm.getSpellAbility().getTargets().isEmpty()) {
+                        for (Ability ability : perm.getAbilities(this)) {
+                            if ((ability instanceof SpellAbility)
+                                    && SpellAbilityType.BASE_ALTERNATE.equals(((SpellAbility) ability).getSpellAbilityType())
+                                    && !ability.getTargets().isEmpty()) {
+                                spellAbility = (SpellAbility) ability;
+                                break;
+                            }
+                        }
+                    }
+                    if (spellAbility.getTargets().isEmpty()) {
                         Permanent enchanted = this.getPermanent(perm.getAttachedTo());
                         logger.error("Aura without target: " + perm.getName() + " attached to " + (enchanted == null ? " null" : enchanted.getName()));
                     } else {
-                        Target target = perm.getSpellAbility().getTargets().get(0);
+                        Target target = spellAbility.getTargets().get(0);
                         if (target instanceof TargetPermanent) {
                             Permanent attachedTo = getPermanent(perm.getAttachedTo());
                             if (attachedTo == null || !attachedTo.getAttachments().contains(perm.getId())) {
@@ -1706,7 +1719,7 @@ public abstract class GameImpl implements Game, Serializable {
                                     }
                                 }
                             } else {
-                                Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
+                                Filter auraFilter = spellAbility.getTargets().get(0).getFilter();
                                 if (auraFilter instanceof FilterControlledCreaturePermanent) {
                                     if (!((FilterControlledCreaturePermanent) auraFilter).match(attachedTo, perm.getId(), perm.getControllerId(), this)
                                             || attachedTo.cantBeEnchantedBy(perm, this)) {
@@ -1737,7 +1750,7 @@ public abstract class GameImpl implements Game, Serializable {
                                     somethingHappened = true;
                                 }
                             } else {
-                                Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
+                                Filter auraFilter = spellAbility.getTargets().get(0).getFilter();
                                 if (!auraFilter.match(attachedToPlayer, this) || attachedToPlayer.hasProtectionFrom(perm, this)) {
                                     if (movePermanentToGraveyardWithInfo(perm)) {
                                         somethingHappened = true;
diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java
index 3b1bdd805a..68f312ad7a 100644
--- a/Mage/src/mage/game/GameState.java
+++ b/Mage/src/mage/game/GameState.java
@@ -624,7 +624,7 @@ public class GameState implements Serializable, Copyable<GameState> {
     public Permanent getPermanent(UUID permanentId) {
         if (permanentId != null && battlefield.containsPermanent(permanentId)) {
             Permanent permanent = battlefield.getPermanent(permanentId);
-            setZone(permanent.getId(), Zone.BATTLEFIELD); // shouldn't this be set anyway? (LevelX2)
+            // setZone(permanent.getId(), Zone.BATTLEFIELD); // shouldn't this be set anyway? (LevelX2)
             return permanent;
         }
         return null;
diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java
index af54c92b1d..2e87290d9e 100644
--- a/Mage/src/mage/game/permanent/PermanentCard.java
+++ b/Mage/src/mage/game/permanent/PermanentCard.java
@@ -1,31 +1,30 @@
 /*
-* 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.
-*/
-
+ * 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.permanent;
 
 import java.util.ArrayList;
@@ -49,20 +48,21 @@ public class PermanentCard extends PermanentImpl {
 
     protected int maxLevelCounters;
     protected Card card;
-    protected int zoneChangeCounter;
+    // protected int zoneChangeCounter;
 
     public PermanentCard(Card card, UUID controllerId, Game game) {
         super(card.getId(), card.getOwnerId(), controllerId, card.getName());
-        this.card = card.copy();
+        // this.card = card.copy();
+        this.card = card;
         init(card, game);
     }
 
     private void init(Card card, Game game) {
         copyFromCard(card);
-        this.zoneChangeCounter = card.getZoneChangeCounter(game);
+        // this.zoneChangeCounter = card.getZoneChangeCounter(game);
         /*if (card.getCardType().contains(CardType.PLANESWALKER)) {
-              this.loyalty = new MageInt(card.getLoyalty().getValue());
-          }*/
+         this.loyalty = new MageInt(card.getLoyalty().getValue());
+         }*/
         if (card instanceof LevelerCard) {
             maxLevelCounters = ((LevelerCard) card).getMaxLevelCounters();
         }
@@ -79,7 +79,6 @@ public class PermanentCard extends PermanentImpl {
         super(permanent);
         this.card = permanent.card.copy();
         this.maxLevelCounters = permanent.maxLevelCounters;
-        this.zoneChangeCounter = permanent.zoneChangeCounter;
     }
 
     @Override
@@ -94,13 +93,12 @@ public class PermanentCard extends PermanentImpl {
         this.name = card.getName();
         this.abilities.clear();
         if (this.faceDown) {
-            for (Ability ability: card.getAbilities()) {
+            for (Ability ability : card.getAbilities()) {
                 if (ability.getWorksFaceDown()) {
                     this.abilities.add(ability.copy());
                 }
             }
-        }
-        else {
+        } else {
             this.abilities = card.getAbilities().copy();
         }
         this.abilities.setControllerId(this.controllerId);
@@ -135,6 +133,7 @@ public class PermanentCard extends PermanentImpl {
     public Card getCard() {
         return card;
     }
+
     @Override
     public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
         return moveToZone(toZone, sourceId, game, flag, null);
@@ -255,20 +254,20 @@ public class PermanentCard extends PermanentImpl {
         }
         return super.getManaCost();
     }
-    
+
     @Override
     public int getZoneChangeCounter(Game game) {
-        return this.zoneChangeCounter;
+        return card.getZoneChangeCounter(game);
     }
 
     @Override
     public void updateZoneChangeCounter(Game game) {
-        this.zoneChangeCounter++;
+        card.updateZoneChangeCounter(game);
     }
 
     @Override
     public void setZoneChangeCounter(int value, Game game) {
-        this.zoneChangeCounter = value;
+        card.setZoneChangeCounter(value, game);
     }
 
 }
diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java
index b1cf695013..2972b65d2d 100644
--- a/Mage/src/mage/game/stack/Spell.java
+++ b/Mage/src/mage/game/stack/Spell.java
@@ -221,14 +221,14 @@ public class Spell extends StackObjImpl implements Card {
         } else if (this.getCardType().contains(CardType.ENCHANTMENT) && this.getSubtype().contains("Aura")) {
             if (ability.getTargets().stillLegal(ability, game)) {
                 updateOptionalCosts(0);
-                boolean bestow = this.getSpellAbility() instanceof BestowAbility;
+                boolean bestow = ability instanceof BestowAbility;
                 if (bestow) {
                     // Must be removed first time, after that will be removed by continous effect
                     // Otherwise effects like evolve trigger from creature comes into play event
                     card.getCardType().remove(CardType.CREATURE);
                     card.getSubtype().add("Aura");
                 }
-                if (card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId)) {
+                if (card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId)) {
                     if (bestow) {
                         // card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed
                         // TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities
@@ -238,8 +238,6 @@ public class Spell extends StackObjImpl implements Card {
                             ((PermanentCard) permanent).getCard().getCardType().add(CardType.CREATURE);
                             ((PermanentCard) permanent).getCard().getSubtype().remove("Aura");
                         }
-                        card.getCardType().add(CardType.CREATURE);
-                        card.getSubtype().remove("Aura");
                     }
                     return ability.resolve(game);
                 }
@@ -251,7 +249,7 @@ public class Spell extends StackObjImpl implements Card {
             // Aura has no legal target and its a bestow enchantment -> Add it to battlefield as creature
             if (this.getSpellAbility() instanceof BestowAbility) {
                 updateOptionalCosts(0);
-                result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId);
+                result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId);
                 return result;
             } else {
                 //20091005 - 608.2b
@@ -263,7 +261,7 @@ public class Spell extends StackObjImpl implements Card {
             }
         } else {
             updateOptionalCosts(0);
-            result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId, false, faceDown);
+            result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId, false, faceDown);
             return result;
         }
     }
@@ -646,6 +644,11 @@ public class Spell extends StackObjImpl implements Card {
         }
     }
 
+    @Override
+    public boolean removeFromZone(Game game, Zone fromZone, UUID sourceId) {
+        return card.removeFromZone(game, fromZone, sourceId);
+    }
+
     @Override
     public boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag) {
         return moveToZone(zone, sourceId, game, flag, null);
@@ -847,4 +850,9 @@ public class Spell extends StackObjImpl implements Card {
         return countered;
     }
 
+    @Override
+    public void checkForCountersToAdd(Permanent permanent, Game game) {
+        throw new UnsupportedOperationException("Not supported for Spell");
+    }
+
 }
diff --git a/Mage/src/mage/game/stack/SpellStack.java b/Mage/src/mage/game/stack/SpellStack.java
index 62ea3bb72c..c22c449d2b 100644
--- a/Mage/src/mage/game/stack/SpellStack.java
+++ b/Mage/src/mage/game/stack/SpellStack.java
@@ -34,6 +34,7 @@ import mage.MageObject;
 import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.events.GameEvent;
+import org.apache.log4j.Logger;
 
 /**
  *
@@ -41,6 +42,8 @@ import mage.game.events.GameEvent;
  */
 public class SpellStack extends ArrayDeque<StackObject> {
 
+    private static final Logger logger = Logger.getLogger(SpellStack.class);
+
     protected Date dateLastAdded;
 
     public SpellStack() {
@@ -61,18 +64,21 @@ public class SpellStack extends ArrayDeque<StackObject> {
             top.resolve(game);
         } finally {
             if (top != null) {
-                this.remove(top);
+                if (contains(top)) {
+                    logger.warn("StackObject was still on the stack after resoving" + top.getName());
+                    this.remove(top);
+                }
             }
         }
     }
 
-    public void remove(StackObject object) {
+    public boolean remove(StackObject object) {
         for (StackObject spell : this) {
             if (spell.getId().equals(object.getId())) {
-                super.remove(spell);
-                return;
+                return super.remove(spell);
             }
         }
+        return false;
     }
 
     public boolean counter(UUID objectId, UUID sourceId, Game game) {
diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java
index 157dace466..b23de50345 100644
--- a/Mage/src/mage/game/stack/StackAbility.java
+++ b/Mage/src/mage/game/stack/StackAbility.java
@@ -104,12 +104,15 @@ public class StackAbility extends StackObjImpl implements Ability {
     @Override
     public boolean resolve(Game game) {
         if (ability.getTargets().stillLegal(ability, game)) {
-            return ability.resolve(game);
+            boolean result = ability.resolve(game);
+            game.getStack().remove(this);
+            return result;
         }
         if (!game.isSimulation()) {
             game.informPlayers("Ability has been fizzled: " + getRule());
         }
         counter(null, game);
+        game.getStack().remove(this);
         return false;
     }
 
diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java
index eb3d7d70b2..fe56815b05 100644
--- a/Mage/src/mage/players/Player.java
+++ b/Mage/src/mage/players/Player.java
@@ -635,6 +635,20 @@ public interface Player extends MageItem, Copyable<Player> {
 
     boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game);
 
+    /**
+     *
+     * @param cards
+     * @param toZone
+     * @param source
+     * @param game
+     * @param tapped tha cards are tapped on the battlefield
+     * @param faceDown the cards are face down in the to zone
+     * @param byOwner the card is moved (or put onto battlefield) by the owner
+     * of the card (instead of the controller of the source)
+     * @return
+     */
+    boolean moveCards(Set<Card> cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList<UUID> appliedEffects);
+
     boolean moveCardsToExile(Card card, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName);
 
     boolean moveCardsToExile(Set<Card> cards, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName);
diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java
index e716270b2e..f1efe5d330 100644
--- a/Mage/src/mage/players/PlayerImpl.java
+++ b/Mage/src/mage/players/PlayerImpl.java
@@ -113,6 +113,7 @@ import mage.game.events.DamagePlayerEvent;
 import mage.game.events.DamagedPlayerEvent;
 import mage.game.events.GameEvent;
 import mage.game.events.GameEvent.EventType;
+import mage.game.events.ZoneChangeEvent;
 import mage.game.events.ZoneChangeGroupEvent;
 import mage.game.match.MatchPlayer;
 import mage.game.permanent.Permanent;
@@ -671,8 +672,7 @@ public abstract class PlayerImpl implements Player, Serializable {
 
     @Override
     public boolean removeFromHand(Card card, Game game) {
-        hand.remove(card);
-        return true;
+        return hand.remove(card.getId());
     }
 
     @Override
@@ -3000,13 +3000,13 @@ public abstract class PlayerImpl implements Player, Serializable {
             case HAND:
                 for (Card card : cards) {
                     fromZone = game.getState().getZone(card.getId());
-                    if (fromZone == Zone.STACK) {
-                        // If a spell is returned to its owner's hand, it's removed from the stack and thus will not resolve
-                        Spell spell = game.getStack().getSpell(card.getId());
-                        if (spell != null) {
-                            game.getStack().remove(spell);
-                        }
-                    }
+//                    if (fromZone == Zone.STACK) {
+//                        // If a spell is returned to its owner's hand, it's removed from the stack and thus will not resolve
+//                        Spell spell = game.getStack().getSpell(card.getId());
+//                        if (spell != null) {
+//                            game.getStack().remove(spell);
+//                        }
+//                    }
                     boolean hideCard = fromZone.equals(Zone.LIBRARY)
                             || (card.isFaceDown(game) && !fromZone.equals(Zone.STACK) && !fromZone.equals(Zone.BATTLEFIELD));
                     if (moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, !hideCard)) {
@@ -3038,6 +3038,69 @@ public abstract class PlayerImpl implements Player, Serializable {
         return successfulMovedCards.size() > 0;
     }
 
+    @Override
+    public boolean moveCards(Set<Card> cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList<UUID> appliedEffects) {
+        if (cards.isEmpty()) {
+            return true;
+        }
+        Set<Card> successfulMovedCards = new LinkedHashSet<>();
+        Zone fromZone = null;
+        switch (toZone) {
+            case BATTLEFIELD:
+                List<Permanent> permanents = new ArrayList<>();
+                List<Permanent> permanentsEntered = new ArrayList<>();
+                for (Card card : cards) {
+                    UUID controllingPlayerId = byOwner ? card.getOwnerId() : source.getControllerId();
+                    fromZone = game.getState().getZone(card.getId());
+                    if (faceDown) {
+                        card.setFaceDown(true, game);
+                    }
+                    ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), source.getSourceId(), controllingPlayerId, fromZone, Zone.BATTLEFIELD, appliedEffects, tapped);
+                    if (!game.replaceEvent(event)) {
+                        // get permanent
+                        Permanent permanent = new PermanentCard(card, controllingPlayerId, game);
+                        permanents.add(permanent);
+                        card.checkForCountersToAdd(permanent, game);
+                        permanent.setTapped(tapped);
+                        permanent.setFaceDown(faceDown, game);
+                    }
+                    if (faceDown) {
+                        card.setFaceDown(false, game);
+                    }
+                }
+                game.setScopeRelevant(true);
+                for (Permanent permanent : permanents) {
+                    fromZone = game.getState().getZone(permanent.getId());
+                    if (permanent.entersBattlefield(source.getSourceId(), game, fromZone, true)) {
+                        permanentsEntered.add(permanent);
+                    }
+                }
+                game.setScopeRelevant(false);
+                game.applyEffects();
+                for (Permanent permanent : permanentsEntered) {
+                    fromZone = game.getState().getZone(permanent.getId());
+                    if (((Card) permanent).removeFromZone(game, fromZone, source.getSourceId())) {
+                        permanent.updateZoneChangeCounter(game);
+                        // make sure the controller of all continuous effects of this card are switched to the current controller
+                        game.getContinuousEffects().setController(permanent.getId(), permanent.getControllerId());
+                        game.addPermanent(permanent);
+                        permanent.setZone(Zone.BATTLEFIELD, game);
+                        // check if there are counters to add to the permanent (e.g. from non replacement effects like Persist)
+
+                        game.setScopeRelevant(true);
+                        successfulMovedCards.add(permanent);
+                        game.addSimultaneousEvent(new ZoneChangeEvent(permanent, permanent.getControllerId(), fromZone, Zone.BATTLEFIELD));
+                    }
+                }
+                break;
+            default:
+                throw new UnsupportedOperationException("to Zone not supported yet");
+        }
+
+        game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone));
+        return successfulMovedCards.size() > 0;
+    }
+
     @Override
     public boolean moveCardsToExile(Card card, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName) {
         Set<Card> cards = new HashSet<>();
diff --git a/Mage/src/mage/util/CardUtil.java b/Mage/src/mage/util/CardUtil.java
index 3af5676fa4..9c6f45db5b 100644
--- a/Mage/src/mage/util/CardUtil.java
+++ b/Mage/src/mage/util/CardUtil.java
@@ -483,23 +483,6 @@ public class CardUtil {
         return getExileZoneId(getCardZoneString(SOURCE_EXILE_ZONE_TEXT, sourceId, game, previous), game);
     }
 
-    public static UUID getObjectExileZoneId(Game game, MageObject mageObject) {
-        return getObjectExileZoneId(game, mageObject, false);
-    }
-
-    public static UUID getObjectExileZoneId(Game game, MageObject mageObject, boolean previous) {
-        int zoneChangeCounter = 0;
-        if (mageObject instanceof Permanent) {
-            zoneChangeCounter = ((Permanent) mageObject).getZoneChangeCounter(game);
-        } else if (mageObject instanceof Card) {
-            zoneChangeCounter = ((Card) mageObject).getZoneChangeCounter(game);
-        }
-        if (zoneChangeCounter > 0 && previous) {
-            zoneChangeCounter--;
-        }
-        return getExileZoneId(getObjectZoneString(SOURCE_EXILE_ZONE_TEXT, mageObject.getId(), game, zoneChangeCounter, false), game);
-    }
-
     public static UUID getExileZoneId(Game game, UUID objectId, int zoneChangeCounter) {
         return getExileZoneId(getObjectZoneString(SOURCE_EXILE_ZONE_TEXT, objectId, game, zoneChangeCounter, false), game);
     }

From f4b667650c66a85251cab6b655f7b95c54077219 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 03:57:29 +0200
Subject: [PATCH 06/13] * Fixed that enters the battlefield replacement effects
 of objects entering the battlefield were able to see permanents that entered
 the battlefield by the same effect (e.g. a Phyrexian Metamorph put onto the
 battlefield with Show and Tell was able to copy permanents that other players
 put onto the battlefield with the same Show and Tell.) fixes #594.

---
 Mage.Sets/src/mage/sets/exodus/Manabond.java  | 48 +++++------
 .../sets/innistrad/GrimoireOfTheDead.java     | 40 +++++----
 .../src/mage/sets/magic2010/LilianaVess.java  | 31 +++----
 .../mage/sets/magic2011/MassPolymorph.java    | 84 ++++++++++---------
 .../sets/magic2014/RiseOfTheDarkRealms.java   | 23 +++--
 .../sets/magicorigins/AnimistsAwakening.java  | 21 +++--
 .../sets/scarsofmirrodin/GenesisWave.java     |  6 +-
 .../src/mage/sets/urzassaga/ShowAndTell.java  | 19 +++--
 8 files changed, 149 insertions(+), 123 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/exodus/Manabond.java b/Mage.Sets/src/mage/sets/exodus/Manabond.java
index 95dcbe4d6c..b3d4487f70 100644
--- a/Mage.Sets/src/mage/sets/exodus/Manabond.java
+++ b/Mage.Sets/src/mage/sets/exodus/Manabond.java
@@ -27,17 +27,19 @@
  */
 package mage.sets.exodus;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
+import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
 import mage.abilities.effects.OneShotEffect;
 import mage.cards.Card;
 import mage.cards.CardImpl;
-import mage.cards.Cards;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
 import mage.game.Game;
 import mage.players.Player;
 
@@ -51,8 +53,7 @@ public class Manabond extends CardImpl {
         super(ownerId, 113, "Manabond", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{G}");
         this.expansionSetCode = "EXO";
 
-
-        // At the beginning of your end step, you may reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand.
+        // At the beginning of your end step, reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand.
         this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new ManabondEffect(), true));
     }
 
@@ -66,12 +67,11 @@ public class Manabond extends CardImpl {
     }
 }
 
-
 class ManabondEffect extends OneShotEffect {
 
     public ManabondEffect() {
         super(Outcome.PutCardInPlay);
-        staticText = "reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand";
+        staticText = "you may reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand";
     }
 
     public ManabondEffect(final ManabondEffect effect) {
@@ -80,24 +80,22 @@ class ManabondEffect extends OneShotEffect {
 
     @Override
     public boolean apply(Game game, Ability source) {
-        Player player = game.getPlayer(source.getControllerId());
-        if (player != null) {
-            player.revealCards("Manabond", player.getHand(), game);
-
-            Cards hand = player.getHand().copy();
-            for(UUID uuid : hand){
+        Player controller = game.getPlayer(source.getControllerId());
+        MageObject sourceObject = source.getSourceObject(game);
+        if (controller != null && sourceObject != null) {
+            controller.revealCards(sourceObject.getIdName(), controller.getHand(), game);
+            Set<Card> toBattlefield = new LinkedHashSet<>();
+            for (UUID uuid : controller.getHand()) {
                 Card card = game.getCard(uuid);
-                if(card != null){
-                    if(card.getCardType().contains(CardType.LAND)){
-                        card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
-                    }
-                    else{
-                        player.discard(card, source, game);
-                    }
+                if (card != null && card.getCardType().contains(CardType.LAND)) {
+                    toBattlefield.add(card);
                 }
+
             }
-            
-        }   
+            controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, false, true, null);
+            controller.discard(controller.getHand().size(), false, source, game);
+            return true;
+        }
         return false;
     }
 
@@ -105,4 +103,4 @@ class ManabondEffect extends OneShotEffect {
     public ManabondEffect copy() {
         return new ManabondEffect(this);
     }
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java b/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java
index 84e2bdea4e..bf41dc6d02 100644
--- a/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java
+++ b/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java
@@ -27,14 +27,9 @@
  */
 package mage.sets.innistrad;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
 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.abilities.Ability;
 import mage.abilities.common.SimpleActivatedAbility;
 import mage.abilities.costs.common.DiscardTargetCost;
@@ -47,6 +42,13 @@ import mage.abilities.effects.OneShotEffect;
 import mage.abilities.effects.common.counter.AddCountersSourceEffect;
 import mage.cards.Card;
 import mage.cards.CardImpl;
+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.counters.CounterType;
 import mage.game.Game;
 import mage.game.permanent.Permanent;
@@ -101,15 +103,21 @@ class GrimoireOfTheDeadEffect extends OneShotEffect {
 
     @Override
     public boolean apply(Game game, Ability source) {
-        for (Player player: game.getPlayers().values()) {
-            for (Card card: player.getGraveyard().getCards(game)) {
-                if (card.getCardType().contains(CardType.CREATURE)) {
-                    card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
-                    game.addEffect(new GrimoireOfTheDeadEffect2(card.getId()), source);
+        Player controller = game.getPlayer(source.getControllerId());
+        if (controller != null) {
+            Set<Card> creatureCards = new LinkedHashSet<>();
+            for (Player player : game.getPlayers().values()) {
+                for (Card card : player.getGraveyard().getCards(game)) {
+                    if (card.getCardType().contains(CardType.CREATURE)) {
+                        creatureCards.add(card);
+                        game.addEffect(new GrimoireOfTheDeadEffect2(card.getId()), source);
+                    }
                 }
             }
+            controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null);
+            return true;
         }
-        return true;
+        return false;
     }
 
     @Override
@@ -121,10 +129,10 @@ class GrimoireOfTheDeadEffect extends OneShotEffect {
 
 class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl {
 
-    private UUID targetId;
+    private final UUID targetId;
 
     public GrimoireOfTheDeadEffect2(UUID targetId) {
-        super(Duration.EndOfGame, Outcome.Neutral);
+        super(Duration.Custom, Outcome.Neutral);
         this.targetId = targetId;
         staticText = "Becomes a black Zombie in addition to its other colors and types";
     }
@@ -170,4 +178,4 @@ class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl {
         return layer == Layer.ColorChangingEffects_5 || layer == Layer.TypeChangingEffects_4;
     }
 
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java
index d03f79e665..5f955caa78 100644
--- a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java
+++ b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,28 +20,29 @@
  *  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.magic2010;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
 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.LoyaltyAbility;
 import mage.abilities.common.EntersBattlefieldAbility;
 import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.discard.DiscardTargetEffect;
 import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.discard.DiscardTargetEffect;
 import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect;
 import mage.cards.Card;
 import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
 import mage.counters.CounterType;
 import mage.game.Game;
 import mage.players.Player;
@@ -98,14 +99,16 @@ class LilianaVessEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player controller = game.getPlayer(source.getControllerId());
-        for (UUID playerId: controller.getInRange()) {
+        for (UUID playerId : controller.getInRange()) {
             Player player = game.getPlayer(playerId);
             if (player != null) {
-                for (Card card: player.getGraveyard().getCards(game)) {
+                Set<Card> creatureCards = new LinkedHashSet<>();
+                for (Card card : player.getGraveyard().getCards(game)) {
                     if (card.getCardType().contains(CardType.CREATURE)) {
-                        card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
+                        creatureCards.add(card);
                     }
                 }
+                controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, false, null);
             }
         }
         return true;
diff --git a/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java b/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java
index 9e159d7af7..95bb22a363 100644
--- a/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java
+++ b/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,32 +20,34 @@
  *  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.magic2011;
 
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import mage.MageObject;
 import mage.abilities.Ability;
 import mage.abilities.effects.OneShotEffect;
 import mage.cards.Card;
 import mage.cards.CardImpl;
 import mage.cards.Cards;
 import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
 import mage.filter.common.FilterCreaturePermanent;
 import mage.game.Game;
 import mage.game.permanent.Permanent;
 import mage.players.Player;
 
-import java.util.List;
-import java.util.UUID;
-
 /**
  *
  * @author BetaSteward_at_googlemail.com
@@ -82,34 +84,36 @@ class MassPolymorphEffect extends OneShotEffect {
 
     @Override
     public boolean apply(Game game, Ability source) {
-        int count;
-        List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game);
-        count = creatures.size();
-        for (Permanent creature: creatures) {
-            creature.moveToExile(null, null, source.getSourceId(), game);
-        }
-        Cards revealed = new CardsImpl();
-        Cards creatureCards = new CardsImpl();
-        Cards nonCreatureCards = new CardsImpl();
-        Player player = game.getPlayer(source.getControllerId());
-        while (creatureCards.size() < count && player.getLibrary().size() > 0) {
-            Card card = player.getLibrary().removeFromTop(game);
-            revealed.add(card);
-            if (card.getCardType().contains(CardType.CREATURE)) {
-                creatureCards.add(card);
-            } else {
-                nonCreatureCards.add(card);
+        Player controller = game.getPlayer(source.getControllerId());
+        MageObject sourceObject = source.getSourceObject(game);
+        if (controller != null && sourceObject != null) {
+            int count;
+            // Cards creatures = new CardsImpl();
+            List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game);
+            Set<Card> creaturesToExile = new HashSet<>();
+            creaturesToExile.addAll(creatures);
+            count = creatures.size();
+            controller.moveCards(creaturesToExile, null, Zone.HAND, source, game);
+
+            Cards revealed = new CardsImpl();
+            Set<Card> creatureCards = new LinkedHashSet<>();
+            Cards nonCreatureCards = new CardsImpl();
+            while (creatureCards.size() < count && controller.getLibrary().size() > 0) {
+                Card card = controller.getLibrary().removeFromTop(game);
+                revealed.add(card);
+                if (card.getCardType().contains(CardType.CREATURE)) {
+                    creatureCards.add(card);
+                } else {
+                    nonCreatureCards.add(card);
+                }
             }
+            controller.revealCards(sourceObject.getIdName(), revealed, game);
+            controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null);
+            controller.putCardsOnTopOfLibrary(nonCreatureCards, game, source, false);
+            controller.shuffleLibrary(game);
+            return true;
         }
-        player.revealCards("Mass Polymorph", revealed, game);
-        for (Card creatureCard: creatureCards.getCards(game)) {
-            creatureCard.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
-        }
-        for (Card card: nonCreatureCards.getCards(game)) {
-            player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true, true);
-        }             
-        player.shuffleLibrary(game);
-        return true;
+        return false;
     }
 
     @Override
@@ -117,4 +121,4 @@ class MassPolymorphEffect extends OneShotEffect {
         return new MassPolymorphEffect(this);
     }
 
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java b/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java
index 8b84ffb612..4fbe776a8c 100644
--- a/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java
+++ b/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java
@@ -27,6 +27,8 @@
  */
 package mage.sets.magic2014;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.UUID;
 import mage.abilities.Ability;
 import mage.abilities.effects.OneShotEffect;
@@ -49,7 +51,6 @@ public class RiseOfTheDarkRealms extends CardImpl {
         super(ownerId, 111, "Rise of the Dark Realms", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{7}{B}{B}");
         this.expansionSetCode = "M14";
 
-
         // Put all creature cards from all graveyards onto the battlefield under your control.
         this.getSpellAbility().addEffect(new RiseOfTheDarkRealmsEffect());
     }
@@ -78,17 +79,23 @@ class RiseOfTheDarkRealmsEffect extends OneShotEffect {
     @Override
     public boolean apply(Game game, Ability source) {
         Player controller = game.getPlayer(source.getControllerId());
-        for (UUID playerId: controller.getInRange()) {
-            Player player = game.getPlayer(playerId);
-            if (player != null) {
-                for (Card card: player.getGraveyard().getCards(game)) {
-                    if (card.getCardType().contains(CardType.CREATURE)) {
-                        card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
+        if (controller != null) {
+
+            Set<Card> creatureCards = new LinkedHashSet<>();
+            for (UUID playerId : controller.getInRange()) {
+                Player player = game.getPlayer(playerId);
+                if (player != null) {
+                    for (Card card : player.getGraveyard().getCards(game)) {
+                        if (card.getCardType().contains(CardType.CREATURE)) {
+                            creatureCards.add(card);
+                        }
                     }
                 }
             }
+            controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null);
+            return true;
         }
-        return true;
+        return false;
     }
 
     @Override
diff --git a/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java
index 4cbe0168fc..4ccfccda7a 100644
--- a/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java
+++ b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java
@@ -27,8 +27,8 @@
  */
 package mage.sets.magicorigins;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.UUID;
 import mage.MageObject;
 import mage.abilities.Ability;
@@ -94,23 +94,22 @@ class AnimistsAwakeningEffect extends OneShotEffect {
         Cards cards = new CardsImpl(Zone.LIBRARY);
         int xValue = source.getManaCostsToPay().getX();
         cards.addAll(controller.getLibrary().getTopCards(game, xValue));
-        List<Permanent> lands = new ArrayList<>();
         if (cards.size() > 0) {
             controller.revealCards(sourceObject.getIdName(), cards, game);
+            Set<Card> toBattlefield = new LinkedHashSet<>();
             for (Card card : cards.getCards(new FilterLandCard(), source.getSourceId(), source.getControllerId(), game)) {
                 cards.remove(card);
-                controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true);
-                Permanent land = game.getPermanent(card.getId());
-                if (land != null) {
-                    lands.add(land);
-                }
-
+                toBattlefield.add(card);
             }
+            controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, true, false, true, null);
             controller.putCardsOnBottomOfLibrary(cards, game, source, true);
 
             if (SpellMasteryCondition.getInstance().apply(game, source)) {
-                for (Permanent land : lands) {
-                    land.untap(game);
+                for (Card card : toBattlefield) {
+                    Permanent land = game.getPermanent(card.getId());
+                    if (land != null) {
+                        land.untap(game);
+                    }
                 }
             }
         }
diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java
index b20a7cfe24..c8224d6d27 100644
--- a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java
+++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java
@@ -27,6 +27,8 @@
  */
 package mage.sets.scarsofmirrodin;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.UUID;
 import mage.MageObject;
 import mage.abilities.Ability;
@@ -115,13 +117,15 @@ class GenesisWaveEffect extends OneShotEffect {
             target1.setRequired(false);
 
             controller.choose(Outcome.PutCardInPlay, cards, target1, game);
+            Set<Card> toBattlefield = new LinkedHashSet<>();
             for (UUID cardId : target1.getTargets()) {
                 Card card = cards.get(cardId, game);
                 if (card != null) {
                     cards.remove(card);
-                    controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId());
+                    toBattlefield.add(card);
                 }
             }
+            controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, false, false, null);
             controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
         }
         return true;
diff --git a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
index 856e29d194..3bbcbbefb1 100644
--- a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
+++ b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
@@ -28,7 +28,9 @@
 package mage.sets.urzassaga;
 
 import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 import mage.abilities.Ability;
 import mage.abilities.effects.OneShotEffect;
@@ -102,7 +104,7 @@ class ShowAndTellEffect extends OneShotEffect {
         if (controller == null) {
             return false;
         }
-        List<Card> cardsToPutIntoPlay = new ArrayList<>();
+        Set<Card> cardsToPutIntoPlay = new LinkedHashSet<>();
         TargetCardInHand target = new TargetCardInHand(filter);
 
         for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
@@ -119,12 +121,13 @@ class ShowAndTellEffect extends OneShotEffect {
                 }
             }
         }
-        for (Card card : cardsToPutIntoPlay) {
-            Player player = game.getPlayer(card.getOwnerId());
-            if (player != null) {
-                player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId());
-            }
-        }
-        return true;
+        return controller.moveCards(cardsToPutIntoPlay, Zone.BATTLEFIELD, source, game, false, false, true, null);
+//        for (Card card : cardsToPutIntoPlay) {
+//            Player player = game.getPlayer(card.getOwnerId());
+//            if (player != null) {
+//                player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId());
+//            }
+//        }
+        // return true;
     }
 }

From 673cd6b38a024e9f658a190a78d944f97aace1c2 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 11:19:19 +0200
Subject: [PATCH 07/13] * Fixed a bug that if opponent left tournament during a
 match, get got points for that mathc if he won more games (fixes #1310).

---
 .../mage/game/tournament/TournamentImpl.java  | 63 +++++++++----------
 1 file changed, 30 insertions(+), 33 deletions(-)

diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java
index 2719c4a277..e326882b29 100644
--- a/Mage/src/mage/game/tournament/TournamentImpl.java
+++ b/Mage/src/mage/game/tournament/TournamentImpl.java
@@ -25,7 +25,6 @@
  *  authors and should not be interpreted as representing official policies, either expressed
  *  or implied, of BetaSteward_at_googlemail.com.
  */
-
 package mage.game.tournament;
 
 import java.util.ArrayList;
@@ -114,7 +113,7 @@ public abstract class TournamentImpl implements Tournament {
         }
         synchronized (this) {
             this.notifyAll();
-        }        
+        }
     }
 
     @Override
@@ -209,7 +208,7 @@ public abstract class TournamentImpl implements Tournament {
     }
 
     protected void playRound(Round round) {
-        for (TournamentPairing pair: round.getPairs()) {
+        for (TournamentPairing pair : round.getPairs()) {
             playMatch(pair);
         }
         updateResults(); // show points from byes
@@ -227,7 +226,7 @@ public abstract class TournamentImpl implements Tournament {
 
     protected List<TournamentPlayer> getActivePlayers() {
         List<TournamentPlayer> activePlayers = new ArrayList<>();
-        for (TournamentPlayer player: players.values()) {
+        for (TournamentPlayer player : players.values()) {
             if (!player.isEliminated()) {
                 activePlayers.add(player);
             }
@@ -240,13 +239,13 @@ public abstract class TournamentImpl implements Tournament {
      */
     @Override
     public void updateResults() {
-        for (TournamentPlayer player: players.values()) {
+        for (TournamentPlayer player : players.values()) {
             player.setResults("");
             player.setPoints(0);
             player.setStateInfo("");
         }
-        for (Round round: rounds) {
-            for (TournamentPairing pair: round.getPairs()) {
+        for (Round round : rounds) {
+            for (TournamentPairing pair : round.getPairs()) {
                 Match match = pair.getMatch();
                 if (match != null && match.hasEnded()) {
                     TournamentPlayer tp1 = pair.getPlayer1();
@@ -276,9 +275,9 @@ public abstract class TournamentImpl implements Tournament {
                     tp2.setResults(addRoundResult(round.getRoundNumber(), pair, tp2, tp1));
 
                     // Add points
-                    if (mp2.hasQuit() || mp1.getWins() > mp2.getWins()) {
+                    if ((!mp1.hasQuit() && mp1.getWins() > mp2.getWins()) || mp2.hasQuit()) {
                         tp1.setPoints(tp1.getPoints() + 3);
-                    } else if (mp1.hasQuit() || mp1.getWins() < mp2.getWins()) {
+                    } else if ((!mp2.hasQuit() && mp1.getWins() < mp2.getWins()) || mp1.hasQuit()) {
                         tp2.setPoints(tp2.getPoints() + 3);
                     } else {
                         tp1.setPoints(tp1.getPoints() + 1);
@@ -299,7 +298,7 @@ public abstract class TournamentImpl implements Tournament {
         playerResult.append(getMatchResultString(tournamentPlayer, opponentPlayer, pair.getMatch()));
         return playerResult.toString();
     }
-    
+
     private static String getMatchResultString(TournamentPlayer p1, TournamentPlayer p2, Match match) {
         MatchPlayer mp1 = match.getPlayer(p1.getPlayer().getId());
         MatchPlayer mp2 = match.getPlayer(p2.getPlayer().getId());
@@ -307,22 +306,22 @@ public abstract class TournamentImpl implements Tournament {
         matchResult.append(p2.getPlayer().getName());
         matchResult.append(" [").append(mp1.getWins());
         if (mp1.hasQuit()) {
-            matchResult.append(mp1.getPlayer().hasIdleTimeout()? "I" :(mp1.getPlayer().hasTimerTimeout()?"T":"Q"));
+            matchResult.append(mp1.getPlayer().hasIdleTimeout() ? "I" : (mp1.getPlayer().hasTimerTimeout() ? "T" : "Q"));
         }
         if (match.getDraws() > 0) {
             matchResult.append("-").append(match.getDraws());
         }
         matchResult.append("-").append(mp2.getWins());
         if (mp2.hasQuit()) {
-            matchResult.append(mp2.getPlayer().hasIdleTimeout()? "I" :(mp2.getPlayer().hasTimerTimeout()?"T":"Q"));
-        }                
+            matchResult.append(mp2.getPlayer().hasIdleTimeout() ? "I" : (mp2.getPlayer().hasTimerTimeout() ? "T" : "Q"));
+        }
         matchResult.append("] ");
         return matchResult.toString();
     }
-    
+
     @Override
     public boolean isDoneConstructing() {
-        for (TournamentPlayer player: this.players.values()) {
+        for (TournamentPlayer player : this.players.values()) {
             if (!player.isDoneConstructing()) {
                 return false;
             }
@@ -332,7 +331,7 @@ public abstract class TournamentImpl implements Tournament {
 
     @Override
     public boolean allJoined() {
-        for (TournamentPlayer player: this.players.values()) {
+        for (TournamentPlayer player : this.players.values()) {
             if (!player.isJoined()) {
                 return false;
             }
@@ -358,27 +357,26 @@ public abstract class TournamentImpl implements Tournament {
     public void construct() {
         tableEventSource.fireTableEvent(EventType.CONSTRUCT);
         if (!isAbort()) {
-            for (final TournamentPlayer player: players.values()) {
+            for (final TournamentPlayer player : players.values()) {
 
                 player.setConstructing();
                 new Thread(
-                    new Runnable() {
-                        @Override
-                        public void run() {
-                            player.getPlayer().construct(TournamentImpl.this, player.getDeck());
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                player.getPlayer().construct(TournamentImpl.this, player.getDeck());
+                            }
                         }
-                    }
                 ).start();
             }
             // add autosubmit trigger
-            
-            
-            synchronized(this) {
+
+            synchronized (this) {
                 while (!isDoneConstructing()) {
                     try {
                         this.wait();
                     } catch (InterruptedException ex) {
-                        
+
                     }
                 }
             }
@@ -387,7 +385,7 @@ public abstract class TournamentImpl implements Tournament {
     }
 
     protected void openBoosters() {
-        for (TournamentPlayer player: this.players.values()) {
+        for (TournamentPlayer player : this.players.values()) {
             player.setDeck(new Deck());
             if (options.getLimitedOptions().getDraftCube() != null) {
                 DraftCube cube = options.getLimitedOptions().getDraftCube();
@@ -395,7 +393,7 @@ public abstract class TournamentImpl implements Tournament {
                     player.getDeck().getSideboard().addAll(cube.createBooster());
                 }
             } else {
-                for (ExpansionSet set: sets) {
+                for (ExpansionSet set : sets) {
                     player.getDeck().getSideboard().addAll(set.createBooster());
                 }
             }
@@ -406,7 +404,7 @@ public abstract class TournamentImpl implements Tournament {
 
     public void resetBufferedCards() {
         HashSet<ExpansionSet> setsDone = new HashSet<>();
-        for(ExpansionSet set: sets) {
+        for (ExpansionSet set : sets) {
             if (!setsDone.contains(set)) {
                 set.removeSavedCards();
                 setsDone.add(set);
@@ -454,7 +452,7 @@ public abstract class TournamentImpl implements Tournament {
     protected void winners() {
         List<TournamentPlayer> winners = new ArrayList<>();
         int pointsWinner = 1; // with less than 1 point you can't win
-        for(TournamentPlayer tournamentPlayer: this.getPlayers()) {
+        for (TournamentPlayer tournamentPlayer : this.getPlayers()) {
             if (pointsWinner < tournamentPlayer.getPoints()) {
                 winners.clear();
                 winners.add(tournamentPlayer);
@@ -464,14 +462,14 @@ public abstract class TournamentImpl implements Tournament {
             }
         }
         // set winner state for the players with the most points > 0
-        for (TournamentPlayer tournamentPlayer: winners) {
+        for (TournamentPlayer tournamentPlayer : winners) {
             tournamentPlayer.setStateInfo("Winner");
         }
     }
 
     @Override
     public void cleanUpOnTournamentEnd() {
-        for(TournamentPlayer tournamentPlayer: players.values()) {
+        for (TournamentPlayer tournamentPlayer : players.values()) {
             tournamentPlayer.CleanUpOnTournamentEnd();
         }
     }
@@ -509,7 +507,6 @@ public abstract class TournamentImpl implements Tournament {
         this.startTime = new Date();
     }
 
-
     @Override
     public void setStepStartTime(Date stepStartTime) {
         this.stepStartTime = stepStartTime;

From 8dad1eeb135d45b91308fe64dc30e76c58e00400 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 11:19:50 +0200
Subject: [PATCH 08/13] Minor most tooltip related changes.

---
 .../mage/sets/shadowmoor/AphoticWisps.java    | 28 +++---
 .../mage/sets/shadowmoor/DrownerInitiate.java | 10 +-
 .../src/mage/sets/shadowmoor/LeechBonder.java |  2 +-
 .../sets/shadowmoor/WickerWarcrawler.java     | 48 ++-------
 .../src/mage/sets/urzassaga/ShowAndTell.java  |  7 --
 .../src/mage/sets/worldwake/FeralContest.java |  7 +-
 .../src/mage/sets/zendikar/BloodTribute.java  | 12 +--
 .../AttacksOrBlocksTriggeredAbility.java      | 11 ++-
 .../abilities/costs/AlternativeCost2Impl.java | 33 ++++---
 .../mage/abilities/costs/CompositeCost.java   | 13 ++-
 Mage/src/mage/abilities/costs/Cost.java       | 62 +++++++-----
 Mage/src/mage/abilities/costs/CostImpl.java   | 54 +++++-----
 Mage/src/mage/abilities/costs/CostsImpl.java  | 99 ++++++++++---------
 .../costs/OptionalAdditionalCostImpl.java     |  4 +-
 Mage/src/mage/abilities/costs/OrCost.java     |  9 +-
 .../abilities/costs/VariableCostImpl.java     |  5 +
 .../costs/common/DiscardTargetCost.java       | 29 +++---
 .../abilities/costs/mana/ManaCostsImpl.java   |  9 ++
 .../effects/common/DrawCardTargetEffect.java  | 15 ++-
 .../BecomesColorOrColorsTargetEffect.java     | 11 ++-
 .../abilities/keyword/BuybackAbility.java     |  4 +-
 .../abilities/keyword/ConspireAbility.java    |  5 +-
 .../abilities/keyword/EntwineAbility.java     |  2 +-
 .../mage/abilities/keyword/KickerAbility.java |  4 +-
 .../abilities/keyword/ReplicateAbility.java   |  2 +-
 .../abilities/keyword/RetraceAbility.java     |  5 +-
 26 files changed, 253 insertions(+), 237 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java
index 20096cb783..588154614b 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java
@@ -25,20 +25,19 @@
  *  authors and should not be interpreted as representing official policies, either expressed
  *  or implied, of BetaSteward_at_googlemail.com.
  */
-
 package mage.sets.shadowmoor;
 
 import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
 import mage.ObjectColor;
+import mage.abilities.effects.Effect;
 import mage.abilities.effects.common.DrawCardSourceControllerEffect;
-import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
 import mage.abilities.effects.common.continuous.BecomesColorTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
 import mage.abilities.keyword.FearAbility;
 import mage.cards.CardImpl;
+import mage.constants.CardType;
 import mage.constants.Duration;
+import mage.constants.Rarity;
 import mage.target.common.TargetCreaturePermanent;
 
 /**
@@ -47,19 +46,25 @@ import mage.target.common.TargetCreaturePermanent;
  */
 public class AphoticWisps extends CardImpl {
 
-    public AphoticWisps (UUID ownerId) {
+    public AphoticWisps(UUID ownerId) {
         super(ownerId, 55, "Aphotic Wisps", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}");
         this.expansionSetCode = "SHM";
 
-        //    Target creature becomes black and gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.)
+        // Target creature becomes black and gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.)
         this.getSpellAbility().addTarget(new TargetCreaturePermanent());
-        this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.EndOfTurn));
-        this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FearAbility.getInstance(), Duration.EndOfTurn));
+        Effect effect = new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.EndOfTurn);
+        effect.setText("Target creature becomes black");
+        this.getSpellAbility().addEffect(effect);
+        effect = new GainAbilityTargetEffect(FearAbility.getInstance(), Duration.EndOfTurn);
+        effect.setText("and gains fear until end of turn");
+        this.getSpellAbility().addEffect(effect);
         // Draw a card.
-        this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+        effect = new DrawCardSourceControllerEffect(1);
+        effect.setText("<br>Draw a card");
+        this.getSpellAbility().addEffect(effect);
     }
 
-    public AphoticWisps (final AphoticWisps card) {
+    public AphoticWisps(final AphoticWisps card) {
         super(card);
     }
 
@@ -69,4 +74,3 @@ public class AphoticWisps extends CardImpl {
     }
 
 }
-
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/DrownerInitiate.java b/Mage.Sets/src/mage/sets/shadowmoor/DrownerInitiate.java
index e2c04a54d6..67b9eda309 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/DrownerInitiate.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/DrownerInitiate.java
@@ -45,12 +45,12 @@ import mage.target.TargetPlayer;
 /**
  *
  * @author jeffwadsworth
-
+ *
  */
 public class DrownerInitiate extends CardImpl {
-    
+
     private static final FilterSpell filter = new FilterSpell("a blue spell");
-    
+
     static {
         filter.add(new ColorPredicate(ObjectColor.BLUE));
     }
@@ -65,10 +65,10 @@ public class DrownerInitiate extends CardImpl {
         this.toughness = new MageInt(1);
 
         // Whenever a player casts a blue spell, you may pay {1}. If you do, target player puts the top two cards of his or her library into his or her graveyard.
-        Ability ability = new SpellCastAllTriggeredAbility(new DoIfCostPaid(new PutLibraryIntoGraveTargetEffect(2), new ManaCostsImpl("{1}")), filter, true);
+        Ability ability = new SpellCastAllTriggeredAbility(new DoIfCostPaid(new PutLibraryIntoGraveTargetEffect(2), new ManaCostsImpl("{1}")), filter, false);
         ability.addTarget(new TargetPlayer());
         this.addAbility(ability);
-        
+
     }
 
     public DrownerInitiate(final DrownerInitiate card) {
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/LeechBonder.java b/Mage.Sets/src/mage/sets/shadowmoor/LeechBonder.java
index 623580db2d..7e6f922d10 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/LeechBonder.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/LeechBonder.java
@@ -72,7 +72,7 @@ public class LeechBonder extends CardImpl {
         // Leech Bonder enters the battlefield with two -1/-1 counters on it.
         this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2))));
 
-        // {U}, {untap}: Move a counter from target creature onto a second target creature.
+        // {U}, {untap}: Move a counter from target creature onto another target creature.
         Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LeechBonderEffect(), new ManaCostsImpl("{U}"));
         ability.addCost(new UntapSourceCost());
         ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature to remove counter from")));
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/WickerWarcrawler.java b/Mage.Sets/src/mage/sets/shadowmoor/WickerWarcrawler.java
index 4ea92e7207..597a65871a 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/WickerWarcrawler.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/WickerWarcrawler.java
@@ -29,19 +29,16 @@ package mage.sets.shadowmoor;
 
 import java.util.UUID;
 import mage.MageInt;
-import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
 import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
 import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
 import mage.cards.CardImpl;
 import mage.constants.CardType;
-import mage.constants.Outcome;
 import mage.constants.Rarity;
 import mage.counters.CounterType;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.target.targetpointer.FixedTarget;
 
 /**
  *
@@ -57,7 +54,10 @@ public class WickerWarcrawler extends CardImpl {
         this.toughness = new MageInt(6);
 
         // Whenever Wicker Warcrawler attacks or blocks, put a -1/-1 counter on it at end of combat.
-        this.addAbility(new AttacksOrBlocksTriggeredAbility(new WickerWarcrawlerEffect(), false));
+        Effect effect = new AddCountersSourceEffect(CounterType.M1M1.createInstance(), true);
+        effect.setText("put a -1/-1 counter on it at end of combat");
+        DelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
+        this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(ability, false, false), false));
 
     }
 
@@ -70,35 +70,3 @@ public class WickerWarcrawler extends CardImpl {
         return new WickerWarcrawler(this);
     }
 }
-
-class WickerWarcrawlerEffect extends OneShotEffect {
-
-    WickerWarcrawlerEffect() {
-        super(Outcome.Detriment);
-        staticText = "put a -1/-1 counter on {this} at the end of combat";
-    }
-
-    WickerWarcrawlerEffect(final WickerWarcrawlerEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        Permanent wickerWarcrawler = game.getPermanent(source.getSourceId());
-        if (wickerWarcrawler != null) {
-            AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance()));
-            delayedAbility.setSourceId(source.getSourceId());
-            delayedAbility.setControllerId(source.getControllerId());
-            delayedAbility.setSourceObject(source.getSourceObject(game), game);
-            delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(source.getSourceId()));
-            game.addDelayedTriggeredAbility(delayedAbility);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public WickerWarcrawlerEffect copy() {
-        return new WickerWarcrawlerEffect(this);
-    }
-}
diff --git a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
index 3bbcbbefb1..0161b4f0df 100644
--- a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
+++ b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java
@@ -122,12 +122,5 @@ class ShowAndTellEffect extends OneShotEffect {
             }
         }
         return controller.moveCards(cardsToPutIntoPlay, Zone.BATTLEFIELD, source, game, false, false, true, null);
-//        for (Card card : cardsToPutIntoPlay) {
-//            Player player = game.getPlayer(card.getOwnerId());
-//            if (player != null) {
-//                player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId());
-//            }
-//        }
-        // return true;
     }
 }
diff --git a/Mage.Sets/src/mage/sets/worldwake/FeralContest.java b/Mage.Sets/src/mage/sets/worldwake/FeralContest.java
index f0af7b313e..b519cab6c9 100644
--- a/Mage.Sets/src/mage/sets/worldwake/FeralContest.java
+++ b/Mage.Sets/src/mage/sets/worldwake/FeralContest.java
@@ -32,7 +32,6 @@ import java.util.UUID;
 import mage.constants.CardType;
 import mage.constants.Rarity;
 import mage.abilities.Ability;
-import mage.abilities.effects.Effect;
 import mage.abilities.effects.RequirementEffect;
 import mage.abilities.effects.common.counter.AddCountersTargetEffect;
 import mage.cards.CardImpl;
@@ -53,8 +52,7 @@ public class FeralContest extends CardImpl {
         super(ownerId, 100, "Feral Contest", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{G}");
         this.expansionSetCode = "WWK";
 
-
-        // Put a +1/+1 counter on target creature you control. 
+        // Put a +1/+1 counter on target creature you control.
         this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
         this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
         // Another target creature blocks it this turn if able.
@@ -88,7 +86,7 @@ class FeralContestEffect extends RequirementEffect {
     }
 
     @Override
-    public boolean applies(Permanent permanent, Ability source, Game game) {        
+    public boolean applies(Permanent permanent, Ability source, Game game) {
         if (permanent.getId().equals(source.getTargets().get(1).getFirstTarget())) {
             return permanent.canBlock(source.getFirstTarget(), game);
         }
@@ -116,4 +114,3 @@ class FeralContestEffect extends RequirementEffect {
     }
 
 }
-
diff --git a/Mage.Sets/src/mage/sets/zendikar/BloodTribute.java b/Mage.Sets/src/mage/sets/zendikar/BloodTribute.java
index 43437afc3f..1335d9f4be 100644
--- a/Mage.Sets/src/mage/sets/zendikar/BloodTribute.java
+++ b/Mage.Sets/src/mage/sets/zendikar/BloodTribute.java
@@ -33,8 +33,6 @@ import mage.constants.Outcome;
 import mage.constants.Rarity;
 import mage.abilities.Ability;
 import mage.abilities.condition.common.KickedCondition;
-import mage.abilities.costs.OptionalAdditionalCost;
-import mage.abilities.costs.OptionalAdditionalCostImpl;
 import mage.abilities.costs.common.TapTargetCost;
 import mage.abilities.decorator.ConditionalOneShotEffect;
 import mage.abilities.effects.Effect;
@@ -56,7 +54,7 @@ import mage.target.common.TargetOpponent;
  */
 public class BloodTribute extends CardImpl {
 
-    private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Vampire you control");
+    private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an untapped Vampire you control");
 
     static {
         filter.add(Predicates.not(new TappedPredicate()));
@@ -67,20 +65,18 @@ public class BloodTribute extends CardImpl {
         super(ownerId, 81, "Blood Tribute", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{B}{B}");
         this.expansionSetCode = "ZEN";
 
-
         // Kicker - Tap an untapped Vampire you control.
-        OptionalAdditionalCost cost = new OptionalAdditionalCostImpl("Kicker-","",new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)));
-        this.addAbility(new KickerAbility(cost));
+        this.addAbility(new KickerAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))));
 
         // Target opponent loses half his or her life, rounded up.
         this.getSpellAbility().addTarget(new TargetOpponent());
         this.getSpellAbility().addEffect(new BloodTributeLoseLifeEffect());
-         
+
         // If Blood Tribute was kicked, you gain life equal to the life lost this way.
         Effect effect = new ConditionalOneShotEffect(
                 new BloodTributeGainLifeEffect(),
                 KickedCondition.getInstance(),
-                "If Blood Tribute was kicked, you gain life equal to the life lost this way");
+                "If {this} was kicked, you gain life equal to the life lost this way");
         this.getSpellAbility().addEffect(effect);
     }
 
diff --git a/Mage/src/mage/abilities/common/AttacksOrBlocksTriggeredAbility.java b/Mage/src/mage/abilities/common/AttacksOrBlocksTriggeredAbility.java
index 7c1bb12348..732e6c59a7 100644
--- a/Mage/src/mage/abilities/common/AttacksOrBlocksTriggeredAbility.java
+++ b/Mage/src/mage/abilities/common/AttacksOrBlocksTriggeredAbility.java
@@ -2,17 +2,25 @@ package mage.abilities.common;
 
 import mage.abilities.TriggeredAbilityImpl;
 import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
 import mage.constants.Zone;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 
 public class AttacksOrBlocksTriggeredAbility extends TriggeredAbilityImpl {
+
+    protected String startText = "Whenever";
+
     public AttacksOrBlocksTriggeredAbility(Effect effect, boolean optional) {
         super(Zone.BATTLEFIELD, effect, optional);
+        if (effect instanceof CreateDelayedTriggeredAbilityEffect) {
+            startText = "When";
+        }
     }
 
     public AttacksOrBlocksTriggeredAbility(final AttacksOrBlocksTriggeredAbility ability) {
         super(ability);
+        this.startText = ability.startText;
     }
 
     @Override
@@ -22,8 +30,9 @@ public class AttacksOrBlocksTriggeredAbility extends TriggeredAbilityImpl {
 
     @Override
     public String getRule() {
-        return "When {this} attacks or blocks, " + super.getRule();
+        return startText + " {this} attacks or blocks, " + super.getRule();
     }
+
     @Override
     public boolean checkEventType(GameEvent event, Game game) {
         return event.getType() == GameEvent.EventType.ATTACKER_DECLARED || event.getType() == GameEvent.EventType.BLOCKER_DECLARED;
diff --git a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java
index b6b73034a9..03a0be13f4 100644
--- a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java
+++ b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java
@@ -25,20 +25,18 @@
  *  authors and should not be interpreted as representing official policies, either expressed
  *  or implied, of BetaSteward_at_googlemail.com.
  */
-
 package mage.abilities.costs;
 
 import mage.game.Game;
 
 /**
  * Alternative costs
- * 
+ *
  * @author LevelX2
- * 
+ *
  * @param <T>
  */
-
-public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends CostsImpl<Cost> implements AlternativeCost2 {
+public class AlternativeCost2Impl<T extends AlternativeCost2Impl<T>> extends CostsImpl<Cost> implements AlternativeCost2 {
 
     protected String name;
     protected String reminderText;
@@ -72,6 +70,7 @@ public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends Co
     public String getName() {
         return this.name;
     }
+
     /**
      * Returns the complete text for the addional cost or if onlyCost is true
      * only the pure text for the included native cost
@@ -84,7 +83,7 @@ public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends Co
         if (onlyCost) {
             return getText();
         } else {
-            return new StringBuffer(name != null ? name: "").append(delimiter != null ? delimiter: "").append(getText()).toString();
+            return (name != null ? name : "") + (delimiter != null ? delimiter : "") + getText();
         }
     }
 
@@ -103,20 +102,20 @@ public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends Co
     }
 
     /**
-     * Returns a text suffix for the game log, that can be added to
-     * the cast message.
+     * Returns a text suffix for the game log, that can be added to the cast
+     * message.
      *
-     * @param position - if there are multiple costs, it's the postion the cost is set (starting with 0)
+     * @param position - if there are multiple costs, it's the postion the cost
+     * is set (starting with 0)
      * @return
      */
     @Override
     public String getCastSuffixMessage(int position) {
-        StringBuilder sb = new StringBuilder(position > 0 ? " and ":"").append(" with ");
+        StringBuilder sb = new StringBuilder(position > 0 ? " and " : "").append(" with ");
         sb.append(name);
-        return  sb.toString();
+        return sb.toString();
     }
 
-
     /**
      * If the player intends to pay the cost, the cost will be activated
      *
@@ -124,7 +123,9 @@ public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends Co
     @Override
     public void activate() {
         activated = true;
-    };
+    }
+
+    ;
 
     /**
      * Reset the activate and count information
@@ -142,9 +143,11 @@ public class AlternativeCost2Impl <T extends AlternativeCost2Impl<T>> extends Co
      * @return
      */
     @Override
-    public boolean isActivated(Game game){
+    public boolean isActivated(Game game) {
         return activated;
-    };
+    }
+
+    ;
 
     @Override
     public AlternativeCost2Impl copy() {
diff --git a/Mage/src/mage/abilities/costs/CompositeCost.java b/Mage/src/mage/abilities/costs/CompositeCost.java
index f76693fb18..1d497d4379 100644
--- a/Mage/src/mage/abilities/costs/CompositeCost.java
+++ b/Mage/src/mage/abilities/costs/CompositeCost.java
@@ -1,14 +1,14 @@
 package mage.abilities.costs;
 
+import java.util.UUID;
 import mage.abilities.Ability;
 import mage.game.Game;
 import mage.target.Targets;
 
-import java.util.UUID;
-
 public class CompositeCost implements Cost {
-    private Cost firstCost;
-    private Cost secondCost;
+
+    private final Cost firstCost;
+    private final Cost secondCost;
     private String description;
 
     public CompositeCost(Cost firstCost, Cost secondCost, String description) {
@@ -28,6 +28,11 @@ public class CompositeCost implements Cost {
         throw new RuntimeException("Not supported method");
     }
 
+    @Override
+    public void setText(String text) {
+        this.description = text;
+    }
+
     @Override
     public String getText() {
         return description;
diff --git a/Mage/src/mage/abilities/costs/Cost.java b/Mage/src/mage/abilities/costs/Cost.java
index cd8696cd13..885ff8376f 100644
--- a/Mage/src/mage/abilities/costs/Cost.java
+++ b/Mage/src/mage/abilities/costs/Cost.java
@@ -1,31 +1,30 @@
 /*
-* 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.
-*/
-
+ * 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.abilities.costs;
 
 import java.io.Serializable;
@@ -37,12 +36,21 @@ import mage.target.Targets;
 public interface Cost extends Serializable {
 
     UUID getId();
+
     String getText();
+
+    void setText(String text);
+
     boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game);
+
     boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana);
+
     boolean isPaid();
+
     void clearPaid();
+
     void setPaid();
+
     Targets getTargets();
 
     Cost copy();
diff --git a/Mage/src/mage/abilities/costs/CostImpl.java b/Mage/src/mage/abilities/costs/CostImpl.java
index e423f30fed..57f6c5a747 100644
--- a/Mage/src/mage/abilities/costs/CostImpl.java
+++ b/Mage/src/mage/abilities/costs/CostImpl.java
@@ -1,31 +1,30 @@
 /*
-* 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.
-*/
-
+ * 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.abilities.costs;
 
 import java.util.UUID;
@@ -57,6 +56,7 @@ public abstract class CostImpl implements Cost {
         return text;
     }
 
+    @Override
     public void setText(String text) {
         this.text = text;
     }
diff --git a/Mage/src/mage/abilities/costs/CostsImpl.java b/Mage/src/mage/abilities/costs/CostsImpl.java
index a2624f3f29..df64087a37 100644
--- a/Mage/src/mage/abilities/costs/CostsImpl.java
+++ b/Mage/src/mage/abilities/costs/CostsImpl.java
@@ -1,31 +1,30 @@
 /*
-* 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.
-*/
-
+ * 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.abilities.costs;
 
 import java.util.ArrayList;
@@ -44,12 +43,16 @@ import mage.target.Targets;
  */
 public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T> {
 
-    public CostsImpl() {}
+    protected String text = null;
+
+    public CostsImpl() {
+    }
 
     public CostsImpl(final CostsImpl<T> costs) {
-        for (Cost cost: costs) {
-            this.add((T)cost.copy());
+        for (Cost cost : costs) {
+            this.add((T) cost.copy());
         }
+        this.text = costs.text;
     }
 
     @Override
@@ -57,20 +60,28 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
         throw new RuntimeException("Not supported method");
     }
 
+    @Override
+    public void setText(String text) {
+        this.text = text;
+    }
+
     @Override
     public String getText() {
+        if (text != null) {
+            return text;
+        }
         if (this.size() == 0) {
             return "";
         }
 
         StringBuilder sbText = new StringBuilder();
-        for (T cost: this) {
-            String text = cost.getText();
-            if (text != null && !text.isEmpty()) {
-                sbText.append(Character.toUpperCase(text.charAt(0))).append(text.substring(1)).append(", ");
+        for (T cost : this) {
+            String textCost = cost.getText();
+            if (textCost != null && !textCost.isEmpty()) {
+                sbText.append(Character.toUpperCase(textCost.charAt(0))).append(textCost.substring(1)).append(", ");
             }
         }
-        if (sbText.length() > 1){
+        if (sbText.length() > 1) {
             sbText.setLength(sbText.length() - 2);
         }
         return sbText.toString();
@@ -78,7 +89,7 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
 
     @Override
     public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
-        for (T cost: this) {
+        for (T cost : this) {
             if (!cost.canPay(ability, sourceId, controllerId, game)) {
                 return false;
             }
@@ -101,7 +112,7 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
 
     @Override
     public boolean isPaid() {
-        for (T cost: this) {
+        for (T cost : this) {
             if (!(cost instanceof VariableManaCost) && !cost.isPaid()) {
                 return false;
             }
@@ -111,14 +122,14 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
 
     @Override
     public void clearPaid() {
-        for (T cost: this) {
+        for (T cost : this) {
             cost.clearPaid();
         }
     }
 
     @Override
     public void setPaid() {
-        for (T cost: this) {
+        for (T cost : this) {
             cost.setPaid();
         }
     }
@@ -126,7 +137,7 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
     @Override
     public Costs<T> getUnpaid() {
         Costs<T> unpaid = new CostsImpl<>();
-        for (T cost: this) {
+        for (T cost : this) {
             if (!cost.isPaid()) {
                 unpaid.add(cost);
             }
@@ -140,17 +151,17 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
             return unpaid.get(0);
         }
         return null;
-     }
+    }
 
     @Override
     public List<VariableCost> getVariableCosts() {
         List<VariableCost> variableCosts = new ArrayList<>();
-        for (T cost: this) {
+        for (T cost : this) {
             if (cost instanceof VariableCost) {
                 variableCosts.add((VariableCost) cost);
             }
             if (cost instanceof ManaCosts) {
-                variableCosts.addAll(((ManaCosts)cost).getVariableCosts());
+                variableCosts.addAll(((ManaCosts) cost).getVariableCosts());
             }
         }
         return variableCosts;
@@ -159,7 +170,7 @@ public class CostsImpl<T extends Cost> extends ArrayList<T> implements Costs<T>
     @Override
     public Targets getTargets() {
         Targets targets = new Targets();
-        for (T cost: this) {
+        for (T cost : this) {
             if (cost.getTargets() != null) {
                 targets.addAll(cost.getTargets());
             }
diff --git a/Mage/src/mage/abilities/costs/OptionalAdditionalCostImpl.java b/Mage/src/mage/abilities/costs/OptionalAdditionalCostImpl.java
index 489d8690ea..3646a9c3ec 100644
--- a/Mage/src/mage/abilities/costs/OptionalAdditionalCostImpl.java
+++ b/Mage/src/mage/abilities/costs/OptionalAdditionalCostImpl.java
@@ -50,7 +50,7 @@ public class OptionalAdditionalCostImpl<T extends OptionalAdditionalCostImpl> ex
         this.activated = false;
         this.name = name;
         this.delimiter = delimiter;
-        this.reminderText = new StringBuilder("<i>").append(reminderText).append("</i>").toString();
+        this.reminderText = "<i>(" + reminderText + ")</i>";
         this.activatedCounter = 0;
         this.add((Cost) cost);
     }
@@ -81,7 +81,7 @@ public class OptionalAdditionalCostImpl<T extends OptionalAdditionalCostImpl> ex
         if (onlyCost) {
             return getText();
         } else {
-            return new StringBuffer(name).append(delimiter).append(getText()).toString();
+            return name + delimiter + getText();
         }
     }
 
diff --git a/Mage/src/mage/abilities/costs/OrCost.java b/Mage/src/mage/abilities/costs/OrCost.java
index 2c5a7740e7..0707741244 100644
--- a/Mage/src/mage/abilities/costs/OrCost.java
+++ b/Mage/src/mage/abilities/costs/OrCost.java
@@ -37,8 +37,8 @@ import mage.target.Targets;
 
 public class OrCost implements Cost {
 
-    private Cost firstCost;
-    private Cost secondCost;
+    private final Cost firstCost;
+    private final Cost secondCost;
     private String description;
     // which cost was slected to pay
     private Cost selectedCost;
@@ -61,6 +61,11 @@ public class OrCost implements Cost {
         throw new RuntimeException("Not supported method");
     }
 
+    @Override
+    public void setText(String text) {
+        this.description = text;
+    }
+
     @Override
     public String getText() {
         return description;
diff --git a/Mage/src/mage/abilities/costs/VariableCostImpl.java b/Mage/src/mage/abilities/costs/VariableCostImpl.java
index 68557546df..e1002b91eb 100644
--- a/Mage/src/mage/abilities/costs/VariableCostImpl.java
+++ b/Mage/src/mage/abilities/costs/VariableCostImpl.java
@@ -77,6 +77,11 @@ public abstract class VariableCostImpl implements Cost, VariableCost {
         this.amountPaid = cost.amountPaid;
     }
 
+    @Override
+    public void setText(String text) {
+        this.text = text;
+    }
+
     @Override
     public String getText() {
         return text;
diff --git a/Mage/src/mage/abilities/costs/common/DiscardTargetCost.java b/Mage/src/mage/abilities/costs/common/DiscardTargetCost.java
index 69fb9b6229..3cb460452a 100644
--- a/Mage/src/mage/abilities/costs/common/DiscardTargetCost.java
+++ b/Mage/src/mage/abilities/costs/common/DiscardTargetCost.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,21 +20,20 @@
  *  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.ArrayList;
 import java.util.List;
 import java.util.UUID;
-import mage.constants.Outcome;
 import mage.abilities.Ability;
 import mage.abilities.costs.CostImpl;
 import mage.cards.Card;
+import mage.constants.Outcome;
 import mage.game.Game;
 import mage.players.Player;
 import mage.target.common.TargetCardInHand;
@@ -44,23 +43,23 @@ import mage.target.common.TargetCardInHand;
  * @author BetaSteward_at_googlemail.com
  */
 public class DiscardTargetCost extends CostImpl {
-    
+
     List<Card> cards = new ArrayList<>();
     protected boolean randomDiscard;
 
     public DiscardTargetCost(TargetCardInHand target) {
         this(target, false);
     }
-    
+
     public DiscardTargetCost(TargetCardInHand target, boolean randomDiscard) {
         this.addTarget(target);
         this.randomDiscard = randomDiscard;
-        this.text = "Discard " + target.getTargetName();
+        this.text = "discard " + target.getTargetName();
     }
 
     public DiscardTargetCost(DiscardTargetCost cost) {
         super(cost);
-        for (Card card: cost.cards) {
+        for (Card card : cost.cards) {
             this.cards.add(card.copy());
         }
         this.randomDiscard = cost.randomDiscard;
@@ -74,11 +73,11 @@ public class DiscardTargetCost extends CostImpl {
             return false;
         }
         int amount = this.getTargets().get(0).getNumberOfTargets();
-        if (randomDiscard) {            
+        if (randomDiscard) {
             this.cards.addAll(player.discard(amount, true, ability, game).getCards(game));
         } else {
-            if (targets.choose(Outcome.Discard, controllerId, sourceId, game)) {            
-                for (UUID targetId: targets.get(0).getTargets()) {
+            if (targets.choose(Outcome.Discard, controllerId, sourceId, game)) {
+                for (UUID targetId : targets.get(0).getTargets()) {
                     Card card = player.getHand().get(targetId, game);
                     if (card == null) {
                         return false;
@@ -94,7 +93,7 @@ public class DiscardTargetCost extends CostImpl {
 
     @Override
     public void clearPaid() {
-        super.clearPaid(); 
+        super.clearPaid();
         cards.clear();
     }
 
diff --git a/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java
index 5c6cb083be..ac056ba437 100644
--- a/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java
+++ b/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java
@@ -51,6 +51,7 @@ import mage.util.ManaUtil;
 public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements ManaCosts<T> {
 
     protected UUID id;
+    protected String text = null;
 
     private static Map<String, ManaCosts> costs = new HashMap<>();
 
@@ -372,8 +373,16 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
         return this.id;
     }
 
+    @Override
+    public void setText(String text) {
+        this.text = text;
+    }
+
     @Override
     public String getText() {
+        if (text != null) {
+            return text;
+        }
         if (this.size() == 0) {
             return "";
         }
diff --git a/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java b/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java
index 6443cc2efb..7d7556fc7c 100644
--- a/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,12 +20,11 @@
  *  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.abilities.Ability;
@@ -51,6 +50,7 @@ public class DrawCardTargetEffect extends OneShotEffect {
     public DrawCardTargetEffect(int amount) {
         this(new StaticValue(amount));
     }
+
     public DrawCardTargetEffect(int amount, boolean optional) {
         this(new StaticValue(amount), optional);
     }
@@ -117,7 +117,7 @@ public class DrawCardTargetEffect extends OneShotEffect {
         if (upTo) {
             sb.append("up to ");
         }
-        sb.append(CardUtil.numberToText(amount.toString())).append(" card");
+        sb.append(CardUtil.numberToText(amount.toString(), "a")).append(" card");
         try {
             if (Integer.parseInt(amount.toString()) > 1) {
                 sb.append("s");
@@ -133,5 +133,4 @@ public class DrawCardTargetEffect extends OneShotEffect {
         return sb.toString();
     }
 
-
 }
diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java
index dcdbe3ef9f..c8fc6e2e6c 100644
--- a/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java
@@ -44,14 +44,14 @@ import mage.target.targetpointer.FixedTarget;
  *
  * @author LevelX2
  */
-
 public class BecomesColorOrColorsTargetEffect extends OneShotEffect {
 
     Duration duration;
+
     /**
      * This effect let the controller choose one or more colors the target will
-     * become to.
-     * Use effect.setText() if case you use a targetPointer, otherwise the rule text will be empty.
+     * become to. Use effect.setText() if case you use a targetPointer,
+     * otherwise the rule text will be empty.
      *
      * @param duration
      */
@@ -81,8 +81,9 @@ public class BecomesColorOrColorsTargetEffect extends OneShotEffect {
                 if (!controller.canRespond()) {
                     return false;
                 }
-                if (!game.isSimulation())
+                if (!game.isSimulation()) {
                     game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + choiceColor.getChoice());
+                }
                 if (choiceColor.getColor().isBlack()) {
                     sb.append("B");
                 } else if (choiceColor.getColor().isBlue()) {
@@ -119,7 +120,7 @@ public class BecomesColorOrColorsTargetEffect extends OneShotEffect {
         StringBuilder sb = new StringBuilder();
         if (mode.getTargets().size() > 0) {
             sb.append("target ");
-            sb.append(mode.getTargets().get(0).getMessage());
+            sb.append(mode.getTargets().get(0).getFilter().getMessage());
             sb.append(" becomes the color or colors of your choice");
             if (duration.toString().length() > 0) {
                 sb.append(" ").append(duration.toString());
diff --git a/Mage/src/mage/abilities/keyword/BuybackAbility.java b/Mage/src/mage/abilities/keyword/BuybackAbility.java
index 05059e4e53..f35c32c874 100644
--- a/Mage/src/mage/abilities/keyword/BuybackAbility.java
+++ b/Mage/src/mage/abilities/keyword/BuybackAbility.java
@@ -63,8 +63,8 @@ import mage.players.Player;
 public class BuybackAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
 
     private static final String keywordText = "Buyback";
-    private static final String reminderTextCost = "<i>(You may {cost} in addition to any other costs as you cast this spell. If you do, put this card into your hand as it resolves.)</i>";
-    private static final String reminderTextMana = "<i>(You may pay an additional {cost} as you cast this spell. If you do, put this card into your hand as it resolves.)</i>";
+    private static final String reminderTextCost = "You may {cost} in addition to any other costs as you cast this spell. If you do, put this card into your hand as it resolves.";
+    private static final String reminderTextMana = "You may pay an additional {cost} as you cast this spell. If you do, put this card into your hand as it resolves.";
     protected OptionalAdditionalCost buybackCost;
 
     public BuybackAbility(String manaString) {
diff --git a/Mage/src/mage/abilities/keyword/ConspireAbility.java b/Mage/src/mage/abilities/keyword/ConspireAbility.java
index 7d48fe50e0..674505173b 100644
--- a/Mage/src/mage/abilities/keyword/ConspireAbility.java
+++ b/Mage/src/mage/abilities/keyword/ConspireAbility.java
@@ -113,8 +113,9 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
                 reminderText = "As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it  and you may choose a new targets for the copy.)";
                 break;
         }
-        conspireCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText,
-                new TapTargetCost(new TargetControlledPermanent(2, 2, filter, true)));
+        Cost cost = new TapTargetCost(new TargetControlledPermanent(2, 2, filter, true));
+        cost.setText("");
+        conspireCost = new OptionalAdditionalCostImpl(keywordText, " ", reminderText, cost);
         addSubAbility(new ConspireTriggeredAbility(conspireId));
     }
 
diff --git a/Mage/src/mage/abilities/keyword/EntwineAbility.java b/Mage/src/mage/abilities/keyword/EntwineAbility.java
index 8448463486..c81d1cbd95 100644
--- a/Mage/src/mage/abilities/keyword/EntwineAbility.java
+++ b/Mage/src/mage/abilities/keyword/EntwineAbility.java
@@ -59,7 +59,7 @@ import mage.players.Player;
 public class EntwineAbility extends StaticAbility implements OptionalAdditionalModeSourceCosts {
 
     private static final String keywordText = "Entwine";
-    private static final String reminderText = "<i> (Choose both if you pay the entwine cost.)</i>";
+    private static final String reminderText = "Choose both if you pay the entwine cost.";
     protected OptionalAdditionalCost additionalCost;
 
     public EntwineAbility(String manaString) {
diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java
index d28edb5307..f7bc6c8ff8 100644
--- a/Mage/src/mage/abilities/keyword/KickerAbility.java
+++ b/Mage/src/mage/abilities/keyword/KickerAbility.java
@@ -85,8 +85,8 @@ import mage.players.Player;
 public class KickerAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
 
     protected static final String KICKER_KEYWORD = "Kicker";
-    protected static final String KICKER_REMINDER_MANA = "(You may pay an additional {cost} as you cast this spell.)";
-    protected static final String KICKER_REMINDER_COST = "(You may {cost} in addition to any other costs as you cast this spell.)";
+    protected static final String KICKER_REMINDER_MANA = "You may pay an additional {cost} as you cast this spell.";
+    protected static final String KICKER_REMINDER_COST = "You may {cost} in addition to any other costs as you cast this spell.";
 
     protected Map<String, Integer> activations = new HashMap<>(); // zoneChangeCounter, activations
 
diff --git a/Mage/src/mage/abilities/keyword/ReplicateAbility.java b/Mage/src/mage/abilities/keyword/ReplicateAbility.java
index 8be57a3997..ed5c34e1a2 100644
--- a/Mage/src/mage/abilities/keyword/ReplicateAbility.java
+++ b/Mage/src/mage/abilities/keyword/ReplicateAbility.java
@@ -56,7 +56,7 @@ import mage.players.Player;
 public class ReplicateAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
 
     private static final String keywordText = "Replicate";
-    private static final String reminderTextMana = "<i>(When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)</i>";
+    private static final String reminderTextMana = "When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.";
     protected OptionalAdditionalCost additionalCost;
 
     public ReplicateAbility(Card card, String manaString) {
diff --git a/Mage/src/mage/abilities/keyword/RetraceAbility.java b/Mage/src/mage/abilities/keyword/RetraceAbility.java
index 2ce121fc25..21e6b84d9e 100644
--- a/Mage/src/mage/abilities/keyword/RetraceAbility.java
+++ b/Mage/src/mage/abilities/keyword/RetraceAbility.java
@@ -28,6 +28,7 @@
 package mage.abilities.keyword;
 
 import mage.abilities.SpellAbility;
+import mage.abilities.costs.Cost;
 import mage.abilities.costs.common.DiscardTargetCost;
 import mage.cards.Card;
 import mage.constants.SpellAbilityType;
@@ -44,7 +45,9 @@ public class RetraceAbility extends SpellAbility {
     public RetraceAbility(Card card) {
         super(card.getManaCost(), card.getName() + " with retrace", Zone.GRAVEYARD, SpellAbilityType.BASE_ALTERNATE);
         this.getCosts().addAll(card.getSpellAbility().getCosts().copy());
-        this.addCost(new DiscardTargetCost(new TargetCardInHand(new FilterLandCard())));
+        Cost cost = new DiscardTargetCost(new TargetCardInHand(new FilterLandCard()));
+        cost.setText("");
+        this.addCost(cost);
         this.getEffects().addAll(card.getSpellAbility().getEffects().copy());
         this.getTargets().addAll(card.getSpellAbility().getTargets().copy());
         this.getChoices().addAll(card.getSpellAbility().getChoices().copy());

From 981a27ccbf19acbbc84fc20de1a1503703688537 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 18:13:14 +0200
Subject: [PATCH 09/13] * Fate transfer - Fixed that +1/+1 or -1/-1 counters on
 target permanent were not applied.

---
 .../mage/sets/shadowmoor/FateTransfer.java    |  6 +--
 .../oneshot/counter/MovingCounterTest.java    | 51 +++++++++++++++----
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/shadowmoor/FateTransfer.java b/Mage.Sets/src/mage/sets/shadowmoor/FateTransfer.java
index dcfe9b5a38..811237a3b4 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/FateTransfer.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/FateTransfer.java
@@ -53,7 +53,6 @@ public class FateTransfer extends CardImpl {
         super(ownerId, 161, "Fate Transfer", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U/B}");
         this.expansionSetCode = "SHM";
 
-
         // Move all counters from target creature onto another target creature.
         this.getSpellAbility().addEffect(new FateTransferEffect());
         this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
@@ -96,9 +95,8 @@ class FateTransferEffect extends OneShotEffect {
                 && creatureToMoveCountersTo != null) {
             Permanent copyCreature = creatureToMoveCountersFrom.copy();
             for (Counter counter : copyCreature.getCounters().values()) {
-                Counter newCounterTest = new Counter(counter.getName(), counter.getCount());
-                creatureToMoveCountersFrom.removeCounters(newCounterTest, game);
-                creatureToMoveCountersTo.addCounters(newCounterTest, game);
+                creatureToMoveCountersFrom.removeCounters(counter, game);
+                creatureToMoveCountersTo.addCounters(counter, game);
             }
             return true;
         }
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/counter/MovingCounterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/counter/MovingCounterTest.java
index 8e687a50e9..a1ef2b75ec 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/counter/MovingCounterTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/counter/MovingCounterTest.java
@@ -36,7 +36,6 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
  *
  * @author LevelX2
  */
-
 public class MovingCounterTest extends CardTestPlayerBase {
 
     /**
@@ -51,12 +50,11 @@ public class MovingCounterTest extends CardTestPlayerBase {
 
         // Move any number of +1/+1 counters from target creature onto another target creature with the same controller.
         addCard(Zone.HAND, playerA, "Bioshift", 1);
-        
-        // Protean Hydra enters the battlefield with X +1/+1 counters on it.        
-        // If damage would be dealt to Protean Hydra, prevent that damage and remove that many +1/+1 counters from it.
-        // Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.        
-        addCard(Zone.HAND, playerA, "Protean Hydra", 1);
 
+        // Protean Hydra enters the battlefield with X +1/+1 counters on it.
+        // If damage would be dealt to Protean Hydra, prevent that damage and remove that many +1/+1 counters from it.
+        // Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.
+        addCard(Zone.HAND, playerA, "Protean Hydra", 1);
 
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Protean Hydra");
         setChoice(playerA, "X=4");
@@ -67,14 +65,45 @@ public class MovingCounterTest extends CardTestPlayerBase {
         execute();
 
         assertGraveyardCount(playerA, "Bioshift", 1);
-        
-        assertPermanentCount(playerA, "Silvercoat Lion", 1);        
+
+        assertPermanentCount(playerA, "Silvercoat Lion", 1);
         assertPowerToughness(playerA, "Silvercoat Lion", 4, 4); // added 2 counters
 
-        assertPermanentCount(playerA, "Protean Hydra", 1);        
+        assertPermanentCount(playerA, "Protean Hydra", 1);
         assertPowerToughness(playerA, "Protean Hydra", 6, 6); // started with 4, removed 2, added 4 at end = 6
-        
 
     }
 
-}
\ No newline at end of file
+    /**
+     * I'm having an issue when using Bioshift to move only a portion of
+     * counters to another creature. When I attempt to do this, it moves all of
+     * the counters (and in some cases with my Simic deck) kills the creature.
+     */
+    @Test
+    public void testFateTransfer() {
+        addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
+        // Noxious Hatchling enters the battlefield with four -1/-1 counters on it.
+        // Wither (This deals damage to creatures in the form of -1/-1 counters.)
+        // Whenever you cast a black spell, remove a -1/-1 counter from Noxious Hatchling.
+        // Whenever you cast a green spell, remove a -1/-1 counter from Noxious Hatchling.
+        addCard(Zone.HAND, playerA, "Noxious Hatchling", 1);// 6/6
+        addCard(Zone.BATTLEFIELD, playerA, "Ruin Processor", 1); // Creature 7/8
+
+        addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+        // Move all counters from target creature onto another target creature.
+        addCard(Zone.HAND, playerB, "Fate Transfer", 1);
+
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Noxious Hatchling");
+        castSpell(1, PhaseStep.BEGIN_COMBAT, playerB, "Fate Transfer", "Noxious Hatchling^Ruin Processor");
+
+        setStopAt(1, PhaseStep.END_COMBAT);
+        execute();
+
+        assertGraveyardCount(playerB, "Fate Transfer", 1);
+
+        assertPowerToughness(playerA, "Noxious Hatchling", 6, 6);
+
+        assertPowerToughness(playerA, "Ruin Processor", 3, 4);
+
+    }
+}

From ef3e4321883f984a98e2aeac649bc6c7faf0e745 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 18:32:37 +0200
Subject: [PATCH 10/13] * Domineering Will - Fixed not correctly working
 effects.

---
 .../sets/commander2014/DomineeringWill.java   | 129 ++----------------
 Mage/src/mage/game/combat/Combat.java         |   2 +-
 2 files changed, 15 insertions(+), 116 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/commander2014/DomineeringWill.java b/Mage.Sets/src/mage/sets/commander2014/DomineeringWill.java
index df27ae5176..31497d4ee8 100644
--- a/Mage.Sets/src/mage/sets/commander2014/DomineeringWill.java
+++ b/Mage.Sets/src/mage/sets/commander2014/DomineeringWill.java
@@ -30,25 +30,25 @@ package mage.sets.commander2014;
 import java.util.UUID;
 import mage.abilities.Ability;
 import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.ContinuousEffectImpl;
 import mage.abilities.effects.Effect;
 import mage.abilities.effects.OneShotEffect;
 import mage.abilities.effects.RequirementEffect;
+import mage.abilities.effects.common.UntapTargetEffect;
+import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
 import mage.cards.CardImpl;
 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.filter.common.FilterCreaturePermanent;
 import mage.filter.predicate.Predicates;
 import mage.filter.predicate.permanent.AttackingPredicate;
 import mage.game.Game;
-import mage.game.permanent.Permanent;
 import mage.players.Player;
 import mage.target.TargetPlayer;
 import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetpointer.SecondTargetPointer;
 
 /**
  *
@@ -66,7 +66,6 @@ public class DomineeringWill extends CardImpl {
         super(ownerId, 13, "Domineering Will", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{U}");
         this.expansionSetCode = "C14";
 
-
         // Target player gains control of up to three target nonattacking creatures until end of turn. Untap those creatures. They block this turn if able.
         this.getSpellAbility().addEffect(new DomineeringWillEffect());
         this.getSpellAbility().addTarget(new TargetPlayer());
@@ -102,14 +101,20 @@ class DomineeringWillEffect extends OneShotEffect {
 
     @Override
     public boolean apply(Game game, Ability source) {
-        Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
+        Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
         if (targetPlayer != null) {
-            ContinuousEffect effect = new DomineeringWillControlEffect();
+            ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, targetPlayer.getId());
+            effect.setTargetPointer(new SecondTargetPointer());
+            effect.setText("Target player gains control of up to three target nonattacking creatures until end of turn");
             game.addEffect(effect, source);
-            Effect effect2 = new DomineeringWillUntapTargetEffect();
+
+            Effect effect2 = new UntapTargetEffect();
+            effect2.setTargetPointer(new SecondTargetPointer());
             effect2.setText("Untap those creatures");
             effect2.apply(game, source);
-            RequirementEffect effect3 = new DomineeringWillBlocksIfAbleTargetEffect(Duration.EndOfTurn);
+
+            RequirementEffect effect3 = new BlocksIfAbleTargetEffect(Duration.EndOfTurn);
+            effect3.setTargetPointer(new SecondTargetPointer());
             effect3.setText("They block this turn if able");
             game.addEffect(effect3, source);
             return true;
@@ -117,109 +122,3 @@ class DomineeringWillEffect extends OneShotEffect {
         return false;
     }
 }
-
-class DomineeringWillControlEffect extends ContinuousEffectImpl {
-
-    public DomineeringWillControlEffect() {
-        super(Duration.EndOfTurn, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
-    }
-
-    public DomineeringWillControlEffect(final DomineeringWillControlEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public DomineeringWillControlEffect copy() {
-        return new DomineeringWillControlEffect(this);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
-        if (targetPlayer != null) {
-            boolean targetStillExists = false;
-            for (UUID permanentId : source.getTargets().get(1).getTargets()) {
-                Permanent permanent = game.getPermanent(permanentId);
-                if (permanent != null) {
-                    targetStillExists = true;
-                    if (targetPlayer != null) {
-                        permanent.changeControllerId(targetPlayer.getId(), game);
-                        permanent.getAbilities().setControllerId(targetPlayer.getId());
-                    } else {
-                        permanent.changeControllerId(source.getControllerId(), game);
-                        permanent.getAbilities().setControllerId(source.getControllerId());
-                    }
-                }
-            }
-            if (!targetStillExists) {
-                // no valid target exists, effect can be discarded
-                discard();
-            }
-            return true;
-        }
-        return false;
-    }
-}
-
-class DomineeringWillUntapTargetEffect extends OneShotEffect {
-
-    public DomineeringWillUntapTargetEffect() {
-        super(Outcome.Untap);
-    }
-
-    public DomineeringWillUntapTargetEffect(final DomineeringWillUntapTargetEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public DomineeringWillUntapTargetEffect copy() {
-        return new DomineeringWillUntapTargetEffect(this);
-    }
-
-    @Override
-    public boolean apply(Game game, Ability source) {
-        for (UUID target : source.getTargets().get(1).getTargets()) {
-            Permanent permanent = game.getPermanent(target);
-            if (permanent != null) {
-                permanent.untap(game);
-            }
-        }
-        return true;
-    }
-}
-
-class DomineeringWillBlocksIfAbleTargetEffect extends RequirementEffect {
-
-    public DomineeringWillBlocksIfAbleTargetEffect(Duration duration) {
-        super(duration);
-    }
-
-    public DomineeringWillBlocksIfAbleTargetEffect(final DomineeringWillBlocksIfAbleTargetEffect effect) {
-        super(effect);
-    }
-
-    @Override
-    public DomineeringWillBlocksIfAbleTargetEffect copy() {
-        return new DomineeringWillBlocksIfAbleTargetEffect(this);
-    }
-
-    @Override
-    public boolean applies(Permanent permanent, Ability source, Game game) {
-        return source.getTargets().get(1).getTargets().contains(permanent.getId());
-    }
-
-    @Override
-    public boolean mustAttack(Game game) {
-        return false;
-    }
-
-    @Override
-    public boolean mustBlock(Game game) {
-        return false;
-    }
-
-    @Override
-    public boolean mustBlockAny(Game game) {
-        return true;
-    }
-}
diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java
index 1aa89433f7..b03625617c 100644
--- a/Mage/src/mage/game/combat/Combat.java
+++ b/Mage/src/mage/game/combat/Combat.java
@@ -663,7 +663,7 @@ public class Combat implements Serializable, Copyable<Combat> {
                             if (mayBlock) {
                                 if (controller.isHuman()) {
                                     if (!game.isSimulation()) {
-                                        game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName());
+                                        game.informPlayer(controller, "Creature should block this turn: " + creature.getIdName());
                                     }
                                 } else {
                                     Player defender = game.getPlayer(creature.getControllerId());

From 01a14a26653b3df0d450273f33f2d403e56fe957 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 19:20:12 +0200
Subject: [PATCH 11/13] * Fixed function and handling of the Ice Age depletion
 counter lands.

---
 .../mage/sets/fifthdawn/GoblinBrawler.java    | 20 ++---
 Mage.Sets/src/mage/sets/iceage/LandCap.java   |  9 +-
 Mage.Sets/src/mage/sets/iceage/LavaTubes.java |  6 +-
 .../src/mage/sets/iceage/RiverDelta.java      |  7 +-
 .../src/mage/sets/iceage/TimberlineRidge.java |  6 +-
 Mage.Sets/src/mage/sets/iceage/Veldt.java     |  6 +-
 ...ditionalContinuousRuleModifyingEffect.java | 19 +++-
 .../ContinuousRuleModifyingEffectImpl.java    | 90 +++++++++----------
 ...tapInControllersUntapStepSourceEffect.java | 11 ++-
 9 files changed, 95 insertions(+), 79 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/fifthdawn/GoblinBrawler.java b/Mage.Sets/src/mage/sets/fifthdawn/GoblinBrawler.java
index 13b1344e3d..5851db6705 100644
--- a/Mage.Sets/src/mage/sets/fifthdawn/GoblinBrawler.java
+++ b/Mage.Sets/src/mage/sets/fifthdawn/GoblinBrawler.java
@@ -31,9 +31,7 @@ import java.util.UUID;
 import mage.MageInt;
 import mage.abilities.Ability;
 import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.ContinuousEffect;
 import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
-import mage.abilities.effects.ReplacementEffectImpl;
 import mage.abilities.keyword.FirstStrikeAbility;
 import mage.cards.CardImpl;
 import mage.constants.CardType;
@@ -83,12 +81,12 @@ class CantBeEquippedSourceEffect extends ContinuousRuleModifyingEffectImpl {
     }
 
     public CantBeEquippedSourceEffect() {
-       super(Duration.WhileOnBattlefield, Outcome.Neutral);
-       staticText = "{this} can't be equipped";
+        super(Duration.WhileOnBattlefield, Outcome.Neutral);
+        staticText = "{this} can't be equipped";
     }
-  
+
     @Override
-    public ContinuousEffect copy() {
+    public CantBeEquippedSourceEffect copy() {
         return new CantBeEquippedSourceEffect(this);
     }
 
@@ -96,14 +94,14 @@ class CantBeEquippedSourceEffect extends ContinuousRuleModifyingEffectImpl {
     public boolean checksEventType(GameEvent event, Game game) {
         return event.getType() == GameEvent.EventType.ATTACH;
     }
-    
+
     @Override
     public boolean applies(GameEvent event, Ability source, Game game) {
         if (event.getTargetId().equals(source.getSourceId())) {
-           Permanent permanent = game.getPermanent(event.getSourceId());
-           if(permanent != null && permanent.getSubtype().contains("Equipment")){
-            return true;
-           }
+            Permanent permanent = game.getPermanent(event.getSourceId());
+            if (permanent != null && permanent.getSubtype().contains("Equipment")) {
+                return true;
+            }
         }
         return false;
     }
diff --git a/Mage.Sets/src/mage/sets/iceage/LandCap.java b/Mage.Sets/src/mage/sets/iceage/LandCap.java
index c430a5be24..9049711a15 100644
--- a/Mage.Sets/src/mage/sets/iceage/LandCap.java
+++ b/Mage.Sets/src/mage/sets/iceage/LandCap.java
@@ -34,7 +34,6 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
 import mage.abilities.common.SimpleStaticAbility;
 import mage.abilities.condition.common.SourceHasCounterCondition;
 import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.decorator.ConditionalContinuousEffect;
 import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
 import mage.abilities.effects.Effect;
 import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
@@ -50,7 +49,7 @@ import mage.counters.CounterType;
 
 /**
  *
- * @author anonymous
+ * @author Luna Skyrise
  */
 public class LandCap extends CardImpl {
 
@@ -59,15 +58,15 @@ public class LandCap extends CardImpl {
         this.expansionSetCode = "ICE";
 
         // Land Cap doesn't untap during your untap step if it has a depletion counter on it.
-        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(),
-                new SourceHasCounterCondition(CounterType.DEPLETION, 0));
+        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(false, true),
+                new SourceHasCounterCondition(CounterType.DEPLETION, 1, Integer.MAX_VALUE));
         effect.setText("{this} doesn't untap during your untap step if it has a depletion counter on it");
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
         this.addAbility(ability);
         // At the beginning of your upkeep, remove a depletion counter from Land Cap.
         Ability ability2 = new BeginningOfUpkeepTriggeredAbility(new RemoveCounterSourceEffect(CounterType.DEPLETION.createInstance()), TargetController.YOU, false);
         this.addAbility(ability2);
-        // {tap}: Add {W} or {U} to your mana pool. Put a depletion counter on Land Cap.
+        // {T}: Add {W} or {U} to your mana pool. Put a depletion counter on Land Cap.
         Ability ability3 = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.WhiteMana, new TapSourceCost());
         ability3.addEffect(new AddCountersSourceEffect(CounterType.DEPLETION.createInstance()));
         this.addAbility(ability3);
diff --git a/Mage.Sets/src/mage/sets/iceage/LavaTubes.java b/Mage.Sets/src/mage/sets/iceage/LavaTubes.java
index 26cd59dc92..ba64530064 100644
--- a/Mage.Sets/src/mage/sets/iceage/LavaTubes.java
+++ b/Mage.Sets/src/mage/sets/iceage/LavaTubes.java
@@ -49,7 +49,7 @@ import mage.counters.CounterType;
 
 /**
  *
- * @author anonymous
+ * @author Luna Skyrise
  */
 public class LavaTubes extends CardImpl {
 
@@ -58,8 +58,8 @@ public class LavaTubes extends CardImpl {
         this.expansionSetCode = "ICE";
 
         // Lava Tubes doesn't untap during your untap step if it has a depletion counter on it.
-        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(),
-                new SourceHasCounterCondition(CounterType.DEPLETION, 0));
+        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(false, true),
+                new SourceHasCounterCondition(CounterType.DEPLETION, 1, Integer.MAX_VALUE));
         effect.setText("{this} doesn't untap during your untap step if it has a depletion counter on it");
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
         this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/iceage/RiverDelta.java b/Mage.Sets/src/mage/sets/iceage/RiverDelta.java
index b5f91fff06..008c5d3f15 100644
--- a/Mage.Sets/src/mage/sets/iceage/RiverDelta.java
+++ b/Mage.Sets/src/mage/sets/iceage/RiverDelta.java
@@ -34,7 +34,6 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
 import mage.abilities.common.SimpleStaticAbility;
 import mage.abilities.condition.common.SourceHasCounterCondition;
 import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.decorator.ConditionalContinuousEffect;
 import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
 import mage.abilities.effects.Effect;
 import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
@@ -50,7 +49,7 @@ import mage.counters.CounterType;
 
 /**
  *
- * @author anonymous
+ * @author Luna Skyrise
  */
 public class RiverDelta extends CardImpl {
 
@@ -59,8 +58,8 @@ public class RiverDelta extends CardImpl {
         this.expansionSetCode = "ICE";
 
         // River Delta doesn't untap during your untap step if it has a depletion counter on it.
-        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(),
-                new SourceHasCounterCondition(CounterType.DEPLETION, 0));
+        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(false, true),
+                new SourceHasCounterCondition(CounterType.DEPLETION, 1, Integer.MAX_VALUE));
         effect.setText("{this} doesn't untap during your untap step if it has a depletion counter on it");
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
         this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/iceage/TimberlineRidge.java b/Mage.Sets/src/mage/sets/iceage/TimberlineRidge.java
index 56a826a8e0..e10a000945 100644
--- a/Mage.Sets/src/mage/sets/iceage/TimberlineRidge.java
+++ b/Mage.Sets/src/mage/sets/iceage/TimberlineRidge.java
@@ -49,7 +49,7 @@ import mage.counters.CounterType;
 
 /**
  *
- * @author anonymous
+ * @author Luna Skyrise
  */
 public class TimberlineRidge extends CardImpl {
 
@@ -58,8 +58,8 @@ public class TimberlineRidge extends CardImpl {
         this.expansionSetCode = "ICE";
 
         // Timberline Ridge doesn't untap during your untap step if it has a depletion counter on it.
-        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(),
-                new SourceHasCounterCondition(CounterType.DEPLETION, 0));
+        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(false, true),
+                new SourceHasCounterCondition(CounterType.DEPLETION, 1, Integer.MAX_VALUE));
         effect.setText("{this} doesn't untap during your untap step if it has a depletion counter on it");
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
         this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/iceage/Veldt.java b/Mage.Sets/src/mage/sets/iceage/Veldt.java
index 437370080e..29f1e423aa 100644
--- a/Mage.Sets/src/mage/sets/iceage/Veldt.java
+++ b/Mage.Sets/src/mage/sets/iceage/Veldt.java
@@ -49,7 +49,7 @@ import mage.counters.CounterType;
 
 /**
  *
- * @author anonymous
+ * @author Luna Skyrise
  */
 public class Veldt extends CardImpl {
 
@@ -58,8 +58,8 @@ public class Veldt extends CardImpl {
         this.expansionSetCode = "ICE";
 
         // Veldt doesn't untap during your untap step if it has a depletion counter on it.
-        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(),
-                new SourceHasCounterCondition(CounterType.DEPLETION, 0));
+        Effect effect = new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepSourceEffect(false, true),
+                new SourceHasCounterCondition(CounterType.DEPLETION, 1, Integer.MAX_VALUE));
         effect.setText("{this} doesn't untap during your untap step if it has a depletion counter on it");
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
         this.addAbility(ability);
diff --git a/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java b/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java
index 8028e72706..c289550a5f 100644
--- a/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java
+++ b/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java
@@ -41,7 +41,7 @@ import mage.game.events.GameEvent;
  *
  * @author LevelX2
  */
-public class ConditionalContinuousRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl  {
+public class ConditionalContinuousRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl {
 
     protected ContinuousRuleModifyingEffect effect;
     protected ContinuousRuleModifyingEffect otherwiseEffect;
@@ -88,7 +88,6 @@ public class ConditionalContinuousRuleModifyingEffect extends ContinuousRuleModi
         initDone = true;
     }
 
-
     @Override
     public boolean isDiscarded() {
         return effect.isDiscarded() || (otherwiseEffect != null && otherwiseEffect.isDiscarded());
@@ -136,4 +135,20 @@ public class ConditionalContinuousRuleModifyingEffect extends ContinuousRuleModi
     public ConditionalContinuousRuleModifyingEffect copy() {
         return new ConditionalContinuousRuleModifyingEffect(this);
     }
+
+    @Override
+    public boolean sendMessageToGameLog() {
+        return effect.sendMessageToGameLog(); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public boolean sendMessageToUser() {
+        return effect.sendMessageToUser(); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public String getInfoMessage(Ability source, GameEvent event, Game game) {
+        return effect.getInfoMessage(source, event, game); //To change body of generated methods, choose Tools | Templates.
+    }
+
 }
diff --git a/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java
index 5dcf58d5e9..541873718f 100644
--- a/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java
+++ b/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java
@@ -1,31 +1,30 @@
 /*
-* 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.
-*/
-
+ * 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.abilities.effects;
 
 import mage.MageObject;
@@ -45,20 +44,18 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect
     protected final boolean messageToUser;
     protected final boolean messageToGameLog;
     protected final String infoMessage;
-    
+
     // 613.10
-    // Some continuous effects affect game rules rather than objects. For example, effects may modify 
+    // Some continuous effects affect game rules rather than objects. For example, effects may modify
     // a player’s maximum hand size, or say that a creature must attack this turn if able. These effects
     // are applied after all other continuous effects have been applied. Continuous effects that affect
-    // the costs of spells or abilities are applied according to the order specified in rule 601.2e. 
-    // All other such effects are applied in timestamp order. See also the rules for timestamp order 
+    // the costs of spells or abilities are applied according to the order specified in rule 601.2e.
+    // All other such effects are applied in timestamp order. See also the rules for timestamp order
     // and dependency (rules 613.6 and 613.7).
-    
     // Some of this rule modifying effects are implemented as normal CONTINUOUS effects using the Layer.RulesEffects.
     // But if the rule change can be implemented simply by preventing an event from happening, CONTINUOUS_RULE_MODIFICATION effects can be used.
-    // They work technical like a replacement effect that replaces the event completely. 
+    // They work technical like a replacement effect that replaces the event completely.
     // But player isn't asked to choose order of effects if multiple are applied to the same event.
-
     public ContinuousRuleModifyingEffectImpl(Duration duration, Outcome outcome) {
         this(duration, outcome, true, false);
     }
@@ -67,11 +64,13 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect
      *
      * @param duration
      * @param outcome
-     * @param messageToUser - Every time the effect replaces an event, the user gets a message in a dialog window.
-     *                        Don't set it to true if the event happens regularly or very often. The message itself can be
-     *                        changed by overriding the getInfoMessage method.
-     * @param messageToLog  - Every time the effect replaces an event, a message is posted to the game log. The message
-     *                        can be changed by overriding the getInfoMessage method.
+     * @param messageToUser - Every time the effect replaces an event, the user
+     * gets a message in a dialog window. Don't set it to true if the event
+     * happens regularly or very often. The message itself can be changed by
+     * overriding the getInfoMessage method.
+     * @param messageToLog - Every time the effect replaces an event, a message
+     * is posted to the game log. The message can be changed by overriding the
+     * getInfoMessage method.
      */
     public ContinuousRuleModifyingEffectImpl(Duration duration, Outcome outcome, boolean messageToUser, boolean messageToLog) {
         super(duration, outcome);
@@ -89,9 +88,11 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect
     }
 
     /**
-     * An early check for the event types this effect applies to. This check was added
-     * to speed up event handling. Once all existing ContinuousRuleModifiyingEffects have
-     * implemented this method, the method should be changed to abstract here or removed.
+     * An early check for the event types this effect applies to. This check was
+     * added to speed up event handling. Once all existing
+     * ContinuousRuleModifiyingEffects have implemented this method, the method
+     * should be changed to abstract here or removed.
+     *
      * @param event
      * @param game
      * @return
@@ -112,10 +113,10 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect
             String message;
             MageObject object = game.getObject(source.getSourceId());
             if (object != null) {
-                message = source.getRule(object.getLogName());
+                message = source.getRule(messageToUser ? object.getIdName() : object.getLogName());
             } else {
                 message = source.getRule();
-            }            
+            }
             return message;
         } else {
             return infoMessage;
@@ -132,5 +133,4 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect
         return messageToGameLog;
     }
 
-    
 }
diff --git a/Mage/src/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java b/Mage/src/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java
index 576628205d..fd5d40ed8a 100644
--- a/Mage/src/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java
+++ b/Mage/src/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java
@@ -27,11 +27,11 @@
  */
 package mage.abilities.effects.common;
 
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
 import mage.constants.Duration;
 import mage.constants.Outcome;
 import mage.constants.PhaseStep;
-import mage.abilities.Ability;
-import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
 import mage.game.Game;
 import mage.game.events.GameEvent;
 import mage.game.events.GameEvent.EventType;
@@ -44,7 +44,11 @@ import mage.game.permanent.Permanent;
 public class DontUntapInControllersUntapStepSourceEffect extends ContinuousRuleModifyingEffectImpl {
 
     public DontUntapInControllersUntapStepSourceEffect() {
-        super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true);
+        this(false, true);
+    }
+
+    public DontUntapInControllersUntapStepSourceEffect(boolean messageToUser, boolean messageToLog) {
+        super(Duration.WhileOnBattlefield, Outcome.Detriment, messageToUser, messageToLog);
         staticText = "{this} doesn't untap during your untap step";
     }
 
@@ -78,4 +82,5 @@ public class DontUntapInControllersUntapStepSourceEffect extends ContinuousRuleM
         }
         return false;
     }
+
 }

From a54843fd260d7c143bd59cb36f663bfe5092e050 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 23:55:45 +0200
Subject: [PATCH 12/13] * Fixed that players during elemination tournaments
 could get multiple byes in a row.

---
 .../mage/game/tournament/TournamentImpl.java  | 45 ++++++++++++++++---
 .../mage/game/tournament/TournamentSwiss.java | 17 +++----
 2 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java
index e326882b29..a578a68110 100644
--- a/Mage/src/mage/game/tournament/TournamentImpl.java
+++ b/Mage/src/mage/game/tournament/TournamentImpl.java
@@ -32,6 +32,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
@@ -187,15 +188,16 @@ public abstract class TournamentImpl implements Tournament {
         Round round = new Round(rounds.size() + 1, this);
         rounds.add(round);
         List<TournamentPlayer> roundPlayers = getActivePlayers();
+
+        // search the player with a bye last round
+        List<TournamentPlayer> playerWithByes = getTournamentPlayersWithBye(roundPlayers);
+
         while (roundPlayers.size() > 1) {
-            int i = rnd.nextInt(roundPlayers.size());
-            TournamentPlayer player1 = roundPlayers.get(i);
-            roundPlayers.remove(i);
-            i = rnd.nextInt(roundPlayers.size());
-            TournamentPlayer player2 = roundPlayers.get(i);
-            roundPlayers.remove(i);
+            TournamentPlayer player1 = getNextAvailablePlayer(roundPlayers, playerWithByes);
+            TournamentPlayer player2 = getNextAvailablePlayer(roundPlayers, playerWithByes);
             round.addPairing(new TournamentPairing(player1, player2));
         }
+
         if (roundPlayers.size() > 0) {
             // player free round - add to bye players of this round
             TournamentPlayer player1 = roundPlayers.get(0);
@@ -207,6 +209,37 @@ public abstract class TournamentImpl implements Tournament {
         return round;
     }
 
+    private TournamentPlayer getNextAvailablePlayer(List<TournamentPlayer> roundPlayers, List<TournamentPlayer> playerWithByes) {
+        TournamentPlayer nextPlayer;
+        if (playerWithByes.isEmpty()) {
+            int i = rnd.nextInt(roundPlayers.size());
+            nextPlayer = roundPlayers.get(i);
+            roundPlayers.remove(i);
+        } else { // prefer players with byes to pair
+            Iterator<TournamentPlayer> iterator = playerWithByes.iterator();
+            nextPlayer = iterator.next();
+            iterator.remove();
+            roundPlayers.remove(nextPlayer);
+        }
+        return nextPlayer;
+    }
+
+    private List<TournamentPlayer> getTournamentPlayersWithBye(List<TournamentPlayer> roundPlayers) {
+        List<TournamentPlayer> playersWithBye = new ArrayList<>();
+        if (rounds.size() > 1) {
+            for (int i = rounds.size() - 2; i >= 0; i--) {
+                Round oldRound = rounds.get(i);
+                if (oldRound != null && !oldRound.getPlayerByes().isEmpty()) {
+                    TournamentPlayer tournamentPlayerWithBye = oldRound.getPlayerByes().iterator().next();
+                    if (roundPlayers.contains(tournamentPlayerWithBye)) {
+                        playersWithBye.add(tournamentPlayerWithBye);
+                    }
+                }
+            }
+        }
+        return playersWithBye;
+    }
+
     protected void playRound(Round round) {
         for (TournamentPairing pair : round.getPairs()) {
             playMatch(pair);
diff --git a/Mage/src/mage/game/tournament/TournamentSwiss.java b/Mage/src/mage/game/tournament/TournamentSwiss.java
index 9f6c970bd4..6855e57eb0 100644
--- a/Mage/src/mage/game/tournament/TournamentSwiss.java
+++ b/Mage/src/mage/game/tournament/TournamentSwiss.java
@@ -46,8 +46,8 @@ public abstract class TournamentSwiss extends TournamentImpl {
     }
 
     @Override
-    protected void runTournament() {        
-        for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) {
+    protected void runTournament() {
+        for (Map.Entry<UUID, TournamentPlayer> entry : players.entrySet()) {
             if (entry.getValue().getPlayer().autoLoseGame()) {
                 entry.getValue().setEliminated();
                 entry.getValue().setResults("Auto Eliminated");
@@ -57,7 +57,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
         while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
             // check if some player got killed / disconnected meanwhile and update their state
             tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
-            // Swiss pairing 
+            // Swiss pairing
             Round round = createRoundSwiss();
             playRound(round);
         }
@@ -70,8 +70,9 @@ public abstract class TournamentSwiss extends TournamentImpl {
         List<TournamentPlayer> roundPlayers = getActivePlayers();
         // sort players by tournament points
         Collections.sort(roundPlayers, new Comparator<TournamentPlayer>() {
-            @Override public int compare(TournamentPlayer p1, TournamentPlayer p2) {
-                return  p2.getPoints() - p1.getPoints();
+            @Override
+            public int compare(TournamentPlayer p1, TournamentPlayer p2) {
+                return p2.getPoints() - p1.getPoints();
             }
 
         });
@@ -80,9 +81,9 @@ public abstract class TournamentSwiss extends TournamentImpl {
             TournamentPlayer player1 = roundPlayers.get(0);
             roundPlayers.remove(0);
             TournamentPlayer playerForPossibleSecondPairing = null;
-            for (TournamentPlayer player2: roundPlayers) {
+            for (TournamentPlayer player2 : roundPlayers) {
                 if (alreadyPaired(player1, player2)) {
-                    // if laready paired but equal ponts -> remember if second pairing is needed
+                    // if already paired but equal points -> remember if second pairing is needed
                     if (playerForPossibleSecondPairing == null) {
                         playerForPossibleSecondPairing = player2;
                     }
@@ -126,7 +127,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
 
     protected boolean alreadyPaired(TournamentPlayer player1, TournamentPlayer player2) {
         for (Round round : rounds) {
-            for (TournamentPairing pairing: round.getPairs()) {
+            for (TournamentPairing pairing : round.getPairs()) {
                 if (pairing.getPlayer1().equals(player1) || pairing.getPlayer2().equals(player1)) {
                     if (pairing.getPlayer1().equals(player2) || pairing.getPlayer2().equals(player2)) {
                         return true;

From 8dd9fbea40ecf327826a494f0b8f411012155b5d Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Sun, 11 Oct 2015 23:56:29 +0200
Subject: [PATCH 13/13] Conspire - The player is now asked to use conspire only
 if he is able to pay the tap costs.

---
 .../mage/sets/eventide/MerrowBonegnawer.java  | 12 +++++------
 .../test/cards/triggers/OblivionRingTest.java |  4 ++--
 .../abilities/costs/common/TapTargetCost.java |  2 +-
 .../common/ExileFromZoneTargetEffect.java     | 21 ++++++++-----------
 .../abilities/keyword/ConspireAbility.java    |  5 +++--
 5 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/Mage.Sets/src/mage/sets/eventide/MerrowBonegnawer.java b/Mage.Sets/src/mage/sets/eventide/MerrowBonegnawer.java
index f8be8da2f8..2273adfe09 100644
--- a/Mage.Sets/src/mage/sets/eventide/MerrowBonegnawer.java
+++ b/Mage.Sets/src/mage/sets/eventide/MerrowBonegnawer.java
@@ -50,11 +50,11 @@ import mage.target.TargetPlayer;
  * @author jeffwadsworth
  */
 public class MerrowBonegnawer extends CardImpl {
-    
+
     private UUID exileId = UUID.randomUUID();
-    
+
     private static final FilterSpell filter = new FilterSpell("black spell");
-    
+
     static {
         filter.add(new ColorPredicate(ObjectColor.BLACK));
     }
@@ -69,13 +69,13 @@ public class MerrowBonegnawer extends CardImpl {
         this.toughness = new MageInt(1);
 
         // {tap}: Target player exiles a card from his or her graveyard.
-        Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, exileId, "Merrow Bonegnawer", new FilterCard("a card")), new TapSourceCost());
+        Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, exileId, getIdName(), new FilterCard()), new TapSourceCost());
         ability.addTarget(new TargetPlayer());
         this.addAbility(ability);
-        
+
         // Whenever you cast a black spell, you may untap Merrow Bonegnawer.
         this.addAbility(new SpellCastControllerTriggeredAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), filter, true, false));
-        
+
     }
 
     public MerrowBonegnawer(final MerrowBonegnawer card) {
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/OblivionRingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/OblivionRingTest.java
index 1324dee059..ef5dc6ae62 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/OblivionRingTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/OblivionRingTest.java
@@ -92,10 +92,10 @@ public class OblivionRingTest extends CardTestPlayerBase {
         addCard(Zone.BATTLEFIELD, playerA, "Jace Beleren");
         addCard(Zone.HAND, playerA, "Revoke Existence");
 
-        activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-1: Target player draws one card", playerA);
+        activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-1: Target player draws a card", playerA);
         castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring");
         castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Revoke Existence", "Oblivion Ring");
-        activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "-1: Target player draws one card", playerA);
+        activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "-1: Target player draws a card", playerA);
 
         setStopAt(1, PhaseStep.END_TURN);
         execute();
diff --git a/Mage/src/mage/abilities/costs/common/TapTargetCost.java b/Mage/src/mage/abilities/costs/common/TapTargetCost.java
index 749eea7aff..8f448eaa09 100644
--- a/Mage/src/mage/abilities/costs/common/TapTargetCost.java
+++ b/Mage/src/mage/abilities/costs/common/TapTargetCost.java
@@ -76,7 +76,7 @@ public class TapTargetCost extends CostImpl {
 
     @Override
     public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
-        return target.canChoose(controllerId, game);
+        return target.canChoose(sourceId, controllerId, game);
     }
 
     @Override
diff --git a/Mage/src/mage/abilities/effects/common/ExileFromZoneTargetEffect.java b/Mage/src/mage/abilities/effects/common/ExileFromZoneTargetEffect.java
index 48be98f689..028237b01c 100644
--- a/Mage/src/mage/abilities/effects/common/ExileFromZoneTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/ExileFromZoneTargetEffect.java
@@ -1,16 +1,16 @@
 /*
  *  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
@@ -20,7 +20,7 @@
  *  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.
@@ -28,17 +28,18 @@
 package mage.abilities.effects.common;
 
 import java.util.UUID;
-import mage.constants.Outcome;
-import mage.constants.Zone;
 import mage.abilities.Ability;
 import mage.abilities.effects.OneShotEffect;
 import mage.cards.Card;
+import mage.constants.Outcome;
+import mage.constants.Zone;
 import mage.filter.FilterCard;
 import mage.game.Game;
 import mage.players.Player;
 import mage.target.Target;
 import mage.target.common.TargetCardInHand;
 import mage.target.common.TargetCardInYourGraveyard;
+import mage.util.CardUtil;
 
 /**
  *
@@ -110,10 +111,6 @@ public class ExileFromZoneTargetEffect extends OneShotEffect {
     }
 
     private void setText() {
-        if (amount == 1) {
-            staticText = "Target player exiles a " + filter.getMessage() + " from his or her " + zone.toString().toLowerCase();
-        } else {
-            staticText = "Target player exiles " + amount + " " + filter.getMessage() + " from his or her " + zone.toString().toLowerCase();
-        }
+        staticText = "target player exiles " + CardUtil.numberToText(exileName, "a") + filter.getMessage() + " from his or her " + zone.toString().toLowerCase();
     }
 }
diff --git a/Mage/src/mage/abilities/keyword/ConspireAbility.java b/Mage/src/mage/abilities/keyword/ConspireAbility.java
index 674505173b..cef23120fe 100644
--- a/Mage/src/mage/abilities/keyword/ConspireAbility.java
+++ b/Mage/src/mage/abilities/keyword/ConspireAbility.java
@@ -158,10 +158,11 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
     @Override
     public void addOptionalAdditionalCosts(Ability ability, Game game) {
         if (ability instanceof SpellAbility) {
-            Player player = game.getPlayer(controllerId);
+            Player player = game.getPlayer(getControllerId());
             if (player != null) {
                 resetConspire(ability, game);
-                if (player.chooseUse(Outcome.Benefit, "Pay " + conspireCost.getText(false) + " ?", ability, game)) {
+                if (conspireCost.canPay(ability, getSourceId(), getControllerId(), game)
+                        && player.chooseUse(Outcome.Benefit, "Pay " + conspireCost.getText(false) + " ?", ability, game)) {
                     activateConspire(ability, game);
                     for (Iterator it = ((Costs) conspireCost).iterator(); it.hasNext();) {
                         Cost cost = (Cost) it.next();