code: @Override
      public CallEvent next(long systemCurrentTimeMillis) {
          // check for time passing
          if (systemCurrentTimeMillis > currentSystemMilliTimestamp) {
              // build a target for this 1ms window
              long eventBacklog = targetEventsThisMillisecond - eventsSoFarThisMillisecond;
              targetEventsThisMillisecond = (long) Math.floor(targetEventsPerMillisecond);
              double targetFraction = targetEventsPerMillisecond - targetEventsThisMillisecond;
              targetEventsThisMillisecond += (rand.nextDouble() <= targetFraction) ? 1 : 0;
              targetEventsThisMillisecond += eventBacklog;
              // reset counter for this 1ms window
              eventsSoFarThisMillisecond = 0;
              currentSystemMilliTimestamp = systemCurrentTimeMillis;
          }
  
          // drain scheduled events first
          CallEvent callEvent = delayedEvents.nextReady(systemCurrentTimeMillis);
          if (callEvent != null) {
              // double check this is an end event
              assert(callEvent.startTS == null);
              assert(callEvent.endTS != null);
  
              // return the agent/phone for this event to the available lists
              agentsAvailable.add(callEvent.agentId);
              phoneNumbersAvailable.add(callEvent.phoneNo);
  
              validate();
              return callEvent;
          }
  
          // check if we made all the target events for this 1ms window
          if (targetEventsThisMillisecond == eventsSoFarThisMillisecond) {
              validate();
              return null;
          }
  
          // generate rando event (begin/end pair)
          CallEvent[] event = makeRandomEvent();
          // this means all agents are busy
          if (event == null) {
              validate();
              return null;
          }
  
          // schedule the end event
          long endTimeKey = event[1].endTS.getTime();
          assert((endTimeKey - systemCurrentTimeMillis) < (config.maxcalldurationseconds * 1000));
          delayedEvents.add(endTimeKey, event[1]);
  
          eventsSoFarThisMillisecond++;
  
          validate();
          return event[0];
      }
docs: Return the next call event that is safe for delivery or null
  if there are no safe objects to deliver.
  
  Null response could mean empty, or could mean all objects
  are scheduled for the future.
  
  @param systemCurrentTimeMillis The current time.
  @return CallEvent