logger.debug("evaluateThreatAssetMembership called with " + changesToProcess.size() + " events");
if (logger.isDebugEnabled()) logger.debug("evaluateThreatAssetMembership called with " + changesToProcess.size() + " events");
    private void evaluateThreatAssetMembership() {        synchronized(changesToProcess) {            //If no new assets or new threats, don't do anything            if (changesToProcess.size() == 0 ) { return; }                        ThreatDescription metaModel;            AssetChangeEvent event;            DefaultThreatModel threatModel;            DefaultAssetTechSpec asset;                        Vector hosts  = new Vector();            Vector nodes  = new Vector();            Vector agents = new Vector();            //Emit list of assets to consider            Iterator itr = changesToProcess.iterator();            while (itr.hasNext()) {                event = (AssetChangeEvent)itr.next();                asset = (DefaultAssetTechSpec) event.getAsset();                logger.debug("evaluateThreatAssetMembership looking at asset " + asset.getName() + "["+asset.getAssetType()+"]");                if (asset.getAssetType().equals(AssetType.HOST)) { hosts.add(asset); }                else if (asset.getAssetType().equals(AssetType.NODE)) { nodes.add(asset); }                else if (asset.getAssetType().equals(AssetType.AGENT)) { agents.add(asset); }            }                                    Vector changedModels = new Vector(); //keep track so we can publish change them to the BB.            logger.debug("evaluateThreatAssetMembership called with " + changesToProcess.size() + " events");            //Iterate over threatDescriptions            if ( (threatDescriptions != null && threatDescriptions.size() > 0) ) {//logger.debug("evaluateThreatAssetMembership has " + threatDescriptions.size() + " threatDescriptions to examine.");                Iterator i = threatDescriptions.iterator();                while (i.hasNext()) {                    metaModel = (ThreatDescription)i.next();//logger.debug("evaluateThreatAssetMembership looking at threat " + metaModel.getName() );                                                Iterator ctp = changesToProcess.iterator();                        while (ctp.hasNext()) {                            threatModel = null;                            event = (AssetChangeEvent)ctp.next();                            asset = (DefaultAssetTechSpec) event.getAsset();                            if (event.moveEvent() || event.newAssetEvent() ) {                                //IF the agent moved or is new                                //check to see if the asset qualifies                                //** First check type of asset against type of threatModel. Ignore if they don't match                                if (!(metaModel.getAffectedAssetType().equals(asset.getAssetType()))) {//logger.debug("evaluateThreatAssetMembership -- asset types don't match: \n modelAssetType="+metaModel.getAffectedAssetType()+"\nasset's type["+asset.getName()+"] = "+asset.getAssetType());                                    continue;                                }                                boolean qualifies = true; //assume the asset qualifies, until a filter rejects it.                                ThreatVulnerabilityFilter filter = metaModel.getVulnerabilityFilter();                                //IF NO FILTER -- add the asset as a member                                if (filter == null) {                                    qualifies = true;                                } else { //OK, there are FILTERS, so see if the asset qualifies                                    qualifies = filter.qualifies(this, asset);                                                                    }                                if (qualifies) {                                    threatModel = addAssetAsMember(asset, metaModel);                                    if (threatModel == null) {                                        logger.debug("==> "+asset.getName()+"["+asset.getAssetType().getName()+"] Qualifies! But already exists in the "+metaModel.getName()+" threatModel ["+metaModel.getAffectedAssetType().getName()+"]");                                    } else {                                        logger.debug("==> "+asset.getName()+"["+asset.getAssetType().getName()+"] Qualifies! Adding to the "+metaModel.getName()+" threatModel ["+metaModel.getAffectedAssetType().getName()+"], memberCount="+threatModel.getAssetList().size());                                    }                                } else { //remove the asset from the threat model's membership, if it's there                         //logger.debug("evaluateThreatAssetMembership - doesn't qualify.");                                    threatModel = removeAssetAsMember(asset, metaModel);                                                                                            if (threatModel != null) {                                        logger.debug("==> "+asset.getName()+"["+asset.getAssetType().getName()+"] was REMOVED from "+metaModel.getName()+" threatModel ["+metaModel.getAffectedAssetType().getName()+"]");                                    }                                }                                                              //If the asset was removed, just remove from this threat, if there                            } else if (event.assetRemovedEvent() ) {                                    threatModel = removeAssetAsMember(asset, metaModel);                                                                                           if (threatModel != null) {                                        logger.debug("==> "+asset.getName()+"["+asset.getAssetType().getName()+"] was REMOVED from "+metaModel.getName()+" threatModel ["+metaModel.getAffectedAssetType().getName()+"]");                                    }                            }                            //Now if the threatModel != null, then it was changed so add it to the list to publishChange                            if (threatModel != null) {                                if (! changedModels.contains(threatModel)) {                                    changedModels.addElement(threatModel);                                }                            }                                                    } //while loop - on asset change events                } //while() loop on ThreatDescriptions iterator                if (changedModels.size() > 0) {                     Collection changes;                    Iterator cModels = changedModels.iterator();                    while (cModels.hasNext()) {                        DefaultThreatModel dtm = (DefaultThreatModel) cModels.next();                                                //Announce newly added assets                        Vector added = dtm.clearNewAssets();                        Vector removed = dtm.clearRemovedAssets();                        if (added.size() > 0 || removed.size() > 0) { //some assets were added to this threat, so announce it                            changes = Collections.singleton( new ThreatModelChangeEvent( dtm, added, removed, ThreatModelChangeEvent.MEMBERSHIP_CHANGE) );                            this.blackboard.publishChange(dtm, changes);                            logger.debug("Announced "+added.size()+" assets were added, and " +removed.size()+" assets were removed in threat = " + dtm.getName());                        }                                            }                }                //Now process the transitive effects                                processEnclaveTransitiveEffects(hosts, nodes, agents);                processHostTransitiveEffects(nodes, agents);                processNodeTransitiveEffects(agents);                                                                            } //if - there are any threat models            //Now remove all processed events            changesToProcess.removeAllElements();        } //synchronized    }