virtual ReadResult readNode(std::istream& in, const osgDB::Options* options ) const
        {
            // pull the URI context from the options structure (since we're reading
            // from an "anonymous" stream here)
            URIContext uriContext( options ); 

            osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in, uriContext );
            if ( !doc.valid() )
                return ReadResult::ERROR_IN_READING_FILE;

            Config docConf = doc->getConfig();

            // support both "map" and "earth" tag names at the top level
            Config conf;
            if ( docConf.hasChild( "map" ) )
                conf = docConf.child( "map" );
            else if ( docConf.hasChild( "earth" ) )
                conf = docConf.child( "earth" );

            MapNode* mapNode =0L;
            if ( !conf.empty() )
            {
                // see if we were given a reference URI to use:
                std::string refURI = uriContext.referrer();

                if ( conf.value("version") == "1" )
                {
                    OE_INFO << LC << "Detected a version 1.x earth file" << std::endl;
                    EarthFileSerializer1 ser;
                    mapNode = ser.deserialize( conf, refURI );
                }

                else
                {
                    if ( conf.value("version") != "2" )
                        OE_INFO << LC << "No valid earth file version; assuming version='2'" << std::endl;

                    EarthFileSerializer2 ser;
                    mapNode = ser.deserialize( conf, refURI );
                }
            }

            return ReadResult(mapNode);
        }
    virtual ReadResult readNode(std::istream& in, const osgDB::Options* options ) const
    {
        // pull the URI context from the options structure (since we're reading
        // from an "anonymous" stream here)
        URIContext uriContext( options );

        osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in, uriContext );
        if ( !doc.valid() )
            return ReadResult::ERROR_IN_READING_FILE;

        Config docConf = doc->getConfig();

        // support both "map" and "earth" tag names at the top level
        Config conf;
        if ( docConf.hasChild( "map" ) )
            conf = docConf.child( "map" );
        else if ( docConf.hasChild( "earth" ) )
            conf = docConf.child( "earth" );

        MapNode* mapNode =0L;
        if ( !conf.empty() )
        {
            // see if we were given a reference URI to use:
            std::string refURI = uriContext.referrer();

            if ( conf.value("version") == "1" )
            {
                OE_INFO << LC << "Detected a version 1.x earth file" << std::endl;
                EarthFileSerializer1 ser;
                mapNode = ser.deserialize( conf, refURI );
            }

            else
            {
                if ( conf.value("version") != "2" )
                    OE_DEBUG << LC << "No valid earth file version; assuming version='2'" << std::endl;

                // attempt to parse a "default options" JSON string:
                std::string defaultConfStr;
                if ( options )
                {
                    defaultConfStr = options->getPluginStringData("osgEarth.defaultOptions");
                    if ( !defaultConfStr.empty() )
                    {
                        Config optionsConf("options");
                        if (optionsConf.fromJSON(defaultConfStr))
                        {
                            //OE_NOTICE << "\n\nOriginal = \n" << conf.toJSON(true) << "\n";
                            Config* original = conf.mutable_child("options");
                            if ( original )
                            {
                                recursiveUniqueKeyMerge(optionsConf, *original);
                            }
                            if ( !optionsConf.empty() )
                            {
                                conf.set("options", optionsConf);
                            }
                            //OE_NOTICE << "\n\nMerged = \n" << conf.toJSON(true) << "\n";
                        }
                    }
                }

                EarthFileSerializer2 ser;
                mapNode = ser.deserialize( conf, refURI );
            }
        }

        return ReadResult(mapNode);
    }