// <HostBuilderImplementation>
HRESULT CreateStockQuoteHost(
                LPCWSTR pszDeviceAddress,
                const WSD_THIS_DEVICE_METADATA* pThisDeviceMetadata,
                IStockQuote* pIStockQuote,
                IWSDDeviceHost** ppHostOut,
                IWSDXMLContext** ppContextOut)
{
    HRESULT hr = S_OK;
    IWSDXMLContext* pContext = NULL;
    IWSDDeviceHost* pHost = NULL;

    // 
    // Validate parameters
    // 
    if( NULL == pszDeviceAddress )
    {
        return E_INVALIDARG;
    }

    if( NULL == pThisDeviceMetadata )
    {
        return E_INVALIDARG;
    }

    // pIStockQuote is optional
    if( NULL == ppHostOut )
    {
        return E_POINTER;
    }

    // ppContextOut is optional

    *ppHostOut = NULL;
    if( NULL != ppContextOut )
    {
        *ppContextOut = NULL;
    }

    // 
    // Create XML context for namespace and type registration
    // 
    hr = WSDXMLCreateContext(&pContext);

    // 
    // Register types used by the service
    // 
    if( S_OK == hr )
    {
        hr = StockQuoteRegisterTypes(pContext);
    }

    // 
    // Register namespaces used by the service
    // 
    if( S_OK == hr )
    {
        hr = StockQuoteRegisterNamespaces(pContext);
    }

    // 
    // Create device host
    // 
    if( S_OK == hr )
    {
        hr = WSDCreateDeviceHost(pszDeviceAddress, pContext, &pHost);
    }

    // 
    // Register port types
    // 
    if( S_OK == hr )
    {
        hr = pHost->RegisterPortType(&PortType_StockQuotePortType);
    }

    // 
    // Set metadata
    // 
    if( S_OK == hr )
    {
        hr = pHost->SetMetadata(&thisModelMetadata, pThisDeviceMetadata, &hostMetadata, NULL);
    }

    // 
    // Register services and set discoverability
    // 
    if( S_OK == hr && pIStockQuote != NULL )
    {
        hr = pHost->RegisterService(L"http://example.com/stockquote/definitions/StockQuotePortType0", pIStockQuote);
    }

    // 
    // Cleanup
    // 
    if( S_OK == hr && ppContextOut )
    {
        *ppContextOut = pContext;
    }
    else
    {
        if( NULL != pContext )
        {
            pContext->Release();
        }
    }

    if( S_OK == hr )
    {
        *ppHostOut = pHost;
    }
    else
    {
        if( NULL != pHost )
        {
            pHost->Release();
        }
    }

    return hr;
}
// <ProxyBuilderImplementations>
HRESULT CreateCStockQuoteProxy(
    LPCWSTR pszDeviceAddress,
    LPCWSTR pszLocalAddress,
    CStockQuoteProxy** ppProxyOut,
    IWSDXMLContext** ppContextOut)
{
    HRESULT hr = S_OK;
    IWSDXMLContext* pContext = NULL;
    IWSDDeviceProxy* pDeviceProxy = NULL;
    IWSDServiceProxy* pServiceProxy = NULL;
    CStockQuoteProxy* pProxy = NULL;

    //
    // Validate parameters
    //
    if( NULL == pszDeviceAddress )
    {
        return E_INVALIDARG;
    }

    if( NULL == pszLocalAddress )
    {
        return E_INVALIDARG;
    }

    if( NULL == ppProxyOut )
    {
        return E_POINTER;
    }

    // ppContextOut is optional

    *ppProxyOut = NULL;
    if( NULL != ppContextOut )
    {
        *ppContextOut = NULL;
    }

    //
    // Create XML context for namespace and type registration
    //
    hr = WSDXMLCreateContext(&pContext);

    //
    // Register types used by the service
    //
    if( S_OK == hr )
    {
        hr = StockQuoteRegisterTypes(pContext);
    }

    //
    // Register namespaces used by the service
    //
    if( S_OK == hr )
    {
        hr = StockQuoteRegisterNamespaces(pContext);
    }

    //
    // Create a proxy for the device host
    //
    if( S_OK == hr )
    {
        hr = WSDCreateDeviceProxy(pszDeviceAddress, pszLocalAddress, pContext, &pDeviceProxy);
    }

    //
    // Create a proxy for the service
    //
    if( S_OK == hr )
    {
        hr = pDeviceProxy->GetServiceProxyByType(&Names_Definitions[0], &pServiceProxy);
    }

    //
    // Create a proxy for the port type
    //
    if( S_OK == hr )
    {
        pProxy = new CStockQuoteProxy();
        if( NULL == pProxy )
        {
            hr = E_OUTOFMEMORY;
        }
    }

    if( S_OK == hr )
    {
        hr = pProxy->Init(pServiceProxy);
    }

    //
    // Cleanup
    //
    if( NULL != pServiceProxy )
    {
        pServiceProxy->Release();
    }

    if( NULL != pDeviceProxy )
    {
        pDeviceProxy->Release();
    }

    if( S_OK == hr && ppContextOut )
    {
        *ppContextOut = pContext;
    }
    else
    {
        if( NULL != pContext )
        {
            pContext->Release();
        }
    }

    if( S_OK == hr )
    {
        *ppProxyOut = pProxy;
    }
    else
    {
        if( NULL != pProxy )
        {
            pProxy->Release();
        }
    }

    return hr;
}