public List<SIREventWithRate> generateEvents() {
        List<SIREventWithRate> events = new ArrayList<>();
        
        
        for ( SIREventType etype : rates.getEventTypes() ) {
            
            // EXPOSURE, BECOME_INFECTIOUS, INFECTION, RECOVERY, IMMUNITY, SUSCEPTIBILITY;
            IndividualStateType fromState = null;
            IndividualStateType toState   = null;
            double              rr        = 0.0;
            
            switch (etype) {
                case EXPOSURE: {
                        int numS  = getNumberOfAgentsInState(IndividualStateType.SUSCEPTIBLE);
                        int numI  = getNumberOfAgentsInState(IndividualStateType.INFECTED);
                        rr        = rates.getRate(etype) * (double)numS * (double)numI / (double)getN();
                        fromState = IndividualStateType.INFECTED;
                        toState   = IndividualStateType.EXPOSED;
                    }
                    break;
                    
                case BECOME_INFECTIOUS: {
                        int numE  = getNumberOfAgentsInState(IndividualStateType.EXPOSED);
                        rr        = rates.getRate(etype) * (double)numE;
                        fromState = IndividualStateType.EXPOSED;
                        toState   = IndividualStateType.INFECTED;
                    }
                    break;
                    
                case INFECTION: {
                        int numS  = getNumberOfAgentsInState(IndividualStateType.SUSCEPTIBLE);
                        int numI  = getNumberOfAgentsInState(IndividualStateType.INFECTED);
                        rr        = rates.getRate(etype) * (double)numS * (double)numI / (double)getN();
                        fromState = IndividualStateType.INFECTED;
                        toState   = IndividualStateType.INFECTED;
                    }
                    break;
                    
                case RECOVERY: {
                        int numI  = getNumberOfAgentsInState(IndividualStateType.INFECTED);
                        rr        = rates.getRate(etype) * (double)numI;
                        fromState = IndividualStateType.INFECTED;
                        toState   = IndividualStateType.RECOVERED;
                    }
                    break;
                    
                case IMMUNITY: {
                        int numR  = getNumberOfAgentsInState(IndividualStateType.RECOVERED);
                        rr        = rates.getRate(etype) * (double)numR;
                        fromState = IndividualStateType.RECOVERED;
                        toState   = IndividualStateType.IMMUNE;
                    }
                    break;
               
                case SUSCEPTIBILITY: {
                        fromState = rates.getLastState();
                        int num   = getNumberOfAgentsInState(fromState);
                        rr        = rates.getRate(etype) * (double)num;
                        toState   = IndividualStateType.SUSCEPTIBLE;
                    }
                    break;
            }    
                
            if (rr > 0) {
                SIREventWithRate ev  = new SIREventWithRate(etype, 
                                        new IndividualSimulationState(fromState), 
                                        new IndividualSimulationState(toState),
                                        rr);  
           
                events.add(ev);
            }
          
        }
        
        return events;
        
    }