void
ViewerDatabaseCorrelationMethods::CreateNode(DataNode *parentNode, 
    const std::map<std::string, std::string> &dbToSource, bool detailed)
{
    // Create a copy of the database correlation list.
    DatabaseCorrelationList dbcl(*GetViewerState()->GetDatabaseCorrelationList());
    dbcl.ClearCorrelations();
    for(int i = 0; 
        i < GetViewerState()->GetDatabaseCorrelationList()->GetNumCorrelations(); ++i)
    {
        const DatabaseCorrelation &corr = 
            GetViewerState()->GetDatabaseCorrelationList()->GetCorrelations(i);
        // Let's only save out correlations that have more than 1 db.
        if(corr.GetNumDatabases() > 1)
        {
            // Map database names to source names.
            const stringVector &dbNames = corr.GetDatabaseNames();
            stringVector sourceIds;
            for(size_t j = 0; j < dbNames.size(); ++j)
            {
                std::map<std::string, std::string>::const_iterator pos =
                    dbToSource.find(dbNames[j]);
                if(pos == dbToSource.end())
                    sourceIds.push_back(dbNames[j]);
                else
                    sourceIds.push_back(pos->second);
            }

            // Create a copy of the correlation but override its database
            // names with source ids. Also, note that we're not using a
            // copy constructor because we want most of the correlation
            // information to be absent so we can repopulate it on session read
            // in case a new database is chosen.
            DatabaseCorrelation modCorr;                       
            if(corr.GetMethod() != DatabaseCorrelation::UserDefinedCorrelation)
            {
                modCorr.SetName(corr.GetName());
                modCorr.SetNumStates(corr.GetNumStates());
                modCorr.SetMethod(corr.GetMethod());
            }
            else
            {
               // A user-defined correlation should be saved mostly as-is.
               modCorr = corr;
            }
            modCorr.SetDatabaseNames(sourceIds);

            // Add the modified correlation to the list.
            dbcl.AddCorrelations(modCorr);
        }
    }

    // Add the database correlation list information to the session.
    dbcl.CreateNode(parentNode, detailed, false);
}
DatabaseCorrelation *
ViewerDatabaseCorrelationMethods::CreateDatabaseCorrelation(const std::string &name,
    const stringVector &dbs, int method, int nStates)
{
    if(dbs.size() < 1)
    {
        GetViewerMessaging()->Error(
            TR("VisIt cannot create a database correlation that does "
               "not use any databases."));
        return 0;
    }

    //
    // Create a new correlation and set its basic attributes.
    //
    DatabaseCorrelation *correlation = new DatabaseCorrelation;
    correlation->SetName(name);
    DatabaseCorrelation::CorrelationMethod m =
        (DatabaseCorrelation::CorrelationMethod)method;
    correlation->SetMethod(m);
    if(nStates != -1 &&
       (m == DatabaseCorrelation::IndexForIndexCorrelation ||
        m == DatabaseCorrelation::StretchedIndexCorrelation))
    {
        correlation->SetNumStates(nStates);
    }

    // Add the different databases to the correlation.
    for(size_t i = 0; i < dbs.size(); ++i)
    {
        //
        // Split the database name into host and database components
        // and expand it too.
        //
        std::string host, db;
        std::string correlationDB(dbs[i]);
        GetViewerFileServer()->ExpandDatabaseName(correlationDB, host, db);

        //
        // Get the metadata for the database.
        //
        const avtDatabaseMetaData *md = GetViewerFileServer()->GetMetaData(host, db);

        //
        // We might need to re-acqure metadata if we are doing
        // time or cycle correlations and times or cycles are not
        // all accurate and valid
        //
        if(md)
        {
            const bool forceReadAllCyclesAndTimes = true;

            if ((m == DatabaseCorrelation::TimeCorrelation &&
                 md->AreAllTimesAccurateAndValid() == false) ||
                (m == DatabaseCorrelation::CycleCorrelation &&
                 md->AreAllCyclesAccurateAndValid() == false))
            {
                md = GetViewerFileServer()->GetMetaData(host, db, forceReadAllCyclesAndTimes);
            }
        }

        if(md)
        {
            //
            // Issue warning messages if we're doing time or cycle
            // correlations and the metadata cannot be trusted.
            //
            if(m == DatabaseCorrelation::TimeCorrelation)
            {
                bool accurate = true;
                for(int j = 0; j < md->GetNumStates() && accurate; ++j)
                    accurate &= md->IsTimeAccurate(j);

                if(!accurate)
                {
                    GetViewerMessaging()->Warning(
                        TR("The times for %1 may not be accurate so the new "
                           "correlation %2 might not work as expected.").
                          arg(correlationDB).
                          arg(name));
                }
            }
            else if(m == DatabaseCorrelation::CycleCorrelation)
            {
                bool accurate = true;
                for(int j = 0; j < md->GetNumStates() && accurate; ++j)
                    accurate &= md->IsCycleAccurate(j);

                if(!accurate)
                {
                    GetViewerMessaging()->Warning(
                        TR("The cycles for %1 may not be accurate so the new "
                           "correlation %2 might not work as expected.").
                        arg(correlationDB).
                        arg(name));
                }
            }

            //
            // Add the database to the new correlation.
            //
            correlation->AddDatabase(correlationDB, md->GetNumStates(),
                md->GetTimes(), md->GetCycles()); 
        }
        else
        {
            delete correlation; correlation = 0;
            GetViewerMessaging()->Error(
                TR("VisIt could not retrieve metadata for %1 so the "
                   "correlation %2 could not be created.").
                  arg(correlationDB).
                  arg(name));
            break;
        }
    }

    return correlation;
}