/**
       Parse configuration stream.

       \returns this
    */
    const RunAsConfigurator& RunAsConfigurator::Parse()
    {
        m_Parser->Parse();

        SCXCoreLib::SCXLogHandle log = SCXLogHandleFactory::GetLogHandle(L"scx.core.providers.runasprovider.configurator");

        ConfigurationParser::const_iterator allowRoot = m_Parser->find(L"AllowRoot");
        if (allowRoot != m_Parser->end() && (
                allowRoot->second == L"false" ||
                allowRoot->second == L"no" ||
                allowRoot->second == L"0"))
        {
            m_AllowRoot = false;
        }

        ConfigurationParser::const_iterator chRootPath = m_Parser->find(L"ChRootPath");
        if (chRootPath != m_Parser->end())
        {
            m_ChRootPath = ResolveEnvVars(chRootPath->second);
            if (L"" == m_ChRootPath)
            {
                SCX_LOGINFO(log, L"ChRootPath has been resolved to empty string");
            }
        }

        ConfigurationParser::const_iterator cwd = m_Parser->find(L"CWD");
        if (cwd != m_Parser->end())
        {
            m_CWD = ResolveEnvVars(cwd->second);
            if (L"" == m_CWD)
            {
                SCX_LOGINFO(log, L"CWD has been resolved to empty string");
            }
        }

        return *this;
    }
/**
   Update the Solaris Sparc instance.
*/
    void StaticDiskPartitionInstance::Update_Solaris()
    {

        SCX_LOGTRACE(m_log, L"DiskPartition::Update_Solaris():: Entering, DeviceID is:" + m_deviceID);

        // Execute 'df -g' and retrieve result to determine filesystem that is mounted on
        // and block size.  Then, go through output of prtvtoc for this filesystem to
        // retrieve the remaining partition information.
#if PF_MAJOR == 5 && (PF_MINOR  == 9 || PF_MINOR == 10)
        wstring cmdStringDf = L"/usr/sbin/df -g";
#elif PF_MAJOR == 5 && PF_MINOR  == 11
        wstring cmdStringDf = L"/sbin/df -g";
#else
#error "Platform not supported"
#endif
        int status;
        std::istringstream processInputDf;
        std::ostringstream processOutputDf;
        std::ostringstream processErrDf;
        wstring curLine;
        curLine.clear();
        wstring mountedStr;
        wstring blockSizeStr;
        std::string dfResult;
        vector<wstring>  allLines;                       // all lines read from output
        allLines.clear();
        SCXStream::NLFs nlfs;
        bool foundIt = false;
        vector<wstring> matchingVector;

        SCXRegexPtr solDfPatternPtr(NULL);
        SCXRegexPtr solPrtvtocBpSPatternPtr(NULL);
        SCXRegexPtr solPrtvtocDetailPatternPtr(NULL);

        // Let's build our RegEx:
        try
        {
            solDfPatternPtr = new SCXCoreLib::SCXRegex(c_SolDfPattern);
            solPrtvtocBpSPatternPtr = new SCXCoreLib::SCXRegex(c_SolPrtvtocBpSPattern);
            solPrtvtocDetailPatternPtr = new SCXCoreLib::SCXRegex(c_SolprtvtocDetailPattern);
        }
        catch(SCXCoreLib::SCXInvalidRegexException &e)
        {
            SCX_LOGERROR(m_log, L"Exception caught in compiling regex: " + e.What());
            return;
        }

        try 
        {
            status = SCXCoreLib::SCXProcess::Run(cmdStringDf, processInputDf, processOutputDf, processErrDf, 15000);
            if (status != 0)
            {
                SCX_LOGERROR(m_log, StrAppend(L"Error on command " + cmdStringDf + L" - status ", status));
                SCX_LOGERROR(m_log, StrFromUTF8("Output - " + processOutputDf.str()));
                SCX_LOGERROR(m_log, StrFromUTF8("Error - " + processErrDf.str()));
                return;
            }
            dfResult = processOutputDf.str();
        }
        catch(SCXCoreLib::SCXException &e)
        {
            SCX_LOGERROR(m_log, L"Unable to retrieve partition information from OS using 'df -g'..." + e.What());
        }

        std::istringstream stringStrmDf_g(dfResult);
        allLines.clear();
        size_t dfLineCt = 100;
        allLines.reserve(dfLineCt);
        foundIt = false;
        SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmDf_g, allLines, nlfs);

        for (vector<wstring>::iterator it = allLines.begin(); it != allLines.end() && !foundIt; it++)
        {
            curLine.assign(*it);
            matchingVector.clear();

            if ((solDfPatternPtr->ReturnMatch(curLine, matchingVector, 0)) && (matchingVector.size() >= 4) && 
                (m_deviceID == matchingVector[2]))
            {
                mountedStr = matchingVector[1];
                blockSizeStr = matchingVector[3];
                foundIt = true; 
            }
            else if (matchingVector.size() > 0)
            {
                //Have an error message
                SCX_LOGINFO(m_log, L"No match found! Error: " + matchingVector[0]);
            }

        }

        //Check the results
        if (!foundIt || mountedStr .size() == 0)
        {
            SCX_LOGERROR(m_log, L"Failed to find this partition info with df -g: " + m_deviceID );
            return;
        }     


        //The next (and last) step is to do a prtvtoc [dir] command to retrieve the rest of the partition info:
#if PF_MAJOR == 5 && (PF_MINOR  == 9 || PF_MINOR == 10)
        wstring cmdStringPrtvToc = L"/usr/sbin/prtvtoc " + m_deviceID;
#elif PF_MAJOR == 5 && PF_MINOR  == 11
        wstring cmdStringPrtvToc = L"/sbin/prtvtoc " + m_deviceID;
#else
#error "Platform not supported"
#endif
        std::istringstream processInputPrtvtoc;
        std::ostringstream processOutputPrtvtoc;
        std::ostringstream processErrPrtvtoc;
        curLine.clear();
        wstring firstSectorStr;
        wstring sectorCountStr;
        wstring bytesPerSectorStr;

        std::string prtResult("");

        try 
        {
            SCXCoreLib::SCXProcess::Run(cmdStringPrtvToc, processInputPrtvtoc, processOutputPrtvtoc, processErrPrtvtoc, 15000);
            prtResult = processOutputPrtvtoc.str();
            size_t lengthCaptured = prtResult.length();

            // Truncate trailing newline if there in captured output                  
            if (lengthCaptured > 0)
            {
                if (prtResult[lengthCaptured - 1] == '\n')
                {
                    prtResult[lengthCaptured - 1] = '\0';
                }
            }

        }
        catch(SCXCoreLib::SCXException &e)
        {
            SCX_LOGERROR(m_log, L"Unable to retrieve partition information from OS using 'df -g'..." + e.What());
        }

        std::istringstream stringStrmPrtvtoc(prtResult);
        allLines.clear();
        foundIt = false;
        SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmPrtvtoc, allLines, nlfs);;

        for(vector<wstring>::iterator it = allLines.begin(); it != allLines.end() && !foundIt; it++)
        {
            curLine.assign(*it);
            matchingVector.clear();

            // First, we match on a comment line that tells us the Sector Size
            if (solPrtvtocBpSPatternPtr->ReturnMatch(curLine, matchingVector, 0)) 
            {
                bytesPerSectorStr = matchingVector[1];
            } // Next, we look for a detail line that matches our index:
            else if ((solPrtvtocDetailPatternPtr->ReturnMatch(curLine, matchingVector, 0)) && 
                     (matchingVector.size() >= 5) && 
                     (m_index == SCXCoreLib::StrToUInt(matchingVector[1])))
            {
                // This is our row in the Partion info output
                firstSectorStr = matchingVector[2];
                sectorCountStr = matchingVector[3];
                foundIt = true;
               
            }
        }

        //Check the results
        if (!foundIt || bytesPerSectorStr.size() == 0)
        {
            SCX_LOGERROR(m_log, L"Failed to find this partition info with prtvtoc: " + m_deviceID +
                         L"  And Regex Error Msg: " + matchingVector[0]);
            return;
        }     

        // If we reached here we have everything we need
        //  just need to do a little arithmetic and fill in our Properties struct:
        m_blockSize = SCXCoreLib::StrToULong(blockSizeStr);

        char dummyChar;
        unsigned int sectorSz = StrToUInt(bytesPerSectorStr);
        unsigned long long totalSectors = StrToUInt(sectorCountStr);
        unsigned long long startingSector = StrToUInt(firstSectorStr);

        m_partitionSize = totalSectors * sectorSz;
        m_startingOffset = startingSector * sectorSz;
        m_numberOfBlocks = RoundToUnsignedInt(static_cast<double>(m_partitionSize) / 
                                              static_cast<double>(m_blockSize));

        return;
    }