Index: src/mlx/acft.py
===================================================================
--- src/mlx/acft.py	(revision 117)
+++ src/mlx/acft.py	(revision 134)
@@ -5,4 +5,5 @@
 import const
 import checks
+import fs
 import util
 
@@ -54,4 +55,7 @@
         self._checkers.append(checks.CruiseSpeedLogger())
         self._checkers.append(checks.SpoilerLogger())
+
+        if flight.config.isMessageTypeFS(const.MESSAGETYPE_VISIBILITY):
+            self._checkers.append(checks.VisibilityChecker())
 
         # Fault checkers
@@ -134,4 +138,9 @@
                 self.logger.message(aircraftState.timestamp, 
                                     "Zero-fuel weight: %.0f kg" % (aircraftState.zfw))
+                flight = self._flight
+                if flight.v1 is None or flight.vr is None or flight.v2 is None:
+                    fs.sendMessage(const.MESSAGETYPE_HELP,
+                                   "Don't forget to set the takeoff V-speeds!",
+                                   5)
             elif newStage==const.STAGE_TAKEOFF:
                 self.logger.message(aircraftState.timestamp, "Flight time start")
@@ -145,4 +154,9 @@
                 self._logV1R2()
             elif newStage==const.STAGE_TAXIAFTERLAND:
+                bookedFlight = self._flight.bookedFlight
+                if bookedFlight.arrivalICAO=="LHBP" and \
+                   self._flight.config.isMessageTypeFS(const.MESSAGETYPE_GATE_SYSTEM):
+                    self._flight.getFleet(callback = self._fleetRetrieved,
+                                          force = True)
                 self.logger.message(aircraftState.timestamp, "Flight time end")
                 self.logFuel(aircraftState)
@@ -167,4 +181,10 @@
                                     "Block time: " +
                                     util.getTimeIntervalString(blockLength))
+                bookedFlight = self._flight.bookedFlight
+                # FIXME: translate the ICAO into an airport name
+                fs.sendMessage(const.MESSAGETYPE_ENVIRONMENT,
+                               "Flight plan closed. Welcome to %s" % \
+                               (bookedFlight.arrivalICAO,),
+                               5)
 
     def prepareFlare(self):
@@ -189,4 +209,5 @@
         self._logVRef()
         self.flight.flareStarted(flareStart, flareStartFS)
+        fs.sendMessage(const.MESSAGETYPE_INFORMATION, "Flare-time", 3)
          
     def flareFinished(self, flareEnd, flareEndFS, tdRate, tdRateCalculatedByFS,
@@ -265,4 +286,17 @@
         else:
             self.logger.updateLine(self._vrefLineIndex, message)
+
+    def _fleetRetrieved(self, fleet):
+        """Callback for the fleet retrieval result."""
+        if fleet is not None:
+            gateList = ""
+            occupiedGateNumbers = fleet.getOccupiedGateNumbers()
+            for gateNumber in const.lhbpGateNumbers:
+                if gateNumber not in occupiedGateNumbers:
+                    if gateList: gateList += ", "
+                    gateList += gateNumber
+            fs.sendMessage(const.MESSAGETYPE_GATE_SYSTEM,
+                           "Free gates: " + gateList, 20)
+        
 
 #---------------------------------------------------------------------------------------
Index: src/mlx/checks.py
===================================================================
--- src/mlx/checks.py	(revision 60)
+++ src/mlx/checks.py	(revision 134)
@@ -3,5 +3,7 @@
 #---------------------------------------------------------------------------------------
 
+import fs
 import const
+import util
 
 #---------------------------------------------------------------------------------------
@@ -143,4 +145,30 @@
 #---------------------------------------------------------------------------------------
 
+class VisibilityChecker(StateChecker):
+    """Inform the pilot of the visibility once when descending below 2000 ft,
+    then when descending below 1000 ft."""
+    def __init__(self):
+        """Construct the visibility checker."""
+        self._informedBelow2000 = False
+        self._informedBelow1000 = False
+
+    def check(self, flight, aircraft, logger, oldState, state):
+        """Check if we need to inform the pilot of the visibility."""
+        if flight.stage==const.STAGE_DESCENT or \
+           flight.stage==const.STAGE_LANDING:
+            if (state.radioAltitude<2000 and not self._informedBelow2000) or \
+               (state.radioAltitude<1000 and not self._informedBelow1000):
+                visibilityString = util.visibility2String(state.visibility)
+                fs.sendMessage(const.MESSAGETYPE_VISIBILITY,
+                               "Current visibility: " + visibilityString,
+                               5)
+                logger.message(state.timestamp,
+                               "Pilot was informed about the visibility: " +
+                               visibilityString)
+                self._informedBelow2000 = True
+                self._informedBelow1000 = state.radioAltitude<1000
+
+#---------------------------------------------------------------------------------------
+
 class StateChangeLogger(StateChecker):
     """Base class for classes the instances of which check if a specific change has
Index: src/mlx/config.py
===================================================================
--- src/mlx/config.py	(revision 133)
+++ src/mlx/config.py	(revision 134)
@@ -114,4 +114,11 @@
                else const.MESSAGELEVEL_NONE
 
+    def isMessageTypeFS(self, messageType):
+        """Determine if the given message type is displayed in the
+        simulator."""
+        level = self.getMessageTypeLevel(messageType)
+        return level==const.MESSAGELEVEL_FS or \
+               level==const.MESSAGELEVEL_BOTH
+        
     def setMessageTypeLevel(self, messageType, level):
         """Set the level of the given message type."""
Index: src/mlx/const.py
===================================================================
--- src/mlx/const.py	(revision 133)
+++ src/mlx/const.py	(revision 134)
@@ -202,5 +202,4 @@
 
 # Message type: information
-# FIXME: flare time begin (3 sec)
 MESSAGETYPE_INFORMATION = 2
 
@@ -212,5 +211,4 @@
 
 # Message type: gate system messages
-# FIXME: the available gates when arriving to LHBP (10 sec)
 MESSAGETYPE_GATE_SYSTEM = 5
 
@@ -220,9 +218,7 @@
 
 # Message type: help messages
-# FIXME: don't forget V speeds when stage is PUSHANDTAXI (5 sec)
 MESSAGETYPE_HELP = 7
 
 # Message type: visibility messages
-# FIXME: the visibility, once when below 2000 RA, then when below 1000 RA (5 sec)
 MESSAGETYPE_VISIBILITY = 8
 
Index: src/mlx/flight.py
===================================================================
--- src/mlx/flight.py	(revision 89)
+++ src/mlx/flight.py	(revision 134)
@@ -60,7 +60,17 @@
 
     @property
+    def config(self):
+        """Get the configuration."""
+        return self._gui.config
+
+    @property
     def stage(self):
         """Get the flight stage."""
         return self._stage
+
+    @property
+    def bookedFlight(self):
+        """Get the booked flight."""
+        return self._gui.bookedFlight
 
     @property
@@ -163,4 +173,8 @@
                 self._endCondition.wait(1)
 
+    def getFleet(self, callback, force = False):
+        """Get the fleet and call the given callback."""
+        self._gui.getFleetAsync(callback = callback, force = force)
+
     def _updateFlownDistance(self, currentState):
         """Update the flown distance."""
Index: src/mlx/fs.py
===================================================================
--- src/mlx/fs.py	(revision 133)
+++ src/mlx/fs.py	(revision 134)
@@ -199,4 +199,5 @@
     - windSpeed: the speed of the wind at the aircraft in knots (float)
     - windDirection: the direction of the wind at the aircraft in degrees (float)
+    - visibility: the visibility in metres (float)
 
     FIXME: needed when taxiing only:
Index: src/mlx/fsuipc.py
===================================================================
--- src/mlx/fsuipc.py	(revision 133)
+++ src/mlx/fsuipc.py	(revision 134)
@@ -830,5 +830,6 @@
                       ("squawk", 0x0354, "H"),
                       ("windSpeed", 0x0e90, "H"),
-                      ("windDirection", 0x0e92, "H")]
+                      ("windDirection", 0x0e92, "H"),
+                      ("visibility", 0x0e8a, "H")]
 
 
@@ -1003,4 +1004,6 @@
         state.windDirection = data[self._monidx_windDirection]*360.0/65536.0
         if state.windDirection<0.0: state.windDirection += 360.0
+
+        state.visibility = data[self._monidx_visibility]*1609.344/100.0
         
         return state
Index: src/mlx/gui/gui.py
===================================================================
--- src/mlx/gui/gui.py	(revision 133)
+++ src/mlx/gui/gui.py	(revision 134)
@@ -400,4 +400,6 @@
         self._statusbar.updateConnection(False, False)
         self._weightHelp.disable()
+
+        return True
             
     def addFlightLogLine(self, timeStr, line):
@@ -442,5 +444,8 @@
         self._wizard.setStage(stage)
         if stage==const.STAGE_END:
-            self._disconnect()
+            # FIXME: perhaps a more elegant method, e.g.
+            # the simulator should provide a function disconnect
+            # with a final message
+            gobject.timeout_add(1.0, self._disconnect)
 
     def setRating(self, rating):
@@ -564,4 +569,8 @@
         self._weightHelp.reset()
         self._weightHelp.enable()
+
+    def getFleetAsync(self, callback = None, force = None):
+        """Get the fleet asynchronously."""
+        gobject.idle_add(self.getFleet, callback, force)
 
     def getFleet(self, callback = None, force = False):
Index: src/mlx/logger.py
===================================================================
--- src/mlx/logger.py	(revision 133)
+++ src/mlx/logger.py	(revision 134)
@@ -75,5 +75,6 @@
         if stage==const.STAGE_END:
             self.untimedMessage("Rating: %.0f" % (self.getRating(),))
-        sendMessage(const.MESSAGETYPE_INFORMATION, "Flight stage: " + s, 3)
+        else:
+            sendMessage(const.MESSAGETYPE_INFORMATION, "Flight stage: " + s, 3)
         
     def fault(self, faultID, timestamp, what, score):
Index: src/mlx/util.py
===================================================================
--- src/mlx/util.py	(revision 97)
+++ src/mlx/util.py	(revision 134)
@@ -149,2 +149,8 @@
     return (radians2nm(d), math.degrees(tc))
 
+#------------------------------------------------------------------------------
+
+def visibility2String(visibility):
+    """Convert the given visibility expressed in metres into a string."""
+    return "%.0f metres" % (visibility,) if visibility<10000 \
+           else "%.1f kilometres" % (visibility/1000.0,)
