int main(int argc,char *argv[])
{
    PvaClientPtr pva = PvaClient::create();
    try {
        PvaClientChannelPtr channel = pva->channel("helloPutGet");
        PvaClientPutGetPtr putGet = channel->createPutGet();
        putGet->connect();
        PvaClientPutDataPtr putData = putGet->getPutData();
        PVStructurePtr arg = putData->getPVStructure();
        PVStringPtr pvValue = arg->getSubField<PVString>("argument.value");
        pvValue->put("World");
        putGet->putGet();
        PvaClientGetDataPtr getData = putGet->getGetData();
        cout << getData->getPVStructure() << endl;
    } catch (std::runtime_error e) {
        cout << "exception " << e.what() << endl;
        return 1;
    }
    return 0;
}
static void exampleCADoubleArray(PvaClientPtr const &pva)
{
    cout << "__exampleCADoubleArray__\n";
    shared_vector<const double> value;
    try {
        cout << "short way\n";
        value =  pva->channel("DBRdoubleArray","ca",5.0)->get()->getData()->getDoubleArray();
        cout << "as doubleArray " << value << endl;
    } catch (std::runtime_error e) {
        cout << "exception " << e.what() << endl;
    }
    try {
        cout << "long way\n";
        PvaClientChannelPtr pvaChannel = pva->createChannel("DBRdoubleArray","ca");
        pvaChannel->connect(2.0);
        PvaClientGetPtr pvaGet = pvaChannel->createGet();
        PvaClientGetDataPtr pvaData = pvaGet->getData();
        value = pvaData->getDoubleArray();
        cout << "as doubleArray " << value << endl;
    } catch (std::runtime_error e) {
        cout << "exception " << e.what() << endl;
    }
}
static void exampleCADouble(PvaClientPtr const &pva)
{
    cout << "__exampleCADouble__\n";
    double value;
    try {
        cout << "short way\n";
        value =  pva->channel("DBRdouble00","ca",5.0)->get()->getData()->getDouble();
        cout << "as double " << value << endl;
    } catch (std::runtime_error e) {
        cout << "exception " << e.what() << endl;
    }
    cout << "long way\n";
    PvaClientChannelPtr pvaChannel = pva->createChannel("DBRdouble00","ca");
    pvaChannel->issueConnect();
    Status status = pvaChannel->waitConnect(2.0);
    if(!status.isOK()) {cout << " connect failed\n"; return;}
    PvaClientGetPtr pvaGet = pvaChannel->createGet();
    pvaGet->issueConnect();
    status = pvaGet->waitConnect();
    if(!status.isOK()) {cout << " createGet failed\n"; return;}
    PvaClientGetDataPtr pvaData = pvaGet->getData();
    value = pvaData->getDouble();
    cout << "as double " << value << endl;
}
static void exampleDouble(PvaClientPtr const &pvaClient)
{
    testDiag("== exampleDouble ==");

    PvaClientChannelPtr pvaChannel;
    try {
        pvaChannel = pvaClient->createChannel("PVRdouble");
        pvaChannel->connect(2.0);
        testDiag("channel connected");
    } catch (std::runtime_error e) {
        testAbort("channel connection exception '%s'", e.what());
    }

    PvaClientPutPtr put;
    PvaClientPutDataPtr putData;
    try {
        put = pvaChannel->createPut();
        putData = put->getData();
        testDiag("put connected");
        if (!putData)
            testAbort("NULL data pointer from putGet");
    } catch (std::runtime_error e) {
        testAbort("put connection exception '%s'", e.what());
    }

    PvaClientGetPtr get;
    PvaClientGetDataPtr getData;
    try {
        get = pvaChannel->createGet();
        getData = get->getData();
        testDiag("get connected");
        if (!getData)
            testAbort("NULL data pointer from putGet");
    } catch (std::runtime_error e) {
        testAbort("get connection exception '%s'", e.what());
    }

    PvaClientMonitorRequesterPtr requester(new MyMonitor());
    PvaClientMonitorPtr monitor;
    expected.set(0);        // structure definition
    try {
        monitor = pvaChannel->monitor(requester);
        testDiag("monitor connected");
    } catch (std::runtime_error e) {
        testAbort("monitor connection exception '%s'", e.what());
    }
    epicsThreadSleep(0.1);  // Allow connection monitor event to fire

    expected.clear();       // FIXME: Magic numbers here...
    expected.set(1);        // value
    expected.set(6);        // timestamp

    try {
        for (int i=0; i<5; ++i) {
            testDiag("= put %d =", i);

            double out = i;
            putData->putDouble(out);
            put->put();

            get->get();
            double in = getData->getDouble();
            testOk(in == out, "get value matches put");
        }

        PvaClientProcessPtr process = pvaChannel->createProcess();
        process->connect();

        testDiag("= process =");
        expected.clear(1);  // no value change
        process->process();
    } catch (std::runtime_error e) {
        testAbort("exception '%s'", e.what());
    }
}