virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>&  args, QDataStream& socketStream)
    {
        int caseId = args[1].toInt();
        RimCase* rimCase = server->findReservoir(caseId);
        if (!rimCase)
        {
            server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId));

            return true;
        }

        std::vector<QString> wellNames;

        const cvf::Collection<RigSingleWellResultsData>& wells = rimCase->reservoirData()->wellResults();
 
        for (size_t wIdx = 0; wIdx < wells.size(); ++wIdx)
        {
            wellNames.push_back(wells[wIdx]->m_wellName);
        }

        quint64 byteCount = sizeof(quint64);
        quint64 wellCount = wellNames.size();

        for (size_t wIdx = 0; wIdx < wellCount; wIdx++)
        {
            byteCount += wellNames[wIdx].size() * sizeof(QChar);
        }

        socketStream << byteCount;
        socketStream << wellCount;

        for (size_t wIdx = 0; wIdx < wellCount; wIdx++)
        {
            socketStream << wellNames[wIdx];
        }

        return true;
    }
    virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>&  args, QDataStream& socketStream)
    {
        int caseId          = args[1].toInt();
        QString wellName    = args[2];

        RimCase* rimCase = server->findReservoir(caseId);
        if (!rimCase)
        {
            server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId));

            return true;
        }

        // Create a list of all the requested time steps

        std::vector<size_t> requestedTimesteps;
        //First find the well result for the correct well

        const cvf::Collection<RigSingleWellResultsData>& allWellRes =  rimCase->reservoirData()->wellResults();
        cvf::ref<RigSingleWellResultsData> currentWellResult;
        for (size_t tsIdx = 0; tsIdx < allWellRes.size(); ++tsIdx)
        {
            if (allWellRes[tsIdx]->m_wellName == wellName)
            {
                currentWellResult = allWellRes[tsIdx];
                break;
            }
        }

        if (currentWellResult.isNull())
        {
            server->errorMessageDialog()->showMessage(
                RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the well with name : \"%1\"").arg(wellName));

            return true;
        }


        if (args.size() <= 3)
        {
            // Select all timesteps. 

            for (size_t tsIdx = 0; tsIdx <  currentWellResult->m_resultTimeStepIndexToWellTimeStepIndex.size(); ++tsIdx)
            {
                requestedTimesteps.push_back(tsIdx);
            }
        }
        else
        {
            bool timeStepReadError = false;
            for (int argIdx = 3; argIdx < args.size(); ++argIdx)
            {
                bool conversionOk = false;
                int tsIdx = args[argIdx].toInt(&conversionOk);

                if (conversionOk)
                {
                    requestedTimesteps.push_back(tsIdx);
                }
                else
                {
                    timeStepReadError = true;
                }
            }

            if (timeStepReadError)
            {
                server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riGetGridProperty : \n")
                    + RiaSocketServer::tr("An error occured while interpreting the requested timesteps."));
            }
        }

        std::vector<QString> wellTypes;
        std::vector<qint32> wellStatuses;

        for (size_t tsIdx = 0; tsIdx < requestedTimesteps.size(); ++tsIdx)
        {
            QString wellType = "NotDefined";
            qint32 wellStatus = 0;
            if (currentWellResult->hasWellResult(tsIdx))
            {
                switch(currentWellResult->wellResultFrame(tsIdx).m_productionType)
                {
                case RigWellResultFrame::PRODUCER:
                    wellType = "Producer";
                    break;
                case RigWellResultFrame::OIL_INJECTOR:
                    wellType = "OilInjector";
                    break;
                case RigWellResultFrame::WATER_INJECTOR:
                    wellType = "WaterInjector";
                    break;
                case RigWellResultFrame::GAS_INJECTOR:
                    wellType = "GasInjector";
                    break;
                }

                wellStatus = currentWellResult->wellResultFrame(tsIdx).m_isOpen ? 1 : 0;
            }

            wellTypes.push_back(wellType);
            wellStatuses.push_back(wellStatus);
        }

        quint64 byteCount = sizeof(quint64);
        quint64 timeStepCount = wellTypes.size();

        for (size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++)
        {
            byteCount += wellTypes[tsIdx].size() * sizeof(QChar);
            byteCount += sizeof(qint32);
        }

        socketStream << byteCount;
        socketStream << timeStepCount;

        for (size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++)
        {
            socketStream << wellTypes[tsIdx];
            socketStream << wellStatuses[tsIdx];
        }

        return true;
    }
    virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>&  args, QDataStream& socketStream)
    {
        int caseId          = args[1].toInt();
        QString wellName    = args[2];
        size_t timeStepIdx  = args[3].toInt() - 1; // Interpret timeStepIdx from octave as 1-based

        RimCase* rimCase = server->findReservoir(caseId);
        if (!rimCase)
        {
            server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId));

            socketStream << (quint64)0;
            return true;
        }
 
        const cvf::Collection<RigSingleWellResultsData>& allWellRes =  rimCase->reservoirData()->wellResults();
        cvf::ref<RigSingleWellResultsData> currentWellResult;
        for (size_t cIdx = 0; cIdx < allWellRes.size(); ++cIdx)
        {
            if (allWellRes[cIdx]->m_wellName == wellName)
            {
                currentWellResult = allWellRes[cIdx];
                break;
            }
        }

        if (currentWellResult.isNull())
        {
            server->errorMessageDialog()->showMessage(
                RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the well with name : \"%1\"").arg(wellName));

            socketStream << (quint64)0;
            return true;
        }

        if (!currentWellResult->hasWellResult(timeStepIdx))
        {
            socketStream << (quint64)0;
            return true;
        }

        std::vector<qint32> cellIs; 
        std::vector<qint32> cellJs; 
        std::vector<qint32> cellKs;
        std::vector<qint32> gridIndices;
        std::vector<qint32> cellStatuses;
        std::vector<qint32> branchIds;
        std::vector<qint32> segmentIds;

        // Fetch results
        const RigWellResultFrame& wellResFrame = currentWellResult->wellResultFrame(timeStepIdx); 
        std::vector<RigGridBase*> grids;
        rimCase->reservoirData()->allGrids(&grids);

        for (size_t bIdx = 0; bIdx < wellResFrame.m_wellResultBranches.size(); ++bIdx)
        {
            const std::vector<RigWellResultPoint>& branchResPoints =  wellResFrame.m_wellResultBranches[bIdx].m_branchResultPoints;
            for (size_t rpIdx = 0; rpIdx < branchResPoints.size(); ++rpIdx)
            {
                const RigWellResultPoint& resPoint = branchResPoints[rpIdx];

                if (resPoint.isCell())
                {
                    size_t i; 
                    size_t j;
                    size_t k;
                    size_t gridIdx =  resPoint.m_gridIndex ;
                    grids[gridIdx]->ijkFromCellIndex(resPoint.m_gridCellIndex, &i, &j, &k);
                    bool isOpen    = resPoint.m_isOpen;
                    int branchId   = resPoint.m_ertBranchId;
                    int segmentId  = resPoint.m_ertSegmentId;

                    cellIs      .push_back( static_cast<qint32>(i) ); 
                    cellJs      .push_back( static_cast<qint32>(j) ); 
                    cellKs      .push_back( static_cast<qint32>(k) );
                    gridIndices .push_back( static_cast<qint32>(gridIdx) );
                    cellStatuses.push_back( static_cast<qint32>(isOpen) );
                    branchIds   .push_back( branchId );
                    segmentIds  .push_back( segmentId);
                }
            }
        }

        quint64 byteCount = sizeof(quint64);
        quint64 cellCount = cellIs.size();

        byteCount += cellCount*( 7 * sizeof(qint32));

        socketStream << byteCount;
        socketStream << cellCount;

        for (size_t cIdx = 0; cIdx < cellCount; cIdx++)
        {
            socketStream << cellIs[cIdx]; 
            socketStream << cellJs[cIdx]; 
            socketStream << cellKs[cIdx];
            socketStream << gridIndices[cIdx];
            socketStream << cellStatuses[cIdx];
            socketStream << branchIds[cIdx];
            socketStream << segmentIds[cIdx];
        }

        return true;
    }
    virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>&  args, QDataStream& socketStream)
    {
        RimCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);

        QString propertyName = args[2];
        QString porosityModelName = args[3];

        RifReaderInterface::PorosityModelResultType porosityModelEnum = RifReaderInterface::MATRIX_RESULTS;
        if (porosityModelName == "Fracture")
        {
            porosityModelEnum = RifReaderInterface::FRACTURE_RESULTS;
        }

        // Find the requested data

        size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T;
        std::vector< std::vector<double> >* scalarResultFrames = NULL;

        if (rimCase && rimCase->results(porosityModelEnum))
        {
            scalarResultIndex = rimCase->results(porosityModelEnum)->findOrLoadScalarResult(propertyName);

            if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
            {
                scalarResultFrames = &(rimCase->results(porosityModelEnum)->cellResults()->cellScalarResults(scalarResultIndex));
            }

        }

        if (scalarResultFrames == NULL)
        {
            server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the %1 model property named: \"%2\"").arg(porosityModelName).arg(propertyName));
        }

        // Write data back : timeStepCount, bytesPrTimestep, dataForTimestep0 ... dataForTimestepN

        if ( scalarResultFrames == NULL)
        {
            // No data available
            socketStream << (quint64)0 << (quint64)0 ;
        }
        else
        {
            // Create a list of all the requested timesteps

            std::vector<size_t> requestedTimesteps;

            if (args.size() <= 4)
            {
                // Select all
                for (size_t tsIdx = 0; tsIdx < scalarResultFrames->size(); ++tsIdx)
                {
                    requestedTimesteps.push_back(tsIdx);
                }
            }
            else
            {
                bool timeStepReadError = false;
                for (int argIdx = 4; argIdx < args.size(); ++argIdx)
                {
                    bool conversionOk = false;
                    int tsIdx = args[argIdx].toInt(&conversionOk);

                    if (conversionOk)
                    {
                        requestedTimesteps.push_back(tsIdx);
                    }
                    else
                    {
                        timeStepReadError = true;
                    }
                }

                if (timeStepReadError)
                {
                    server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riGetActiveCellProperty : \n") + RiaSocketServer::tr("An error occured while interpreting the requested timesteps."));
                }

            }

            // First write timestep count
            quint64 timestepCount = (quint64)requestedTimesteps.size();
            socketStream << timestepCount;

            // then the byte-size of the result values in one timestep

            const RigActiveCellInfo* activeInfo = rimCase->reservoirData()->activeCellInfo(porosityModelEnum);
            size_t  timestepResultCount = activeInfo->globalActiveCellCount();

            quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double));
            socketStream << timestepByteCount ;

            // Then write the data.

            size_t globalCellCount = activeInfo->globalCellCount();
            for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx)
            {
                for (size_t gcIdx = 0; gcIdx < globalCellCount; ++gcIdx)
                {
                    size_t resultIdx = activeInfo->cellResultIndex(gcIdx);
                    if (resultIdx != cvf::UNDEFINED_SIZE_T)
                    {
                        if (resultIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size())
                        {
                            socketStream << scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx];
                        }
                        else
                        {
                            socketStream << HUGE_VAL;
                        }
                    }
                }
            }
#if 0
            // This aproach is faster but does not handle coarsening
            size_t  timestepResultCount = scalarResultFrames->front().size();
            quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double));
            socketStream << timestepByteCount ;

            // Then write the data.

            for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx)
            {
#if 1 // Write data as raw bytes, fast but does not handle byteswapping
                server->currentClient()->write((const char *)scalarResultFrames->at(requestedTimesteps[tIdx]).data(), timestepByteCount); // Raw print of data. Fast but no platform conversion
#else  // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well
                for (size_t cIdx = 0; cIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size(); ++cIdx)
                {
                    socketStream << scalarResultFrames->at(tIdx)[cIdx];
                }
#endif
            }
#endif
        }

        return true;
    }