docs: public Alarm create(long delta, int percentLate, AlarmListener listener, Object context)
     throws SIErrorException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.entry(
          tc,
          "create",
          new Object[] { this, Long.valueOf(delta), Integer.valueOf(percentLate), listener, context });
  
      //calculate the target time for the new alarm
      long time = System.currentTimeMillis() + delta;
  
      // Defect 516583 - catch and report the situation where an arithmetic overflow has occurred
      if(time <0)
      {
        SIErrorException e =
          new SIErrorException(
            nls.getFormattedMessage(
              "INTERNAL_MESSAGING_ERROR_CWSIP0001",
              new Object[] {
                "com.ibm.ws.sib.processor.utils.am.MPAlarmManager",
                "1:269:1.28" },
              null));
        FFDCFilter.processException(
          e,
          "com.ibm.ws.sib.processor.utils.am.MPAlarmManager.create",
          "1:274:1.28",
          this);
        SibTr.exception(tc, e);
        SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0001",
          new Object[] {
            "com.ibm.ws.sib.processor.utils.am.MPAlarmManager",
            "1:280:1.28" });
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          SibTr.exit(tc, "MPAlarmManager", e);
        throw e;      
      }
      
      //calculate the latest time the alarm can be fired
      long latest = time + ((delta / 100) * percentLate);
      //try to get an existing alarm object from the pool
      MPAlarmImpl alarm = (MPAlarmImpl) _alarmPool.remove();
      //if we were unable to get one from the pool
      if(alarm == null)
      {
        //create a new one
        alarm = new MPAlarmImpl(time,latest,listener,context,index++);
      }
      else
      {
        //reset the values on the alarm retrieved from the pool
        alarm.reset(time,latest,listener,context,index++);
      }
      //take the pending alarms list lock
      synchronized(_pendingAlarmsLock)
      {
        //start at the bottom of the list
        //new alarms should generally come chronologically after existing ones
        //the insertPoint is the entry before where we are going to put the new alarm
        MPAlarmImpl insertPoint = (MPAlarmImpl) _pendingAlarms.getLast();
        //if the list is empty      
        if(insertPoint == null)
        {
          //just put the new alarm in to the list
          _pendingAlarms.put(alarm);
        }
        else //otherwise search for the correct place in the list
        {
          //if the current entry is after the time for the new alarm
          if(insertPoint.time() > time)
          {      
            do
            {
              //go to the next entry up
              insertPoint = insertPoint.previous();           
            }//until either we reach the top of the list or the current one is before the new one
            while(insertPoint !=null && insertPoint.time() > time);
          }
          //if we did reach the top of the list
          if(insertPoint == null)
          {
            //up the new alarm in at the top
            _pendingAlarms.insertAtTop(alarm);
          }
          else //if we are somewhere in the middle of the list
          {
            //insert the new alarm after the one we just found
            _pendingAlarms.insertAfter(alarm, insertPoint);
          }
        }
        //if the next alarm is MPAlarmThread.SUSPEND (i.e. the alarm thread is suspended)
        //or the time for the new alarm is before the time that the
        //alarm thread is currently due to wake up
        if(_nextAlarm == MPAlarmThread.SUSPEND || time < _nextAlarm)
        {
          //set the new target wakeup time
          _nextAlarm = time;
        }
        
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        {
          long now = System.currentTimeMillis();
          SibTr.debug(tc, "now " + now + "Alarm Start : "+listener+
            " - "+(time - now)+
            " ("+(latest - now)+")");
          
          SibTr.debug(tc, "" + _pendingAlarms);
        }
        
      }
      
      //and wake up the the alarm thread with the new time
      _alarmThread.requestNextWakeup(_nextAlarm);
      
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.exit(tc, "create", alarm);
  
      //return the alarm reference
      return alarm;
    }