From 391c3db02e616be549ee96ed66921c2ed41874c1 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Thu, 21 Feb 2013 00:15:11 +0100
Subject: [PATCH] Fixed to do the check of existing abilities always by rule
 text. Added a new abilities.containsRule() method to check by rule, that's
 sometimes needed. To check always by rule text leaded to bugs during applying
 copy effects.

---
 Mage/src/mage/abilities/Abilities.java     |  8 ++++++++
 Mage/src/mage/abilities/AbilitiesImpl.java | 21 ++++++++++++++++++++-
 Mage/src/mage/abilities/Ability.java       |  7 +++++++
 Mage/src/mage/abilities/AbilityImpl.java   |  7 ++++++-
 Mage/src/mage/game/stack/StackAbility.java |  5 +++++
 5 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/Mage/src/mage/abilities/Abilities.java b/Mage/src/mage/abilities/Abilities.java
index da8cd7ff4a..578852dc16 100644
--- a/Mage/src/mage/abilities/Abilities.java
+++ b/Mage/src/mage/abilities/Abilities.java
@@ -214,6 +214,14 @@ public interface Abilities<T extends Ability> extends List<T>, Serializable {
      */
     boolean contains(T ability);
 
+    /**
+     * Searches an ability with the same rule text as the passed in ability.
+     * 
+     * @param ability
+     * @return
+     */
+    boolean containsRule(T ability);
+
     /**
      * Searches this set of abilities for the existence of each of the passed in
      * set of abilities.
diff --git a/Mage/src/mage/abilities/AbilitiesImpl.java b/Mage/src/mage/abilities/AbilitiesImpl.java
index 76b3bd0c8b..3ca3dca985 100644
--- a/Mage/src/mage/abilities/AbilitiesImpl.java
+++ b/Mage/src/mage/abilities/AbilitiesImpl.java
@@ -232,7 +232,26 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
     @Override
     public boolean contains(T ability) {
         for (T test: this) {
-            if (ability.getId().equals(test.getId()) || ability.getRule().equals(test.getRule())) {
+            // Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability
+            // already before the copy. Because then it keeps the triggered ability twice and it triggers twice.
+            // e.g. 2 Biovisonary and one enchanted with Infinite Reflection
+            if (ability.getId().equals(test.getId())) {
+                return true;
+            }
+            if (ability.getOriginalId().equals(test.getId())) {
+                return true;
+            }
+            if (ability instanceof MageSingleton && ability.getRule().equals(test.getRule())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean containsRule(T ability) {
+        for (T test: this) {
+            if (ability.getRule().equals(test.getRule())) {
                 return true;
             }
         }
diff --git a/Mage/src/mage/abilities/Ability.java b/Mage/src/mage/abilities/Ability.java
index 48e4282fad..bd2149aabc 100644
--- a/Mage/src/mage/abilities/Ability.java
+++ b/Mage/src/mage/abilities/Ability.java
@@ -379,4 +379,11 @@ public interface Ability extends Controllable, Serializable {
      */
     void setRuleAtTheTop(boolean ruleAtTheTop);
 
+    /**
+     * Get the originalId of the ability
+     * 
+     * @return originalId
+     */
+    UUID getOriginalId();
+    
 }
diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java
index 1eae2f5fa4..8a6b3150f7 100644
--- a/Mage/src/mage/abilities/AbilityImpl.java
+++ b/Mage/src/mage/abilities/AbilityImpl.java
@@ -580,6 +580,11 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
     @Override
     public void setRuleAtTheTop(boolean ruleAtTheTop) {
         this.ruleAtTheTop = ruleAtTheTop;
-    }    
+    }
+
+    @Override
+    public UUID getOriginalId() {
+        return this.originalId;
+    }
 }
 
diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java
index 45128fa8d9..a1f3535863 100644
--- a/Mage/src/mage/game/stack/StackAbility.java
+++ b/Mage/src/mage/game/stack/StackAbility.java
@@ -372,4 +372,9 @@ public class StackAbility implements StackObject, Ability {
     public void setRuleAtTheTop(boolean ruleAtTheTop) {
         this.ability.setRuleAtTheTop(ruleAtTheTop);
     }
+
+    @Override
+    public UUID getOriginalId() {
+        return this.ability.getOriginalId();
+    }
 }