Example usage for java.util Collections disjoint

List of usage examples for java.util Collections disjoint

Introduction

In this page you can find the example usage for java.util Collections disjoint.

Prototype

public static boolean disjoint(Collection<?> c1, Collection<?> c2) 

Source Link

Document

Returns true if the two specified collections have no elements in common.

Usage

From source file:org.apache.hadoop.hbase.regionserver.Store.java

public CompactionRequest requestCompaction(int priority) throws IOException {
    // don't even select for compaction if writes are disabled
    if (!this.region.areWritesEnabled()) {
        return null;
    }//  w w w .java  2 s . co m

    CompactionRequest ret = null;
    this.lock.readLock().lock();
    try {
        synchronized (filesCompacting) {
            // candidates = all storefiles not already in compaction queue
            List<StoreFile> candidates = Lists.newArrayList(storefiles);
            if (!filesCompacting.isEmpty()) {
                // exclude all files older than the newest file we're currently
                // compacting. this allows us to preserve contiguity (HBASE-2856)
                StoreFile last = filesCompacting.get(filesCompacting.size() - 1);
                int idx = candidates.indexOf(last);
                Preconditions.checkArgument(idx != -1);
                candidates.subList(0, idx + 1).clear();
            }

            boolean override = false;
            if (region.getCoprocessorHost() != null) {
                override = region.getCoprocessorHost().preCompactSelection(this, candidates);
            }
            CompactSelection filesToCompact;
            if (override) {
                // coprocessor is overriding normal file selection
                filesToCompact = new CompactSelection(conf, candidates);
            } else {
                filesToCompact = compactSelection(candidates, priority);
            }

            if (region.getCoprocessorHost() != null) {
                region.getCoprocessorHost().postCompactSelection(this,
                        ImmutableList.copyOf(filesToCompact.getFilesToCompact()));
            }

            // no files to compact
            if (filesToCompact.getFilesToCompact().isEmpty()) {
                return null;
            }

            // basic sanity check: do not try to compact the same StoreFile twice.
            if (!Collections.disjoint(filesCompacting, filesToCompact.getFilesToCompact())) {
                // TODO: change this from an IAE to LOG.error after sufficient testing
                Preconditions.checkArgument(false, "%s overlaps with %s", filesToCompact, filesCompacting);
            }
            filesCompacting.addAll(filesToCompact.getFilesToCompact());
            Collections.sort(filesCompacting, StoreFile.Comparators.FLUSH_TIME);

            // major compaction iff all StoreFiles are included
            boolean isMajor = (filesToCompact.getFilesToCompact().size() == this.storefiles.size());
            if (isMajor) {
                // since we're enqueuing a major, update the compaction wait interval
                this.forceMajor = false;
            }

            // everything went better than expected. create a compaction request
            int pri = getCompactPriority(priority);
            ret = new CompactionRequest(region, this, filesToCompact, isMajor, pri);
        }
    } finally {
        this.lock.readLock().unlock();
    }
    if (ret != null) {
        CompactionRequest.preRequest(ret);
    }
    return ret;
}

From source file:net.java.jaspicoil.MSPacSpnegoServerAuthModule.java

/**
 * Fetch the list of SID group from the PAC for a given Kerberos service
 * token//  w  w w . java 2 s .c  o  m
 * 
 * @param serviceToken
 *            the service token
 * @param serverSubject
 *            the subject of the server containing the KerberosKey
 * @param groups
 *            a set of extra groups, if null a new empty set will be created
 *            as a basis
 * @return the array of matching roles or null if an error happens
 */
private String[] buildGroupsFromPAC(byte[] serviceToken, Subject serverSubject, Set<String> groups) {
    final KerberosKey[] keys = getSubjectKeys(serverSubject);

    try {
        final SpnegoToken spnegoToken = SpnegoToken.parse(serviceToken);
        final String mechanism = spnegoToken.getMechanism();

        debug("Mechanism found {0}", mechanism);

        // Fetch all the SIDs and put it in a set
        final Set<String> sids = groups == null ? new HashSet<String>() : groups;

        if (SpnegoConstants.KERBEROS_MECHANISM.equals(mechanism)
                || SpnegoConstants.LEGACY_KERBEROS_MECHANISM.equals(mechanism)) {

            final byte[] mechanismToken = spnegoToken.getMechanismToken();

            // Decoding Kerberos token
            final KerberosToken kerberosToken = new KerberosToken(mechanismToken, keys);
            final List<KerberosAuthData> userAuthorizations = kerberosToken.getTicket().getEncData()
                    .getUserAuthorizations();
            for (final KerberosAuthData kerberosAuthData : userAuthorizations) {
                if (kerberosAuthData instanceof KerberosPacAuthData) {
                    final Pac pac = ((KerberosPacAuthData) kerberosAuthData).getPac();
                    final PacLogonInfo logonInfo = pac.getLogonInfo();

                    if (logonInfo.getGroupSid() != null) {
                        final PacSid sid = logonInfo.getGroupSid();
                        sids.add(ADUtil.convertSID(sid.getBytes()));
                        // sids.add( "SID_"+sid.toString());
                    }

                    for (final PacSid pacSid : logonInfo.getGroupSids()) {
                        sids.add(ADUtil.convertSID(pacSid.getBytes()));
                        // sids.add("SID_" + pacSid.toString());

                    }

                    for (final PacSid pacSid : logonInfo.getExtraSids()) {
                        sids.add(ADUtil.convertSID(pacSid.getBytes()));
                        // sids.add("SID_" + pacSid.toString());
                    }

                    for (final PacSid pacSid : logonInfo.getResourceGroupSids()) {
                        sids.add(ADUtil.convertSID(pacSid.getBytes()));
                        // sids.add("SID_" + pacSid.toString());
                    }

                    // Remove fake Smarcard Logon Role if existing
                    if (sids.contains(GROUP_SMARTCARD_AUTHENTICATED)) {
                        // Right, there is a role matching the
                        sids.remove(GROUP_SMARTCARD_AUTHENTICATED);
                        LOG.warning(
                                "Smartcard role was already assigned to a user, this could be a security issue. Meanwhile, the fake role was removed.");
                    }

                    // Let's check for smartcard logon
                    debug("Testing MS-PAC for Smartcard Logon");
                    if (pac.getCredentialType() != null) {
                        // Add the synthetic group to indicate a smartcard
                        // logon was secured
                        sids.add(GROUP_SMARTCARD_AUTHENTICATED);
                        debug("Smartcard logon was detected from the MS-PAC");
                    }

                    debug("Checking secure SIDs indicating MS-KILE Authentication Mechanism Assurance");
                    if (this.secureGroups != null && !Collections.disjoint(sids, this.secureGroups)) {
                        // Add the synthetic group to indicate a smartcard
                        // logon was secured
                        sids.add(GROUP_SMARTCARD_AUTHENTICATED);
                        debug("Smartcard logon was detected because of MS-KILE Authentication Mechanism Assurance");
                    }

                    debug("Checking KCD call scenario");
                    if (pac.getDelegationInfos() != null && pac.getDelegationInfos().size() > 0) {
                        // There is some delegation info found, so let's add
                        // the synthetic group to indicate KCD was detected
                        sids.add(GROUP_DELEGATED_AUTHENTICATED);
                        debug("Kerberos Constrainted Delegation call scenario was detected");
                    }

                    if (this.groupMapping != null && this.groupMapping.size() > 0) {
                        for (final String groupKey : this.groupMapping.stringPropertyNames()) {
                            // provide some mapping
                            // TODO provide a better mapping with N-N
                            // support
                            if (sids.contains(groupKey)) {
                                final String groupValue = this.groupMapping.getProperty(groupKey);
                                sids.add(groupValue);
                            }
                        }
                    }

                }
            }
        }
        debug("Groups assigned from PAC : {0}", sids);

        // Return the group sids as an array
        final String[] idsArray = new String[sids.size()];
        return sids.toArray(idsArray);

    } catch (final Exception e) {
        // In any case it will just fail to prevent any groups from beeing
        // fetched
        debugToken("Failed to fetch credential from PAC with service token {0}", serviceToken);
        LOG.log(Level.WARNING, "Unable to get the groups from the given PAC, will return null to the caller",
                e);
        return null;
    }

}

From source file:com.flexive.tests.embedded.cmis.CmisSearchEngineTest.java

private int getExpectedPartialMatches(CmisResultSet result, final List<FxSelectListItem> queryItems) {
    return Iterables.size(Iterables.filter(result, new Predicate<CmisResultRow>() {
        @Override/*from  w  w  w . ja  va2 s . c  om*/
        public boolean apply(CmisResultRow row) {
            final SelectMany selectMany = (SelectMany) row.getColumn(2).getValue();
            return !Collections.disjoint(queryItems, selectMany.getSelected());
        }
    }));
}

From source file:org.apache.hadoop.hbase.regionserver.HStore.java

/** Adds the files to compacting files. filesCompacting must be locked. */
private void addToCompactingFiles(final Collection<StoreFile> filesToAdd) {
    if (filesToAdd == null)
        return;//from  w w  w  .  ja  v  a 2 s  .c  om
    // Check that we do not try to compact the same StoreFile twice.
    if (!Collections.disjoint(filesCompacting, filesToAdd)) {
        Preconditions.checkArgument(false, "%s overlaps with %s", filesToAdd, filesCompacting);
    }
    filesCompacting.addAll(filesToAdd);
    Collections.sort(filesCompacting, StoreFile.Comparators.SEQ_ID);
}

From source file:org.talend.mdm.webapp.browserecords.server.actions.BrowseRecordsAction.java

@Override
public List<ItemBaseModel> getViewsList(String language) throws ServiceException {
    try {//  w w  w.  j  a va2s . c  om
        Map<String, String> unsortedViewsMap = new HashMap<String, String>();
        String model = getCurrentDataModel();
        if (model != null) {
            MetadataRepository repository = ServerContext.INSTANCE.get().getMetadataRepositoryAdmin()
                    .get(model);
            Set<String> userRoles = LocalUser.getLocalUser().getRoles();
            // It is faster to retrieve all view then look on them (alternatives imply "search by exception").
            WSViewPKArray viewPKs = CommonUtil.getPort().getViewPKs(new WSGetViewPKs(".*")); //$NON-NLS-1$
            for (WSViewPK viewPK : viewPKs.getWsViewPK()) {
                String typeName = ViewHelper.getConceptFromDefaultViewName(viewPK.getPk());
                ComplexTypeMetadata type = repository.getComplexType(typeName);
                if (type != null) {
                    // Hides the entity if at least one of user's role is in the "hide" roles (i.e. "No Access"
                    // roles).
                    if (type.getHideUsers().isEmpty() || Collections.disjoint(type.getHideUsers(), userRoles)) {
                        WSView view = CommonUtil.getPort().getView(new WSGetView(viewPK));
                        String viewLabel = ViewHelper.getViewLabel(language, view);
                        unsortedViewsMap.put(view.getName(), viewLabel);
                    }
                }
            }
        }
        // Filter based on access roles on views
        Util.filterAuthViews(unsortedViewsMap);
        // Build results for web UI
        return getViewsListOrderedByLabels(unsortedViewsMap);
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        throw new ServiceException(e.getLocalizedMessage());
    }
}

From source file:org.opencb.opencga.storage.mongodb.variant.VariantMongoDBAdaptor.java

private DocumentToVariantConverter getDocumentToVariantConverter(Query query, QueryOptions options) {
    List<Integer> studyIds = utils.getStudyIds(query.getAsList(VariantQueryParams.STUDIES.key(), ",|;"),
            options);/*from   w w  w. j a  v  a2 s .  c  om*/

    DocumentToSamplesConverter samplesConverter;
    if (studyIds.isEmpty()) {
        samplesConverter = new DocumentToSamplesConverter(studyConfigurationManager);
    } else {
        List<StudyConfiguration> studyConfigurations = new LinkedList<>();
        for (Integer studyId : studyIds) {
            QueryResult<StudyConfiguration> queryResult = studyConfigurationManager
                    .getStudyConfiguration(studyId, options);
            if (queryResult.getResult().isEmpty()) {
                throw VariantQueryException.studyNotFound(studyId);
                //                    throw new IllegalArgumentException("Couldn't find studyConfiguration for StudyId '" + studyId + "'");
            } else {
                studyConfigurations.add(queryResult.first());
            }
        }
        samplesConverter = new DocumentToSamplesConverter(studyConfigurations);
    }
    if (query.containsKey(VariantQueryParams.UNKNOWN_GENOTYPE.key())) {
        samplesConverter.setReturnedUnknownGenotype(query.getString(VariantQueryParams.UNKNOWN_GENOTYPE.key()));
    }

    samplesConverter.setReturnedSamples(utils.getReturnedSamples(query, options));

    DocumentToStudyVariantEntryConverter studyEntryConverter;
    Collection<Integer> returnedFiles;
    if (!Collections.disjoint(options.getAsStringList(QueryOptions.EXCLUDE),
            DocumentToVariantConverter.EXCLUDE_STUDIES_FILES_FIELD)) {
        returnedFiles = Collections.emptyList();
    } else if (query.containsKey(VariantQueryParams.RETURNED_FILES.key())) {
        returnedFiles = query.getAsIntegerList(VariantQueryParams.RETURNED_FILES.key());
    } else {
        returnedFiles = null;
    }

    studyEntryConverter = new DocumentToStudyVariantEntryConverter(false, returnedFiles, samplesConverter);
    studyEntryConverter.setStudyConfigurationManager(studyConfigurationManager);
    List<Integer> returnedStudies = query.containsKey(VariantQueryParams.RETURNED_STUDIES.key())
            ? utils.getStudyIds(query.getAsList(VariantQueryParams.RETURNED_STUDIES.key()), options)
            : null;
    return new DocumentToVariantConverter(studyEntryConverter,
            new DocumentToVariantStatsConverter(studyConfigurationManager), returnedStudies);
}

From source file:forge.game.card.Card.java

@Override
public boolean hasProperty(final String property, final Player sourceController, final Card source) {
    final Game game = getGame();
    final Combat combat = game.getCombat();
    // 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;
        }//ww w.  java 2  s.co m
    } else if (property.startsWith("notnamed")) {
        if (getName().equals(property.substring(8))) {
            return false;
        }
    } else if (property.startsWith("sameName")) {
        if (getName().equals("") || !getName().equals(source.getName())) {
            return false;
        }
    } else if (property.equals("NamedCard")) {
        if (!getName().equals(source.getNamedCard())) {
            return false;
        }
    } else if (property.equals("NamedByRememberedPlayer")) {
        if (!source.hasRemembered()) {
            final Card newCard = game.getCardState(source);
            for (final Object o : newCard.getRemembered()) {
                if (o instanceof Player) {
                    if (!getName().equals(((Player) o).getNamedCard())) {
                        return false;
                    }
                }
            }
        }
        for (final Object o : source.getRemembered()) {
            if (o instanceof Player) {
                if (!getName().equals(((Player) o).getNamedCard())) {
                    return false;
                }
            }
        }
    } else if (property.equals("Permanent")) {
        if (isInstant() || isSorcery()) {
            return false;
        }
    } else if (property.startsWith("CardUID_")) {// Protection with "doesn't remove effect"
        if (id != Integer.parseInt(property.split("CardUID_")[1])) {
            return false;
        }
    } else if (property.equals("ChosenCard")) {
        if (!source.hasChosenCard(this)) {
            return false;
        }
    } else if (property.equals("nonChosenCard")) {
        if (source.hasChosenCard(this)) {
            return false;
        }
    }
    // ... Card colors
    else if (property.contains("White") || property.contains("Blue") || property.contains("Black")
            || property.contains("Red") || property.contains("Green")) {
        boolean mustHave = !property.startsWith("non");
        int desiredColor = MagicColor.fromName(mustHave ? property : property.substring(3));
        boolean hasColor = CardUtil.getColors(this).hasAnyColor(desiredColor);
        if (mustHave != hasColor)
            return false;

    } else if (property.contains("Colorless")) { // ... Card is colorless
        if (property.startsWith("non") == CardUtil.getColors(this).isColorless())
            return false;

    } else if (property.contains("MultiColor")) { // ... Card is multicolored
        if (property.startsWith("non") == CardUtil.getColors(this).isMulticolor())
            return false;

    } else if (property.contains("MonoColor")) { // ... Card is monocolored
        if (property.startsWith("non") == CardUtil.getColors(this).isMonoColor())
            return false;

    } else if (property.equals("ChosenColor")) {
        if (!source.hasChosenColor()
                || !CardUtil.getColors(this).hasAnyColor(MagicColor.fromName(source.getChosenColor())))
            return false;

    } else if (property.equals("AllChosenColors")) {
        if (!source.hasChosenColor() || !CardUtil.getColors(this)
                .hasAllColors(ColorSet.fromNames(source.getChosenColors()).getColor()))
            return false;

    } else if (property.equals("AnyChosenColor")) {
        if (!source.hasChosenColor() || !CardUtil.getColors(this)
                .hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()))
            return false;

    } else if (property.equals("DoubleFaced")) {
        if (!isDoubleFaced()) {
            return false;
        }
    } else if (property.equals("Flip")) {
        if (!isFlipCard()) {
            return false;
        }
    } else if (property.startsWith("YouCtrl")) {
        if (!getController().equals(sourceController)) {
            return false;
        }
    } else if (property.startsWith("YouDontCtrl")) {
        if (getController().equals(sourceController)) {
            return false;
        }
    } else if (property.startsWith("OppCtrl")) {
        if (!getController().getOpponents().contains(sourceController)) {
            return false;
        }
    } else if (property.startsWith("ChosenCtrl")) {
        if (!getController().equals(source.getChosenPlayer())) {
            return false;
        }
    } else if (property.startsWith("DefenderCtrl")) {
        if (!game.getPhaseHandler().inCombat()) {
            return false;
        }
        if (property.endsWith("ForRemembered")) {
            if (!source.hasRemembered()) {
                return false;
            }
            if (getGame().getCombat()
                    .getDefendingPlayerRelatedTo((Card) source.getFirstRemembered()) != getController()) {
                return false;
            }
        } else {
            if (getGame().getCombat().getDefendingPlayerRelatedTo(source) != getController()) {
                return false;
            }
        }
    } else if (property.startsWith("DefendingPlayerCtrl")) {
        if (!game.getPhaseHandler().inCombat()) {
            return false;
        }
        if (!getGame().getCombat().isPlayerAttacked(getController())) {
            return false;
        }
    } else if (property.startsWith("EnchantedPlayerCtrl")) {
        final Object o = source.getEnchanting();
        if (o instanceof Player) {
            if (!getController().equals(o)) {
                return false;
            }
        } else { // source not enchanting a player
            return false;
        }
    } else if (property.startsWith("EnchantedControllerCtrl")) {
        final Object o = source.getEnchanting();
        if (o instanceof Card) {
            if (!getController().equals(((Card) o).getController())) {
                return false;
            }
        } else { // source not enchanting a card
            return false;
        }
    } else if (property.startsWith("RememberedPlayer")) {
        Player p = property.endsWith("Ctrl") ? getController() : getOwner();
        if (!source.hasRemembered()) {
            final Card newCard = game.getCardState(source);
            for (final Object o : newCard.getRemembered()) {
                if (o instanceof Player) {
                    if (!p.equals(o)) {
                        return false;
                    }
                }
            }
        }

        for (final Object o : source.getRemembered()) {
            if (o instanceof Player) {
                if (!p.equals(o)) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("nonRememberedPlayerCtrl")) {
        if (!source.hasRemembered()) {
            final Card newCard = game.getCardState(source);
            if (newCard.isRemembered(getController())) {
                return false;
            }
        }

        if (source.isRemembered(getController())) {
            return false;
        }
    } else if (property.equals("TargetedPlayerCtrl")) {
        for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
            final SpellAbility saTargeting = sa.getSATargetingPlayer();
            if (saTargeting != null) {
                for (final Player p : saTargeting.getTargets().getTargetPlayers()) {
                    if (!getController().equals(p)) {
                        return false;
                    }
                }
            }
        }
    } else if (property.equals("TargetedControllerCtrl")) {
        for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
            final CardCollectionView cards = AbilityUtils.getDefinedCards(source, "Targeted", sa);
            final List<SpellAbility> sas = AbilityUtils.getDefinedSpellAbilities(source, "Targeted", sa);
            for (final Card c : cards) {
                final Player p = c.getController();
                if (!getController().equals(p)) {
                    return false;
                }
            }
            for (final SpellAbility s : sas) {
                final Player p = s.getHostCard().getController();
                if (!getController().equals(p)) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("ActivePlayerCtrl")) {
        if (!game.getPhaseHandler().isPlayerTurn(getController())) {
            return false;
        }
    } else if (property.startsWith("NonActivePlayerCtrl")) {
        if (game.getPhaseHandler().isPlayerTurn(getController())) {
            return false;
        }
    } else if (property.startsWith("YouOwn")) {
        if (!getOwner().equals(sourceController)) {
            return false;
        }
    } else if (property.startsWith("YouDontOwn")) {
        if (getOwner().equals(sourceController)) {
            return false;
        }
    } else if (property.startsWith("OppOwn")) {
        if (!getOwner().getOpponents().contains(sourceController)) {
            return false;
        }
    } else if (property.equals("TargetedPlayerOwn")) {
        for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
            final SpellAbility saTargeting = sa.getSATargetingPlayer();
            if (saTargeting != null) {
                for (final Player p : saTargeting.getTargets().getTargetPlayers()) {
                    if (!getOwner().equals(p)) {
                        return false;
                    }
                }
            }
        }
    } else if (property.startsWith("OwnedBy")) {
        final String valid = property.substring(8);
        if (!getOwner().isValid(valid, sourceController, source)) {
            return false;
        }
    } else if (property.startsWith("ControlledBy")) {
        final String valid = property.substring(13);
        if (!getController().isValid(valid, sourceController, source)) {
            return false;
        }
    } else if (property.startsWith("OwnerDoesntControl")) {
        if (getOwner().equals(getController())) {
            return false;
        }
    } else if (property.startsWith("ControllerControls")) {
        final String type = property.substring(18);
        if (type.startsWith("AtLeastAsMany")) {
            String realType = type.split("AtLeastAsMany")[1];
            CardCollectionView cards = CardLists.getType(getController().getCardsIn(ZoneType.Battlefield),
                    realType);
            CardCollectionView yours = CardLists.getType(sourceController.getCardsIn(ZoneType.Battlefield),
                    realType);
            if (cards.size() < yours.size()) {
                return false;
            }
        } else {
            final CardCollectionView cards = getController().getCardsIn(ZoneType.Battlefield);
            if (CardLists.getType(cards, type).isEmpty()) {
                return false;
            }
        }
    } else if (property.startsWith("Other")) {
        if (equals(source)) {
            return false;
        }
    } else if (property.startsWith("Self")) {
        if (!equals(source)) {
            return false;
        }
    } else if (property.startsWith("AttachedBy")) {
        if (!isEquippedBy(source) && !isEnchantedBy(source) && !isFortifiedBy(source)) {
            return false;
        }
    } else if (property.equals("Attached")) {
        if (equipping != source && !source.equals(enchanting) && fortifying != source) {
            return false;
        }
    } else if (property.startsWith("AttachedTo")) {
        final String restriction = property.split("AttachedTo ")[1];
        if (restriction.equals("Targeted")) {
            if (!source.currentState.getTriggers().isEmpty()) {
                for (final Trigger t : source.currentState.getTriggers()) {
                    final SpellAbility sa = t.getTriggeredSA();
                    final CardCollectionView cards = AbilityUtils.getDefinedCards(source, "Targeted", sa);
                    for (final Card c : cards) {
                        if (equipping != c && !c.equals(enchanting)) {
                            return false;
                        }
                    }
                }
            } else {
                for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                    final CardCollectionView cards = AbilityUtils.getDefinedCards(source, "Targeted", sa);
                    for (final Card c : cards) {
                        if (equipping == c || c.equals(enchanting)) { // handle multiple targets
                            return true;
                        }
                    }
                }
                return false;
            }
        } else {
            if ((enchanting == null || !enchanting.isValid(restriction, sourceController, source))
                    && (equipping == null || !equipping.isValid(restriction, sourceController, source))
                    && (fortifying == null || !fortifying.isValid(restriction, sourceController, source))) {
                return false;
            }
        }
    } else if (property.equals("NameNotEnchantingEnchantedPlayer")) {
        Player enchantedPlayer = source.getEnchantingPlayer();
        if (enchantedPlayer == null) {
            return false;
        }
        for (Card c : enchantedPlayer.getEnchantedBy(false)) {
            if (getName().equals(c.getName())) {
                return false;
            }
        }
    } else if (property.equals("NotAttachedTo")) {
        if (equipping == source || source.equals(enchanting) || fortifying == source) {
            return false;
        }
    } else if (property.startsWith("EnchantedBy")) {
        if (property.equals("EnchantedBy")) {
            if (!isEnchantedBy(source) && !equals(source.getEnchanting())) {
                return false;
            }
        } else {
            final String restriction = property.split("EnchantedBy ")[1];
            switch (restriction) {
            case "Imprinted":
                for (final Card card : source.getImprintedCards()) {
                    if (!isEnchantedBy(card) && !equals(card.getEnchanting())) {
                        return false;
                    }
                }
                break;
            case "Targeted":
                for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                    final SpellAbility saTargeting = sa.getSATargetingCard();
                    if (saTargeting != null) {
                        for (final Card c : saTargeting.getTargets().getTargetCards()) {
                            if (!isEnchantedBy(c) && !equals(c.getEnchanting())) {
                                return false;
                            }
                        }
                    }
                }
                break;
            default: // EnchantedBy Aura.Other
                for (final Card aura : getEnchantedBy(false)) {
                    if (aura.isValid(restriction, sourceController, source)) {
                        return true;
                    }
                }
                return false;
            }
        }
    } else if (property.startsWith("NotEnchantedBy")) {
        if (property.substring(14).equals("Targeted")) {
            for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                final SpellAbility saTargeting = sa.getSATargetingCard();
                if (saTargeting != null) {
                    for (final Card c : saTargeting.getTargets().getTargetCards()) {
                        if (isEnchantedBy(c)) {
                            return false;
                        }
                    }
                }
            }
        } else {
            if (isEnchantedBy(source)) {
                return false;
            }
        }
    } else if (property.startsWith("Enchanted")) {
        if (!source.equals(enchanting)) {
            return false;
        }
    } else if (property.startsWith("CanEnchant")) {
        final String restriction = property.substring(10);
        if (restriction.equals("Remembered")) {
            for (final Object rem : source.getRemembered()) {
                if (!(rem instanceof Card) || !((Card) rem).canBeEnchantedBy(this))
                    return false;
            }
        } else if (restriction.equals("Source")) {
            if (!source.canBeEnchantedBy(this))
                return false;
        }
    } else if (property.startsWith("CanBeEnchantedBy")) {
        if (property.substring(16).equals("Targeted")) {
            for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                final SpellAbility saTargeting = sa.getSATargetingCard();
                if (saTargeting != null) {
                    for (final Card c : saTargeting.getTargets().getTargetCards()) {
                        if (!canBeEnchantedBy(c)) {
                            return false;
                        }
                    }
                }
            }
        } else if (property.substring(16).equals("AllRemembered")) {
            for (final Object rem : source.getRemembered()) {
                if (rem instanceof Card) {
                    final Card card = (Card) rem;
                    if (!canBeEnchantedBy(card)) {
                        return false;
                    }
                }
            }
        } else {
            if (!canBeEnchantedBy(source)) {
                return false;
            }
        }
    } else if (property.startsWith("EquippedBy")) {
        if (property.substring(10).equals("Targeted")) {
            for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                final SpellAbility saTargeting = sa.getSATargetingCard();
                if (saTargeting != null) {
                    for (final Card c : saTargeting.getTargets().getTargetCards()) {
                        if (!isEquippedBy(c)) {
                            return false;
                        }
                    }
                }
            }
        } else if (property.substring(10).equals("Enchanted")) {
            if (source.getEnchantingCard() == null || !isEquippedBy(source.getEnchantingCard())) {
                return false;
            }
        } else {
            if (!isEquippedBy(source)) {
                return false;
            }
        }
    } else if (property.startsWith("FortifiedBy")) {
        if (!isFortifiedBy(source)) {
            return false;
        }
    } else if (property.startsWith("CanBeEquippedBy")) {
        if (!canBeEquippedBy(source)) {
            return false;
        }
    } else if (property.startsWith("Equipped")) {
        if (equipping != source) {
            return false;
        }
    } else if (property.startsWith("Fortified")) {
        if (fortifying != source) {
            return false;
        }
    } else if (property.startsWith("HauntedBy")) {
        if (!isHauntedBy(source)) {
            return false;
        }
    } else if (property.startsWith("notTributed")) {
        if (tributed) {
            return false;
        }
    } else if (property.startsWith("madness")) {
        if (!madness) {
            return false;
        }
    } else if (property.contains("Paired")) {
        if (property.contains("With")) { // PairedWith
            if (!isPaired() || pairedWith != source) {
                return false;
            }
        } else if (property.startsWith("Not")) { // NotPaired
            if (isPaired()) {
                return false;
            }
        } else { // Paired
            if (!isPaired()) {
                return false;
            }
        }
    } else if (property.startsWith("Above")) { // "Are Above" Source
        final CardCollectionView cards = getOwner().getCardsIn(ZoneType.Graveyard);
        if (cards.indexOf(source) >= cards.indexOf(this)) {
            return false;
        }
    } else if (property.startsWith("DirectlyAbove")) { // "Are Directly Above" Source
        final CardCollectionView cards = getOwner().getCardsIn(ZoneType.Graveyard);
        if (cards.indexOf(this) - cards.indexOf(source) != 1) {
            return false;
        }
    } else if (property.startsWith("TopGraveyardCreature")) {
        CardCollection cards = CardLists.filter(getOwner().getCardsIn(ZoneType.Graveyard),
                CardPredicates.Presets.CREATURES);
        Collections.reverse(cards);
        if (cards.isEmpty() || !equals(cards.get(0))) {
            return false;
        }
    } else if (property.startsWith("TopGraveyard")) {
        final CardCollection cards = new CardCollection(getOwner().getCardsIn(ZoneType.Graveyard));
        Collections.reverse(cards);
        if (property.substring(12).matches("[0-9][0-9]?")) {
            int n = Integer.parseInt(property.substring(12));
            int num = Math.min(n, cards.size());
            final CardCollection newlist = new CardCollection();
            for (int i = 0; i < num; i++) {
                newlist.add(cards.get(i));
            }
            if (cards.isEmpty() || !newlist.contains(this)) {
                return false;
            }
        } else {
            if (cards.isEmpty() || !equals(cards.get(0))) {
                return false;
            }
        }
    } else if (property.startsWith("BottomGraveyard")) {
        final CardCollectionView cards = getOwner().getCardsIn(ZoneType.Graveyard);
        if (cards.isEmpty() || !equals(cards.get(0))) {
            return false;
        }
    } else if (property.startsWith("TopLibrary")) {
        final CardCollectionView cards = getOwner().getCardsIn(ZoneType.Library);
        if (cards.isEmpty() || !equals(cards.get(0))) {
            return false;
        }
    } else if (property.startsWith("Cloned")) {
        if ((cloneOrigin == null) || !cloneOrigin.equals(source)) {
            return false;
        }
    } else if (property.startsWith("DamagedBy")) {
        if ((property.endsWith("Source") || property.equals("DamagedBy"))
                && !receivedDamageFromThisTurn.containsKey(source)) {
            return false;
        } else if (property.endsWith("Remembered")) {
            boolean matched = false;
            for (final Object obj : source.getRemembered()) {
                if (!(obj instanceof Card)) {
                    continue;
                }
                matched |= receivedDamageFromThisTurn.containsKey(obj);
            }
            if (!matched)
                return false;
        }
    } else if (property.startsWith("Damaged")) {
        if (!dealtDamageToThisTurn.containsKey(source)) {
            return false;
        }
    } else if (property.startsWith("IsTargetingSource")) {
        for (final SpellAbility sa : currentState.getNonManaAbilities()) {
            final SpellAbility saTargeting = sa.getSATargetingCard();
            if (saTargeting != null) {
                for (final Card c : saTargeting.getTargets().getTargetCards()) {
                    if (c.equals(source)) {
                        return true;
                    }
                }
            }
        }
        return false;
    } else if (property.startsWith("SharesColorWith")) {
        if (property.equals("SharesColorWith")) {
            if (!sharesColorWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("SharesColorWith ")[1];
            switch (restriction) {
            case "TopCardOfLibrary":
                final CardCollectionView cards = sourceController.getCardsIn(ZoneType.Library);
                if (cards.isEmpty() || !sharesColorWith(cards.get(0))) {
                    return false;
                }
                break;
            case "Remembered":
                for (final Object obj : source.getRemembered()) {
                    if (!(obj instanceof Card) || !sharesColorWith((Card) obj)) {
                        return false;
                    }
                }
                break;
            case "Imprinted":
                for (final Card card : source.getImprintedCards()) {
                    if (!sharesColorWith(card)) {
                        return false;
                    }
                }
                break;
            case "Equipped":
                if (!source.isEquipment() || !source.isEquipping() || !sharesColorWith(source.getEquipping())) {
                    return false;
                }
                break;
            case "MostProminentColor":
                byte mask = CardFactoryUtil.getMostProminentColors(game.getCardsIn(ZoneType.Battlefield));
                if (!CardUtil.getColors(this).hasAnyColor(mask))
                    return false;
                break;
            case "LastCastThisTurn":
                final List<Card> c = game.getStack().getSpellsCastThisTurn();
                if (c.isEmpty() || !sharesColorWith(c.get(c.size() - 1))) {
                    return false;
                }
                break;
            case "ActivationColor":
                byte manaSpent = source.getColorsPaid();
                if (!CardUtil.getColors(this).hasAnyColor(manaSpent)) {
                    return false;
                }
                break;
            default:
                for (final Card card : sourceController.getCardsIn(ZoneType.Battlefield)) {
                    if (card.isValid(restriction, sourceController, source) && sharesColorWith(card)) {
                        return true;
                    }
                }
                return false;
            }
        }
    } else if (property.startsWith("MostProminentColor")) {
        // MostProminentColor <color>
        // e.g. MostProminentColor black
        String[] props = property.split(" ");
        if (props.length == 1) {
            System.out.println("WARNING! Using MostProminentColor property without a color.");
            return false;
        }
        String color = props[1];

        byte mostProm = CardFactoryUtil.getMostProminentColors(game.getCardsIn(ZoneType.Battlefield));
        return ColorSet.fromMask(mostProm).hasAnyColor(MagicColor.fromName(color));
    } else if (property.startsWith("notSharesColorWith")) {
        if (property.equals("notSharesColorWith")) {
            if (sharesColorWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("notSharesColorWith ")[1];
            for (final Card card : sourceController.getCardsIn(ZoneType.Battlefield)) {
                if (card.isValid(restriction, sourceController, source) && sharesColorWith(card)) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("sharesCreatureTypeWith")) {
        if (property.equals("sharesCreatureTypeWith")) {
            if (!sharesCreatureTypeWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesCreatureTypeWith ")[1];
            switch (restriction) {
            case "TopCardOfLibrary":
                final CardCollectionView cards = sourceController.getCardsIn(ZoneType.Library);
                if (cards.isEmpty() || !sharesCreatureTypeWith(cards.get(0))) {
                    return false;
                }
                break;
            case "Enchanted":
                for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                    final SpellAbility root = sa.getRootAbility();
                    Card c = source.getEnchantingCard();
                    if ((c == null) && (root != null) && (root.getPaidList("Sacrificed") != null)
                            && !root.getPaidList("Sacrificed").isEmpty()) {
                        c = root.getPaidList("Sacrificed").get(0).getEnchantingCard();
                        if (!sharesCreatureTypeWith(c)) {
                            return false;
                        }
                    }
                }
                break;
            case "Equipped":
                if (source.isEquipping() && sharesCreatureTypeWith(source.getEquipping())) {
                    return true;
                }
                return false;
            case "Remembered":
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (sharesCreatureTypeWith(card)) {
                            return true;
                        }
                    }
                }
                return false;
            case "AllRemembered":
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (!sharesCreatureTypeWith(card)) {
                            return false;
                        }
                    }
                }
                break;
            default:
                boolean shares = false;
                for (final Card card : sourceController.getCardsIn(ZoneType.Battlefield)) {
                    if (card.isValid(restriction, sourceController, source) && sharesCreatureTypeWith(card)) {
                        shares = true;
                    }
                }
                if (!shares) {
                    return false;
                }
                break;
            }
        }
    } else if (property.startsWith("sharesCardTypeWith")) {
        if (property.equals("sharesCardTypeWith")) {
            if (!sharesCardTypeWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesCardTypeWith ")[1];
            switch (restriction) {
            case "Imprinted":
                if (!source.hasImprintedCard()
                        || !sharesCardTypeWith(Iterables.getFirst(source.getImprintedCards(), null))) {
                    return false;
                }
                break;
            case "Remembered":
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (sharesCardTypeWith(card)) {
                            return true;
                        }
                    }
                }
                return false;
            case "EachTopLibrary":
                final CardCollection cards = new CardCollection();
                for (Player p : game.getPlayers()) {
                    final Card top = p.getCardsIn(ZoneType.Library).get(0);
                    cards.add(top);
                }
                for (Card c : cards) {
                    if (sharesCardTypeWith(c)) {
                        return true;
                    }
                }
                return false;
            }
        }
    } else if (property.equals("sharesPermanentTypeWith")) {
        if (!sharesPermanentTypeWith(source)) {
            return false;
        }
    } else if (property.equals("canProduceSameManaTypeWith")) {
        if (!canProduceSameManaTypeWith(source)) {
            return false;
        }
    } else if (property.startsWith("sharesNameWith")) {
        if (property.equals("sharesNameWith")) {
            if (!getName().equals(source.getName())) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesNameWith ")[1];
            if (restriction.equals("YourGraveyard")) {
                for (final Card card : sourceController.getCardsIn(ZoneType.Graveyard)) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            } else if (restriction.equals(ZoneType.Graveyard.toString())) {
                for (final Card card : game.getCardsIn(ZoneType.Graveyard)) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            } else if (restriction.equals(ZoneType.Battlefield.toString())) {
                for (final Card card : game.getCardsIn(ZoneType.Battlefield)) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            } else if (restriction.equals("ThisTurnCast")) {
                for (final Card card : CardUtil.getThisTurnCast("Card", source)) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            } else if (restriction.equals("Remembered")) {
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (getName().equals(card.getName())) {
                            return true;
                        }
                    }
                }
                return false;
            } else if (restriction.equals("Imprinted")) {
                for (final Card card : source.getImprintedCards()) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            } else if (restriction.equals("MovedToGrave")) {
                for (final SpellAbility sa : source.currentState.getNonManaAbilities()) {
                    final SpellAbility root = sa.getRootAbility();
                    if (root != null && (root.getPaidList("MovedToGrave") != null)
                            && !root.getPaidList("MovedToGrave").isEmpty()) {
                        final CardCollectionView cards = root.getPaidList("MovedToGrave");
                        for (final Card card : cards) {
                            String name = card.getName();
                            if (StringUtils.isEmpty(name)) {
                                name = card.getPaperCard().getName();
                            }
                            if (getName().equals(name)) {
                                return true;
                            }
                        }
                    }
                }
                return false;
            } else if (restriction.equals("NonToken")) {
                final CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
                        Presets.NON_TOKEN);
                for (final Card card : cards) {
                    if (getName().equals(card.getName())) {
                        return true;
                    }
                }
                return false;
            }
        }
    } else if (property.startsWith("doesNotShareNameWith")) {
        if (property.equals("doesNotShareNameWith")) {
            if (getName().equals(source.getName())) {
                return false;
            }
        } else {
            final String restriction = property.split("doesNotShareNameWith ")[1];
            if (restriction.equals("Remembered")) {
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (getName().equals(card.getName())) {
                            return false;
                        }
                    }
                }
            }
        }
    } else if (property.startsWith("sharesControllerWith")) {
        if (property.equals("sharesControllerWith")) {
            if (!sharesControllerWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesControllerWith ")[1];
            if (restriction.equals("Remembered")) {
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (!sharesControllerWith(card)) {
                            return false;
                        }
                    }
                }
            } else if (restriction.equals("Imprinted")) {
                for (final Card card : source.getImprintedCards()) {
                    if (!sharesControllerWith(card)) {
                        return false;
                    }
                }
            }
        }
    } else if (property.startsWith("sharesOwnerWith")) {
        if (property.equals("sharesOwnerWith")) {
            if (!getOwner().equals(source.getOwner())) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesOwnerWith ")[1];
            if (restriction.equals("Remembered")) {
                for (final Object rem : source.getRemembered()) {
                    if (rem instanceof Card) {
                        final Card card = (Card) rem;
                        if (!getOwner().equals(card.getOwner())) {
                            return false;
                        }
                    }
                }
            }
        }
    } else if (property.startsWith("SecondSpellCastThisTurn")) {
        final CardCollectionView cards = CardUtil.getThisTurnCast("Card", source);
        if (cards.size() < 2) {
            return false;
        } else if (cards.get(1) != this) {
            return false;
        }
    } else if (property.equals("ThisTurnCast")) {
        for (final Card card : CardUtil.getThisTurnCast("Card", source)) {
            if (equals(card)) {
                return true;
            }
        }
        return false;
    } else if (property.startsWith("ThisTurnEntered")) {
        final String restrictions = property.split("ThisTurnEntered_")[1];
        final String[] res = restrictions.split("_");
        final ZoneType destination = ZoneType.smartValueOf(res[0]);
        ZoneType origin = null;
        if (res.length > 1 && res[1].equals("from")) {
            origin = ZoneType.smartValueOf(res[2]);
        }
        CardCollectionView cards = CardUtil.getThisTurnEntered(destination, origin, "Card", source);
        if (!cards.contains(this)) {
            return false;
        }
    } else if (property.startsWith("ControlledByPlayerInTheDirection")) {
        final String restrictions = property.split("ControlledByPlayerInTheDirection_")[1];
        final String[] res = restrictions.split("_");
        final Direction direction = Direction.valueOf(res[0]);
        Player p = null;
        if (res.length > 1) {
            for (Player pl : game.getPlayers()) {
                if (pl.isValid(res[1], sourceController, source)) {
                    p = pl;
                    break;
                }
            }
        } else {
            p = sourceController;
        }
        if (p == null || !getController().equals(game.getNextPlayerAfter(p, direction))) {
            return false;
        }
    } else if (property.startsWith("sharesTypeWith")) {
        if (property.equals("sharesTypeWith")) {
            if (!sharesTypeWith(source)) {
                return false;
            }
        } else {
            final String restriction = property.split("sharesTypeWith ")[1];
            final Card checkCard;
            if (restriction.startsWith("Triggered")) {
                final Object triggeringObject = source
                        .getTriggeringObject(restriction.substring("Triggered".length()));
                if (!(triggeringObject instanceof Card)) {
                    return false;
                }
                checkCard = (Card) triggeringObject;
            } else {
                return false;
            }

            if (!sharesTypeWith(checkCard)) {
                return false;
            }
        }
    } else if (property.startsWith("hasKeyword")) {
        // "withFlash" would find Flashback cards, add this to fix Mystical Teachings
        if (!hasKeyword(property.substring(10))) {
            return false;
        }
    } else if (property.startsWith("withFlashback")) {
        boolean fb = false;
        if (hasStartOfUnHiddenKeyword("Flashback")) {
            fb = true;
        }
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.isFlashBackAbility()) {
                fb = true;
            }
        }
        if (!fb) {
            return false;
        }
    } else if (property.startsWith("with")) {
        // ... Card keywords
        if (property.startsWith("without") && hasStartOfUnHiddenKeyword(property.substring(7))) {
            return false;
        }
        if (!property.startsWith("without") && !hasStartOfUnHiddenKeyword(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("faceUp")) {
        if (isFaceDown()) {
            return false;
        }
    } else if (property.startsWith("hasLevelUp")) {
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.getApi() == ApiType.PutCounter && sa.hasParam("LevelUp")) {
                return true;
            }
        }
        return false;
    } else if (property.startsWith("DrawnThisTurn")) {
        if (!getDrawnThisTurn()) {
            return false;
        }
    } else if (property.startsWith("enteredBattlefieldThisTurn")) {
        if (!(getTurnInZone() == game.getPhaseHandler().getTurn())) {
            return false;
        }
    } else if (property.startsWith("notEnteredBattlefieldThisTurn")) {
        if (getTurnInZone() == game.getPhaseHandler().getTurn()) {
            return false;
        }
    } else if (property.startsWith("firstTurnControlled")) {
        if (!isFirstTurnControlled()) {
            return false;
        }
    } else if (property.startsWith("notFirstTurnControlled")) {
        if (isFirstTurnControlled()) {
            return false;
        }
    } else if (property.startsWith("startedTheTurnUntapped")) {
        if (!hasStartedTheTurnUntapped()) {
            return false;
        }
    } else if (property.startsWith("cameUnderControlSinceLastUpkeep")) {
        if (!cameUnderControlSinceLastUpkeep()) {
            return false;
        }
    } else if (property.equals("attackedOrBlockedSinceYourLastUpkeep")) {
        if (!getDamageHistory().hasAttackedSinceLastUpkeepOf(sourceController)
                && !getDamageHistory().hasBlockedSinceLastUpkeepOf(sourceController)) {
            return false;
        }
    } else if (property.equals("blockedOrBeenBlockedSinceYourLastUpkeep")) {
        if (!getDamageHistory().hasBeenBlockedSinceLastUpkeepOf(sourceController)
                && !getDamageHistory().hasBlockedSinceLastUpkeepOf(sourceController)) {
            return false;
        }
    } else if (property.startsWith("dealtDamageToYouThisTurn")) {
        if (!getDamageHistory().getThisTurnDamaged().contains(sourceController)) {
            return false;
        }
    } else if (property.startsWith("dealtDamageToOppThisTurn")) {
        if (!hasDealtDamageToOpponentThisTurn()) {
            return false;
        }
    } else if (property.startsWith("controllerWasDealtCombatDamageByThisTurn")) {
        if (!source.getDamageHistory().getThisTurnCombatDamaged().contains(getController())) {
            return false;
        }
    } else if (property.startsWith("controllerWasDealtDamageByThisTurn")) {
        if (!source.getDamageHistory().getThisTurnDamaged().contains(getController())) {
            return false;
        }
    } else if (property.startsWith("wasDealtDamageThisTurn")) {
        if ((getReceivedDamageFromThisTurn().keySet()).isEmpty()) {
            return false;
        }
    } else if (property.equals("wasDealtDamageByHostThisTurn")) {
        if (!getReceivedDamageFromThisTurn().keySet().contains(source)) {
            return false;
        }
    } else if (property.equals("wasDealtDamageByEquipeeThisTurn")) {
        Card equipee = source.getEquipping();
        if (equipee == null || getReceivedDamageFromThisTurn().keySet().isEmpty()
                || !getReceivedDamageFromThisTurn().keySet().contains(equipee)) {
            return false;
        }
    } else if (property.equals("wasDealtDamageByEnchantedThisTurn")) {
        Card enchanted = source.getEnchantingCard();
        if (enchanted == null || getReceivedDamageFromThisTurn().keySet().isEmpty()
                || !getReceivedDamageFromThisTurn().keySet().contains(enchanted)) {
            return false;
        }
    } else if (property.startsWith("dealtDamageThisTurn")) {
        if (getTotalDamageDoneBy() == 0) {
            return false;
        }
    } else if (property.startsWith("attackedThisTurn")) {
        if (!getDamageHistory().getCreatureAttackedThisTurn()) {
            return false;
        }
    } else if (property.startsWith("attackedLastTurn")) {
        return getDamageHistory().getCreatureAttackedLastTurnOf(getController());
    } else if (property.startsWith("blockedThisTurn")) {
        if (!getDamageHistory().getCreatureBlockedThisTurn()) {
            return false;
        }
    } else if (property.startsWith("gotBlockedThisTurn")) {
        if (!getDamageHistory().getCreatureGotBlockedThisTurn()) {
            return false;
        }
    } else if (property.startsWith("notAttackedThisTurn")) {
        if (getDamageHistory().getCreatureAttackedThisTurn()) {
            return false;
        }
    } else if (property.startsWith("notAttackedLastTurn")) {
        return !getDamageHistory().getCreatureAttackedLastTurnOf(getController());
    } else if (property.startsWith("notBlockedThisTurn")) {
        if (getDamageHistory().getCreatureBlockedThisTurn()) {
            return false;
        }
    } else if (property.startsWith("greatestPower")) {
        CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
        if (property.contains("ControlledBy")) {
            FCollectionView<Player> p = AbilityUtils.getDefinedPlayers(source,
                    property.split("ControlledBy")[1], null);
            cards = CardLists.filterControlledBy(cards, p);
            if (!cards.contains(this)) {
                return false;
            }
        }
        for (final Card crd : cards) {
            if (crd.getNetPower() > getNetPower()) {
                return false;
            }
        }
    } else if (property.startsWith("yardGreatestPower")) {
        final CardCollectionView cards = CardLists.filter(sourceController.getCardsIn(ZoneType.Graveyard),
                Presets.CREATURES);
        for (final Card crd : cards) {
            if (crd.getNetPower() > getNetPower()) {
                return false;
            }
        }
    } else if (property.startsWith("leastPower")) {
        final CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
                Presets.CREATURES);
        for (final Card crd : cards) {
            if (crd.getNetPower() < getNetPower()) {
                return false;
            }
        }
    } else if (property.startsWith("leastToughness")) {
        final CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
                Presets.CREATURES);
        for (final Card crd : cards) {
            if (crd.getNetToughness() < getNetToughness()) {
                return false;
            }
        }
    } else if (property.startsWith("greatestCMC")) {
        CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
        if (property.contains("ControlledBy")) {
            FCollectionView<Player> p = AbilityUtils.getDefinedPlayers(source,
                    property.split("ControlledBy")[1], null);
            cards = CardLists.filterControlledBy(cards, p);
            if (!cards.contains(this)) {
                return false;
            }
        }
        for (final Card crd : cards) {
            if (crd.isSplitCard()) {
                if (crd.getCMC(Card.SplitCMCMode.LeftSplitCMC) > getCMC()
                        || crd.getCMC(Card.SplitCMCMode.RightSplitCMC) > getCMC()) {
                    return false;
                }
            } else {
                if (crd.getCMC() > getCMC()) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("greatestRememberedCMC")) {
        CardCollection cards = new CardCollection();
        for (final Object o : source.getRemembered()) {
            if (o instanceof Card) {
                cards.add(game.getCardState((Card) o));
            }
        }
        if (!cards.contains(this)) {
            return false;
        }
        cards = CardLists.getCardsWithHighestCMC(cards);
        if (!cards.contains(this)) {
            return false;
        }
    } else if (property.startsWith("lowestRememberedCMC")) {
        CardCollection cards = new CardCollection();
        for (final Object o : source.getRemembered()) {
            if (o instanceof Card) {
                cards.add(game.getCardState((Card) o));
            }
        }
        if (!cards.contains(this)) {
            return false;
        }
        cards = CardLists.getCardsWithLowestCMC(cards);
        if (!cards.contains(this)) {
            return false;
        }
    } else if (property.startsWith("lowestCMC")) {
        final CardCollectionView cards = game.getCardsIn(ZoneType.Battlefield);
        for (final Card crd : cards) {
            if (!crd.isLand() && !crd.isImmutable()) {
                if (crd.isSplitCard()) {
                    if (crd.getCMC(Card.SplitCMCMode.LeftSplitCMC) < getCMC()
                            || crd.getCMC(Card.SplitCMCMode.RightSplitCMC) < getCMC()) {
                        return false;
                    }
                } else {
                    if (crd.getCMC() < getCMC()) {
                        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("hasXCost")) {
        SpellAbility sa1 = getFirstSpellAbility();
        if (sa1 != null && !sa1.isXCost()) {
            return false;
        }
    } else if (property.startsWith("suspended")) {
        if (!hasSuspend() || !game.isCardExiled(this) || !(getCounters(CounterType.getType("TIME")) >= 1)) {
            return false;
        }
    } else if (property.startsWith("delved")) {
        if (!source.getDelved().contains(this)) {
            return false;
        }
    } else if (property.startsWith("unequalPT")) {
        if (getNetPower() == getNetToughness()) {
            return false;
        }
    } else if (property.startsWith("power") || property.startsWith("toughness") || property.startsWith("cmc")
            || property.startsWith("totalPT")) {
        int x;
        int y = 0;
        int y2 = -1; // alternative value for the second split face of a split card
        String rhs = "";

        if (property.startsWith("power")) {
            rhs = property.substring(7);
            y = getNetPower();
        } else if (property.startsWith("toughness")) {
            rhs = property.substring(11);
            y = getNetToughness();
        } else if (property.startsWith("cmc")) {
            rhs = property.substring(5);
            if (isSplitCard() && getCurrentStateName() == CardStateName.Original) {
                y = getState(CardStateName.LeftSplit).getManaCost().getCMC();
                y2 = getState(CardStateName.RightSplit).getManaCost().getCMC();
            } else {
                y = getCMC();
            }
        } else if (property.startsWith("totalPT")) {
            rhs = property.substring(10);
            y = getNetPower() + getNetToughness();
        }
        try {
            x = Integer.parseInt(rhs);
        } catch (final NumberFormatException e) {
            x = CardFactoryUtil.xCount(source, source.getSVar(rhs));
        }

        if (y2 == -1) {
            if (!Expressions.compare(y, property, x)) {
                return false;
            }
        } else {
            if (!Expressions.compare(y, property, x) && !Expressions.compare(y2, 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;
        final String[] splitProperty = property.split("_");
        final String strNum = splitProperty[1].substring(2);
        final String comparator = splitProperty[1].substring(0, 2);
        String counterType;
        try {
            number = Integer.parseInt(strNum);
        } catch (final NumberFormatException e) {
            number = CardFactoryUtil.xCount(source, source.getSVar(strNum));
        }
        counterType = splitProperty[2];

        final int actualnumber = getCounters(CounterType.getType(counterType));

        if (!Expressions.compare(actualnumber, comparator, number)) {
            return false;
        }
    }
    // These predicated refer to ongoing combat. If no combat happens, they'll return false (meaning not attacking/blocking ATM)
    else if (property.startsWith("attacking")) {
        if (null == combat)
            return false;
        if (property.equals("attacking"))
            return combat.isAttacking(this);
        if (property.equals("attackingLKI"))
            return combat.isLKIAttacking(this);
        if (property.equals("attackingYou"))
            return combat.isAttacking(this, sourceController);
    } else if (property.startsWith("notattacking")) {
        return null == combat || !combat.isAttacking(this);
    } else if (property.equals("attackedThisCombat")) {
        if (null == combat || !this.getDamageHistory().getCreatureAttackedThisCombat()) {
            return false;
        }
    } else if (property.equals("attackedBySourceThisCombat")) {
        if (null == combat)
            return false;
        final GameEntity defender = combat.getDefenderByAttacker(source);
        if (defender instanceof Card && !equals(defender)) {
            return false;
        }
    } else if (property.startsWith("blocking")) {
        if (null == combat)
            return false;
        String what = property.substring("blocking".length());

        if (StringUtils.isEmpty(what))
            return combat.isBlocking(this);
        if (what.startsWith("Source"))
            return combat.isBlocking(this, source);
        if (what.startsWith("CreatureYouCtrl")) {
            for (final Card c : CardLists.filter(sourceController.getCardsIn(ZoneType.Battlefield),
                    Presets.CREATURES))
                if (combat.isBlocking(this, c))
                    return true;
            return false;
        }
        if (what.startsWith("Remembered")) {
            for (final Object o : source.getRemembered()) {
                if (o instanceof Card && combat.isBlocking(this, (Card) o)) {
                    return true;
                }
            }
            return false;
        }
    } else if (property.startsWith("sharesBlockingAssignmentWith")) {
        if (null == combat) {
            return false;
        }
        if (null == combat.getAttackersBlockedBy(source) || null == combat.getAttackersBlockedBy(this)) {
            return false;
        }

        CardCollection sourceBlocking = new CardCollection(combat.getAttackersBlockedBy(source));
        CardCollection thisBlocking = new CardCollection(combat.getAttackersBlockedBy(this));
        if (Collections.disjoint(sourceBlocking, thisBlocking)) {
            return false;
        }
    } else if (property.startsWith("notblocking")) {
        return null == combat || !combat.isBlocking(this);
    }
    // Nex predicates refer to past combat and don't need a reference to actual combat
    else if (property.equals("blocked")) {
        return null != combat && combat.isBlocked(this);
    } else if (property.startsWith("blockedBySource")) {
        return null != combat && combat.isBlocking(source, this);
    } else if (property.startsWith("blockedThisTurn")) {
        return getBlockedThisTurn() != null;
    } else if (property.startsWith("blockedByThisTurn")) {
        return getBlockedByThisTurn() != null;
    } else if (property.startsWith("blockedBySourceThisTurn")) {
        return source.blockedByThisTurn != null && source.blockedByThisTurn.contains(this);
    } else if (property.startsWith("blockedSource")) {
        return null != combat && combat.isBlocking(this, source);
    } else if (property.startsWith("isBlockedByRemembered")) {
        if (null == combat)
            return false;
        for (final Object o : source.getRemembered()) {
            if (o instanceof Card && combat.isBlocking((Card) o, this)) {
                return true;
            }
        }
        return false;
    } else if (property.startsWith("blockedRemembered")) {
        Card rememberedcard;
        for (final Object o : source.getRemembered()) {
            if (o instanceof Card) {
                rememberedcard = (Card) o;
                if (blockedThisTurn == null || !blockedThisTurn.contains(rememberedcard)) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("blockedByRemembered")) {
        Card rememberedcard;
        for (final Object o : source.getRemembered()) {
            if (o instanceof Card) {
                rememberedcard = (Card) o;
                if (blockedByThisTurn == null || !blockedByThisTurn.contains(rememberedcard)) {
                    return false;
                }
            }
        }
    } else if (property.startsWith("unblocked")) {
        if (game.getCombat() == null || !game.getCombat().isUnblocked(this)) {
            return false;
        }
    } else if (property.equals("attackersBandedWith")) {
        if (equals(source)) {
            // You don't band with yourself
            return false;
        }
        AttackingBand band = combat == null ? null : combat.getBandOfAttacker(source);
        if (band == null || !band.getAttackers().contains(this)) {
            return false;
        }
    } else if (property.startsWith("kicked")) {
        if (property.equals("kicked")) {
            if (getKickerMagnitude() == 0) {
                return false;
            }
        } else {
            String s = property.split("kicked ")[1];
            if ("1".equals(s) && !isOptionalCostPaid(OptionalCost.Kicker1))
                return false;
            if ("2".equals(s) && !isOptionalCostPaid(OptionalCost.Kicker2))
                return false;
        }
    } else if (property.startsWith("notkicked")) {
        if (getKickerMagnitude() > 0) {
            return false;
        }
    } else if (property.startsWith("pseudokicked")) {
        if (property.equals("pseudokicked")) {
            if (!isOptionalCostPaid(OptionalCost.Generic))
                return false;
        }
    } else if (property.startsWith("notpseudokicked")) {
        if (property.equals("pseudokicked")) {
            if (isOptionalCostPaid(OptionalCost.Generic))
                return false;
        }
    } else if (property.startsWith("evoked")) {
        if (!isEvoked()) {
            return false;
        }
    } else if (property.equals("HasDevoured")) {
        if (devouredCards == null || devouredCards.isEmpty()) {
            return false;
        }
    } else if (property.equals("HasNotDevoured")) {
        if (devouredCards != null && !devouredCards.isEmpty()) {
            return false;
        }
    } else if (property.equals("IsMonstrous")) {
        if (!isMonstrous()) {
            return false;
        }
    } else if (property.equals("IsNotMonstrous")) {
        if (isMonstrous()) {
            return false;
        }
    } else if (property.equals("IsRenowned")) {
        if (!isRenowned()) {
            return false;
        }
    } else if (property.equals("IsNotRenowned")) {
        if (isRenowned()) {
            return false;
        }
    } else if (property.startsWith("non")) {
        // ... Other Card types
        if (getType().hasStringType(property.substring(3))) {
            return false;
        }
    } else if (property.equals("CostsPhyrexianMana")) {
        if (!currentState.getManaCost().hasPhyrexian()) {
            return false;
        }
    } else if (property.startsWith("RememberMap")) {
        System.out.println(source.getRememberMap());
        for (SpellAbility sa : source.getSpellAbilities()) {
            if (sa.getActivatingPlayer() == null)
                continue;
            for (Player p : AbilityUtils.getDefinedPlayers(source, property.split("RememberMap_")[1], sa)) {
                if (source.getRememberMap().get(p).contains(this)) {
                    return true;
                }
            }
        }
        return false;
    } else if (property.equals("IsRemembered")) {
        if (!source.isRemembered(this)) {
            return false;
        }
    } else if (property.equals("IsNotRemembered")) {
        if (source.isRemembered(this)) {
            return false;
        }
    } else if (property.equals("IsImprinted")) {
        if (!source.hasImprintedCard(this)) {
            return false;
        }
    } else if (property.equals("IsNotImprinted")) {
        if (source.hasImprintedCard(this)) {
            return false;
        }
    } else if (property.equals("hasActivatedAbilityWithTapCost")) {
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.isAbility() && (sa.getPayCosts() != null) && sa.getPayCosts().hasTapCost()) {
                return true;
            }
        }
        return false;
    } else if (property.equals("hasActivatedAbility")) {
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.isAbility()) {
                return true;
            }
        }
        return false;
    } else if (property.equals("hasManaAbility")) {
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.isManaAbility()) {
                return true;
            }
        }
        return false;
    } else if (property.equals("hasNonManaActivatedAbility")) {
        for (final SpellAbility sa : getSpellAbilities()) {
            if (sa.isAbility() && !sa.isManaAbility()) {
                return true;
            }
        }
        return false;
    } else if (property.equals("NoAbilities")) {
        if (!((getAbilityText().trim().equals("") || isFaceDown()) && (getUnhiddenKeywords().isEmpty()))) {
            return false;
        }
    } else if (property.equals("HasCounters")) {
        if (!hasCounters()) {
            return false;
        }
    } else if (property.equals("wasCast")) {
        if (null == getCastFrom()) {
            return false;
        }
    } else if (property.equals("wasNotCast")) {
        if (null != getCastFrom()) {
            return false;
        }
    } else if (property.startsWith("wasCastFrom")) {
        // How are we getting in here with a comma?
        final String strZone = property.split(",")[0].substring(11);
        final ZoneType realZone = ZoneType.smartValueOf(strZone);
        if (realZone != getCastFrom()) {
            return false;
        }
    } else if (property.startsWith("wasNotCastFrom")) {
        final String strZone = property.substring(14);
        final ZoneType realZone = ZoneType.smartValueOf(strZone);
        if (realZone == getCastFrom()) {
            return false;
        }
    } else if (property.startsWith("set")) {
        final String setCode = property.substring(3, 6);
        if (!getSetCode().equals(setCode)) {
            return false;
        }
    } else if (property.startsWith("inZone")) {
        final String strZone = property.substring(6);
        final ZoneType realZone = ZoneType.smartValueOf(strZone);
        if (!isInZone(realZone)) {
            return false;
        }
    } else if (property.equals("ChosenType")) {
        if (!getType().hasStringType(source.getChosenType())) {
            return false;
        }
    } else if (property.equals("IsNotChosenType")) {
        if (getType().hasStringType(source.getChosenType())) {
            return false;
        }
    } else if (property.equals("IsCommander")) {
        if (!isCommander) {
            return false;
        }
    } else if (property.startsWith("HasSVar")) {
        final String svar = property.substring(8);
        if (!hasSVar(svar)) {
            return false;
        }
    } else if (property.startsWith("HasSubtype")) {
        final String subType = property.substring(11);
        if (!getType().hasSubtype(subType)) {
            return false;
        }
    } else if (property.startsWith("HasNoSubtype")) {
        final String subType = property.substring(13);
        if (getType().hasSubtype(subType)) {
            return false;
        }
    } else {
        if (!getType().hasStringType(property)) {
            return false;
        }
    }
    return true;
}