double event_trans[][][] = new double[threat_var_collection.getNumEvents()][][];        double event_probs[] = new double[threat_var_collection.getNumEvents()];    Enumeration event_name_enum = threat_var_collection.eventNameEnumeration(); for ( int idx = 0; event_name_enum.hasMoreElements(); idx++ ) { String event_name = (String) event_name_enum.nextElement();  HashSet threat_var_set = (HashSet) threat_var_collection.getThreatVariationSet ( event_name );         ThreatVariationModel threat_var = (ThreatVariationModel) threat_var_set.iterator().next();  event_trans[idx] = threat_var.getEventTransitionMatrix();  event_probs[idx] = getEventProbability( threat_var_set, start_time, end_time ); logDebug( "Event prob for  " + event_name + " is " + event_probs[idx] );  if ( OVERRIDE_EVENT_PROBABILITIES ) { logError( "OVERRIDE EVENT PROBS.  THIS IS FOR TESTING ONLY!");  if ( event_probs[idx] < 0.0001 ) event_probs[idx] = 0.1; else if ( event_probs[idx] > 0.9999 ) event_probs[idx] = 0.9; else event_probs[idx] = 0.5;  logDebug( "New event prob for  " + event_name + " is " + event_probs[idx] ); }  }  logDebug( "Event probs: " + ProbabilityUtils.arrayToString( event_probs ));
return event_collection.getTransitionMatrix( start_time, end_time );
    double[][] getThreatTransitionMatrix( AssetID asset_id,                                          long start_time,                                          long end_time )            throws BelievabilityException    {        // Note that because of the parameterize-by-time nature of        // the threat probabilities and the dynamic asset        // membership of the threats, we *cannopt* precompute this        // transition matrix.         //        // Getting the transition probability matrix at the most        // abstract is a two step process.  We have to find all the        // unique events that are acting on this asset state        // dimension, and blend their individual transition matrices        // according to the probability of each event.  But to do        // this, requires us to blend together all the possible        // threats that can cause each event event.        //                // General algorithm: Find each event, and compute the        // probability of each event (possibly factoring in multiple        // threats.)  Blending the threats together is done in        // ProbabilityUtils.computeEventUnionProbability(). Then,        // consider all possible combinations of the events occurring        // and not occurring, building up the transition matrix from        // the individual event components.  This blending of events        // occurs in the ProbabilityUtils.mergeMultiEventTransitions()        // method.        //        // First, get the threat variation set so we can see how many        // *different* events exist.        //        ThreatVariationCollection threat_var_collection                = getThreatVariations( asset_id );        logDebug( "Threat collection for asset '" + asset_id.getName()                   + "', state dim. '"                  + _state_dim_name + "'\n"                  + threat_var_collection.toString() );        // The nature of the getThreatVariations() code should never        // result in a NULL being returned, but it never hurts to        // check (it is supposed to create the set when it finds there        // is none).  Also, if there are no threats, then the        // probability of the threat should be zero.  However, rather        // than couting on that, we will assume that the absence of a        // threat means that the "threat transition" effect is to not        // change state, so we return the indentity matrix.        //        //        if (( threat_var_collection == null )            || ( threat_var_collection.getNumEvents() < 1 ))        {            double[][] probs = new double[_possible_states.length]                    [_possible_states.length];                        for ( int i = 0; i < _possible_states.length; i++ )                probs[i][i] = 1.0;                        return probs;        } // if no threats acting on this asset state dimension        // This array will hold (for each event) the transition matrix        // *given* the event occurs. (We will assume the transitions        // are the identity matrix for the case when the event does        // not occur.) First index: the event, second index: the 'from'        // asset state, third index: the 'to' asset state.        //        double event_trans[][][]                = new double[threat_var_collection.getNumEvents()][][];        // This will hold (for each event) the probability that the        // event occurs (independent of all others).  This may need to        // factor in one or more threats by computing the probability        // of the union of all the threats that can cause a given        // event.        //        double event_probs[]                = new double[threat_var_collection.getNumEvents()];        // Fill out the arrays by looping over each event.        //        Enumeration event_name_enum                 = threat_var_collection.eventNameEnumeration();        for ( int idx = 0; event_name_enum.hasMoreElements(); idx++ )        {            String event_name = (String) event_name_enum.nextElement();                        HashSet threat_var_set                     = (HashSet) threat_var_collection.getThreatVariationSet                    ( event_name );            //  The nature of this threat variation set is such that            //  it should not be empty (we would not consider an event            //  unless some threat could cause it), and every threat            //  variation in there should refer to the same event.            //  Because of that, we can get the first item and get the            //  event transition from that.            //            ThreatVariationModel threat_var                     = (ThreatVariationModel) threat_var_set.iterator().next();                        event_trans[idx] = threat_var.getEventTransitionMatrix();            event_probs[idx] = getEventProbability( threat_var_set,                                                    start_time,                                                    end_time );            logDebug( "Event prob for  " + event_name                       + " is " + event_probs[idx] );                        if ( OVERRIDE_EVENT_PROBABILITIES )            {                logError( "OVERRIDE EVENT PROBS.  THIS IS FOR TESTING ONLY!");                                if ( event_probs[idx] < 0.0001 )                    event_probs[idx] = 0.1;                else if ( event_probs[idx] > 0.9999 )                    event_probs[idx] = 0.9;                else                    event_probs[idx] = 0.5;                logDebug( "New event prob for  " + event_name                           + " is " + event_probs[idx] );            }        } // for idx        logDebug( "Event probs: "                   + ProbabilityUtils.arrayToString( event_probs ));                logDebug( "Event transitions: "                   + ProbabilityUtils.arrayToString( event_trans ));                // Ok, so now we have the individual state transition        // probabilities for each event and the individual        // probabilities that each event will occur.  Next up is        // merging these into a single transition matrix. Note the        // assumption that if an event does not occur, then the state        // remains unchanged. Or more accurately, if no events occurs,        // there is no state change.        //        return ProbabilityUtils.mergeMultiEventTransitions( event_probs,                                                            event_trans );    } // method getThreatTransitionMatrix