*/
    public boolean hasProperty(String Property, final Player sourceController, final Card source) {
        //by name can also have color names, so needs to happen before colors.
        if (Property.startsWith("named")) {
            if (!getName().equals(Property.substring(5))) return false;
        } else if (Property.startsWith("notnamed")) {
            if (getName().equals(Property.substring(8))) return false;
        } else if (Property.startsWith("sameName")) {
            if (!getName().equals(source.getName())) return false;
        }
        // ... Card colors
        else if (Property.contains("White")
                || Property.contains("Blue")
                || Property.contains("Black")
                || Property.contains("Red")
                || Property.contains("Green")
                || Property.contains("Colorless")) {
            if (Property.startsWith("non")) {
                if (CardUtil.getColors(this).contains(Property.substring(3).toLowerCase())) return false;
            } else if (!CardUtil.getColors(this).contains(Property.toLowerCase())) return false;
        } else if (Property.contains("MultiColor")) // ... Card is multicolored
        {
            if (Property.startsWith("non") && (CardUtil.getColors(this).size() > 1)) return false;
            if (!Property.startsWith("non") && (CardUtil.getColors(this).size() <= 1)) return false;
        } else if (Property.contains("MonoColor")) // ... Card is monocolored
        {
            if (Property.startsWith("non") && (CardUtil.getColors(this).size() == 1 && !isColorless())) return false;
            if (!Property.startsWith("non") && (CardUtil.getColors(this).size() > 1 || isColorless())) return false;
        } else if (Property.startsWith("YouCtrl")) {
            if (!getController().isPlayer(sourceController)) return false;
        } else if (Property.startsWith("YouDontCtrl")) {
            if (getController().isPlayer(sourceController)) return false;
        } else if (Property.startsWith("YouOwn")) {
            if (!getOwner().isPlayer(sourceController)) return false;
        } else if (Property.startsWith("YouDontOwn")) {
            if (getOwner().isPlayer(sourceController)) return false;
        } else if (Property.startsWith("ControllerControls")) {
            String type = Property.substring(18);
            CardList list = AllZoneUtil.getPlayerCardsInPlay(getController());
            if (list.getType(type).isEmpty()) return false;
        } else if (Property.startsWith("Other")) {
            if (this.equals(source)) return false;
        } else if (Property.startsWith("Self")) {
            if (!this.equals(source)) return false;
        } else if (Property.startsWith("AttachedBy")) {
            if (!equippedBy.contains(source) && !enchantedBy.contains(source)) return false;
        } else if (Property.startsWith("Attached")) {
            if (!equipping.contains(source) && !enchanting.contains(source)) return false;
        } else if (Property.startsWith("EnchantedBy")) {
            if (!enchantedBy.contains(source)) return false;
        } else if (Property.startsWith("Enchanted")) {
            if (!enchanting.contains(source)) return false;
        } else if (Property.startsWith("EquippedBy")) {
            if (!equippedBy.contains(source)) return false;
        } else if (Property.startsWith("Equipped")) {
            if (!equipping.contains(source)) return false;
        } else if (Property.startsWith("Cloned")) {
            if (cloneOrigin == null || !cloneOrigin.equals(source)) return false;
        } else if (Property.startsWith("DamagedBy")) {
            if (!receivedDamageFromThisTurn.containsKey(source)) return false;
        } else if (Property.startsWith("Damaged")) {
            if (!dealtDamageToThisTurn.containsKey(source)) return false;
        } else if (Property.startsWith("SharesColorWith")) {
            if (!sharesColorWith(source)) return false;
        } else if (Property.startsWith("with")) // ... Card keywords
        {
            if (Property.startsWith("without") && hasStartOfKeyword(Property.substring(7))) return false;
            if (!Property.startsWith("without") && !hasStartOfKeyword(Property.substring(4))) return false;
        } else if (Property.startsWith("tapped")) {
            if (!isTapped()) return false;
        } else if (Property.startsWith("untapped")) {
            if (!isUntapped()) return false;
        } else if (Property.startsWith("faceDown")) {
            if (!isFaceDown()) return false;
        } else if (Property.startsWith("hasLevelUp")) {
            if (!hasLevelUp()) return false;
        } else if (Property.startsWith("enteredBattlefieldThisTurn")) {
            if (!(getTurnInZone() == AllZone.getPhase().getTurn())) return false;
        } else if (Property.startsWith("dealtDamageToYouThisTurn")) {
            if (!(dealtDmgToHumanThisTurn && getController().isPlayer(AllZone.getComputerPlayer()))
                    && !(dealtDmgToComputerThisTurn && getController().isPlayer(AllZone.getHumanPlayer())))
                return false;
        } else if (Property.startsWith("wasDealtDamageThisTurn")) {
            if ((getReceivedDamageFromThisTurn().keySet()).isEmpty()) return false;
        } else if (Property.startsWith("enchanted")) {
            if (!isEnchanted()) return false;
        } else if (Property.startsWith("unenchanted")) {
            if (isEnchanted()) return false;
        } else if (Property.startsWith("enchanting")) {
            if (!isEnchanting()) return false;
        } else if (Property.startsWith("equipped")) {
            if (!isEquipped()) return false;
        } else if (Property.startsWith("unequipped")) {
            if (isEquipped()) return false;
        } else if (Property.startsWith("equipping")) {
            if (!isEquipping()) return false;
        } else if (Property.startsWith("token")) {
            if (!isToken()) return false;
        } else if (Property.startsWith("nonToken")) {
            if (isToken()) return false;
        } else if (Property.startsWith("power") ||     // 8/10
                Property.startsWith("toughness") ||
                Property.startsWith("cmc")) {
            int x = 0;
            int y = 0;
            int z = 0;

            if (Property.startsWith("power")) {
                z = 7;
                y = getNetAttack();
            } else if (Property.startsWith("toughness")) {
                z = 11;
                y = getNetDefense();
            } else if (Property.startsWith("cmc")) {
                z = 5;
                y = getCMC();
            }

            if (Property.substring(z).equals("X")) {
                x = CardFactoryUtil.xCount(source, source.getSVar("X"));
            } else if (Property.substring(z).equals("Y")) {
                x = CardFactoryUtil.xCount(source, source.getSVar("Y"));
            } else
                x = Integer.parseInt(Property.substring(z));

            if (!AllZoneUtil.compare(y, Property, x))
                return false;
        }

        // syntax example: countersGE9 P1P1 or countersLT12TIME (greater number than 99 not supported)
        /*
               * slapshot5 - fair warning, you cannot use numbers with 2 digits (greater number than 9 not supported
               * you can use X and the SVar:X:Number$12 to get two digits.  This will need a better fix, and I have the
               * beginnings of a regex below
               */
        else if (Property.startsWith("counters")) {
            /*
                    Pattern p = Pattern.compile("[a-z]*[A-Z][A-Z][X0-9]+.*$");
                    String[] parse = ???
                    System.out.println("Parsing completed of: "+Property);
                    for(int i = 0; i < parse.length; i++) {
                        System.out.println("parse["+i+"]: "+parse[i]);
                    }*/

            // TODO: get a working regex out of this pattern so the amount of digits doesn't matter
            int number = 0;
            if (Property.substring(10, 11).equals("X"))
                number = CardFactoryUtil.xCount(source, getSVar("X"));
            else if (Property.substring(10, 11).equals("Y"))
                number = CardFactoryUtil.xCount(source, getSVar("Y"));
            else
                number = Integer.parseInt(Property.substring(10, 11));

            String type = Property.substring(11);
            String comparator = Property.substring(8, 10); // comparator = EQ, LE, GE etc.
            int actualnumber = getCounters(Counters.getType(type));

            if (!AllZoneUtil.compare(actualnumber, comparator, number))
                return false;
        } else if (Property.startsWith("attacking")) {
            if (!isAttacking()) return false;
        } else if (Property.startsWith("notattacking")) {
            if (isAttacking()) return false;
        } else if (Property.equals("blocking")) {
            if (!isBlocking()) return false;
        } else if (Property.startsWith("blockingSource")) {
            if (!isBlocking(source)) return false;
        } else if (Property.startsWith("notblocking")) {
            if (isBlocking()) return false;
        } else if (Property.startsWith("blocked")) {
            if (!AllZone.getCombat().isBlocked(this)) return false;
        } else if (Property.startsWith("blockedBySource")) {
            if (!isBlockedBy(source)) return false;
        } else if (Property.startsWith("unblocked")) {
            if (!AllZone.getCombat().isUnblocked(this)) return false;
        } else if (Property.startsWith("kicked")) {
            if (!isKicked()) return false;
        } else if (Property.startsWith("notkicked")) {
            if (isKicked()) return false;
        } else if (Property.startsWith("evoked")) {
            if (!isEvoked()) return false;
        } else if (Property.equals("HasDevoured")) {
            if(devouredCards.size() == 0) return false;
        } else if (Property.equals("HasNotDevoured")) {
            if(devouredCards.size() != 0) return false;
        } else if (Property.startsWith("non")) // ... Other Card types
        {
            if (isType(Property.substring(3))) return false;
        } else if (Property.equals("CostsPhyrexianMana")) {
            if (!manaCost.contains("P")) return false;
        } else if (Property.equals("IsRemembered")) {
            if(!source.getRemembered().contains(this)) return false;
        } else {
            if (Property.equals("ChosenType")) {
                if (!isType(source.getChosenType())) return false;
            } else {
                if (!isType(Property)) return false;
            }
        }
        return true;
    }