Hi Matthew ; Well , that explained a lot :) .
Even I went though the code very carefully and found that you have not break any thing (but we need to make sure all the samples are running w.o any problem , b'coz we do not have enough test cases to cover all the scenarios). Therefore I will removed my -1 and I am waiting to see comments from other devs. so here is the +1 for the commit , but next time if you are going to do any API changes pls send a mail to the list Thanks Deepal >Hi Deepal (and everyone else) > >Sorry that I didn't bring this up on the mailing list, I thought that the >doc in the Jira was sufficient: >https://issues.apache.org/jira/browse/AXIS2-2020 > >However, I'm more than happy to have a proper discussion. Perhaps the >right place to start is the overview I gave in the Jira: > >"I have been doing some testing with jax-ws applications with Sandesha >engaged, and I hit an issue with sync-2-way messaging. The axis >ServiceClient and OutInOperationClient have some logic to force the >invocation down the async path, which is what is needed in this case. (The >addition of RM into the mix effectively makes the invocation async, even >though we are using synchronous comms). Unfortunately, the jax-ws layer >calls into the OutInOperationClient, and bypasses the logic in the >ServiceClient. The same issue would apply to any other component that >chooses to use the operation client directly. > >My suggested fix is to push some of the logic that is currently in the >ServiceClient down into the operation client. I'll attach a patch soon, >but the basic idea is to move the SyncCallBack class down. " > >I certainly don't mean to steamroller this into the codebase, but I do >think that the changes make sense. There is no API change, but some of the >impl has been moved. > >Thanks > >Matt > > >Deepal Jayasinghe <[EMAIL PROTECTED]> wrote on 25/01/2007 08:46:38: > > > >>Hi ; >> >>My mistake I didnt see the JIRA , but I am still in -1 state until we >>come to a conclusion. >> >>Specially when we change API and their implementation we need to discuss >>that in the mailing list and then implement . >> >>Thnaks >>Deepal >> >>Deepal Jayasinghe wrote: >> >> >> >>>Hi Bill; >>> >>>I am -1 on this since no one discuss about this change before in the >>>mailing list and I didnt find any JIRA related to this. So I think we >>>need to revert this changes until we come to an conclusion. >>> >>>Thanks >>>Deepal >>> >>>[EMAIL PROTECTED] wrote: >>> >>> >>> >>> >>> >>>>Author: nagy >>>>Date: Wed Jan 24 10:38:56 2007 >>>>New Revision: 499521 >>>> >>>>URL: http://svn.apache.org/viewvc?view=rev&rev=499521 >>>>Log: >>>>AXIS2-2020 >>>>Contributor: Matt Lovett >>>>Fix to allow clients/other layers that use the OperationClient >>>> >>>> >>directly (as opposed to going through the ServiceClient) to function >>correctly with sync 2-way messaging and RM enabled. >> >> >>>>Modified: >>>> >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient. > > >>java >> >> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation. > > >>java >> >> >>>>Modified: >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient. > > >>java >> >> >>>>URL: http://svn.apache. >>>> >>>> >org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient. > > >>java?view=diff&rev=499521&r1=499520&r2=499521 >> >> >> >>>============================================================================== >>> >>> >>>>--- >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient. > > >>java (original) >> >> >>>>+++ >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient. > > >>java Wed Jan 24 10:38:56 2007 >> >> >>>>@@ -20,17 +20,13 @@ >>>>import org.apache.axiom.om.OMElement; >>>>import org.apache.axiom.soap.*; >>>>import org.apache.axis2.AxisFault; >>>>-import org.apache.axis2.Constants; >>>>import org.apache.axis2.addressing.EndpointReference; >>>>-import org.apache.axis2.client.async.AsyncResult; >>>>import org.apache.axis2.client.async.Callback; >>>>import org.apache.axis2.context.*; >>>>import org.apache.axis2.description.*; >>>>import org.apache.axis2.engine.AxisConfiguration; >>>>import org.apache.axis2.engine.ListenerManager; >>>>-import org.apache.axis2.engine.MessageReceiver; >>>>import org.apache.axis2.i18n.Messages; >>>>-import org.apache.axis2.util.CallbackReceiver; >>>>import org.apache.axis2.wsdl.WSDLConstants; >>>> >>>>import javax.wsdl.Definition; >>>>@@ -396,65 +392,11 @@ >>>> * @see #createClient(QName) >>>> */ >>>> public void sendRobust(QName operation, OMElement elem) throws >>>> >>>> >>AxisFault { >> >> >>>>- if (options.isUseSeparateListener()) { >>>>- >>>>- // This mean doing a Fault may come through a >>>> >>>> >>different channel . >> >> >>>>- // If the >>>>- // transport is two way transport (e.g. http) Only >>>> >>>> >>one channel is >> >> >>>>- // used (e.g. in http cases >>>>- // 202 OK is sent to say no response available). >>>> >>>> >>Axis2 get blocked >> >> >>>>- // return when the response is available. >>>>- SyncCallBack callback = new SyncCallBack(); >>>>- >>>>- // this method call two channel non blocking method >>>> >>>> >>to do the work >> >> >>>>- // and wait on the callback >>>>- sendReceiveNonBlocking(operation, elem, callback); >>>>- >>>>- long timeout = options.getTimeOutInMilliSeconds(); >>>>- long waitTime = timeout; >>>>- long startTime = System.currentTimeMillis(); >>>>- >>>>- synchronized (callback) { >>>>- while (! callback.isComplete() && waitTime >= 0) { >>>>- try { >>>>- callback.wait(timeout); >>>>- } catch (InterruptedException e) { >>>>- // We were interrupted for some reason, >>>> >>>> >>keep waiting >> >> >>>>- // or throw new AxisFault( "Callback was >>>> >>>> >>interrupted by someone?" ); >> >> >>>>- } >>>>- // The wait finished, compute remaining time >>>>- // - wait can end prematurely, see Object. >>>> >>>> >>wait( int timeout ) >> >> >>>>- waitTime = timeout - (System. >>>> >>>> >>currentTimeMillis() - startTime); >> >> >>>>- } >>>>- >>>>- } >>>>- SOAPEnvelope envelope = callback.envelope; >>>>- // process the result of the invocation >>>>- if (envelope != null) { >>>>- // building soap envelope >>>>- envelope.build(); >>>>- // closing transport >>>>- if (envelope.getBody().hasFault()) { >>>>- SOAPFault soapFault = >>>> >>>> >envelope.getBody().getFault(); > > >>>>- throw new AxisFault(soapFault.getCode(), >>>> >>>> >>soapFault.getReason(), >> >> >>>>- soapFault.getNode(), soapFault. >>>> >>>> >>getRole(), soapFault.getDetail()); >> >> >>>>- } >>>>- } else { >>>>- if (callback.error instanceof AxisFault) { >>>>- throw (AxisFault) callback.error; >>>>- } else if (callback.error != null) { >>>>- throw new AxisFault(callback.error); >>>>- } else if (! callback.isComplete()) { >>>>- //no exception has occurred >>>>- } >>>>- } >>>>- } else { >>>>- MessageContext mc = new MessageContext(); >>>>- fillSOAPEnvelope(mc, elem); >>>>- OperationClient mepClient = createClient(operation); >>>>- mepClient.addMessageContext(mc); >>>>- mepClient.execute(true); >>>>- } >>>>+ MessageContext mc = new MessageContext(); >>>>+ fillSOAPEnvelope(mc, elem); >>>>+ OperationClient mepClient = createClient(operation); >>>>+ mepClient.addMessageContext(mc); >>>>+ mepClient.execute(true); >>>> } >>>> >>>> /** >>>>@@ -524,76 +466,14 @@ >>>> */ >>>> public OMElement sendReceive(QName operationQName, OMElement >>>> >>>> >xmlPayload) > > >>>> throws AxisFault { >>>>- /** >>>>- * If a module has set the USE_ASYNC_OPERATIONS option >>>> >>>> >>then we override the behaviour >> >> >>>>- * for sync calls. However we leave real async calls alone. >>>>- */ >>>>- boolean useAsync = false; >>>>- if (!options.isUseSeparateListener()) { >>>>- Boolean useAsyncOption = (Boolean) configContext. >>>> >>>> >>getProperty(Constants.Configuration.USE_ASYNC_OPERATIONS); >> >> >>>>- if (useAsyncOption != null) useAsync = >>>> >>>> >>useAsyncOption.booleanValue(); >> >> >>>>- } >>>>- >>>>- if (useAsync || options.isUseSeparateListener()) { >>>>- >>>>- // Here we are trying to do a request-response >>>> >>>> >>invocation using two different channels for the request >> >> >>>>- // and the response. >>>>- // For example, if the IN and OUT transports are >>>> >>>> >>HTTP, then two different HTTP channels will be used. The first >> >> >>>>- // channel will be used to send the request, which >>>> >>>> >>the server respond sending HTTP 200, if accepted and uses >> >> >>>>- // a completely different channel to send the >>>> >>>> >>response. This flag, informs the Axis2 client engine to >> >> >>>>- // keep listeners ready to receive the response. >>>>- >>>>- // even if the client is blocking we use a Callback, >>>> >>>> >>internally, to relate the response back to the client. >> >> >>>>- SyncCallBack callback = new SyncCallBack(); >>>>- >>>>- // this method call two channel non blocking method >>>> >>>> >>to do the work >> >> >>>>- // and wait on the callback >>>>- sendReceiveNonBlocking(operationQName, xmlPayload, >>>> >>>> >callback); > > >>>>- >>>>- long timeout = options.getTimeOutInMilliSeconds(); >>>>- long waitTime = timeout; >>>>- long startTime = System.currentTimeMillis(); >>>>- >>>>- synchronized (callback) { >>>>- while (! callback.isComplete() && waitTime >= 0) { >>>>- try { >>>>- callback.wait(timeout); >>>>- } catch (InterruptedException e) { >>>>- // We were interrupted for some reason, >>>> >>>> >>keep waiting >> >> >>>>- // or throw new AxisFault( "Callback was >>>> >>>> >>interrupted by someone?" ); >> >> >>>>- } >>>>- // The wait finished, compute remaining time >>>>- // - wait can end prematurely, see Object. >>>> >>>> >>wait( int timeout ) >> >> >>>>- waitTime = timeout - (System. >>>> >>>> >>currentTimeMillis() - startTime); >> >> >>>>- } >>>>- >>>>- } >>>>- // process the result of the invocation >>>>- if (callback.envelope != null) { >>>>- // transport was already returned by the call back >>>> >>>> >receiver > > >>>>- //Building of the Envelope should happen at the >>>> >>>> >>setComplete() >> >> >>>>- // or onComplete() methods of the Callback class >>>>- return callback.envelope.getBody().getFirstElement(); >>>>- } else { >>>>- if (callback.error instanceof AxisFault) { >>>>- throw (AxisFault) callback.error; >>>>- } else if (callback.error != null) { >>>>- throw new AxisFault(callback.error); >>>>- } else if (! callback.isComplete()) { >>>>- throw new AxisFault(Messages. >>>> >>>> >>getMessage("responseTimeOut")); >> >> >>>>- } else >>>>- throw new AxisFault(Messages. >>>> >>>> >>getMessage("callBackCompletedWithError")); >> >> >>>>- } >>>>- } else { >>>>- MessageContext messageContext = new MessageContext(); >>>>- fillSOAPEnvelope(messageContext, xmlPayload); >>>>- OperationClient operationClient = >>>> >>>> >createClient(operationQName); > > >>>>- operationClient.addMessageContext(messageContext); >>>>- operationClient.execute(true); >>>>- MessageContext response = operationClient >>>>- .getMessageContext(WSDLConstants. >>>> >>>> >>MESSAGE_LABEL_IN_VALUE); >> >> >>>>- return >>>> >>>> >response.getEnvelope().getBody().getFirstElement(); > > >>>>- } >>>>+ MessageContext messageContext = new MessageContext(); >>>>+ fillSOAPEnvelope(messageContext, xmlPayload); >>>>+ OperationClient operationClient = >>>> >>>> >createClient(operationQName); > > >>>>+ operationClient.addMessageContext(messageContext); >>>>+ operationClient.execute(true); >>>>+ MessageContext response = operationClient >>>>+ .getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); >>>>+ return response.getEnvelope().getBody().getFirstElement(); >>>> } >>>> >>>> /** >>>>@@ -635,24 +515,6 @@ >>>> // progamming model is non blocking >>>> mepClient.setCallback(callback); >>>> mepClient.addMessageContext(mc); >>>>- >>>>- /** >>>>- * If a module has set the USE_ASYNC_OPERATIONS option >>>> >>>> >>then we override the behaviour >> >> >>>>- * for sync calls. However we leave real async calls alone. >>>>- */ >>>>- boolean useAsync = false; >>>>- if (!options.isUseSeparateListener()) { >>>>- Boolean useAsyncOption = (Boolean) configContext. >>>> >>>> >>getProperty(Constants.Configuration.USE_ASYNC_OPERATIONS); >> >> >>>>- if (useAsyncOption != null) useAsync = >>>> >>>> >>useAsyncOption.booleanValue(); >> >> >>>>- } >>>>- >>>>- if (useAsync || options.isUseSeparateListener()) { >>>>- MessageReceiver messageReceiver = axisService. >>>> >>>> >>getOperation(operation).getMessageReceiver(); >> >> >>>>- if (messageReceiver == null || !(messageReceiver >>>> >>>> >>instanceof CallbackReceiver)) { >> >> >>>>- CallbackReceiver callbackReceiver = new >>>> >>>> >CallbackReceiver(); > > >>>>- axisService.getOperation(operation). >>>> >>>> >>setMessageReceiver(callbackReceiver); >> >> >>>>- } >>>>- } >>>> mepClient.execute(false); >>>> } >>>> >>>>@@ -785,42 +647,6 @@ >>>> serviceContext.setCachingOperationContext(cachingOpContext); >>>> } >>>> >>>>- >>>>- /** >>>>- * This class acts as a callback that allows users to wait on >>>> >>>> >>the result. >> >> >>>>- */ >>>>- private class SyncCallBack extends Callback { >>>>- private SOAPEnvelope envelope; >>>>- >>>>- private MessageContext msgctx; >>>>- >>>>- private Exception error; >>>>- >>>>- public void onComplete(AsyncResult result) { >>>>- this.envelope = result.getResponseEnvelope(); >>>>- // Transport input stream gets closed after calling >>>> >>>> >setComplete > > >>>>- // method. Have to build the whole envelope including the >>>>- // attachments at this stage. Data might get lost if the >>>> >>>> >input > > >>>>- // stream gets closed before building the whole envelope. >>>>- this.envelope.buildWithAttachments(); >>>>- this.msgctx = result.getResponseMessageContext(); >>>>- } >>>>- >>>>- public void setComplete(boolean complete) { >>>>- super.setComplete(complete); >>>>- synchronized (this) { >>>>- notify(); >>>>- } >>>>- } >>>>- >>>>- public void onError(Exception e) { >>>>- error = e; >>>>- } >>>>- >>>>- public MessageContext getMsgctx() { >>>>- return msgctx; >>>>- } >>>>- } >>>> >>>> /** >>>> * Get the service context. >>>> >>>>Modified: >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation. > > >>java >> >> >>>>URL: http://svn.apache. >>>> >>>> >org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation. > > >>java?view=diff&rev=499521&r1=499520&r2=499521 >> >> >> >>>============================================================================== >>> >>> >>>>--- >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation. > > >>java (original) >> >> >>>>+++ >>>> >>>> >webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation. > > >>java Wed Jan 24 10:38:56 2007 >> >> >>>>@@ -35,6 +35,8 @@ >>>>import org.apache.axis2.util.CallbackReceiver; >>>>import org.apache.axiom.om.util.UUIDGenerator; >>>>import org.apache.axis2.wsdl.WSDLConstants; >>>>+import org.apache.commons.logging.Log; >>>>+import org.apache.commons.logging.LogFactory; >>>> >>>>import javax.xml.namespace.QName; >>>>import java.util.HashMap; >>>>@@ -95,6 +97,8 @@ >>>>*/ >>>>class OutInAxisOperationClient extends OperationClient { >>>> >>>>+ private static Log log = LogFactory. >>>> >>>> >>getLog(OutInAxisOperationClient.class); >> >> >>>>+ >>>> OutInAxisOperationClient(OutInAxisOperation axisOp, ServiceContext >>>> >>>> >sc, > > >>>> Options options) { >>>> super(axisOp, sc, options); >>>>@@ -149,6 +153,7 @@ >>>> * @throws AxisFault if something goes wrong during the >>>> >>>> >>execution of the MEP. >> >> >>>> */ >>>> public void execute(boolean block) throws AxisFault { >>>>+ if(log.isDebugEnabled()) log.debug("Entry: >>>> >>>> >>OutInAxisOperationClient::execute, " + block); >> >> >>>> if (completed) { >>>> throw new AxisFault(Messages.getMessage("mepiscomplted")); >>>> } >>>>@@ -181,9 +186,29 @@ >>>> } >>>> >>>> if (useAsync || options.isUseSeparateListener()) { >>>>- CallbackReceiver callbackReceiver = (CallbackReceiver) >>>> >>>> >axisOp > > >>>>- .getMessageReceiver(); >>>>- callbackReceiver.addCallback(mc.getMessageID(), >>>> >>>> >callback); > > >>>>+ if(log.isDebugEnabled()) >>>>+ log.debug("useAsync=" + useAsync + ", >>>> >>>> >>seperateListener=" + options.isUseSeparateListener()); >> >> >>>>+ /** >>>>+ * We are following the async path. If the user hasn't >>>> >>>> >>set a callback object then we must >> >> >>>>+ * block until the whole MEP is complete, as they have >>>> >>>> >>no other way to get their reply message. >> >> >>>>+ */ >>>>+ CallbackReceiver callbackReceiver = null; >>>>+ if(axisOp.getMessageReceiver() != null && axisOp. >>>> >>>> >>getMessageReceiver() instanceof CallbackReceiver) { >> >> >>>>+ callbackReceiver = (CallbackReceiver) axisOp. >>>> >>>> >>getMessageReceiver(); >> >> >>>>+ } else { >>>>+ if(log.isDebugEnabled()) log.debug("Creating new >>>> >>>> >>callback receiver"); >> >> >>>>+ callbackReceiver = new CallbackReceiver(); >>>>+ axisOp.setMessageReceiver(callbackReceiver); >>>>+ } >>>>+ >>>>+ SyncCallBack internalCallback = null; >>>>+ if(callback != null) { >>>>+ callbackReceiver.addCallback(mc.getMessageID(), >>>> >>>> >callback); > > >>>>+ } else { >>>>+ if(log.isDebugEnabled()) log.debug("Creating >>>> >>>> >>internal callback"); >> >> >>>>+ internalCallback = new SyncCallBack(); >>>>+ callbackReceiver.addCallback(mc.getMessageID(), >>>> >>>> >>internalCallback); >> >> >>>>+ } >>>> >>>> /** >>>> * If USE_CUSTOM_LISTENER is set to 'true' the replyTo >>>> >>>> >>value will not be replaced and Axis2 will not >> >> >>>>@@ -205,14 +230,45 @@ >>>> mc.getReplyTo(). >>>> >>>> >>setAddress(replyToFromTransport.getAddress()); >> >> >>>> } >>>> } >>>>- >>>>- >>>> >>>> //if we don't do this , this guy will wait till it >>>> >>>> >>gets HTTP 202 in the HTTP case >> >> >>>> mc.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, >>>> >>>> >>Boolean.TRUE); >> >> >>>> AxisEngine engine = new AxisEngine(cc); >>>> mc.getConfigurationContext(). >>>> >>>> >>registerOperationContext(mc.getMessageID(), oc); >> >> >>>> engine.send(mc); >>>>+ >>>>+ if(internalCallback != null) { >>>>+ long timeout = options.getTimeOutInMilliSeconds(); >>>>+ long waitTime = timeout; >>>>+ long startTime = System.currentTimeMillis(); >>>>+ >>>>+ synchronized (internalCallback) { >>>>+ while (! internalCallback.isComplete() && >>>> >>>> >>waitTime >= 0) { >> >> >>>>+ try { >>>>+ internalCallback.wait(timeout); >>>>+ } catch (InterruptedException e) { >>>>+ // We were interrupted for some >>>> >>>> >>reason, keep waiting >> >> >>>>+ // or throw new AxisFault( "Callback >>>> >>>> >>was interrupted by someone?" ); >> >> >>>>+ } >>>>+ // The wait finished, compute remaining time >>>>+ // - wait can end prematurely, see Object. >>>> >>>> >>wait( int timeout ) >> >> >>>>+ waitTime = timeout - (System. >>>> >>>> >>currentTimeMillis() - startTime); >> >> >>>>+ } >>>>+ } >>>>+ // process the result of the invocation >>>>+ if (internalCallback.envelope != null) { >>>>+ // The call ended normally, so there is nothing to do >>>>+ } else { >>>>+ if (internalCallback.error instanceof AxisFault) { >>>>+ throw (AxisFault) internalCallback.error; >>>>+ } else if (internalCallback.error != null) { >>>>+ throw new AxisFault(internalCallback.error); >>>>+ } else if (! internalCallback.isComplete()) { >>>>+ throw new AxisFault(Messages. >>>> >>>> >>getMessage("responseTimeOut")); >> >> >>>>+ } else >>>>+ throw new AxisFault(Messages. >>>> >>>> >>getMessage("callBackCompletedWithError")); >> >> >>>>+ } >>>>+ } >>>> } else { >>>> if (block) { >>>> // Send the SOAP Message and receive a response >>>>@@ -344,4 +400,41 @@ >>>> } >>>> } >>>> } >>>>+ >>>>+ /** >>>>+ * This class acts as a callback that allows users to wait on >>>> >>>> >>the result. >> >> >>>>+ */ >>>>+ private class SyncCallBack extends Callback { >>>>+ >>>>+ private SOAPEnvelope envelope; >>>>+ >>>>+ private Exception error; >>>>+ >>>>+ public void onComplete(AsyncResult result) { >>>>+ if(log.isDebugEnabled()) log.debug("Entry: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::onComplete"); >> >> >>>>+ // Transport input stream gets closed after calling >>>> >>>> >setComplete > > >>>>+ // method. Have to build the whole envelope including the >>>>+ // attachments at this stage. Data might get lost if the >>>> >>>> >input > > >>>>+ // stream gets closed before building the whole envelope. >>>>+ this.envelope = result.getResponseEnvelope(); >>>>+ this.envelope.buildWithAttachments(); >>>>+ if(log.isDebugEnabled()) log.debug("Exit: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::onComplete"); >> >> >>>>+ } >>>>+ >>>>+ public void setComplete(boolean complete) { >>>>+ if(log.isDebugEnabled()) log.debug("Entry: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::setComplete, " + complete); >> >> >>>>+ super.setComplete(complete); >>>>+ synchronized (this) { >>>>+ notify(); >>>>+ } >>>>+ if(log.isDebugEnabled()) log.debug("Exit: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::setComplete, " + complete); >> >> >>>>+ } >>>>+ >>>>+ public void onError(Exception e) { >>>>+ if(log.isDebugEnabled()) log.debug("Entry: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::onError, " + e); >> >> >>>>+ error = e; >>>>+ if(log.isDebugEnabled()) log.debug("Exit: >>>> >>>> >>OutInAxisOperationClient$SyncCallBack::onError"); >> >> >>>>+ } >>>>+ } >>>>+ >>>>} >>>> >>>> >>>> >>>>--------------------------------------------------------------------- >>>>To unsubscribe, e-mail: [EMAIL PROTECTED] >>>>For additional commands, e-mail: [EMAIL PROTECTED] >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >>> >>> >>-- >>Thanks, >>Deepal >>................................................................ >>"The highest tower is built one brick at a time" >> >> >> >>--------------------------------------------------------------------- >>To unsubscribe, e-mail: [EMAIL PROTECTED] >>For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> > > >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] > > > > > -- Thanks, Deepal ................................................................ "The highest tower is built one brick at a time" --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
