+ sipRequest.getRequestURI());
+ sipRequest.getFirstLine());
	public void deliverEvent(EventWrapper eventWrapper) {		EventObject sipEvent = eventWrapper.sipEvent;		SipListener sipListener = ((SipProviderImpl) sipEvent.getSource()).sipListener;		if (sipEvent instanceof RequestEvent) {		  			// Check if this request has already created a			// transaction			SIPRequest sipRequest = (SIPRequest) ((RequestEvent) sipEvent)					.getRequest();			  		    if (LogWriter.needsLogging)			sipStackImpl.logMessage("deliverEvent : " 				+ sipRequest.getFirstLine() + 				" transaction " + eventWrapper.transaction );			// If this is a dialog creating method for which a server			// transaction already exists or a method which is			// not dialog creating and not within an existing dialog			// (special handling for cancel) then check to see if			// the listener already created a transaction to handle			// this request and discard the duplicate request if a			// transaction already exists. If the listener chose			// to handle the request statelessly, then the listener			// will see the retransmission.			// Note that in both of these two cases, JAIN SIP will allow			// you to handle the request statefully or statelessly.			// An example of the latter case is REGISTER and an example			// of the former case is INVITE.			if (sipStackImpl.isDialogCreated(sipRequest.getMethod())) {				SIPServerTransaction tr = (SIPServerTransaction) sipStackImpl						.findTransaction(sipRequest, true);				SIPDialog dialog = sipStackImpl.getDialog(sipRequest						.getDialogId(true));				synchronized (this) {					if (tr != null && !tr.passToListener()) {						if (LogWriter.needsLogging)							sipStackImpl									.logMessage("transaction already exists! " + tr);						return;					} else if (sipStackImpl.findPendingTransaction(sipRequest) != null) {						if (LogWriter.needsLogging)							sipStackImpl									.logMessage("transaction already exists!!");						return;					} else {						// Put it in the pending list so that if a repeat						// request comes along it will not get assigned a new						// transaction						SIPServerTransaction st = (SIPServerTransaction) eventWrapper.transaction;						sipStackImpl.putPendingTransaction(st);					}				}			} else if ((!sipRequest.getMethod().equals(Request.CANCEL))					&& sipStackImpl.getDialog(sipRequest.getDialogId(true)) == null) {				// not dialog creating and not a cancel.				// transaction already processed this message.				SIPTransaction tr = sipStackImpl.findTransaction(sipRequest,						true);				// If transaction already exists bail.				if (tr != null) {					if (LogWriter.needsLogging)						sipStackImpl.logMessage("transaction already exists!");					return;				}			}			// Set up a pointer to the transaction.			sipRequest.setTransaction(eventWrapper.transaction);			// Processing incoming CANCEL.			if (sipRequest.getMethod().equals(Request.CANCEL)) {				SIPTransaction tr = sipStackImpl.findCancelTransaction(sipRequest,						true);				if (tr != null						&& tr.getState() == SIPTransaction.TERMINATED_STATE) {					// If transaction already exists but it is					// too late to cancel the transaction then					// just respond OK to the CANCEL and bail.					if (LogWriter.needsLogging)						sipStackImpl								.logMessage("Too late to cancel Transaction");					// send OK and just ignore the CANCEL.					try {						tr.sendMessage(sipRequest.createResponse(Response.OK));					} catch (IOException ex) {						// Ignore?					}					return;				} 				if (LogWriter.needsLogging)						sipStackImpl.logMessage("Cancel transaction = " + tr );							}			// Change made by SIPquest			try {				if (LogWriter.needsLogging) {					sipStackImpl.logMessage("Calling listener "							+ sipRequest.getRequestURI());					sipStackImpl.logMessage("Calling listener " + eventWrapper.transaction);                                }				if (sipListener != null)					sipListener.processRequest((RequestEvent) sipEvent);				sipStackImpl						.removePendingTransaction((SIPServerTransaction) eventWrapper.transaction);				if (eventWrapper.transaction != null) {					SIPDialog dialog = (SIPDialog) eventWrapper.transaction							.getDialog();					// Tell the dialog that request has been consumed - this					// copies the remote seqno					if (dialog != null)						dialog.requestConsumed();				}			} catch (Exception ex) {				// We cannot let this thread die under any				// circumstances. Protect ourselves by logging				// errors to the console but continue.				ex.printStackTrace();			}			if (eventWrapper.transaction != null) {				((SIPServerTransaction) eventWrapper.transaction)						.clearPending();			}		} else if (sipEvent instanceof ResponseEvent) {			// Change made by SIPquest			try {				if (LogWriter.needsLogging) {					SIPResponse sipResponse = (SIPResponse) ((ResponseEvent) sipEvent)							.getResponse();					sipStackImpl.logMessage("Calling listener for "							+ sipResponse.getFirstLine());				}				if (sipListener != null)					sipListener.processResponse((ResponseEvent) sipEvent);			} catch (Exception ex) {				// We cannot let this thread die under any				// circumstances. Protect ourselves by logging				// errors to the console but continue.				ex.printStackTrace();			}			// The original request is not needed except for INVITE			// transactions -- null the pointers to the transactions so			// that state may be released.			SIPClientTransaction ct = (SIPClientTransaction) eventWrapper.transaction;			if (ct != null					&& TransactionState.COMPLETED == ct.getState()					&& ct.getOriginalRequest() != null					&& !ct.getOriginalRequest().getMethod().equals(							Request.INVITE)) {				// reduce the state to minimum				// This assumes that the application will not need				// to access the request once the transaction is				// completed.				ct.clearState();			}			// mark no longer in the event queue.			if (ct != null) {				// If responses have been received in the window				// notify the pending response thread so he can take care of it.				// cannot do this in the context of the current thread else it				// will deadlock.				ct.clearPending();			}		} else if (sipEvent instanceof TimeoutEvent) {			// Change made by SIPquest			try {				// Check for null as listener could be removed.				if (sipListener != null)					sipListener.processTimeout((TimeoutEvent) sipEvent);			} catch (Exception ex) {				// We cannot let this thread die under any				// circumstances. Protect ourselves by logging				// errors to the console but continue.				ex.printStackTrace();			}			//Mark that TImeout event has been processed			//Bug fix by Shu-Lin			if (eventWrapper.transaction != null) {			   eventWrapper.transaction.clearPending();			}		} else {			if (LogWriter.needsLogging)				sipStackImpl.logMessage("bad event" + sipEvent);		}	}