From 5b5344a1a0b90a16a9568577c48a0693a09d1db1 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Tue, 23 Sep 2014 17:01:09 +0200
Subject: [PATCH] * MorphAbility - Fixed copying a face-down creature (fixes
 #566). Morph cards are indicated as playable now if you have the needed mana
 to play it by Morph. Cast of Morph spell is now colorless (fixes #569).

---
 .../cards/abilities/keywords/MorphTest.java   | 179 ++++++++++++++++++
 .../common/FaceDownSourceCondition.java       |  63 ++++++
 ...OrMoreSpellsWereCastLastTurnCondition.java |   2 +-
 .../costs/AlternativeSourceCosts.java         |   4 +-
 .../mage/abilities/keyword/EvokeAbility.java  |   8 +
 .../mage/abilities/keyword/MorphAbility.java  |  80 +++++---
 Mage/src/mage/game/GameImpl.java              |   4 +
 Mage/src/mage/players/PlayerImpl.java         |  43 +++--
 .../common/CastSpellLastTurnWatcher.java      |   6 +-
 9 files changed, 340 insertions(+), 49 deletions(-)
 create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java
 create mode 100644 Mage/src/mage/abilities/condition/common/FaceDownSourceCondition.java

diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java
new file mode 100644
index 0000000000..1c8325675d
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java
@@ -0,0 +1,179 @@
+/*
+ *  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 org.mage.test.cards.abilities.keywords;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author levelX2
+ */
+
+public class MorphTest extends CardTestPlayerBase {
+
+    /**
+     * Tests if a creature with Morph is cast normal, it behaves as normal creature
+     *
+     */
+    @Test
+    public void testCastMoprhCreatureWithoutMorph() {
+        /*    
+        Pine Walker
+        Creature - Elemental
+        5/5
+        Morph {4}{G} (You may cast this card face down as a 2/2 creature for . Turn it face up any time for its morph cost.)
+        Whenever Pine Walker or another creature you control is turned face up, untap that creature.
+        */
+        addCard(Zone.HAND, playerA, "Pine Walker");
+        addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
+        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
+        setChoice(playerA, "No"); // cast it normal as 5/5
+        
+        setStopAt(1, PhaseStep.BEGIN_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "Pine Walker", 1);
+        assertPowerToughness(playerA, "Pine Walker", 5, 5);
+
+    }
+
+
+    /**
+     * Cast the creature face down as a 2/2
+     */
+    @Test
+    public void testCastFaceDown() {
+        addCard(Zone.HAND, playerA, "Pine Walker");
+        addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
+        setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
+        
+        setStopAt(1, PhaseStep.BEGIN_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "", 1);
+        assertPowerToughness(playerA, "", 2, 2);
+
+    }
+    /**
+     * Test triggered turn face up ability of Pine Walker
+     */
+    @Test
+    public void testCopyFaceDwonMorphCreature() {
+        addCard(Zone.HAND, playerA, "Pine Walker");
+        addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
+        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
+        setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
+        
+        attack(3, playerA, "");
+        
+        activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{4}{G}: Turn this face-down permanent face up.");
+        setStopAt(3, PhaseStep.END_TURN);
+        execute();
+
+        assertLife(playerB, 18);
+        
+        assertPermanentCount(playerA, "", 0);
+        assertPermanentCount(playerA, "Pine Walker", 1);        
+        assertPowerToughness(playerA, "Pine Walker", 5, 5);
+        assertTapped("Pine Walker", false);
+
+    }
+    /**
+     * Test that Morph creature do not trigger abilities with their face up attributes
+     * 
+     */
+    @Test
+    public void testMorphedRemovesAttributesCreature() {
+        // Ponyback Brigade {3}{R}{W}{B}
+        // Creature - Goblin Warrior
+        // 2/2
+        // When Ponyback Brigade enters the battlefield or is turned face up, put three 1/1 red Goblin creature tokens onto the battlefield.
+        // Morph {2}{R}{W}{B}(You may cast this card face down as a 2/2 creature for . Turn it face up any time for its morph cost.)        
+        addCard(Zone.HAND, playerA, "Ponyback Brigade");
+        addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+        addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
+        
+        addCard(Zone.BATTLEFIELD, playerB, "Soldier of the Pantheon", 1);
+        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ponyback Brigade");
+        setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
+        
+        setStopAt(1, PhaseStep.BEGIN_COMBAT);
+        execute();
+
+        assertLife(playerB, 20); // and not 21 
+        
+        assertPermanentCount(playerA, "", 1);
+        assertPermanentCount(playerB, "Soldier of the Pantheon", 1);
+
+    }
+    
+   /**
+     * Test to copy a morphed 2/2 creature
+     * 
+     */
+    @Test
+    public void testCopyAMorphedCreature() {
+        addCard(Zone.HAND, playerA, "Pine Walker");
+        addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+        
+        // Clever Impersonator  {2}{U}{U}
+        // Creature - Shapeshifter
+        // 0/0
+        // You may have Clever Impersonator enter the battlefield as a copy of any nonland permanent on the battlefield.
+        addCard(Zone.HAND, playerB, "Clever Impersonator", 1);
+        addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
+        
+        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
+        setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
+        
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Clever Impersonator");
+        setChoice(playerB, "Yes"); // use to copy a nonland permanent
+        addTarget(playerB, ""); // Morphed creature
+                
+        setStopAt(2, PhaseStep.BEGIN_COMBAT);
+        execute();
+
+        assertLife(playerB, 20);
+        
+        assertPermanentCount(playerA, "", 1);
+        assertPowerToughness(playerA, "", 2,2);
+        assertPermanentCount(playerB, "", 1);
+        assertPowerToughness(playerB, "", 2,2);
+
+    }    
+    
+}
diff --git a/Mage/src/mage/abilities/condition/common/FaceDownSourceCondition.java b/Mage/src/mage/abilities/condition/common/FaceDownSourceCondition.java
new file mode 100644
index 0000000000..b2918d048c
--- /dev/null
+++ b/Mage/src/mage/abilities/condition/common/FaceDownSourceCondition.java
@@ -0,0 +1,63 @@
+/*
+ *  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.condition.common;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.cards.Card;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class FaceDownSourceCondition implements Condition {
+
+    private final static FaceDownSourceCondition fInstance = new FaceDownSourceCondition();
+
+    public static Condition getInstance() {
+        return fInstance;
+    }
+
+    @Override
+    public boolean apply(Game game, Ability source) {
+        MageObject mageObject = game.getObject(source.getSourceId());
+        if (mageObject != null) {
+            if (mageObject instanceof Permanent) {
+                return ((Permanent)mageObject).isFaceDown();
+            }
+            if (mageObject instanceof Card) {
+                return ((Card)mageObject).isFaceDown();
+            }
+        }
+        return false;
+    }
+}
diff --git a/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java b/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java
index 78d7c09619..c716ebf8a3 100644
--- a/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java
+++ b/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java
@@ -52,7 +52,7 @@ public class TwoOrMoreSpellsWereCastLastTurnCondition implements Condition {
                 return true;
             }
         }
-        // no one cast two or more spells this turn
+        // no one cast two or more spells last turn
         return false;
     }
 }
diff --git a/Mage/src/mage/abilities/costs/AlternativeSourceCosts.java b/Mage/src/mage/abilities/costs/AlternativeSourceCosts.java
index 71b136d0ca..5e9087feb3 100644
--- a/Mage/src/mage/abilities/costs/AlternativeSourceCosts.java
+++ b/Mage/src/mage/abilities/costs/AlternativeSourceCosts.java
@@ -70,6 +70,6 @@ public interface AlternativeSourceCosts {
      * @param game
      * @return 
      */
-    String getCastMessageSuffix(Game game);
-
+    String getCastMessageSuffix(Game game);      
+    
 }
\ No newline at end of file
diff --git a/Mage/src/mage/abilities/keyword/EvokeAbility.java b/Mage/src/mage/abilities/keyword/EvokeAbility.java
index 1569db6ccb..fd32438b0e 100644
--- a/Mage/src/mage/abilities/keyword/EvokeAbility.java
+++ b/Mage/src/mage/abilities/keyword/EvokeAbility.java
@@ -41,6 +41,7 @@ import mage.abilities.costs.AlternativeCost2Impl;
 import mage.abilities.costs.AlternativeSourceCosts;
 import mage.abilities.costs.Cost;
 import mage.abilities.costs.Costs;
+import mage.abilities.costs.CostsImpl;
 import mage.abilities.costs.mana.ManaCostsImpl;
 import mage.abilities.decorator.ConditionalTriggeredAbility;
 import mage.abilities.effects.common.SacrificeSourceEffect;
@@ -190,4 +191,11 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost
         }
         return sb.toString();
     }
+    
+    @Override
+    public Costs<Cost> getCosts() {
+        Costs<Cost> alterCosts = new CostsImpl<>();
+        alterCosts.addAll(evokeCosts);
+        return alterCosts;
+    }    
 }
diff --git a/Mage/src/mage/abilities/keyword/MorphAbility.java b/Mage/src/mage/abilities/keyword/MorphAbility.java
index bdd6f6e508..b1886aa7da 100644
--- a/Mage/src/mage/abilities/keyword/MorphAbility.java
+++ b/Mage/src/mage/abilities/keyword/MorphAbility.java
@@ -30,7 +30,6 @@ package mage.abilities.keyword;
 
 import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import mage.ObjectColor;
 import mage.abilities.Ability;
@@ -38,13 +37,13 @@ import mage.abilities.SpellAbility;
 import mage.abilities.StaticAbility;
 import mage.abilities.common.SimpleStaticAbility;
 import mage.abilities.common.TurnFaceUpAbility;
-import mage.abilities.costs.AlternativeCost2;
 import mage.abilities.costs.AlternativeCost2Impl;
 import mage.abilities.costs.AlternativeSourceCosts;
 import mage.abilities.costs.Cost;
 import mage.abilities.costs.Costs;
 import mage.abilities.costs.CostsImpl;
 import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.costs.mana.ManaCost;
 import mage.abilities.costs.mana.ManaCosts;
 import mage.abilities.costs.mana.ManaCostsImpl;
 import mage.abilities.effects.ContinuousEffectImpl;
@@ -54,6 +53,7 @@ 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.game.Game;
@@ -105,7 +105,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
     protected static final String ABILITY_KEYWORD = "Morph";
     protected static final String REMINDER_TEXT = "(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)";
     protected String ruleText;
-    protected List<AlternativeCost2> alternateCosts = new LinkedList<>();
+    protected AlternativeCost2Impl alternateCosts = new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3));
 
     // needed to check activation status, if card changes zone after casting it
     private   int zoneChangeCounter = 0;
@@ -131,8 +131,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
         sb.append(REMINDER_TEXT);
         ruleText = sb.toString();
 
-        alternateCosts.add(new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3)));
-
+        // alternateCosts.add(new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3)));
         Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesFaceDownCreatureEffect(morphCosts));
         ability.setRuleVisible(false);
         card.addAbility(ability);
@@ -141,13 +140,13 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
 
     public MorphAbility(final MorphAbility ability) {
        super(ability);
-       this.alternateCosts.addAll(ability.alternateCosts);
        this.zoneChangeCounter = ability.zoneChangeCounter;
        this.ruleText = ability.ruleText;
+       this.alternateCosts = ability.alternateCosts.copy();
     }
 
-    private static Costs createCosts(Cost cost) {
-        Costs costs = new CostsImpl();
+    private static Costs<Cost> createCosts(Cost cost) {
+        Costs<Cost> costs = new CostsImpl<>();
         costs.add(cost);
         return costs;
     }
@@ -158,9 +157,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
     }
 
     public void resetMorph() {
-        for (AlternativeCost2 cost: alternateCosts) {
-            cost.reset();
-        }
+        alternateCosts.reset();        
         zoneChangeCounter = 0;
     }
 
@@ -168,11 +165,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
     public boolean isActivated(Ability ability, Game game) {
         Card card = game.getCard(sourceId);
         if (card != null && card.getZoneChangeCounter() <= zoneChangeCounter +1) {
-            for (AlternativeCost2 cost: alternateCosts) {
-                if(cost.isActivated(game)) {
-                    return true;
-                }
-            }
+            return alternateCosts.isActivated(game);
         }
         return false;
     }
@@ -190,20 +183,27 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
             if (player != null && spell != null) {
                 this.resetMorph();
                 spell.setFaceDown(true); // so only the back is visible
-                for (AlternativeCost2 alternateCastingCost: alternateCosts) {
-                    if (alternateCastingCost.canPay(ability, sourceId, controllerId, game) &&
-                        player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(alternateCastingCost.getText(true)).append(" ?").toString(), game)) {
-                        activateMorph(alternateCastingCost, game);
+                if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
+                    if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) {
+                        activateMorph(game);
+                        // change mana costs
                         ability.getManaCostsToPay().clear();
                         ability.getCosts().clear();
-                        for (Iterator it = ((Costs) alternateCastingCost).iterator(); it.hasNext();) {
+                        for (Iterator it = this.alternateCosts.iterator(); it.hasNext();) {
                             Cost cost = (Cost) it.next();
-                            if (cost instanceof ManaCosts) {
-                                ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
+                            if (cost instanceof ManaCost) {
+                                ability.getManaCostsToPay().add((ManaCost)cost.copy());
                             } else {
                                 ability.getCosts().add(cost.copy());
                             }
                         }
+                        // change spell colors
+                        ObjectColor spellColor = spell.getColor();
+                        spellColor.setBlack(false);
+                        spellColor.setRed(false);
+                        spellColor.setGreen(false);
+                        spellColor.setWhite(false);
+                        spellColor.setBlue(false);
                     } else {
                         spell.setFaceDown(false);
                     }
@@ -213,8 +213,8 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
         return isActivated(ability, game);
     }
 
-    private void activateMorph(AlternativeCost2 cost, Game game) {
-        cost.activate();
+    private void activateMorph(Game game) {
+        alternateCosts.activate();
         // remember zone change counter
         if (zoneChangeCounter == 0) {
             Card card = game.getCard(getSourceId());
@@ -240,14 +240,31 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
     public String getCastMessageSuffix(Game game) {
         StringBuilder sb = new StringBuilder();
         int position = 0;
-        for (AlternativeCost2 cost : alternateCosts) {
-            if (cost.isActivated(game)) {
-                sb.append(cost.getCastSuffixMessage(position));
-                ++position;
-            }
-        }
+        sb.append(alternateCosts.getCastSuffixMessage(position));
         return sb.toString();
     }
+
+    @Override
+    @SuppressWarnings({"unchecked"})
+    public Costs<Cost> getCosts() {
+        return alternateCosts;
+    }
+    
+    public static void setPermanentToMorph(Permanent permanent) {
+        permanent.getPower().initValue(2);
+        permanent.getToughness().initValue(2);
+        permanent.getAbilities().clear();
+        permanent.getColor().setColor(new ObjectColor());
+        permanent.setName("");
+        permanent.getCardType().clear();
+        permanent.getCardType().add(CardType.CREATURE);
+        permanent.getSubtype().clear();
+        permanent.getSupertype().clear();
+        permanent.getManaCost().clear();
+        permanent.setExpansionSetCode("KTK");
+        permanent.setRarity(Rarity.NA);
+        
+    }
 }
 
 /**
@@ -348,3 +365,4 @@ class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implements Sour
     }
 
 }
+
diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java
index 802242ecd5..3481dd5799 100644
--- a/Mage/src/mage/game/GameImpl.java
+++ b/Mage/src/mage/game/GameImpl.java
@@ -93,6 +93,7 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.util.*;
 import java.util.Map.Entry;
+import mage.abilities.keyword.MorphAbility;
 
 public abstract class GameImpl implements Game, Serializable {
 
@@ -1237,6 +1238,9 @@ public abstract class GameImpl implements Game, Serializable {
 
         //getState().addCard(permanent);
         permanent.reset(this);
+        if (copyFromPermanent.isMorphCard()) {
+            MorphAbility.setPermanentToMorph(permanent);
+        }
         permanent.assignNewId();
         if (copyFromPermanent.isTransformed()) {
             TransformAbility.transform(permanent, copyFromPermanent.getSecondCardFace(), this);
diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java
index 8154f974c9..e3c69893d7 100644
--- a/Mage/src/mage/players/PlayerImpl.java
+++ b/Mage/src/mage/players/PlayerImpl.java
@@ -1907,7 +1907,7 @@ public abstract class PlayerImpl implements Player, Serializable {
         return result;
     }
 
-    protected boolean canPlay(ActivatedAbility ability, ManaOptions available, Game game) {
+    protected boolean canPlay(ActivatedAbility ability, ManaOptions available, MageObject sourceObject, Game game) {
         if (!(ability instanceof ManaAbility)) {
             ActivatedAbility copy = ability.copy();     
             copy.setCheckPlayableMode(); // prevents from endless loops for asking player to use effects by checking this mode
@@ -1956,6 +1956,20 @@ public abstract class PlayerImpl implements Player, Serializable {
                     return true;
                 }
             }
+            
+            if (!(sourceObject instanceof Permanent)) {
+                for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
+                    // if cast for noMana no Alternative costs are allowed
+                    if (alternateSourceCostsAbility instanceof AlternativeSourceCosts) {                     
+                        if (((AlternativeSourceCosts)alternateSourceCostsAbility).isAvailable(ability, game)) {
+                            if (alternateSourceCostsAbility.getCosts().canPay(ability, playerId, playerId, game)) {
+                                return true;
+                            }
+                        }   
+                    }
+                }
+            }
+            
         }
         return false;
     }
@@ -1971,14 +1985,19 @@ public abstract class PlayerImpl implements Player, Serializable {
 
             if (hidden) {
                 for (Card card : hand.getUniqueCards(game)) {
-                    for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
-                        if (ability instanceof PlayLandAbility) {
-                            if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
-                                break;
+                    for (Ability ability : card.getAbilities()) {
+                        if (ability instanceof ActivatedAbility) {
+                            if (ability instanceof PlayLandAbility) {
+                                if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
+                                    break;
+                                }
+                            }
+                            if (canPlay((ActivatedAbility) ability, availableMana, card, game)) {
+                                playable.add(ability);
                             }
                         }
-                        if (canPlay(ability, availableMana, game)) {
-                            playable.add(ability);
+                        if (ability instanceof AlternativeSourceCosts) {
+                            
                         }
                     }
                 }
@@ -1994,7 +2013,7 @@ public abstract class PlayerImpl implements Player, Serializable {
                             possible = true;
                         }                        
                     } 
-                    if (possible && canPlay(ability, availableMana, game)) {
+                    if (possible && canPlay(ability, availableMana, card, game)) {
                         playable.add(ability);
                     }                    
                 }
@@ -2036,7 +2055,7 @@ public abstract class PlayerImpl implements Player, Serializable {
             for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
                 for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
                     if (!playableActivated.containsKey(ability.toString())) {
-                        if (canPlay(ability, availableMana, game)) {
+                        if (canPlay(ability, availableMana, permanent, game)) {
                             playableActivated.put(ability.toString(), ability);
                         }
                     }
@@ -2049,7 +2068,7 @@ public abstract class PlayerImpl implements Player, Serializable {
                     MageObject object = game.getObject(this.getCommanderId());
                     if (object != null) {
                         for (ActivatedAbility ability : ((Commander) object).getAbilities().getActivatedAbilities(Zone.COMMAND)) {
-                            if (canPlay(ability, availableMana, game)) {
+                            if (canPlay(ability, availableMana, object, game)) {
                                 playableActivated.put(ability.toString(), ability);
                             }
                         }
@@ -2082,13 +2101,13 @@ public abstract class PlayerImpl implements Player, Serializable {
                                 break;
                             }
                         }
-                        if (canPlay(ability, available, game)) {
+                        if (canPlay(ability, available, card, game)) {
                             playable.add(card.getId());
                             break;
                         }
                     }
                     for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
-                        if (!playable.contains(ability.getSourceId()) && canPlay(ability, available, game)) {
+                        if (!playable.contains(ability.getSourceId()) && canPlay(ability, available, card, game)) {
                             playable.add(card.getId());
                             break;
                         }
diff --git a/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java b/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java
index 57772f2dd2..d5800980ea 100644
--- a/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java
+++ b/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java
@@ -70,9 +70,9 @@ public class CastSpellLastTurnWatcher extends Watcher {
            if (playerId != null) {
                Integer amount = amountOfSpellsCastOnCurrentTurn.get(playerId);
                if (amount == null) {
-                   amount = Integer.valueOf(1);
+                   amount = 1;
                } else {
-                   amount = Integer.valueOf(amount+1);
+                   amount = amount+1;
                }
                amountOfSpellsCastOnCurrentTurn.put(playerId, amount);
            }
@@ -98,7 +98,7 @@ public class CastSpellLastTurnWatcher extends Watcher {
     public int getAmountOfSpellsPlayerCastOnCurrentTurn(UUID playerId) {
        Integer value = amountOfSpellsCastOnCurrentTurn.get(playerId);
        if (value != null) {
-           return value.intValue();
+           return value;
        } else {
            return 0;
        }