webservices/wsframework/src/senwebservicesession.cpp
changeset 0 62f9d29f7211
child 14 9e96e2676219
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsframework/src/senwebservicesession.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,2158 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:           
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "senwebservicesession.h"
+
+#include <SenServiceConnection.h> // error codes etc
+
+#include "senservicesession.h"
+#include "SenServiceConnection.h" // session status constants
+#include "SenSoapMessage.h"
+#include "senwsdescription.h"
+#include "msencoreservicemanager.h"
+#include "msenremoteserviceconsumer.h"
+#include "SenXmlUtils.h"
+#include "SenDateUtils.h"
+#include "msentransport.h"
+#include "SenCredential.h"
+//#include "SenPolicy.h"
+#include "SenSoapFault.h"
+#include "sendebug.h"
+#include "senservicemanagerdefines.h"
+#include "senservicepolicy.h"
+#include "seninternalcredential.h"
+#include "sensaxutils.h"
+#include <xmlengnodelist.h>
+#include <SenIdentityProvider.h>
+#include "senlogger.h"
+#include <SenXmlConstants.h>
+
+#include <SenTransportProperties.h>
+// CONSTANTS
+
+namespace
+    {
+    _LIT8(KServiceInterval1,"ServiceInterval");
+    _LIT(KInvalideDate,"19000101:");
+    /* microseconds before actual notOnOrAfter time
+     * when credentials are treated
+     * as expired.
+     */
+    const TInt KClockSlipMicroSeconds = 3*60*1000*1000;
+
+    // constants for parsing
+    _LIT8(KSDFramework,"<ServiceDescription framework=\"");
+    _LIT8(KContractStart, "<Contract>");
+    _LIT8(KContractEnd, "</Contract>");
+    _LIT8(KTagWithAttrEnd, "\">");
+    _LIT8(KEndPointStart, "<Endpoint>");
+    _LIT8(KEndPointStartWithCue, "<Endpoint cue=\"");   
+    _LIT8(KTagWithAttrClose, "\"/>"); 
+    _LIT8(KEndPointEnd, "</Endpoint>");
+    _LIT8(KCredentialsStart, "<Credentials");
+    _LIT8(KCredentialsEnd, "</Credentials>");
+    _LIT8(KNotOnOrAfterFormat, " notOnOrAfter=\"%S\" >");
+    _LIT8(KEmptyTagEnd, " >");
+    _LIT8(KSDEnd, "</ServiceDescription>");
+    // localnames for element(s)
+    _LIT8(KProviderPolicyLocalName, "ProviderPolicy");
+    _LIT8(KNewLine, "\n");
+    
+    const TInt KCredIdBufSize           = 128;
+    _LIT8(KCredentialIdLocalName,       "SenCredentialId");
+    _LIT8(KCredentialIdStart,           "<SenCredentialId>");
+    _LIT8(KCredentialIdEnd,             "</SenCredentialId>");
+    _LIT8(KEndpointLocalname,           "Endpoint");
+//    _LIT8(KContractLocalname,           "Contract");
+    }
+
+EXPORT_C CSenWebServiceSession::CSenWebServiceSession(TDescriptionClassType aType,
+                                                      MSIF& aFramework)
+:   CSenServiceSession(aType, aFramework)
+    {
+    }
+
+EXPORT_C void CSenWebServiceSession::ConstructL()
+    {
+
+    // Sets the local name to "ServiceDescription"
+    // and initiates the inner ipElement
+    CSenServiceSession::BaseConstructL();
+    // Init member variables
+    iClientServerInterval = 0;
+    iValidUntil = Time::NullTTime();
+    iFrameworkId = iFramework.Id().AllocL();
+    }
+
+EXPORT_C CSenWebServiceSession::~CSenWebServiceSession()
+    {
+    delete iSecurity;
+    delete iContract;
+    delete iEndpoint;
+    delete iFrameworkId;
+    iFrameworkId = NULL;
+    delete iTransportCue;
+    iTransportCue = NULL;
+    iCredentialPtr.RemoveCredentialObserver(*this);
+    iCredentialPtr.Close();
+    }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::TransportCue()
+    {
+    if( iTransportCue )
+        {
+        return *iTransportCue;
+        }
+    else 
+        {
+        return CSenServiceSession::TransportCue();
+        }
+    }
+
+EXPORT_C TInt CSenWebServiceSession::InitializeFromL(MSenServiceDescription& aServiceDescription)
+    {
+   TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,_L("Zapping filelogged messages (.xml)"));
+    
+    // Call superclass method to initialize facets, transport (endpoint) cue, etc..
+	CSenServiceSession::InitializeFromL(aServiceDescription);
+
+    HBufC8* pContract = aServiceDescription.Contract().AllocL();
+    delete iContract;
+    iContract = pContract;
+    
+    HBufC8* pEndpoint = aServiceDescription.Endpoint().AllocL();
+    delete iEndpoint;
+    iEndpoint = pEndpoint;
+
+    if(aServiceDescription.DescriptionClassType()
+                        ==
+        MSenServiceDescription::EWSDescription
+                        ||
+        aServiceDescription.DescriptionClassType()
+                        ==
+        MSenServiceDescription::EWSPattern
+                        ||
+        aServiceDescription.DescriptionClassType()
+                        ==
+        MSenServiceDescription::EIdentityProvider
+        )
+        {
+
+        CSenWSDescription& xmlDesc =
+                            (CSenWSDescription&)aServiceDescription;
+
+        CSenElement* pElement =
+                    (xmlDesc.AsElement()).Element(KServiceInterval1);
+        if(pElement)
+            {
+            TLex8 lex(pElement->Content());
+            TInt64 val;
+            User::LeaveIfError(lex.Val(val));
+            iClientServerInterval = val;
+			TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase, KNormalLogLevel , _L8("Interval in microseconds (from file): %d"),
+                                iClientServerInterval.Int64()));
+            }
+
+        RCredentialList& credentials = xmlDesc.Credentials();
+        TInt count(credentials.Count());
+        for(TInt i=0; i<count; i++)
+            {
+            CSenCredential* pCredential = credentials[i];
+            if(pCredential)
+                {
+                // note: errors while adding single credential must ignored:
+                // - the remaining credentials (array) must be processed..
+
+                //CSenCredential* pCopy = CSenCredential::NewL(*pCredential);
+                //CleanupStack::PushL(pCopy);
+                AddCredentialL(*pCredential);
+                //CleanupStack::Pop(); // pCopy
+                }
+            }
+        // rebuild provider policy definition
+        RebuildFrom(xmlDesc);
+        // update provider policy information (new feature)
+
+        MSenServicePolicy* servicePolicy = ServicePolicy();
+        if(servicePolicy)
+            {
+            MSenServicePolicy* givenServicePolicy = xmlDesc.ServicePolicy();
+            if(givenServicePolicy)
+                (CSenServicePolicy*)servicePolicy->RebuildServicePolicyFrom(*givenServicePolicy);
+            }            
+        }
+    SetStatusL();
+    return KErrNone; // err value not currently in use
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ComputeStatusL()
+    {
+    TInt retVal = CSenServiceSession::ComputeStatusL();
+
+    if (retVal == KSenConnectionStatusReady)
+        {
+        TTime now;
+        now.UniversalTime();
+        now += iClientServerInterval;
+
+#ifdef _SENDEBUG
+            if (iValidUntil != Time::NullTTime())
+                {
+			TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase, KNormalLogLevel , _L8("Client-Server Interval in microseconds: %d"),
+                                    iClientServerInterval.Int64()));
+                
+                TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts;
+                TInt leaveCode(KErrNone);
+                TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(ts, now);)
+                if (leaveCode == KErrNone)
+                    {
+                    
+					TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("Fixed client time : %S"), &ts));
+                
+                    TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts2;
+                    TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(ts2, iValidUntil);)
+			     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("Credential time : %S, clockslip: %d micros"), &ts2, KClockSlipMicroSeconds));
+                    }
+                leaveCode = 0; // not used
+                }
+#endif // _SENDEBUG
+
+        if ((iValidUntil != Time::NullTTime() ) &&
+            now >
+            (iValidUntil-TTimeIntervalMicroSeconds(KClockSlipMicroSeconds)))
+            {
+			TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,_L("Credential is expired."));
+            retVal = KSenConnectionStatusExpired;
+            }
+        }
+    return retVal;
+    }
+
+EXPORT_C TBool CSenWebServiceSession::IsExpiredL()
+    {
+    ComputeStatusL();
+    return (CSenServiceSession::StatusL() == KSenConnectionStatusExpired);
+    }
+
+EXPORT_C TInt CSenWebServiceSession::AddCredentialL(
+                                                CSenCredential& aCredential)
+    {
+    if ( aCredential.AsElement().LocalName() == KCredentialIdLocalName )
+        {
+        delete iSecurity;
+        iSecurity = NULL;
+        iSecurity = aCredential.AsXmlL();
+        
+        TInt credentialId;
+        TLex8 lex;
+        lex.Assign(aCredential.AsElement().Content());
+        lex.Val(credentialId);                        
+
+        TInt error(KErrNone);
+        RSenCredentialPtr credentialPtr;
+        credentialPtr = ((MSenServiceManager&)iFramework.Manager()).CredentialL(credentialId,
+                                                                                error);
+        if ( error == KErrNone )
+            {
+            iCredentialPtr = credentialPtr.Clone();
+            iCredentialPtr.AddCredentialObserverL(*this);		//codescannerwarnings
+            iValidUntil = iCredentialPtr.Credential()->ValidUntil();
+            if ( iClientServerInterval == 0 )
+                {
+                TPtrC8 value;
+                TInt ret = iCredentialPtr.Credential()->PropertiesL().PropertyL( KServiceInterval1,
+                                                                                 value );
+                if ( ret == KErrNone )
+                    {
+                    TLex8 lex(value);
+                    TInt64 val;
+                    ret = lex.Val(val);
+                    if ( ret == KErrNone )
+                        {
+                        iClientServerInterval = val;
+                        }
+                    }
+                }
+            }
+        else
+            {
+            // invalidate the session, because we have no credential 
+            iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900
+
+            iCredentialPtr.RemoveCredentialObserver(*this);
+            iCredentialPtr.Close();
+
+            delete iSecurity;
+            iSecurity = NULL;
+
+            TBuf8<KCredIdBufSize> buffer;
+            buffer.Num(KErrNotFound);
+
+            iSecurity = HBufC8::NewL(buffer.Length()+KCredentialIdStart().Length()+KCredentialIdEnd().Length());
+            TPtr8 sec = iSecurity->Des();
+            sec.Append(KCredentialIdStart);
+            sec.Append(buffer);
+            sec.Append(KCredentialIdEnd);
+            }
+        }
+    else
+        {
+        TInt retVal(KErrNone);
+
+        delete iSecurity;
+        iSecurity = NULL;
+        HBufC8* pSecurityToken = 0;
+        retVal = ConstructSecurityTokenL(aCredential, pSecurityToken);
+        if (KErrNone != retVal)
+            {
+            if ( pSecurityToken != NULL )
+                {
+                delete pSecurityToken;
+                pSecurityToken = NULL;
+                iCredentialPtr.RemoveCredentialObserver(*this);
+                iCredentialPtr.Close();
+                }
+            return retVal;
+            }
+            
+        iValidUntil = aCredential.ValidUntil(); // SetSecurityL needs up-to-date iValidUntil(!)
+
+        CleanupStack::PushL(pSecurityToken);
+        SetSecurityL(*pSecurityToken);
+        CleanupStack::PopAndDestroy(pSecurityToken);
+        }
+        
+    SetStatusL();
+    
+    return KErrNone;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ConstructSecurityTokenL( CSenCredential& aCredential,
+                                                              HBufC8*& aToken )
+    {
+    aToken = aCredential.AsXmlL();
+    return KErrNone;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::NewMessageL( CSenSoapMessage*& aMessage )
+    {
+    aMessage = CSenSoapMessage::NewL();
+    return KErrNone;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::MessageForSendingL( const TDesC8& aBody,
+                                                         const TDesC8& /* aSenderID */,
+                                                         CSenSoapMessage*& aMessage )
+    {
+    TInt retVal(KErrNone);
+    aMessage = CSenSoapMessage::NewL();
+    CleanupStack::PushL(aMessage);
+    SetFrameworkHeadersL(*aMessage); 
+    aMessage->SetBodyL(aBody);
+    CleanupStack::Pop(); // aMessage
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ParseResponseL( const TDesC8& aResponse,
+                                                     HBufC8*& aParsed )
+    {
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL(const TDesC8&, HBufC8*&)");
+    // this called only from the synchronous submit(..) methods
+    TInt retVal(KErrNone);
+    CSenSoapMessage* pSoapMessage = NULL;
+    retVal = ParseResponseL(aResponse, pSoapMessage);
+    if(retVal!=KErrNone)
+        {
+        delete pSoapMessage;
+        return retVal;
+        }
+
+    CleanupStack::PushL(pSoapMessage);
+
+    // Check for completeMessages
+    TBool completeServerMessages;
+    HasFacetL(KCompleteMessagesFacet,completeServerMessages);
+    if (completeServerMessages)
+        {
+        aParsed = pSoapMessage->AsXmlL();
+        }
+    else
+        {
+        // If the message contained SOAP fault it will be in the body.
+        // It's up to the client to check for a Fault.
+        aParsed = pSoapMessage->BodyAsStringL();
+        if (!aParsed)
+            {
+            retVal = KErrSenNoSoapBody; 
+						TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL - NULL from BodyAsStringL - return KErrSenNoSoapBody");
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // pSoapMessage
+    return retVal;
+    }
+
+
+EXPORT_C TInt CSenWebServiceSession::SendSoapMessageToConsumerL( CSenSoapMessage* apMessage,
+                                                                 const TInt aTxnId,
+                                                                 MSenRemoteServiceConsumer& aConsumer,
+                                                                 MSenProperties* aResponseTransportProperties )
+    {
+    if ( !apMessage )
+        {
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendSoapMessageToConsumerL");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"Fatal()!: NULL argument passed instead of valid pointer to CSenSoapMessage");
+        return HandleErrorL( KErrSenInternal, NULL, aTxnId, aConsumer, aResponseTransportProperties );
+        }
+
+    CleanupStack::PushL(apMessage);
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendSoapMessageToConsumerL");
+    TInt retVal(KErrNone);
+    // Check if consumer wishes to receive complete server messages:
+    TBool completeServerMessages;
+    HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+    if(completeServerMessages)
+        {
+        HBufC8* pMessageAsXML = apMessage->AsXmlL();
+        CleanupStack::PopAndDestroy(apMessage);
+        if (pMessageAsXML)
+            {
+            retVal = aConsumer.HandleMessageL( pMessageAsXML, aTxnId, aResponseTransportProperties );
+            }
+        }
+    else
+        {
+        //HBufC8* pBody = apMessage->BodyL().Content().AllocL(); 
+        HBufC8* pBody = apMessage->BodyAsStringL();
+        CleanupStack::PopAndDestroy(apMessage);
+        retVal = aConsumer.HandleMessageL( pBody, aTxnId, aResponseTransportProperties );
+        }    
+    return retVal;
+    }
+
+// SYNC, takes ownership of apSoapMessage
+EXPORT_C TInt CSenWebServiceSession::HandleSoapFaultL( CSenSoapMessage* apSoapMessage,
+                                                       HBufC8*& aResponse /*,
+                                                       CSenTransportProperties*& aResponseTransportProperties */) 
+    {
+    if( apSoapMessage )
+        {
+        CleanupStack::PushL(apSoapMessage);
+        CSenSoapFault* pDetached = apSoapMessage->DetachFaultL();
+        CleanupStack::PopAndDestroy( apSoapMessage );
+        TBool completeServerMessages(ETrue);
+        HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+        if(pDetached)
+            {
+            CleanupStack::PushL(pDetached);
+            // Response contains only soapfault in case no completeServerMessages facet 
+            // otherwise it should be left empty
+            // aResponse is updated only when detached soap fault is required.
+            if(completeServerMessages == EFalse)
+            	{
+            	aResponse = pDetached->AsXmlL();	
+            	}
+						TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::HandleErrorL:");
+						TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"- successfully detached SOAP fault:");
+            CleanupStack::PopAndDestroy(pDetached); // pDetached
+            // From *this* method, KErrSenSoapFault is *OK return code*, 
+            // just like KErrNone generally is..
+            return KErrSenSoapFault; 
+            }
+        }
+    return KErrNotFound; // SOAP fault not found
+    }
+
+// ASYNC, takes ownership of apSoapMessage
+EXPORT_C TInt CSenWebServiceSession::HandleSoapFaultL( CSenSoapMessage* apSoapMessage,
+                                                       const TInt aErrorCode,
+                                                       const TInt aTxnId,
+                                                       MSenRemoteServiceConsumer& aConsumer,
+                                                       MSenProperties* aResponseTransportProperties )
+    {
+    TInt retVal( KErrSenInternal );
+    if ( apSoapMessage ) 
+        {
+        CleanupStack::PushL(apSoapMessage); // ownership is here
+    
+        CSenSoapFault* pDetached = apSoapMessage->DetachFaultL();
+        if(pDetached)
+            {
+            CleanupStack::PopAndDestroy( apSoapMessage ); // de-alloc msg, detach OK
+            
+            CleanupStack::PushL(pDetached);
+            HBufC8* pAsXml = pDetached->AsXmlL();
+            CleanupStack::PopAndDestroy(pDetached);
+            
+            retVal = aConsumer.HandleErrorL(pAsXml, aErrorCode, aTxnId, aResponseTransportProperties);
+            }
+        else
+            {
+            // Could not detach Soap fault (this method was called, but aSoapMessage did not include fault!)
+            HBufC8* pAsXml = apSoapMessage->AsXmlL();
+            CleanupStack::PopAndDestroy( apSoapMessage ); // de-alloc, serialization ok
+            retVal = aConsumer.HandleErrorL(pAsXml, aErrorCode, aTxnId, aResponseTransportProperties);
+            }
+        }
+    else
+        {
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"Fatal(!): CSenWebServiceSession::HandleSoapFaultL - apSoapMessage arg is NULL. ");
+            retVal = aConsumer.HandleErrorL(NULL, aErrorCode, aTxnId, aResponseTransportProperties);
+        }        
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SendToConsumerL( HBufC8* apMessage,
+                                                      const TInt aTxnId,
+                                                      MSenRemoteServiceConsumer& aConsumer,
+                                                      MSenProperties* aResponseTransportProperties )
+    {
+    CleanupStack::PushL( apMessage );
+    CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"CSenWebServiceSession::SendToConsumerL - begin" );
+    TInt retVal(KErrNone);
+
+    // Check whether this is a response to one-way request; in such case, 
+    // there is no body to validate (but only few response properties):
+    if ( aResponseTransportProperties )
+        {
+        TBool isOnewayMsgRsp(EFalse);
+        aResponseTransportProperties->BoolPropertyL( KSenOnewayMessageOnOff, isOnewayMsgRsp );
+        if ( isOnewayMsgRsp )
+            {
+            // There is no response body to process, halt the execution of this method in here,
+            // and invoke the consumer immediately:
+            CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"-- About to invoke MSenRemoteServiceConsumer::HandleMessageL" );
+            CleanupStack::Pop( apMessage );
+            retVal = aConsumer.HandleMessageL( apMessage, aTxnId, aResponseTransportProperties );
+            CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("CSenWebServiceSession::SendToConsumerL - end: HandleMessageL returned: %d"), retVal));
+            return retVal; // skip the SOAP validation, response carries no body
+            }
+        }
+
+    
+    // SOAP orientated implementation:
+    CSenSoapMessage* pSoapMessage = NULL;
+    TInt leaveCode(KErrNone); 
+    
+    if( apMessage && apMessage->Length() > 0 )
+        {
+        TRAP( leaveCode, retVal = ParseResponseL( *apMessage, pSoapMessage ); )
+        }
+    else // apMessage == NULL or descriptor is of zero-length
+        {
+        if ( !apMessage )
+            {
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Note: apMessage argument is NULL => response is treated through KErrSenNoSoapBody");
+            }    
+        retVal = KErrSenNoSoapBody; // clearly, WSS assumes that all messages are SOAP!
+        }
+        
+    if( leaveCode != KErrNone )
+        {
+        // Parsing WAS attempted, but it failed(!)  
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Error: response could not be parsed into SOAP msg, leave code from parse: %d"), leaveCode));
+        pSoapMessage = NULL;
+        if( retVal==KErrNone )
+            {
+            // indicate with return value, that response is
+            // invalid - even though submit was ok, the
+            // response could NOT be parsed!
+            retVal = leaveCode;
+            }
+        }
+        
+    if(retVal == KErrNone)
+        {
+        CleanupStack::PopAndDestroy(apMessage);
+        CleanupStack::PushL( pSoapMessage );
+        // Response was parsed OK, now check whether it is a SOAP fault:
+        if (pSoapMessage->IsFault())
+            {
+            CleanupStack::Pop(pSoapMessage); // next method takes the ownership:
+            retVal = HandleSoapFaultL(pSoapMessage, KErrSenSoapFault, aTxnId, aConsumer, aResponseTransportProperties);
+            if( retVal == KErrSenSoapFault )
+                {
+                // SOAP fault response is treated as "OK"
+                retVal = KErrNone;
+                }
+            }
+        else
+            {
+            // Response is a valid SOAP envelope
+            CSLOG_L(aConsumer.ConnectionId()  ,  KMinLogLevel ,"CSenWebServiceSession::SendToConsumerL:");
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel ,"- Sending SOAP message to consumer.");
+            CleanupStack::Pop(pSoapMessage); // next method takes the ownership:
+            retVal = SendSoapMessageToConsumerL( pSoapMessage, aTxnId, aConsumer, aResponseTransportProperties );
+#ifdef _SENDEBUG
+            if( retVal!=KErrNone )
+                {
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL:");
+                CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- SendSoapMessageToConsumerL failed: %d"), retVal ));
+                }
+#endif
+            }
+        }
+    else // error recognized
+        {
+        delete pSoapMessage;
+        pSoapMessage = NULL;
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Error: response is not a SOAP message!");
+        
+        CleanupStack::Pop(apMessage);
+        retVal = HandleErrorL(retVal, apMessage, aTxnId, aConsumer, aResponseTransportProperties);
+        }
+    CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"CSenWebServiceSession::SendToConsumerL - end" );        
+    return retVal;
+    }
+
+// THIS IS WHAT TRANSPORT SEES:
+EXPORT_C TInt CSenWebServiceSession::SendErrorToConsumerL( const TInt aErrorCode,
+                                                           HBufC8* apError,
+                                                           const TInt aTxnId,
+                                                           MSenRemoteServiceConsumer& aConsumer,
+                                                           MSenProperties* aResponseTransportProperties )
+    {
+    CleanupStack::PushL(apError);
+    TInt retVal(KErrNone);
+
+    // Check whether this is a response to one-way request; in such case, 
+    // there is no body to validate (but only few response properties):
+    if ( aResponseTransportProperties )
+        {
+        TBool isOnewayMsgRsp(EFalse);
+        aResponseTransportProperties->BoolPropertyL( KSenOnewayMessageOnOff, isOnewayMsgRsp );
+        if ( isOnewayMsgRsp )
+            {
+            // There is no response body to process, halt the execution of this method in here,
+            // and invoke the consumer immediately:
+            CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"-- About to invoke MSenRemoteServiceConsumer::HandleMessageL" );
+            CleanupStack::Pop( apError );
+            retVal = aConsumer.HandleErrorL( apError, aErrorCode, aTxnId, aResponseTransportProperties );
+            CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("CSenWebServiceSession::SendToConsumerL - end: HandleMessageL returned: %d"), retVal));
+            return retVal; // skip the SOAP validation, response carries no body
+            }
+        }
+    
+    // SOAP orientated implementation:
+    CSenSoapMessage* pSoapMessage = NULL;
+    
+        TInt leaveCode(KErrNone); 
+    
+    if( apError && apError->Length() > 0 )
+        {
+        TRAP( leaveCode, retVal = ParseResponseL( *apError, pSoapMessage ); )
+        }
+    else // apMessage == NULL or descriptor is of zero-length
+        {
+        if ( !apError )
+            {
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Note: apError argument is NULL => response is treated through KErrSenNoSoapBody");
+            }    
+        retVal = KErrSenNoSoapBody; // clearly, WSS assumes that all messages are SOAP!
+        }
+    
+    if( leaveCode != KErrNone )
+        {
+        // Parsing WAS attempted, but it failed(!)
+        pSoapMessage = NULL;
+        
+        // THE RESPONSE IS NOT SOAP
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendErrorToConsumerL");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Error: response could not be parsed into SOAP msg!");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- ParseResponseL leaved: %d"), leaveCode ));
+        if( aErrorCode == KErrNone )
+            {
+            // In this rare case, indicate that SOAP envelope was broken!
+            // So, return KErrSenBrokenSoapEnvelope in here.
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- aErrorCode==KErrNone, but SOAP env is broken!");
+            
+            CleanupStack::Pop(apError);
+            retVal = HandleErrorL(KErrSenBrokenSoapEnvelope, apError, aTxnId, aConsumer, aResponseTransportProperties);
+            }
+        else
+            {
+            CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Returning error code received from transport: %d"), 
+                aErrorCode));
+
+            CleanupStack::Pop(apError);
+            retVal = HandleErrorL(aErrorCode, apError, aTxnId, aConsumer, aResponseTransportProperties);
+            }
+        }
+    else // ParseResponseL did not leave 
+        {
+        if (retVal == KErrNone )
+            {
+            CleanupStack::PopAndDestroy(apError);
+            // ParseResponseL OK
+            // Call for functionality which checks certain, "recoverable" SOAP errors:
+            // Some frameworks might be able to handle certain SOAP faults themselves
+            retVal = HandleSoapFaultL(pSoapMessage, aErrorCode, aTxnId, aConsumer, aResponseTransportProperties);
+            }
+        else // parsing failed or apError == NULL
+            {
+            delete pSoapMessage;
+            // ParseResponseL NOT ok!
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendErrorToConsumerL");
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Error: response is not a SOAP message!");
+            if ( aErrorCode == KErrNone )
+                {
+                // Rare case: for some odd reason transport did not return error code:
+                // - return the error code from ParseResponseL
+                CSLOG_L(aConsumer.ConnectionId()  , KNormalLogLevel,"- Transport did not return error code.");
+                CleanupStack::Pop(apError);
+                retVal = HandleErrorL(retVal, apError, aTxnId, aConsumer, aResponseTransportProperties);
+                }
+            else
+                {
+                // Just pass forward the error code received from transport:
+                CSLOG_L(aConsumer.ConnectionId()  , KNormalLogLevel,"- Just pass forward error code from transport.");
+                CleanupStack::Pop(apError);
+                retVal = HandleErrorL(aErrorCode, apError, aTxnId, aConsumer, aResponseTransportProperties);
+                }
+            }
+        }
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::HandleErrorL( const TInt aErrorCode,
+                                                   HBufC8* apError,
+                                                   const TInt aTxnId,
+                                                   MSenRemoteServiceConsumer& aConsumer,
+                                                   MSenProperties* aResponseTransportProperties )
+    {
+    // Current implementation does not handle non-SOAP errors 
+    // that occured at transport layer. Instead, the error is
+    // simply passed to consumer:
+    return aConsumer.HandleErrorL(apError, aErrorCode, aTxnId, aResponseTransportProperties); 
+    // Frameworks should override this method in order to recover
+    // from specific errors/faults
+    }
+
+
+EXPORT_C CSenXmlReader* CSenWebServiceSession::XmlReader()
+    {
+    return iFramework.Manager().XMLReader();
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ParseResponseL(const TDesC8& aResponse,
+                                                    CSenSoapMessage*& aMessage)
+    {
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL(TDesC8&, CSenSoapMessage*&");
+
+    TInt retVal(KErrNone);
+    retVal = NewMessageL(aMessage);
+
+    CleanupStack::PushL(aMessage);
+
+    if (retVal != KErrNone)
+        {
+        return retVal;
+        }
+
+    //////////////////////////////////////////////////////////////////////////
+		TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(_L("******************************************************")));
+		TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KMaxLogLevel  , _L("Response to be parsed (%d bytes):"), aResponse.Length()));
+        {
+				TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,aResponse);
+        //FILELOGALL(_L("WsLog"), _L("last_rsp.xml"), aResponse);
+        }
+		TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(_L("******************************************************")));
+    //////////////////////////////////////////////////////////////////////////
+
+    aMessage->SetReader(*XmlReader());
+    TInt leaveCode(KErrNone);
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"- Parsing response into SOAP message object:");
+    TBool normalParsing(ETrue);
+    if ( aResponse.Size() > KSenMaxLengthSaxParsingSoapMsg )
+        {
+        TInt ret(KErrNotFound);
+        TRAP(leaveCode, ret = HandleBodyWithoutParsingL(*aMessage, aResponse);)
+        if (leaveCode == KErrNone && ret == KErrNone)
+            {
+            normalParsing = EFalse;
+            }
+        }
+    
+    if ( normalParsing )
+        {
+        TRAP(leaveCode, aMessage->ParseL(aResponse));
+        }
+    
+    if(leaveCode==KErrNone)
+        {
+#ifdef _SENDEBUG
+        ///////////////////////////////////////////////////////////////////////
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(_L("---------------------------------------------------")));
+        HBufC8* pAsXml = aMessage->AsXmlL();
+        if(pAsXml)
+            {
+            CleanupStack::PushL(pAsXml);
+						TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL: OK!");
+						TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KMaxLogLevel  , _L(" SOAP message (%d bytes)"),
+                                pAsXml->Length()));
+						TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(*pAsXml));
+            CleanupStack::PopAndDestroy(); //pAsXml
+            }
+				TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(_L("---------------------------------------------------")));
+        ///////////////////////////////////////////////////////////////////////
+#endif // _SENDEBUG
+        retVal = ParseMessageL(*aMessage);
+        }
+    else
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"- Response is not SOAP message!");
+        retVal = leaveCode;
+        }
+    CleanupStack::Pop(); // aMessage
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ParseMessageL(CSenSoapMessage& aSoapMessage)
+    {
+    // We can verify, that SOAP message has Body:
+    if(!aSoapMessage.HasBody())
+        {
+        return KErrSenNoSoapBody;
+        }
+    else
+        {
+        return KErrNone;
+        }
+    /**
+     * We could verify wsse:Security headers
+     * but we don't have a need for that right now.
+     */
+    }
+
+EXPORT_C TInt CSenWebServiceSession::AddConsumerL(MSenRemoteServiceConsumer& aConsumer)
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::AddConsumerL");
+    iConsumerList.Reset(); 
+    TInt retVal = iConsumerList.Append(&aConsumer);
+    return retVal;
+    }
+
+// 2005: refactored GetConsumer() to Consumer()
+// Note: Same as client() in Java Ref. Impl.
+EXPORT_C MSenRemoteServiceConsumer* CSenWebServiceSession::Consumer()
+    {
+    TInt count(iConsumerList.Count());
+    if(count>0)
+        {
+        return iConsumerList[0];
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+EXPORT_C TBool CSenWebServiceSession::IsReadyL()
+    {
+    return (CSenServiceSession::StatusL() == KSenConnectionStatusReady);
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SubmitL(const TDesC8& aMessage,
+                                             const TDesC8& aTransportProperties,
+                                             MSenRemoteServiceConsumer& aConsumer,
+                                             HBufC8*& aResponse /*,
+                                             CSenTransportProperities*& apResponseTransportProperties */)
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL");
+
+    CSenSoapMessage* pMsg = NULL;
+    TInt retVal( MessageForSendingL(aMessage, aConsumer.Id(), pMsg) ); 
+    CleanupStack::PushL(pMsg);
+
+    if(retVal!=KErrNone)
+        {
+         CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- MessageForSendingL returned an error: %d"), retVal));
+        CleanupStack::PopAndDestroy(); // pMsg
+        return retVal;
+        }
+
+    HBufC8* pHttpBody = pMsg->AsXmlL();
+    if ( pHttpBody )
+        {
+        TPtrC8 endpoint = Endpoint();
+        CleanupStack::PushL(pHttpBody);
+        TPtr8 httpBody = pHttpBody->Des();
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d) about to submit:"),
+                            httpBody.Length()));
+        //CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(httpBody));
+//wslog        FILELOGALL(_L("WsLog"), _L("last_req.xml"), httpBody);
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+
+
+        MSenTransport& transport = aConsumer.TransportL();
+        retVal = transport.SubmitL(endpoint, httpBody, aTransportProperties, aResponse, aConsumer);
+
+        CleanupStack::PopAndDestroy(); // pHttpBody
+        }
+
+    CleanupStack::PopAndDestroy(); //  pMsg
+
+    if ( !aResponse )
+        {
+        // Response was NULL: probably either out
+        // of heap or some transport malfunction.
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Received NULL from transport.");
+        return retVal;
+        }
+
+    else if( aResponse->Length() < KSenSoapEnvelopeName().Length()*2 )
+        {
+        // No use parsing, Envelope -root element not there
+
+        // deliver non-soap body to consumer
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- response is not a SOAP envelope.");
+        return retVal;
+        }
+
+    CSenSoapMessage* pResponseSoapMsg = NULL;
+    TInt leaveCode(KErrNone);
+    TInt parseRetVal(KErrNone);
+    TRAP( leaveCode, parseRetVal = ParseResponseL(*aResponse, pResponseSoapMsg));
+
+    if( leaveCode!=KErrNone ) // parsing leaved!
+        {
+
+        pResponseSoapMsg = NULL; 
+
+        // Return directly the response, which was received from
+        // transport. Note that pResponseSoapMsg has already
+        // been deleted because of leave
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel , "CSenWebServiceSession::SubmitL:");
+       CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel , "- Error: response could not be parsed into SOAP msg!");
+        
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- ParseResponseL leaved: %d"), leaveCode ));
+
+        retVal = leaveCode;
+        // else return the error code received from transport (retVal)
+        }
+    else // parsing did not leave..
+        {
+        if ( parseRetVal != KErrNone ) // .. but parsing failed
+            {
+            // Not mandatory, ParseResponseL should take 
+            // care of gc, if it returns an error:
+            delete pResponseSoapMsg; 
+
+            // NOTE - 2005 change: now the body of such
+            // response will be returned to the caller
+            // (with the error code).
+
+            // Response could not be parsed into SOAP message(!)
+            CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Response could not be parsed, error: (%d)"),
+                parseRetVal));
+
+            if(retVal==KErrNone)
+                {
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning error code from ParseResponseL");
+                // transport did not return error, return error from ParseResponseL
+                retVal = parseRetVal;
+                }
+            // else: return the error code received from transport
+            }
+        else // .. and parsing went ok
+            {
+            CleanupStack::PushL( pResponseSoapMsg );
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Response is a SOAP message");
+
+            // Check whether "complete server messages" is on or off
+            TBool completeServerMessages(EFalse);
+            HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+
+            // Response is OK and SOAP message. 
+            if( pResponseSoapMsg->IsFault() )
+                {
+                // Response is a SOAP fault
+                retVal = KErrSenSoapFault; // might change, if framework handles this fault
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"Response is a SOAP fault. Calling HandleErrorL.");
+
+                // Check if SOAP fault could be handled by the framework:
+                HBufC8* pResponse = NULL;
+
+                // Note that HandleSoapFaultL -method normally detaches any SOAP fault:
+                CleanupStack::Pop(pResponseSoapMsg);
+                retVal = HandleSoapFaultL(pResponseSoapMsg, pResponse);
+                if(retVal == KErrSenSoapFault)
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                    if( completeServerMessages )
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning SOAP envelope with fault");
+                        // The following lines are important when there is a resending
+                        // the new response is copied to aResponse.
+                        // When there is no resend, then pResponse = NULL no copy happens                     
+                        if(pResponse)
+                        	{
+                        	delete aResponse;
+                        	aResponse = pResponse;
+                        	}
+                        // aResponse will be returned (original response from transport)
+                        }
+                    else // we can pass the detached fault
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning detached a SOAP fault.");
+                        // Destroy the original response buffer received from transport,
+                        // since now the parsed SOAP envelope can be returned
+                        delete aResponse;
+                        aResponse = pResponse;
+                        }
+                    }
+                else if ( retVal == KErrNone )
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Framework handled this SOAP fault.");
+                    // KErrNone means that fault was handled
+                    // properly (by framework spesific code)
+                    // and consumer may receive the response 
+                    // it requested.
+
+                    // Currently there are no SOAP faults handled
+                    // in WebServiceSession class, so KErrNone is
+                    // never returned. This if -section is here 
+                    // only for *frameworks to extend*.
+
+                    // Destroy the original response buffer received from transport,
+                    // since now the parsed SOAP envelope can be returned
+                    delete aResponse;
+                    aResponse = pResponse;
+                    }
+                else if ( retVal == KErrNotFound )
+                    {
+                    // SOAP fault element  could not be found
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL - MAJOR:");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"-IsFault()==true BUT fault element NOT found!");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"-returning KErrSenBrokenSoapFault");
+                    retVal = KErrSenBrokenSoapFault;
+                    // Note: 2005 change: now the broken (original) response
+                    // from the transport is returned, instead of NULL
+                    }
+#ifdef _SENDEBUG
+                else 
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                    CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- HandleErrorL failed: %d"), retVal));
+                    }
+#endif // _SENDEBUG
+
+                }
+            else // This SOAP envelope is NOT a fault
+                {
+                if ( completeServerMessages )
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning complete SOAP envelope.");
+                    // Destroy the original response buffer received from
+                    // transport, since now the parsed SOAP envelope can
+                    // be returned
+
+                    delete aResponse;
+                    aResponse = NULL;
+                    aResponse = pResponseSoapMsg->AsXmlL(); 
+                    }
+                else
+                    {
+                    HBufC8* pBody = pResponseSoapMsg->BodyAsStringL();
+                    if(pBody)
+                        {
+                        // Destroy the original response buffer received from 
+                        // transport, since now the SOAP body must be returned
+                        delete aResponse;
+                        aResponse = pBody;
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Detached SOAP message body.");
+                        }
+                    else
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Could not detach SOAP body(!) - return KErrSenNoSoapBody");
+                        retVal = KErrSenNoSoapBody;
+                        }
+                    }
+                CleanupStack::PopAndDestroy(pResponseSoapMsg);
+                }
+            }
+        }
+
+#ifdef _SENDEBUG
+    if(aResponse)
+        {
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"-------------------------------------------------------------------");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("Submit response (%d bytes):"),
+                            aResponse->Length()));
+        //CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( *aResponse ));
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"-------------------------------------------------------------------");
+        }
+#endif
+
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SendL( const TDesC8& aMessage, 
+                                            const TDesC8& aTransportProperties,
+                                            MSenRemoteServiceConsumer& aConsumer,
+                                            TInt& aTxnId,
+                                            HBufC8*& /*aRevalidationError*/ )
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendL");
+
+    CSenSoapMessage* pMsg = NULL;
+    TInt retVal( MessageForSendingL(aMessage, aConsumer.Id(), pMsg) ); 
+    CleanupStack::PushL(pMsg);
+
+    if(retVal!=KErrNone)
+        {
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- MessageForSendingL returned an error: %d"), retVal));
+        CleanupStack::PopAndDestroy(); // pMsg
+        return retVal;
+        }
+
+    HBufC8* pHttpBody = pMsg->AsXmlL();
+    if(pHttpBody)
+        {
+        TPtrC8 endpoint  = Endpoint();
+        CleanupStack::PushL(pHttpBody);
+        TPtr8 httpBody = pHttpBody->Des();
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to send:"), httpBody.Length()));
+        CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(httpBody));
+//wslog        FILELOGALL(_L("WsLog"), _L("last_req.xml"), httpBody);
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+
+        MSenTransport& t = aConsumer.TransportL();
+
+        retVal = t.SendL( endpoint, httpBody, aTransportProperties, *this, aConsumer, aTxnId );
+
+        CleanupStack::PopAndDestroy(); // pHttpBody
+        }
+
+    CleanupStack::PopAndDestroy(); //  pMsg
+    return retVal;
+    }
+
+
+
+EXPORT_C void CSenWebServiceSession::SetFrameworkHeadersL(CSenSoapMessage& aMsg)
+    {
+    if ( iCredentialPtr.Credential() )
+        {
+        CSenInternalCredential* pCred = iCredentialPtr.Credential();
+        HBufC8* pAsXml = pCred->AsXmlL();
+        CleanupStack::PushL(pAsXml);
+        aMsg.SetSecurityHeaderL(*pAsXml);
+        CleanupStack::PopAndDestroy(pAsXml);
+        }
+    else
+        {
+        // There is no credential available
+        aMsg.SetSecurityHeaderL(KNullDesC8); 
+        }
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SetUserNameL(TDesC8& aUsername)
+    {
+    TInt retVal(KErrNone);
+    HBufC8* pToken8 = NULL;
+
+    retVal = CSenWsSecurityHeader::UsernameTokenL(aUsername, pToken8);
+    CleanupStack::PushL(pToken8);
+
+    if(retVal != KErrNone)
+        {
+        CleanupStack::PopAndDestroy(1); // token
+        return retVal;
+        }
+    else if(pToken8)
+        {
+        if(iSecurity == NULL)
+            {
+            iSecurity = pToken8->Des().AllocL();
+            }
+        else
+            {
+            TPtr8 ptr = iSecurity->Des();
+
+            if (ptr.MaxLength() < pToken8->Length() + ptr.Length())
+                {
+                HBufC8* newSecurity = HBufC8::NewLC(pToken8->Length()
+                                                    +ptr.Length());
+                TPtr8 newPtr = newSecurity->Des();
+                newPtr.Append(*iSecurity);
+                newPtr.Append(*pToken8);
+                delete iSecurity;
+                iSecurity = newSecurity;
+                CleanupStack::Pop();    // newSecurity
+                }
+            else
+                {
+                ptr.Append(*pToken8);
+                }
+            }
+        }
+    CleanupStack::PopAndDestroy(); // pToken8
+
+    return retVal;
+    }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::Endpoint()
+    {
+    if(iEndpoint)
+        return *iEndpoint;
+    else
+        return KNullDesC8();
+    }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::Contract()
+    {
+    if(iContract)
+        return *iContract;
+    else
+        return KNullDesC8();
+    }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::FrameworkId()
+    {
+    if(iFrameworkId)
+        return *iFrameworkId;
+    else
+        return KNullDesC8();
+    }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::FrameworkVersion()
+    {
+    return KNullDesC8();
+    }
+
+EXPORT_C void CSenWebServiceSession::SetContractL(const TDesC8& aContract)
+    {
+    HBufC8* pNew = NULL;
+    if(aContract!=KNullDesC8)
+        {
+        pNew = aContract.AllocL();
+        }
+
+    delete iContract;
+    iContract = pNew;
+    }
+
+EXPORT_C void CSenWebServiceSession::SetEndPointL(const TDesC8& aEndpoint)
+    {
+    HBufC8* pNew =NULL;
+    if(aEndpoint!=KNullDesC8)
+        {
+        pNew = aEndpoint.AllocL();
+        }
+
+    delete iEndpoint;
+    iEndpoint = pNew;
+
+    SetStatusL();
+    }
+
+EXPORT_C void CSenWebServiceSession::SetSecurityL(const TDesC8& aSecurity)
+    {
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::SetSecurityL");
+    TInt retVal(KErrNone);
+    
+    if ( aSecurity.Length() < 1 )
+        {
+        delete iSecurity;
+        iSecurity = NULL;
+        iCredentialPtr.RemoveCredentialObserver(*this);
+        iCredentialPtr.Close();
+
+        // invalidate the session, because we have no credential 
+        //iValidUntil.Set(_L("19000101:")); // way back in history: January 1st 1900
+        //acording to ID-WSF no need of reset the credential here
+        }
+     else
+        {
+        if ( HasSecurity() )
+            {
+            iCredentialPtr.RemoveCredentialObserver(*this);
+            ((MSenServiceManager&)iFramework.Manager()).UpdateCredentialL(
+                                iCredentialPtr.Credential()->IdentifierL().IdL(),
+                                aSecurity,
+                                retVal);
+            if ( retVal == KErrNone )
+                {
+                iCredentialPtr.AddCredentialObserverL(*this);
+                CSenInternalCredential* pCred = iCredentialPtr.Credential();
+                
+                if ( iClientServerInterval.Int64() != 0 )
+                    {
+                    TBuf8<64> buf;
+                    buf.AppendNum(iClientServerInterval.Int64());
+                    pCred->PropertiesL().SetPropertyL(KServiceInterval1, buf);
+                    }
+                FillCredentialIdentifierL(pCred->IdentifierL());
+
+                TTime validUntil = iValidUntil;
+                pCred->PropertiesL().SetValidUntilL(validUntil);
+                }
+            else
+                {
+                delete iSecurity;
+                iSecurity = NULL;
+                iCredentialPtr.Close();
+                
+                // invalidate the session, because we have no credential 
+        		iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900  //CodeScannerWarnings
+                }
+            }
+        else
+            {
+            RSenCredentialPtr credentialPtr =
+                    ((MSenServiceManager&)iFramework.Manager()).AddCredentialL(aSecurity, retVal);
+        
+            if ( retVal == KErrNone )
+                {        
+
+                iCredentialPtr.RemoveCredentialObserver(*this);
+                iCredentialPtr.Close();
+                iCredentialPtr = credentialPtr.Clone();
+                iCredentialPtr.AddCredentialObserverL(*this);	//codescannerwarnings
+
+                CSenInternalCredential* pCred = iCredentialPtr.Credential();
+                
+                if ( iClientServerInterval.Int64() != 0 )
+                    {
+                    TBuf8<64> buf;
+                    buf.AppendNum(iClientServerInterval.Int64());
+                    pCred->PropertiesL().SetPropertyL(KServiceInterval1, buf);
+                    }
+                FillCredentialIdentifierL(pCred->IdentifierL());	//codescannerwarnings
+                
+                TTime validUntil = iValidUntil;
+                pCred->PropertiesL().SetValidUntilL(validUntil);
+                
+                SetCredentialIdL(pCred->IdentifierL().IdL());
+                }
+            else
+                {
+                delete iSecurity;
+                iSecurity = NULL;
+                iCredentialPtr.RemoveCredentialObserver(*this);
+                iCredentialPtr.Close();
+                
+                // invalidate the session, because we have no credential 
+                iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900
+                }
+            }
+        }
+    }
+    
+/*    
+EXPORT_C TInt CSenWebServiceSession::RemoveConsumerL(MSenRemoteServiceConsumer& aConsumer)    
+    {
+    LOG_WRITE_L("CSenWebServiceSession::RemoveConsumerL");
+    CSenServiceSession::RemoveConsumerL(aConsumer);
+    
+    // If this session has no consumers, we can hold our grip to the credential
+    // (note: this does NOT mean that credential is removed, not at all(!), but
+    //  that new search for the credential has to be performed).
+    
+    // NOTE: this cannot be done at ws service session layer as long as ID-WSF does not
+    // use credential sharing / lookup mechanism in cases where session is found invalid
+    // (this is done in WS-* framework plug-in)
+    TInt count(iConsumerList.Count());
+    if( count == 0 )
+        {
+        LOG_WRITE_L("- Credential count == 0");
+        LOG_WRITE_L("-> Closing the handle to the credential owned by Credential Manager.");
+        SetSecurityL(KNullDesC8);    
+        }
+    }
+*/    
+void CSenWebServiceSession::SetCredentialIdL(TInt aCredentialId)
+    {
+    TBuf8<KCredIdBufSize> buffer;
+    buffer.Num(aCredentialId);
+
+    delete iSecurity;
+    iSecurity = NULL;
+    TInt leaveCode( KErrNone );
+    TRAP( leaveCode, iSecurity = HBufC8::NewL( buffer.Length()+KCredentialIdStart().Length()+KCredentialIdEnd().Length() ); )
+    if( !leaveCode && iSecurity )
+        {
+        TPtr8 sec = iSecurity->Des();
+        sec.Append( KCredentialIdStart );
+        sec.Append( buffer);
+        sec.Append( KCredentialIdEnd );
+        }
+#ifdef _SENDEBUG
+    else
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::SetCredentialId(): iSecurity = HBufC8::NewL leaved (OOM)!");
+        }
+#endif // _SENDEBUG        
+    }
+
+EXPORT_C TInt CSenWebServiceSession::GetCredentialIdL()
+    {
+    TInt retVal(0);
+    if (HasSecurity())
+        {
+        retVal = iCredentialPtr.Credential()->IdentifierL().IdL();	//codescannerwarnings
+        }
+    return retVal;
+    }
+
+    
+EXPORT_C void CSenWebServiceSession::FillCredentialIdentifierL(CSenCredentialIdentifier& aIdentifier)
+    {
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::FillCredentialIdentifierL");
+    if ( iEndpoint )
+        {
+				TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KNormalLogLevel  ,  _L8("- Setting endpoint to credential as property: %S"), iEndpoint ));
+        aIdentifier.SetPropertyL(KEndpointLocalname, *iEndpoint);
+        }
+    }
+    
+EXPORT_C TInt CSenWebServiceSession::TryToSearchValidCredentialL()
+    {
+		TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL()");
+    
+    // Get CredentialIdentifier which should include ProviderID
+    CSenCredentialIdentifier* pCredIdentifier = CSenCredentialIdentifier::NewLC();
+    FillCredentialIdentifierL(*pCredIdentifier);
+    
+    CSenWSDescription* pPattern = CSenWSDescription::NewLC();
+    CSenElement& patternElement = ((CSenWSDescription*)pPattern)->AsElement();
+    
+    TPtrC8 providerId(KNullDesC8);
+    
+    RXmlEngNodeList<TXmlEngElement> list;
+    CleanupClosePushL(list);
+    TXmlEngElement element = pCredIdentifier->AsElementL();
+    element.GetChildElements(list);
+    while ( list.HasNext() )
+        {
+        TXmlEngElement element = list.Next();
+        if ( element.Name() != KSenIdpProviderIdLocalname )
+            {
+            CSenElement& addedElement = patternElement.AddElementL(element.Name());
+            addedElement.SetContentL(element.Text());
+            }
+        else
+            {
+            providerId.Set(element.Text());
+            }
+        }
+    
+    CSenIdentityProvider* pIdentityProvider = NULL;
+    if ( providerId != KNullDesC8 )
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL():");
+				TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KNormalLogLevel  , _L8("- Trying to search IdentityProvider using ProviderId : %S"), &providerId));
+        CSenWSDescription* pIdpPattern = CSenWSDescription::NewLC();
+        pIdpPattern->SetEndPointL(providerId);
+        pIdentityProvider = iFramework.Manager().IdentityProviderL(*pIdpPattern);
+        CleanupStack::PopAndDestroy(pIdpPattern);
+        }
+
+    RSenCredentialPtrArray credentialPtrsArray;
+    CleanupClosePushL(credentialPtrsArray);
+
+    TInt retVal(KErrNone);
+    if ( pIdentityProvider )
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL() - IdentityProvider was found. Trying to search related Credentials.");
+        retVal = ((MSenServiceManager&)iFramework.Manager()).CredentialsL(*pPattern, 
+                                                                          *pIdentityProvider,
+                                                                          credentialPtrsArray);
+        }
+    else
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL() - FATAL: IdentityProvider was NOT found:");
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"- Trying to search Credentials without IdentityProvider information.");
+                retVal = ((MSenServiceManager&)iFramework.Manager()).CredentialsL(*pPattern,
+                                                                          credentialPtrsArray);
+        }
+        
+    if ( (retVal == KErrNone) && (credentialPtrsArray.Count() > 0) )
+        {
+				TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KNormalLogLevel  ,_L8("CSenWebServiceSession::TryToSearchValidCredentialL(): %d Credentials found."), credentialPtrsArray.Count()));
+        // Take the first valid Credential from found Credentials array.
+        TBool credentialOK(EFalse);
+        TInt count = credentialPtrsArray.Count();
+        for (TInt i=0; i < count; i++)
+            {
+            SetCredentialPtrL(credentialPtrsArray[0]);//codescannerwarnings
+            iValidUntil = iCredentialPtr.Credential()->PropertiesL().ValidUntilL();	//codescannerwarnings
+            
+            if ( ComputeStatusL() == KSenConnectionStatusReady)
+                {
+                credentialOK = ETrue;
+                break;
+                }
+            }
+            
+        if ( credentialOK )
+            {
+						TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KMinLogLevel  , _L8("CSenWebServiceSession::TryToSearchValidCredentialL(): Valid Credential were found. CredentialId : %d"),
+                            iCredentialPtr.Credential()->IdentifierL().IdL()));	//codescannerwarnings
+            retVal = KErrNone;
+            }
+        else
+            {
+						TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL(): Valid Credentials were not found.");
+            SetSecurityL(KNullDesC8);
+            retVal = KErrNotFound;
+            }
+        }
+    else
+        {
+				TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL(): Credentials were not found.");
+        retVal = KErrNotFound;
+        }
+        
+    CleanupStack::PopAndDestroy(&credentialPtrsArray);
+        
+    CleanupStack::PopAndDestroy(&list); // Close()
+    CleanupStack::PopAndDestroy(pPattern);
+    CleanupStack::PopAndDestroy(pCredIdentifier);
+    
+    return retVal;
+    }
+
+EXPORT_C const TTime& CSenWebServiceSession::ValidUntilL()
+    {
+    if (iValidUntil != Time::NullTTime())
+        {
+        return iValidUntil;
+        }
+    else
+        {
+        const TTime& MAX_TIME = Time::MaxTTime();
+        return MAX_TIME; // if no expiration was set, the session is
+                         // valid forever(!)
+        }
+    }
+
+EXPORT_C void CSenWebServiceSession::WriteAsXMLToL(RWriteStream& aWriteStream)
+    {
+    _LIT8(KTouch, "touch");
+    aWriteStream.WriteL(KSDFramework);
+    aWriteStream.WriteL(FrameworkId());
+    CSenElement* elem = &AsElement();
+    
+    const TDesC8* attrVal = elem->AttrValue(KTouch);
+    	if(attrVal != NULL)
+    	{
+    	aWriteStream.WriteL(KSenDblQuot);
+    	aWriteStream.WriteL(KSenSpace);
+    	aWriteStream.WriteL(KTouch);
+    	aWriteStream.WriteL(KSenEqualsDblQuot);
+    	aWriteStream.WriteL(*attrVal);	
+    	}
+    aWriteStream.WriteL(KTagWithAttrEnd);
+
+    // write contract
+    if(iContract && iContract->Length()>0)
+        {
+        aWriteStream.WriteL(KContractStart);
+        aWriteStream.WriteL(*iContract);
+        aWriteStream.WriteL(KContractEnd);
+        }
+
+    // write endpoint
+    TPtrC8 cue = TransportCue();
+    if(iEndpoint && iEndpoint->Length()>0)
+        {
+        if( iTransportCue && iTransportCue->Length()>0)
+            {
+            // both cue and endpoint
+            aWriteStream.WriteL(KEndPointStartWithCue);
+            aWriteStream.WriteL(*iTransportCue);
+            aWriteStream.WriteL(KTagWithAttrEnd);
+            aWriteStream.WriteL(*iEndpoint);
+            aWriteStream.WriteL(KEndPointEnd);
+            
+            }
+        else
+            {
+            // just endpoint
+            aWriteStream.WriteL(KEndPointStart);
+            aWriteStream.WriteL(*iEndpoint);
+            aWriteStream.WriteL(KEndPointEnd);
+            }
+        }
+    else if ( iTransportCue && iTransportCue->Length() > 0 )
+        {
+        // only cue, but no endpoint
+        aWriteStream.WriteL(KEndPointStartWithCue);
+        aWriteStream.WriteL(*iTransportCue);
+        aWriteStream.WriteL(KTagWithAttrClose);
+        }
+
+    // write security credentials
+    if(iSecurity)
+        {
+        aWriteStream.WriteL(KCredentialsStart);
+        if (iValidUntil != Time::NullTTime())
+            {
+            HBufC8* dateDes = HBufC8::NewLC(256);
+            TPtr8 datePtr = dateDes->Des();
+            SenDateUtils::ToXmlDateTimeUtf82L(datePtr, iValidUntil);
+            HBufC8* tempBuf = HBufC8::NewLC(KNotOnOrAfterFormat().Length() +
+                                            datePtr.Length());
+
+            TPtr8 ptr = tempBuf->Des();
+            ptr.Format(KNotOnOrAfterFormat, dateDes);
+
+            aWriteStream.WriteL(ptr);
+            CleanupStack::PopAndDestroy(2); // tempBuf, dateDes
+            tempBuf = NULL;
+            }
+        else
+            {
+            aWriteStream.WriteL(KEmptyTagEnd);
+            }
+
+        aWriteStream.WriteL(*iSecurity);
+        aWriteStream.WriteL(KCredentialsEnd);
+        }
+
+    CSenElement* pProviderPolicyElement =
+                            AsElement().Element(KProviderPolicyLocalName);
+
+    if(pProviderPolicyElement)
+        {
+        HBufC8* pProviderPolicyAsXmlUtf8 = pProviderPolicyElement->AsXmlL();
+        if(pProviderPolicyAsXmlUtf8)
+            {
+            CleanupStack::PushL(pProviderPolicyAsXmlUtf8);
+            aWriteStream.WriteL(*pProviderPolicyAsXmlUtf8);
+            CleanupStack::PopAndDestroy(); // pProviderPolicyAsXmlUtf8
+            }
+        }
+
+    WriteExtensionsAsXMLToL(aWriteStream);
+    
+  //Writing the ServicePolicy to XML  
+    MSenServicePolicy* servicePolicy = ServicePolicy();
+    if(servicePolicy)
+        {
+        CSenServicePolicy* ele = (CSenServicePolicy*)servicePolicy;
+        CSenElement* pServicePolicyElement = &ele->AsElement();          
+        if(pServicePolicyElement)
+            {
+            HBufC8* pServicePolicyAsXmlUtf8 = pServicePolicyElement->AsXmlL();
+            if(pServicePolicyAsXmlUtf8)
+                {
+                CleanupStack::PushL(pServicePolicyAsXmlUtf8);            
+                aWriteStream.WriteL(*pServicePolicyAsXmlUtf8);
+                CleanupStack::PopAndDestroy(); // pProviderPolicyAsXmlUtf8
+                }
+            }
+        }            
+
+    aWriteStream.WriteL(KSDEnd);
+    aWriteStream.WriteL(KNewLine);
+
+
+
+    }
+
+
+
+EXPORT_C TInt CSenWebServiceSession::SubmitSoapL(const TDesC8& aSoapMessage, 
+                                                 const TDesC8& aTransportProperties,
+                                                 MSenRemoteServiceConsumer& aConsumer,
+                                                 HBufC8*& aResponse)
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+    TPtrC8 endpoint  = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to submit:"), aSoapMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( aSoapMessage ));
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+#endif
+
+    MSenTransport& t = aConsumer.TransportL();
+
+    TInt retVal = t.SubmitL(endpoint, aSoapMessage, aTransportProperties, aResponse, aConsumer);
+
+    if(!aResponse)
+        {
+        // Response was NULL: probably either out
+        // of heap or some transport malfunction.
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Received NULL from transport.");
+        return retVal;
+        }
+    else if(aResponse->Length() < KSenSoapEnvelopeName().Length()*2)
+        {
+        // No use parsing, Envelope -root element not there.
+        // Just deliver this "non-soap" response to consumer
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Response is not a SOAP envelope.");
+        return retVal;
+        }
+
+    // Attempt to parse the response here. SOAP faults 
+    // are to be searched after,
+    CSenSoapMessage* pResponseSoapMsg = NULL;
+    TInt leaveCode(KErrNone);
+    TInt parseRetCode(KErrNone);
+    TRAP( leaveCode, (parseRetCode =
+        ParseResponseL(*aResponse, pResponseSoapMsg)) );
+
+    if(leaveCode!=KErrNone)
+        {
+        // Return directly the response, which was received from
+        // transport. Note that pResponseSoapMsg has already
+        // been deleted because of leave
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8(" - ParseResponseL leaved: %d"), leaveCode ));
+        
+        if(retVal==KErrNone) // retVal still SubmitL() return value
+            {
+            // Indicate with return value, that response is
+            // invalid - even though submit was ok, the
+            // response could NOT be parsed(!).
+            retVal = leaveCode;
+            }
+        }
+    else // ParseResponseL did not leave..
+        {
+        if(parseRetCode != KErrNone) // .. but returned an error
+            {
+            // Not mandatory, ParseResponseL should take 
+            // care of gc, if it returns an error:
+             delete pResponseSoapMsg; 
+             CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+
+            CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Parsing failed, error: %d"),
+                    parseRetCode));
+
+            if(retVal==KErrNone) // submit was ok
+                {
+                // Indicate with return value, that response is
+                // invalid - even though submit was ok, the
+                // response could NOT be parsed!
+                retVal = parseRetCode;
+                }
+            }
+        else // .. and parsing was successful
+            {
+            CleanupStack::PushL(pResponseSoapMsg);
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Response is a SOAP message");
+
+            TBool completeServerMessages(ETrue);
+            HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+
+            // response is OK and in SOAP form.
+            if(pResponseSoapMsg->IsFault())
+                {
+                // Response is a SOAP fault
+                retVal = KErrSenSoapFault; // might change, if framework handles this fault
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Response is a SOAP fault. Calling HandleErrorL.");
+
+                // Check if this SOAP fault could be handled by the framework
+                HBufC8* pResponse = NULL;
+                CleanupStack::Pop(pResponseSoapMsg);
+                retVal = HandleSoapFaultL(pResponseSoapMsg, pResponse/*, aResponseTransportProperties */);
+
+                if(retVal == KErrSenSoapFault)
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                    if(completeServerMessages)
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning SOAP envelope with fault");
+						// The following lines are important when there is a resending
+                        // the new response is copied to aResponse.
+                        // When there is no resend, then pResponse = NULL no copy happens                     
+                        if(pResponse)
+                        	{
+                        	delete aResponse;
+                        	aResponse = pResponse;
+                        	}                        // aResponse will be returned (original response from transport)
+                        }
+                    else // Pass the detached fault
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Returning detached a SOAP fault.");
+                        // Destroy the original response buffer received from transport,
+                        // since now the parsed SOAP envelope can be returned
+                        delete aResponse;
+                        aResponse = pResponse;
+                        }
+                    }
+                else if(retVal == KErrNone)
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Framework handled this SOAP fault.");
+                    // KErrNone means that fault was handled
+                    // properly (by framework spesific code)
+                    // and consumer may receive the response 
+                    // it requested.
+
+                    // Currently there are no SOAP faults handled
+                    // in WebServiceSession class, so KErrNone is
+                    // never returned. This if -section is here 
+                    // only for *frameworks to extend*.
+
+                    // Destroy the original response buffer received from transport,
+                    // since now the parsed SOAP envelope can be returned
+                    delete aResponse;
+                    aResponse = pResponse;
+                    }
+                else if(retVal==KErrNotFound)
+                    {
+                    // SOAP fault element  could not be found
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL - MAJOR:");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"-IsFault()==true BUT fault element NOT found!");
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"-returning KErrSenBrokenSoapFault");
+                    retVal = KErrSenBrokenSoapFault;
+                    // Note: 2005 change: now the broken (original) response
+                    // from the transport is returned, instead of NULL
+                    }
+#ifdef _SENDEBUG
+                else 
+                    {
+                    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                    CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- HandleErrorL failed: %d"), retVal));
+                    }
+#endif // _SENDEBUG
+                } 
+            else // this SOAP envelope is NOT a fault
+                {
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Response is a SOAP envelope.");
+
+                // Check complete server messages on/off
+                if(!completeServerMessages)
+                    {
+                    HBufC8* pBody = pResponseSoapMsg->BodyAsStringL();
+                    if(pBody)
+                        {
+                        // Destroy the original response buffer received from transport,
+                        // since now the parsed SOAP envelope can be returned
+                        delete aResponse;
+                        aResponse = pBody;
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Detached SOAP message body.");
+                        }
+                    else
+                        {
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Could not detach SOAP body(!) - return KErrSenNoSoapBody");
+                        // Note: 2005 change: now the broken (original) response
+                        // from the transport is returned, instead of NULL
+                        retVal = KErrSenNoSoapBody;
+                        }
+                    }
+                
+                CleanupStack::PopAndDestroy(pResponseSoapMsg);
+                }
+                // else { // return complete server message }
+                
+            }
+        }
+
+#ifdef _SENDEBUG
+    if(aResponse)
+        {
+        
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"------------------------------------------------------------");
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+        CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Response (%d bytes):"), aResponse->Length()));
+        CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( *aResponse ));
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"------------------------------------------------------------");
+        }
+#endif
+    return retVal;
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SendSoapL( const TDesC8& aSoapMessage, 
+                                                const TDesC8& aTransportProperties,
+                                                MSenRemoteServiceConsumer& aConsumer,
+                                                TInt& aTxnId,
+                                                HBufC8*& /* aRevalidationError*/ ) // SIFs should utilize aRevalidationError
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendSoapL:");
+    TPtrC8 endpoint  = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S:"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to send:"), 
+                    aSoapMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( aSoapMessage ));
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"////////////////////////////////////////////////////////");
+#endif
+
+    MSenTransport& t = aConsumer.TransportL();
+    TInt retVal( t.SendL(endpoint, aSoapMessage, aTransportProperties, *this, aConsumer, aTxnId) );
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenWebServiceSession::SendSoapL:");
+
+    CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Received transaction ID: %d"), aTxnId));
+    return retVal;
+    }
+
+
+
+// NOTE: the ownership of the consumer-pointer(s), which are copied (appended)
+// into aConsumers array is NOT transfered to the caller!
+
+// 2005: refactored GetConsumers() to Consumers()
+EXPORT_C TInt CSenWebServiceSession::Consumers(RServiceConsumerArray& aConsumers) const
+    {
+    TInt count(iConsumerList.Count());
+        {
+        for(TInt i=0; i<count; i++)
+            {
+            // creates a copy of pointers, but ownership is NOT transferred!
+            TInt error = aConsumers.Append(iConsumerList[i]);
+            if(error != KErrNone)
+                return error;
+            }
+        }
+        return KErrNone;
+    }
+
+EXPORT_C TTimeIntervalMicroSeconds
+                                CSenWebServiceSession::ClientServerInterval()
+    {
+    return iClientServerInterval;
+    }
+
+EXPORT_C void CSenWebServiceSession::SetClientServerIntervalL(
+                                        TTimeIntervalMicroSeconds aInterval)	//codescannerwarnings
+    {
+    iClientServerInterval = aInterval;
+    if ( iCredentialPtr.Credential() )
+        {
+        TBuf8<64> buf;
+        buf.AppendNum(iClientServerInterval.Int64());
+        iCredentialPtr.Credential()->PropertiesL().SetPropertyL(KServiceInterval1, buf);	//CodeScannerWarnings
+        }
+    }
+
+EXPORT_C TBool CSenWebServiceSession::HasConsumer() const
+    {
+    if (iConsumerList.Count() > 0) 
+        {
+        return ETrue;
+        }
+    else 
+        {
+        return EFalse;
+        }
+    }
+
+EXPORT_C void CSenWebServiceSession::StartTransaction()
+    {
+    // Nothing in framework base class level
+    }
+
+EXPORT_C void CSenWebServiceSession::TransactionCompleted()
+    {
+    // Nothing in framework base class level
+    }
+
+EXPORT_C TBool CSenWebServiceSession::HasSuperClass( TDescriptionClassType aType )
+    {
+    if( aType == MSenServiceDescription::EServiceSession ) // direct superclass!
+        {
+        // If asked type is the know *direct* father/mother, return true:
+        return ETrue; 
+        } 
+    else
+        { 
+        // Otherwise, ask from direct superclass (may invoke chain of recursive calls)
+        return CSenServiceSession::HasSuperClass( aType ); 
+        }
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SetTransportCueL(const TDesC8& aCue)
+    {
+    HBufC8* pNew =NULL;
+    if(aCue!=KNullDesC8)
+        {
+        pNew = aCue.AllocL();
+        }
+    delete iTransportCue;
+    iTransportCue = pNew;
+    
+    return KErrNone;
+    }
+
+EXPORT_C HBufC8* CSenWebServiceSession::SecurityL()
+    {
+    if ( HasSecurity() )
+        {
+        return iCredentialPtr.Credential()->AsXmlL();
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+    
+EXPORT_C TBool CSenWebServiceSession::HasSecurity()
+    {
+    if ( iCredentialPtr.Credential() )
+        {
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+    
+EXPORT_C void CSenWebServiceSession::SetCredentialPtrL(RSenCredentialPtr aCredentialPtr)	//codescannerwarnings
+    {
+    // Stop observing the removal of credential as this instance is itself doing the removal
+    iCredentialPtr.RemoveCredentialObserver(*this);
+    //temp pointer eliminate self deleting when counter = 1 and aCredentail points same data as iCredentialPtr
+    // in other words there is a chance that closing iCredentialPtr make dirty aCredentialPtr. Temp ptr keeps balance so 
+    //  that counter has proper value.
+    RSenCredentialPtr tempPtr = iCredentialPtr.Clone();
+    iCredentialPtr.Close();
+    iCredentialPtr = aCredentialPtr.Clone();
+    tempPtr.Close();    
+    // Start observing the new credential
+    iCredentialPtr.AddCredentialObserverL(*this);	//codescannerwarnings
+    SetCredentialIdL(iCredentialPtr.Credential()->IdentifierL().IdL());	//codescannerwarnings
+    }
+
+EXPORT_C TInt CSenWebServiceSession::SendToHostletL(MSenRemoteHostlet& aReceiver,
+                                                 const TDesC8& aMessage,
+                                                 const TInt aTxnId,
+                                                 MSenRemoteServiceConsumer& aFrom,
+                                                 MSenProperties* aProperties)
+    {
+    // default impelementation routes the request directly to the hostlet
+    // Handler aware framework could load the required handlers in here
+    // to enable addressing / message correlation etc.
+    return CSenServiceSession::SendToHostletL(aReceiver, aMessage, aTxnId, aFrom, aProperties); 
+    }
+
+EXPORT_C TInt CSenWebServiceSession::ProvideHostletResponseL( MSenRemoteHostlet& aProvider,
+                                                              const TInt aTxnId,
+                                                              const TInt aServiceCode,
+                                                              const TDesC8& aRecipientsConsumerId,
+                                                              CSenChunk& aMessageChunk)
+    {
+    return CSenServiceSession::ProvideHostletResponseL( aProvider, 
+                                                        aTxnId, 
+                                                        aServiceCode, 
+                                                        aRecipientsConsumerId, 
+                                                        aMessageChunk ); 
+    }
+    
+TInt CSenWebServiceSession::HandleBodyWithoutParsingL(CSenSoapMessage& aMessage,
+                                                      const TDesC8& aResponse)
+    {
+    TInt ret;
+    TInt endTagStart;
+    TInt endTagEnd;
+    TInt startTagStart;
+    TInt startTagEnd;
+    TPtrC8 prefix;
+
+    ret = SenSaxUtils::SearchEndTagL(aResponse,KSenSoapEnvelopeBodyName,
+                                     endTagStart, endTagEnd, prefix);
+    if ( ret != KErrNotFound )
+        {
+        ret = SenSaxUtils::SearchStartTagL(aResponse,prefix,KSenSoapEnvelopeBodyName,
+                                           startTagStart, startTagEnd);
+        if ( ret != KErrNotFound )
+            {
+            TPtrC8 startPart(aResponse.Ptr(),startTagEnd+1);
+            TPtrC8 endPart(aResponse.Ptr()+endTagStart,aResponse.Size()-endTagStart);
+            HBufC8* pXmlWithoutBody = HBufC8::NewLC(startPart.Length()+endPart.Length());
+            pXmlWithoutBody->Des().Append(startPart);
+            pXmlWithoutBody->Des().Append(endPart);
+            
+            aMessage.ParseL(*pXmlWithoutBody);
+            CleanupStack::PopAndDestroy(pXmlWithoutBody);
+            
+            TPtrC8 bodyContent(aResponse.Ptr()+startTagEnd+1, endTagStart-startTagEnd-1);
+            aMessage.SetBodyL(bodyContent);
+            }
+        }
+    
+    return ret;
+    }
+
+EXPORT_C void CSenWebServiceSession::CredentialChanged(TSenCredentialChange aChange,
+		                                               TAny* /* aPointer */)
+    {
+    if ( aChange == MSenCredentialObserver::EDestroyed )
+        {
+        iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900  \\CodeScannerWarnings
+        TRAP_IGNORE( SetStatusL(); ) 
+        }
+    }
+    
+EXPORT_C  TInt CSenWebServiceSession::AddCredentialObserverL(CSenInternalCredential& aCredential)
+{
+	TInt error(KErrNone);
+	RSenCredentialPtr credentialPtr = 
+	((MSenServiceManager&)iFramework.Manager()).CredentialL(
+	    aCredential.IdentifierL().IdL(), error);
+	if ( error == KErrNone )
+	{
+		iCredentialPtr.RemoveCredentialObserver(*this);
+		iCredentialPtr.Close();
+		iCredentialPtr = credentialPtr.Clone();
+		iCredentialPtr.AddCredentialObserverL(*this);
+		iValidUntil = credentialPtr.Credential()->PropertiesL().ValidUntilL();
+		if ( iClientServerInterval == 0 )
+		{
+			TPtrC8 value;
+			TInt ret = iCredentialPtr.Credential()->PropertiesL().PropertyL(_L8("ServiceInterval"),
+			                                                               value);
+			if ( ret == KErrNone )
+			{
+				TLex8 lex(value);
+				TInt64 val;
+				ret = lex.Val(val);
+				if ( ret == KErrNone )
+				{
+					iClientServerInterval = val;
+				}
+			}
+		}
+                
+	}
+    CredentialChanged(MSenCredentialObserver::EAdded, NULL);      
+	SetStatusL();
+
+	return KErrNone;
+}
+
+//  End of File