void
GfxCountryMapGenerator::run()
{
   const int maxHandshake = 1024;
   char handshake[maxHandshake];
   
   TCPSocket* socket = waitForConnection(handshake, maxHandshake);

   if ( socket == NULL ) {
      mc2log << error << "No connection for GfxCountryMapGenerator" << endl;
      return;
   }
   
   DEBUG2(uint32 startTime = TimeUtility::getCurrentTime());

   // We've got an request for a map...
   mc2dbg4 << "GfxCountryMapGenerator, sending map with ID " 
           << mapIDs[0] << endl;
   CountryOverviewMap* theMap = 
      dynamic_cast<CountryOverviewMap*>(mapHandler->getMap(mapIDs[0]));
   DEBUG8(cerr << "MAPID " << mapIDs[0] << endl);
      
   // Check if the map is valid or not
   if (theMap != NULL) {
      // OK, map valid!

      uint32 nbrMaps = theMap->getNbrMaps();
      const GfxData* mapGfx = theMap->getGfxData();


      // Calculate the size of the filtered map when written to a buffer.
      uint32 filtMapsBufSize = 0;
      const uint32 nbrFiltLevels = 
         CountryOverviewMap::NBR_SIMPLIFIED_COUNTRY_GFX;
      for (uint32 i = 0; i < nbrFiltLevels; i++ ) {
         for (uint32 j = 0; j < mapGfx->getNbrPolygons(); j++ ) {
            const Stack* filtStack = theMap->getFilterStack(i,j);
            filtMapsBufSize += 4; // writes number of filt stack elements.
            for (uint32 k = 0; k < filtStack->getStackSize(); k++) {
               filtMapsBufSize += 4; // writes filt stack element.
            }
         }            
      }

      // Claculate size of buffer needed.
      uint32 bufSize = 4;     // nbrMaps
      bufSize += nbrMaps * 24; // nbrMaps * (mapId, creationTime, Bbox)
      bufSize += 4;           // polygons closed, nbrPolygons
      bufSize += mapGfx->getNbrPolygons() * 4; // nbr coordinates per polygon.
      bufSize += theMap->getGfxData()->getTotalNbrCoordinates() * 8; // coords.
      bufSize += 4; // nbrFiltLevels
      bufSize += filtMapsBufSize; // Size of the filter data.

      DataBuffer idsAndGfx(bufSize);

      // Note that we multiply the size of the coordinates with two in 
      // order to make space for the filtered versions of the country
      // GfxData as well.
//    DataBuffer idsAndGfx(nbrMaps * 24 + // ID + ver + Bbox
//                         theMap->getGfxData()->getTotalNbrCoordinates()*8*2 +
//                         102400);   // approx gfxdata
      
      idsAndGfx.writeNextLong(nbrMaps);
      for (uint32 i=0; i<nbrMaps; i++) {
         uint32 creationTime;
         int32 maxLat, minLat, maxLon, minLon;
         uint32 mapID = theMap->getMapData(i, creationTime,
                                           maxLat, minLon,
                                           minLat, maxLon);
         idsAndGfx.writeNextLong(mapID);
         idsAndGfx.writeNextLong(creationTime);
         idsAndGfx.writeNextLong(maxLat);
         idsAndGfx.writeNextLong(minLon);
         idsAndGfx.writeNextLong(minLat);
         idsAndGfx.writeNextLong(maxLon);
         mc2dbg1 << "   Wrote mapID=" << mapID << ", version=" 
                 << creationTime << ", bbox="
                 << maxLat << ", " << minLon << ", " << minLat << ", "
                 << maxLon << endl;
      }
      
      // Save the GfxData of the country
      

      //uint32 nbrPolygons = MIN(5, mapGfx->getNbrPolygons());
      uint32 nbrPolygons = 0;
      // The polygons being sorted on nbrCoordinates, we an accept 
      // to skip(send) 5 small polys with many coords, in order to 
      // send larger polygons with fewer coordinates.
      uint32 maxNbrSkipPolys = 5;
      uint32 skipPolys[maxNbrSkipPolys];
      for (uint32 i = 0; i < maxNbrSkipPolys;i++) {
         skipPolys[i] = MAX_UINT32;
      }
      bool cont = true;
      uint32 nbrSkip = 0;
      while (cont && (nbrPolygons < mapGfx->getNbrPolygons())) {
         mc2dbg8 << "poly " << nbrPolygons << " nbrC=" 
                 << mapGfx->getNbrCoordinates(nbrPolygons)
                 << " length=" << mapGfx->getLength(nbrPolygons);
         if (mapGfx->getLength(nbrPolygons) < 35000) {
            skipPolys[nbrSkip] = nbrPolygons;
            mc2dbg8 << "  - \"skipping\" ";
            nbrSkip++;
            if (nbrSkip >= maxNbrSkipPolys) {
               cont = false;
            }
         }
         mc2dbg8 << endl;
         nbrPolygons++;
      }
      // Don't send if any of the small polygons are the last ones..
      uint32 p = maxNbrSkipPolys;
      while ( (p > 0) && (skipPolys[p-1] >= nbrPolygons-1)) {
         if (skipPolys[p-1] == nbrPolygons-1) {
            mc2dbg8 << " skip poly in the end of nbrPolygons" << endl;
            nbrPolygons--;
         }
         p--;
      }

      nbrPolygons=MAX(1, nbrPolygons);
      
      mc2dbg << "Sending " << nbrPolygons << " polygons of "
             << mapGfx->getNbrPolygons() << endl;


      idsAndGfx.writeNextBool(true);        // polygons closed
      idsAndGfx.writeNextByte(0);           // PAD
      idsAndGfx.writeNextShort(nbrPolygons);// # polygons
      for (uint32 p=0; p<nbrPolygons;p++) {
         uint32 nbrCoordinates = mapGfx->getNbrCoordinates(p);
         idsAndGfx.writeNextLong(nbrCoordinates);
         for (uint32 i = 0; i < nbrCoordinates; i++) {
            idsAndGfx.writeNextLong(mapGfx->getLat(p, i));
            idsAndGfx.writeNextLong(mapGfx->getLon(p, i));
         }
      }
      
      // Send filtered gfxdata information.

      // Nbr filtering levels
      idsAndGfx.writeNextLong(nbrFiltLevels);      
      for (uint32 i = 0; i < nbrFiltLevels; i++ ) {
         // Nbr polygons already written before
         for (uint32 j = 0; j < nbrPolygons; j++ ) {
            const Stack* filtStack = theMap->getFilterStack(i,j);
            // Nbr indices in the filtering stack.
            idsAndGfx.writeNextLong(filtStack->getStackSize());
            for (uint32 k = 0; k < filtStack->getStackSize(); k++) {
               // Index
               idsAndGfx.writeNextLong(filtStack->getElementAt(k));
            }
         }            
      }
       
      
      // Create and fill a buffer with the string items in this country
      DataBuffer stringItems(theMap->getMaximunSizeOfStringItems()*2 +
                             40000000); // length of items
      
      if (!theMap->saveStringItems(&stringItems)) {
         mc2log << error <<"Error saving string items for country" << endl;
      }


      // Create and fill buffer with items.
      
      // Nbr items. To be filled in later.
      uint32 offset = stringItems.getCurrentOffset();
      stringItems.writeNextLong(0);
      uint32 maxCountryMapZoom = 3;
      uint32 nbrItems = 0;
      for (uint32 z = 0; z < maxCountryMapZoom; z++) {
         writeItemsInZoomLevel(theMap, &stringItems, z, nbrItems);
      }
      // Fill in nbr items
      stringItems.writeLong(nbrItems, offset);
      
      
      // Create and fill buffer with version and length
      DataBuffer versionAndLengthBuffer(8);
      versionAndLengthBuffer.writeNextLong(theMap->getCreationTime());
      uint32 length = idsAndGfx.getCurrentOffset() +
                      stringItems.getCurrentOffset();
      versionAndLengthBuffer.writeNextLong(length);

      // Send the buffers via TCP
      uint32 nbrBytes = 
         socket->writeAll( versionAndLengthBuffer.getBufferAddress(),
                           versionAndLengthBuffer.getCurrentOffset() );
      mc2dbg4 << "   Sent " << nbrBytes << " with version ("
              << theMap->getCreationTime() << ") and length (" 
              << length << ")" << endl;

      nbrBytes = socket->writeAll( idsAndGfx.getBufferAddress(),
                                   idsAndGfx.getCurrentOffset() );
      mc2dbg4 << "   Sent " << nbrBytes << " with map IDs and GfxData"
              << endl;

      nbrBytes = socket->writeAll( stringItems.getBufferAddress(),
                                   stringItems.getCurrentOffset() );
      mc2dbg4<< "   Sent " << nbrBytes << " with string items"
                  << endl;

      

      // Delete the socket
      delete socket;
   }
   DEBUG2(
   mc2dbg << "GfxCountryMapGenerator sent all data for map " 
               << mapIDs[0] << ", processing time " 
               << TimeUtility::getCurrentTime()-startTime << " ms" << endl;
   );
TCPSocket*
ModuleMap::getMapLoadingSocket( uint32 mapID,
                                uint32 loadMapRequestType,
                                const char* handshake,
                                byte zoomlevel,
                                MapSafeVector* loadedMaps,
                                uint32* mapVersion,
                                uint32* generatorVersion )
{
   uint32 mapVersionToUse = MAX_UINT32;
   uint32 generatorVersionToUse = MAX_UINT32;
   if ( mapVersion != NULL && generatorVersion != NULL ) {
      // Set the versions to use to the ones sent in
      mapVersionToUse = *mapVersion;
      generatorVersionToUse = *generatorVersion;
      // Set the ones sent in to MAX_UINT32 to detect errors
      *mapVersion = MAX_UINT32;
      *generatorVersion = MAX_UINT32;
   }
   
   DatagramReceiver receiver(8000, DatagramReceiver::FINDFREEPORT);
   
   mc2dbg4 << here << " localport " << receiver.getPort() << endl;

   uint32 mapip = MultiCastProperties::getNumericIP( MODULE_TYPE_MAP, true );
   uint16 mapport = MultiCastProperties::getPort( MODULE_TYPE_MAP, true );

   // check map set
   uint32 mapSet = Properties::getMapSet();
   if (mapSet != MAX_UINT32) {
      // code also exists in PacketContainer.cpp, move to utility function?
      mc2dbg4 << "[ModuleMap] going to change IP and port due to mapSet being set. "
                "mapSet: " << mapSet << ", IP before: " << prettyPrintIP(mapip)
             << ", port before: " << mapport << endl;
      mapip = mapip + (mapSet << 8);
      mapport = mapport | (mapSet << 13);
      mc2dbg4 << "[ModuleMap] changed IP and port. IP now: " << prettyPrintIP(mapip)
             << ", port now: " << mapport << endl;
   }
   
   uint32 status = StringTable::NOT;
   int maxRetries = 10;
   int nbrRetries = 0;

   Packet _pack(65536); // For receiving the mapreply
   DatagramSender sock;

   const int originalwaittime    =  2500000; // Wait 2.5 seconds.
   const int mapnotfoundwaittime =  2500000; // Wait 2.5 seconds.
   int waittime = originalwaittime;

   TCPSocket* TCPsock = NULL;
   
   while ( status != StringTable::OK && nbrRetries++ <= maxRetries ) {
      if ( nbrRetries > 1 ) {
         mc2log << info << here << " Retrying " << nbrRetries - 1 
                << " of " << maxRetries << endl;
      }
      if(loadedMaps != NULL)
         loadedMaps->jobThreadIsAlive(); // reset Jthread timeout clock.
      MapRequestPacket reqpack( uint16(1),  // reqID
                                uint16(1),  // PacketID
                                byte(loadMapRequestType), // Type of module
                                mapID,      // mapID
                                zoomlevel,  // Well, zoomlevel.
                                mapVersionToUse,
                                generatorVersionToUse
                                ); 
      reqpack.setOriginIP( NetUtility::getLocalIP() );
      reqpack.setOriginPort( receiver.getPort() );
      reqpack.setResendNbr((byte) nbrRetries-1);
      
      // Send request to open TCP connection between local and mapmodule
      
      if (!(sock.send(&reqpack, mapip, mapport))) {
         mc2log << error << here << " could not send - retrying"
                << endl;
         continue; // Go another round in the loop.
      }
      mc2dbg4 << "After send!" << endl;
      
      // Receive packet with ip and port to a mapModule
      if (!(receiver.receive(&_pack, waittime))) {
         mc2log << error << here << " error receiving ack - retrying"
                << endl;
         waittime = originalwaittime;
         continue; // Go another round in the loop.
      }

      bool timeout = false;
      while ( _pack.getSubType() == Packet::PACKETTYPE_ACKNOWLEDGE &&
              ! timeout ) {
         AcknowledgeRequestReplyPacket* ackPack =
            static_cast<AcknowledgeRequestReplyPacket*>(&_pack);
         uint32 packtime =
            ((AcknowledgeRequestReplyPacket*)&_pack)->getETA() * 1000;
         mc2log << info << "Got ack with " << packtime << " us delay" << endl;
         if ( ackPack->getStatus() != StringTable::OK ) {
            return NULL;
         }
         timeout = !receiver.receive(&_pack, packtime);         
      }

      if ( timeout ) {
         mc2log << error << "Got timeout after receiving ack-pack" << endl;
         continue; // Go around again
      }

      if ( _pack.getSubType() != Packet::PACKETTYPE_MAPREPLY ) {
         mc2log << error << "Got packet with subtype "
                << _pack.getSubTypeAsString()
                << " when expecting loadmapreply" << endl;
         continue; // Please try again.
      }
      
      MapReplyPacket* pack = (MapReplyPacket *)&_pack;
      
      status = pack->getStatus();
      
      if ( status != StringTable::OK || pack->getMapID() != mapID ) {
         mc2log << warn << "Got status \""
                << StringTable::getString(
                   StringTable::stringCode(pack->getStatus()),
                   StringTable::ENGLISH)
                << "\"-retrying. Wanted map = "
                << mapID
                << ", got reply for map = " << pack->getMapID() << endl;
         if ( status == StringTable::MAPNOTFOUND ) {
            // Wait longer if map not found ( loading? )
            waittime = mapnotfoundwaittime; 
         }
         if ( mapID != pack->getMapID() ) {
            status = StringTable::NOT; // Keep the loop running.
         }
         continue; // Go another round in the loop.
      }

      if ( mapVersion != NULL && generatorVersion != NULL ) {
         // Set the versions so that we know what we are caching.
         mc2dbg8 << "[ModuleMap]: Version from packet "
                 << hex << pack->getMapVersion() << ":"
                 << pack->getGeneratorVersion() << dec << endl;
         *mapVersion       = pack->getMapVersion();
         *generatorVersion = pack->getGeneratorVersion();

         // Check if new map is needed.
         if ( ! pack->newMapNeeded(mapVersionToUse,
                                   generatorVersionToUse) ) {
            // Same version. Use the cached map.
            return NULL;
         } 
      }
      
      TCPsock = new TCPSocket;      
      mc2dbg4 << here << " opening socket" << endl;
      TCPsock->open();
      
      uint32 ip = pack->getReplyIP();
      uint16 port = pack->getReplyPort();
      
      if ( ! TCPsock->connect(ip, port ) ) {
         mc2log << error << "Couldn't connect to " << ip
                << ":" << port << " - retrying" << endl;
         // Set status to not ok.
         status = StringTable::NOT;
         TCPsock->close();
         delete TCPsock;
         TCPsock = NULL;                  
         continue; // Please try again.
      }
      
      // Handshaking
      mc2dbg4 << "Starting handshake" << endl;
      int length = strlen(handshake) + 1;
      if ( TCPsock->writeAll( (byte*)handshake, length ) != length ) {
         mc2log << error << here << " handshake failed " << endl;
         status = StringTable::NOT;
         TCPsock->close();
         delete TCPsock;
         TCPsock = NULL;
         continue; // Please try again.
      } else {
         mc2dbg4 << "done" << endl;
      }
   }
   return TCPsock; // Should be NULL if we failed
}