/*============================================================================
 * OpcUa_MemoryStream_CreateWriteable
 *===========================================================================*/
OpcUa_StatusCode OpcUa_MemoryStream_AttachBuffer(   OpcUa_Stream*   a_pStrm,
                                                    OpcUa_Buffer*   a_pBuffer)
{
    OpcUa_MemoryStream* pMemoryStream = (OpcUa_MemoryStream*)a_pStrm->Handle;

    OpcUa_ReturnErrorIfArgumentNull(a_pStrm);
    OpcUa_ReturnErrorIfArgumentNull(a_pBuffer);

    OpcUa_Buffer_Clear(pMemoryStream->pBuffer);

    *(pMemoryStream->pBuffer) = *a_pBuffer;

    a_pBuffer->Data = OpcUa_Null;
    OpcUa_Buffer_Clear(a_pBuffer);

    return OpcUa_Good;
}
/**
* @brief Clean up the given OpcUa_TcpListener_Connection. May be used for static memory.
*/
OpcUa_Void OpcUa_TcpListener_Connection_Clear(OpcUa_TcpListener_Connection* a_pConnection)
{
    if(a_pConnection == OpcUa_Null)
    {
        return;
    }

    OpcUa_MemSet(&(a_pConnection->ConnectTime), 0, sizeof(OpcUa_DateTime));
    OpcUa_MemSet(&(a_pConnection->DisconnectTime), 0, sizeof(OpcUa_DateTime));

    a_pConnection->Socket                   = OpcUa_Null; /* Socket has to be freed externally. */
    a_pConnection->pListenerHandle          = OpcUa_Null;
    a_pConnection->uNoOfRequestsTotal       = 0;

    OpcUa_String_Clear(&a_pConnection->sURL);

    if(a_pConnection->pInputStream != OpcUa_Null)
    {
        OpcUa_TcpStream_Close((OpcUa_Stream*)a_pConnection->pInputStream);
        OpcUa_TcpStream_Delete((OpcUa_Stream**)&a_pConnection->pInputStream);
    }

    while(a_pConnection->pSendQueue != OpcUa_Null)
    {
        OpcUa_BufferList* pCurrentBuffer = a_pConnection->pSendQueue;
        a_pConnection->pSendQueue = pCurrentBuffer->pNext;
        OpcUa_Buffer_Clear(&pCurrentBuffer->Buffer);
        OpcUa_Free(pCurrentBuffer);
    }

    if(a_pConnection->Mutex)
    {
        OPCUA_P_MUTEX_DELETE(&(a_pConnection->Mutex));
    }

    OpcUa_Trace(OPCUA_TRACE_LEVEL_DEBUG, "OpcUa_TcpListener_Connection_Clear: Done!\n");
}
/*============================================================================
 * OpcUa_TcpSecureChannel_Clear
 *===========================================================================*/
OpcUa_StatusCode OpcUa_TcpSecureChannel_Clear(OpcUa_SecureChannel* a_pSecureChannel)
{
OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Clear");

    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel);
    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel->Handle);

    OpcUa_String_Clear(&a_pSecureChannel->SecurityPolicyUri);
    OpcUa_String_Clear(&a_pSecureChannel->sPeerInfo);

    OpcUa_Free(a_pSecureChannel->Handle);
    a_pSecureChannel->Handle = OpcUa_Null;

    OpcUa_ByteString_Clear(&a_pSecureChannel->ClientCertificate);

    OpcUa_ByteString_Clear(&a_pSecureChannel->ServerCertificate);

    if(a_pSecureChannel->pCurrentReceivingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pCurrentReceivingKeyset);
        OpcUa_Free(a_pSecureChannel->pCurrentReceivingKeyset);
        a_pSecureChannel->pCurrentReceivingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pCurrentSendingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pCurrentSendingKeyset);
        OpcUa_Free(a_pSecureChannel->pCurrentSendingKeyset);
        a_pSecureChannel->pCurrentSendingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousReceivingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousReceivingKeyset);
        OpcUa_Free(a_pSecureChannel->pPreviousReceivingKeyset);
        a_pSecureChannel->pPreviousReceivingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousSendingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousSendingKeyset);
        OpcUa_Free(a_pSecureChannel->pPreviousSendingKeyset);
        a_pSecureChannel->pPreviousSendingKeyset = OpcUa_Null;
    }

    /* delete both crypto providers */
    if(a_pSecureChannel->pCurrentCryptoProvider != OpcUa_Null)
    {
        if(a_pSecureChannel->pPreviousCryptoProvider == a_pSecureChannel->pCurrentCryptoProvider)
        {
            /* prevent double deletion */
            a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
        }

        OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pCurrentCryptoProvider);
        OpcUa_Free(a_pSecureChannel->pCurrentCryptoProvider);
        a_pSecureChannel->pCurrentCryptoProvider = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousCryptoProvider != OpcUa_Null)
    {
        OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pPreviousCryptoProvider);
        OpcUa_Free(a_pSecureChannel->pPreviousCryptoProvider);
        a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
    }

    if(a_pSecureChannel->pPendingSecureIStream != OpcUa_Null)
    {
        OpcUa_Stream_Close((OpcUa_Stream*)(a_pSecureChannel->pPendingSecureIStream));
        OpcUa_Stream_Delete((OpcUa_Stream**)&(a_pSecureChannel->pPendingSecureIStream));
    }

    while(a_pSecureChannel->pPendingSendBuffers != OpcUa_Null)
    {
        OpcUa_BufferList* pCurrentBuffer = a_pSecureChannel->pPendingSendBuffers;
        a_pSecureChannel->pPendingSendBuffers = pCurrentBuffer->pNext;
        OpcUa_Buffer_Clear(&pCurrentBuffer->Buffer);
        OpcUa_Free(pCurrentBuffer);
    }

    if(a_pSecureChannel->hSyncAccess != OpcUa_Null)
    {
        OPCUA_P_MUTEX_DELETE(&(a_pSecureChannel->hSyncAccess));
        a_pSecureChannel->hSyncAccess = OpcUa_Null;
    }

    if(a_pSecureChannel->hWriteMutex != OpcUa_Null)
    {
        OPCUA_P_MUTEX_DELETE(&(a_pSecureChannel->hWriteMutex));
        a_pSecureChannel->hWriteMutex = OpcUa_Null;
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}