docs: public void start(boolean deliverImmediately)
        throws SISessionUnavailableException, SISessionDroppedException,
               SIConnectionUnavailableException, SIConnectionDroppedException,
               SIResourceException, SIConnectionLostException,
               SIErrorException
     {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "start", ""+deliverImmediately);
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "**** start invoked with conversation: " + getConversation());
  
        if (executingOnCallbackThread())
        {
           if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Start is being called on the callback thread, callbackThreadState="+callbackThreadState);
  
           if (callbackThreadState == CallbackThreadState.CLOSED ||
               state == StateEnum.CLOSED || state == StateEnum.CLOSING)
           {
                 throw new SISessionUnavailableException(nls.getFormattedMessage("SESSION_CLOSED_SICO1013", null, null));
           }
           else if (callbackThreadState == CallbackThreadState.STOPPED_DEREGISTERED)
           {
              callbackThreadState = CallbackThreadState.STARTED_DEREGISTERED;
           }
           else if (callbackThreadState == CallbackThreadState.STOPPED_REGISTERED)
           {
              callbackThreadState = CallbackThreadState.STARTED_REGISTERED;
           }
        }
        else
        {
           synchronized (callbackLock) {
             if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Got asynch lock");
  
             // Take the synchLock as we intend to change the state
             // of the session and thus must exclude other threads
             // from doing the same.
             synchronized(synchLock)
             {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Got sync lock");
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Current state is: " + state);
  
                if (state == StateEnum.STOPPING)
                {
                   // If we are in stopping state, then another thread must be halfway through
                   // the stop() method.  Go into STOPPING_THEN_STARTED state so that that the
                   // other thread can finish this start operation and we avoid blocking this
                   // thread.
                   if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "currently stopping - will perform start on thread invoking stop() method");
                   state = StateEnum.STOPPING_THEN_STARTED;
                }
                else if (state == StateEnum.CLOSED || state == StateEnum.CLOSING)
                {
                   throw new SISessionUnavailableException(nls.getFormattedMessage("SESSION_CLOSED_SICO1013", null, null));
                }
                else if (state != StateEnum.STARTED)
                {
                   startInternal();
                }
             }
           }
        }
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "start");
     }