Index: src/mlx/const.py
===================================================================
--- src/mlx/const.py	(revision 36)
+++ src/mlx/const.py	(revision 51)
@@ -115,4 +115,42 @@
 #-------------------------------------------------------------------------------
 
+# Plane status: unknown
+PLANE_UNKNOWN = 0
+
+# Plane status: at home, i.e. LHBP
+PLANE_HOME = 1
+
+# Plane status: away
+PLANE_AWAY = 2
+
+# Plane status: parking
+PLANE_PARKING = 3
+
+#-------------------------------------------------------------------------------
+
+# The available gates at LHBP
+lhbpGateNumbers = []
+
+for i in range(1, 7):
+    lhbpGateNumbers.append(str(i))
+
+for i in range(10, 19):
+    lhbpGateNumbers.append(str(i))
+
+for i in range(24, 28):
+    lhbpGateNumbers.append(str(i))
+
+for i in range(31, 39):
+    lhbpGateNumbers.append(str(i))
+
+for i in range(42, 47):
+    lhbpGateNumbers.append(str(i))
+
+for i in range(60, 84):
+    if i!=70 and i!=80:
+        lhbpGateNumbers.append(str(i))
+
+#-------------------------------------------------------------------------------
+
 _stageStrings = { STAGE_BOARDING : "boarding",
                   STAGE_PUSHANDTAXI : "pushback and taxi",
Index: src/mlx/fsuipc.py
===================================================================
--- src/mlx/fsuipc.py	(revision 27)
+++ src/mlx/fsuipc.py	(revision 51)
@@ -17,5 +17,5 @@
     import pyuipc
 else:
-    import pyuipc_emu as pyuipc
+    import pyuipc_sim as pyuipc
 
 #------------------------------------------------------------------------------
Index: src/mlx/gui/flight.py
===================================================================
--- src/mlx/gui/flight.py	(revision 50)
+++ src/mlx/gui/flight.py	(revision 51)
@@ -2,4 +2,10 @@
 
 from mlx.gui.common import *
+
+import mlx.const as const
+import mlx.fs as fs
+from mlx.logger import Logger
+from mlx.flight import Flight
+from mlx.acft import Aircraft
 
 #-----------------------------------------------------------------------------
@@ -62,5 +68,5 @@
         self._mainAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
                                             xscale = 1.0, yscale = 1.0)
-        table.attach(self._mainAlignment, 0, 1, 1, 3)                                    
+        table.attach(self._mainAlignment, 0, 1, 1, 3)
                                             
         buttonAlignment =  gtk.Alignment(xalign = 1.0, xscale=0.0, yscale = 0.0)
@@ -182,7 +188,7 @@
         """Called when the login button was clicked."""
         self._wizard.gui.beginBusy("Logging in...")
-        self._wizard.gui.webHandler.login(self._pilotID.get_text(),
-                                          self._password.get_text(),
-                                          self._loginResultCallback)
+        self._wizard.gui.webHandler.login(self._loginResultCallback,
+                                          self._pilotID.get_text(),
+                                          self._password.get_text())
 
     def _loginResultCallback(self, returned, result):
@@ -275,4 +281,5 @@
         self._button.set_use_stock(True)
         self._button.set_sensitive(False)
+        self._button.connect("clicked", self._forwardClicked)
 
         self._activated = False
@@ -292,4 +299,196 @@
         self._button.set_sensitive(selection.count_selected_rows()==1)
 
+    def _forwardClicked(self, button):
+        """Called when the forward button was clicked."""
+        selection = self._flightList.get_selection()
+        (listStore, iter) = selection.get_selected()
+        path = listStore.get_path(iter)
+        [index] = path.get_indices() if pygobject else path
+
+        flight = self._wizard.loginResult.flights[index]
+        self._wizard._bookedFlight = flight
+
+        self._updateDepartureGate()
+        
+    def _updateDepartureGate(self):
+        """Update the departure gate for the booked flight."""
+        flight = self._wizard._bookedFlight
+        if flight.departureICAO=="LHBP":
+            self._wizard._getFleet(self._fleetRetrieved)
+        else:
+            self._wizard.jumpPage(2)
+
+    def _fleetRetrieved(self, fleet):
+        """Called when the fleet has been retrieved."""
+        if fleet is None:
+            self._wizard.jumpPage(2)
+        else:
+            plane = fleet[self._wizard._bookedFlight.tailNumber]
+            if plane is None:
+                self._wizard.jumpPage(2)
+            
+            if plane.gateNumber is not None and \
+               not fleet.isGateConflicting(plane):
+                self._wizard._departureGate = plane.gateNumber
+                self._wizard.jumpPage(2)
+            else:
+                self._wizard.nextPage()
+        
+#-----------------------------------------------------------------------------
+
+class GateSelectionPage(Page):
+    """Page to select a free gate at LHBP.
+
+    This page should be displayed only if we have fleet information!."""
+    def __init__(self, wizard):
+        """Construct the gate selection page."""
+        help = "The airplane's gate position is invalid.\n\n" \
+               "Select the gate from which you\n" \
+               "would like to begin the flight."
+        super(GateSelectionPage, self).__init__(wizard,
+                                                "LHBP gate selection",
+                                                help)
+
+        self._listStore = gtk.ListStore(str)
+        self._gateList = gtk.TreeView(self._listStore)
+        column = gtk.TreeViewColumn(None, gtk.CellRendererText(),
+                                    text = 0)
+        column.set_expand(True)
+        self._gateList.append_column(column)
+        self._gateList.set_headers_visible(False)
+
+        gateSelection = self._gateList.get_selection()
+        gateSelection.connect("changed", self._selectionChanged)
+
+        scrolledWindow = gtk.ScrolledWindow()
+        scrolledWindow.add(self._gateList)
+        scrolledWindow.set_size_request(50, -1)
+        scrolledWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
+                                  else gtk.POLICY_AUTOMATIC,
+                                  gtk.PolicyType.ALWAYS if pygobject
+                                  else gtk.POLICY_ALWAYS)
+
+        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.0, xscale = 0.0, yscale = 1.0)
+        alignment.add(scrolledWindow)
+
+        self.setMainWidget(alignment)        
+
+        self._button = self.addButton(gtk.STOCK_GO_FORWARD, default = True)
+        self._button.set_use_stock(True)
+        self._button.set_sensitive(False)
+        self._button.connect("clicked", self._forwardClicked)
+
+    def activate(self):
+        """Fill the gate list."""
+        self._listStore.clear()
+        occupiedGateNumbers = self._wizard._fleet.getOccupiedGateNumbers()
+        for gateNumber in const.lhbpGateNumbers:
+            if gateNumber not in occupiedGateNumbers:
+                self._listStore.append([gateNumber])
+
+    def _selectionChanged(self, selection):
+        """Called when the selection is changed."""
+        self._button.set_sensitive(selection.count_selected_rows()==1)
+
+    def _forwardClicked(self, button):
+        """Called when the forward button is clicked."""
+        selection = self._gateList.get_selection()
+        (listStore, iter) = selection.get_selected()
+        (gateNumber,) = listStore.get(iter, 0)
+
+        self._wizard._departureGate = gateNumber
+
+        self._wizard._updatePlane(self._planeUpdated,
+                                  self._wizard._bookedFlight.tailNumber,
+                                  const.PLANE_HOME,
+                                  gateNumber)
+
+    def _planeUpdated(self, success):
+        """Callback for the plane updating call."""
+        if success is None or success:
+            self._wizard.nextPage()
+        else:
+            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
+                                       buttons = BUTTONSTYPE_OK,
+                                       message_format = "Gate conflict detected again")
+            dialog.format_secondary_markup("Try to select a different gate.")
+            dialog.run()
+            dialog.hide()
+
+            self._wizard._getFleet(self._fleetRetrieved)
+
+    def _fleetRetrieved(self, fleet):
+        """Called when the fleet has been retrieved."""
+        if fleet is None:
+            self._wizard.nextPage()
+        else:
+            self.activate()
+            
+#-----------------------------------------------------------------------------
+
+class ConnectPage(Page):
+    """Page which displays the departure airport and gate (if at LHBP)."""
+    def __init__(self, wizard):
+        """Construct the connect page."""
+        help = "The flight begins at the airport given below.\n" \
+               "Park your aircraft there, at the gate below, if given.\n\n" \
+               "Then press the Connect button to connect to the simulator."
+        super(ConnectPage, self).__init__(wizard,
+                                          "Connect to the simulator",
+                                          help)
+        
+        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
+                                  xscale = 0.0, yscale = 0.0)
+
+        table = gtk.Table(2, 2)
+        table.set_row_spacings(4)
+        table.set_col_spacings(16)
+        table.set_homogeneous(True)
+        alignment.add(table)
+        self.setMainWidget(alignment)
+
+        labelAlignment = gtk.Alignment(xalign=1.0, xscale=0.0)
+        label = gtk.Label("ICAO code:")
+        labelAlignment.add(label)
+        table.attach(labelAlignment, 0, 1, 0, 1)
+
+        labelAlignment = gtk.Alignment(xalign=0.0, xscale=0.0)
+        self._departureICAO = gtk.Label()
+        self._departureICAO.set_width_chars(5)
+        self._departureICAO.set_alignment(0.0, 0.5)
+        labelAlignment.add(self._departureICAO)
+        table.attach(labelAlignment, 1, 2, 0, 1)
+
+        labelAlignment = gtk.Alignment(xalign=1.0, xscale=0.0)
+        label = gtk.Label("Gate:")
+        label.set_use_underline(True)
+        labelAlignment.add(label)
+        table.attach(labelAlignment, 0, 1, 1, 2)
+
+        labelAlignment = gtk.Alignment(xalign=0.0, xscale=0.0)
+        self._departureGate = gtk.Label()
+        self._departureGate.set_width_chars(5)
+        self._departureGate.set_alignment(0.0, 0.5)
+        labelAlignment.add(self._departureGate)
+        table.attach(labelAlignment, 1, 2, 1, 2)
+
+
+        self._button = self.addButton("_Connect", default = True)
+        self._button.set_use_underline(True)
+        self._button.connect("clicked", self._connectClicked)
+
+    def activate(self):
+        """Setup the deprature information."""
+        icao = self._wizard._bookedFlight.departureICAO
+        self._departureICAO.set_markup("<b>" + icao + "</b>")
+        gate = self._wizard._departureGate
+        if gate!="-":
+            gate = "<b>" + gate + "</b>"
+        self._departureGate.set_markup(gate)
+
+    def _connectClicked(self, button):
+        """Called when the Connect button is pressed."""
+        self._wizard._connectSimulator()
+
 #-----------------------------------------------------------------------------
 
@@ -307,9 +506,34 @@
         self._pages.append(LoginPage(self))
         self._pages.append(FlightSelectionPage(self))
-
+        self._pages.append(GateSelectionPage(self))
+        self._pages.append(ConnectPage(self))
+
+        maxWidth = 0
+        maxHeight = 0
+        for page in self._pages:
+            page.show_all()
+            pageSizeRequest = page.size_request()
+            width = pageSizeRequest.width if pygobject else pageSizeRequest[0]
+            height = pageSizeRequest.height if pygobject else pageSizeRequest[1]
+            maxWidth = max(maxWidth, width)
+            maxHeight = max(maxHeight, height)
+        maxWidth += 16
+        maxHeight += 32
+        self.set_size_request(maxWidth, maxHeight)
+
+        self._fleet = None
+        self._fleetCallback = None
+        self._updatePlaneCallback = None
+        
         self._loginResult = None
-
+        self._bookedFlight = None
+        self._departureGate = "-"
+
+        self._logger = Logger(output = gui)
+        self._flight = None
+        self._simulator = None
+        
         self.setCurrentPage(0)
-
+        
     @property
     def loginResult(self):
@@ -331,5 +555,9 @@
     def nextPage(self):
         """Go to the next page."""
-        self.setCurrentPage(self._currentPage + 1)
+        self.jumpPage(1)
+
+    def jumpPage(self, count):
+        """Go to the page which is 'count' pages after the current one."""
+        self.setCurrentPage(self._currentPage + count)
         self.grabDefault()
 
@@ -337,4 +565,88 @@
         """Make the default button of the current page the default."""
         self._pages[self._currentPage].grabDefault()
+
+    def _getFleet(self, callback, force = False):
+        """Get the fleet, if needed.
+
+        callback is function that will be called, when the feet is retrieved,
+        or the retrieval fails. It should have a single argument that will
+        receive the fleet object on success, None otherwise.
+        """
+        if self._fleet is not None and not force:
+            callback(self._fleet)
+
+        self.gui.beginBusy("Retrieving fleet...")
+        self._fleetCallback = callback
+        self.gui.webHandler.getFleet(self._fleetResultCallback)
+
+    def _fleetResultCallback(self, returned, result):
+        """Called when the fleet has been queried."""
+        gobject.idle_add(self._handleFleetResult, returned, result)
+
+    def _handleFleetResult(self, returned, result):
+        """Handle the fleet result."""
+        self.gui.endBusy()
+        if returned:
+            self._fleet = result.fleet
+        else:
+            self._fleet = None
+
+            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
+                                       buttons = BUTTONSTYPE_OK,
+                                       message_format =
+                                       "Failed to retrieve the information on "
+                                       "the fleet.")
+            dialog.run()
+            dialog.hide()
+
+        self._fleetCallback(self._fleet)
+
+    def _updatePlane(self, callback, tailNumber, status, gateNumber = None):
+        """Update the given plane's gate information."""
+        self.gui.beginBusy("Updating plane status...")
+        self._updatePlaneCallback = callback
+        self.gui.webHandler.updatePlane(self._updatePlaneResultCallback,
+                                        tailNumber, status, gateNumber)
+
+    def _updatePlaneResultCallback(self, returned, result):
+        """Callback for the plane updating operation."""
+        gobject.idle_add(self._handleUpdatePlaneResult, returned, result)
+
+    def _handleUpdatePlaneResult(self, returned, result):
+        """Handle the result of a plane update operation."""
+        self.gui.endBusy()
+        if returned:
+            success = result.success
+        else:
+            success = None
+
+            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
+                                       buttons = BUTTONSTYPE_OK,
+                                       message_format =
+                                       "Failed to update the statuis of "
+                                       "the airplane.")
+            dialog.run()
+            dialog.hide()
+
+        self._updatePlaneCallback(success)
+
+    def _connectSimulator(self):
+        """Connect to the simulator."""
+        self._logger.reset()
+        self._flight = Flight(self.gui._logger, self.gui)
+
+        self._flight.aircraftType = self._bookedFlight.aircraftType
+        aircraft = self._flight.aircraft = Aircraft.create(self._flight)
+        self._flight.aircraft._checkers.append(self.gui)
+        
+        self._flight.cruiseAltitude = -1        
+        self._flight.zfw = -1
+
+        if self._simulator is None:
+            self._simulator = fs.createSimulator(const.SIM_MSFS9, self.gui)
+
+        self._flight.simulator = self._simulator 
+        self._simulator.connect(aircraft)
+        #self._simulator.startMonitoring()
     
 #-----------------------------------------------------------------------------
Index: src/mlx/gui/gui.py
===================================================================
--- src/mlx/gui/gui.py	(revision 50)
+++ src/mlx/gui/gui.py	(revision 51)
@@ -251,5 +251,4 @@
     def beginBusy(self, message):
         """Begin a period of background processing."""
-        print dir(self._mainWindow)
         self._mainWindow.get_window().set_cursor(self._busyCursor)
         self._statusbar.updateBusyState(message)
@@ -285,5 +284,5 @@
             self._writeLog(text)
             self._stdioAfterNewLine = False
-            
+
     def _connectToggled(self, button):
         """Callback for the connection button."""
Index: src/mlx/pyuipc_sim.py
===================================================================
--- src/mlx/pyuipc_sim.py	(revision 51)
+++ src/mlx/pyuipc_sim.py	(revision 51)
@@ -0,0 +1,130 @@
+# Simulator for the pyuipc module
+#------------------------------------------------------------------------------
+
+import time
+
+#------------------------------------------------------------------------------
+
+# Version constants
+SIM_ANY=0
+SIM_FS98=1
+SIM_FS2K=2
+SIM_CFS2=3
+SIM_CFS1=4
+SIM_FLY=5
+SIM_FS2K2=6
+SIM_FS2K4=7
+
+#------------------------------------------------------------------------------
+
+# Error constants
+ERR_OK=0
+ERR_OPEN=1
+ERR_NOFS=2
+ERR_REGMSG=3
+ERR_ATOM=4
+ERR_MAP=5
+ERR_VIEW=6
+ERR_VERSION=7
+ERR_WRONGFS=8
+ERR_NOTOPEN=9
+ERR_NODATA=10
+ERR_TIMEOUT=11
+ERR_SENDMSG=12
+ERR_DATA=13
+ERR_RUNNING=14
+ERR_SIZE=15
+
+#------------------------------------------------------------------------------
+
+# The version of FSUIPC
+fsuipc_version=0x0401
+lib_version=0x0302
+fs_version=SIM_FS2K4
+
+#------------------------------------------------------------------------------
+
+class FSUIPCException(Exception):
+    """FSUIPC exception class.
+
+    It contains a member variable named errorCode. The string is a text
+    describing the error."""
+
+    errors=["OK",
+            "Attempt to Open when already Open",
+            "Cannot link to FSUIPC or WideClient",
+            "Failed to Register common message with Windows",
+            "Failed to create Atom for mapping filename",
+            "Failed to create a file mapping object",
+            "Failed to open a view to the file map",
+            "Incorrect version of FSUIPC, or not FSUIPC",
+            "Sim is not version requested",
+            "Call cannot execute, link not Open",
+            "Call cannot execute: no requests accumulated",
+            "IPC timed out all retries",
+            "IPC sendmessage failed all retries",
+            "IPC request contains bad data",
+            "Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC",
+            "Read or Write request cannot be added, memory for Process is full"]
+
+    def __init__(self, errorCode):
+        """
+        Construct the exception
+        """
+        if errorCode<len(self.errors):
+            self.errorString =  self.errors[errorCode]
+        else:
+            self.errorString = "Unknown error"
+        Exception.__init__(self, self.errorString)
+        self.errorCode = errorCode
+
+    def __str__(self):
+        """
+        Convert the excption to string
+        """
+        return "FSUIPC error: %d (%s)" % (self.errorCode, self.errorString)
+
+#------------------------------------------------------------------------------
+
+def open(request):
+    """Open the connection."""
+    return True
+
+#------------------------------------------------------------------------------
+
+def prepare_data(pattern, forRead = True):
+    """Prepare the given pattern for reading and/or writing."""
+    return pattern
+
+#------------------------------------------------------------------------------
+
+def read(data):
+    """Read the given data."""
+    result = []
+    for (offset, type) in data:
+        if offset==0x023a:         # Second of time
+            result.append(time.gmtime().tm_sec)
+        elif offset==0x023b:       # Hour of Zulu time
+            result.append(time.gmtime().tm_hour)
+        elif offset==0x023c:       # Minute of Zulu time
+            result.append(time.gmtime().tm_min)
+        elif offset==0x023e:       # Day number on year
+            result.append(time.gmtime().tm_yday)
+        elif offset==0x0240:       # Year in FS
+            result.append(time.gmtime().tm_year)
+        elif offset==0x3c00:       # Path of the current AIR file
+            result.append("c:\\Program Files\\Microsoft Games\\FS9\\Aircraft\\kutya")
+        elif offset==0x3d00:       # Name of the current aircraft
+            result.append("Cessna 172")
+        else:
+            print "Unhandled offset: %04x" % (offset,)
+            raise FSUIPCException(ERR_DATA)
+    return result
+            
+#------------------------------------------------------------------------------
+
+def close():
+    """Close the connection."""
+    pass
+
+#------------------------------------------------------------------------------
Index: src/mlx/web.py
===================================================================
--- src/mlx/web.py	(revision 48)
+++ src/mlx/web.py	(revision 51)
@@ -7,4 +7,5 @@
 import threading
 import sys
+import urllib
 import urllib2
 import hashlib
@@ -102,4 +103,89 @@
 #------------------------------------------------------------------------------
 
+class Plane(object):
+    """Information about an airplane in the fleet."""
+    def __init__(self, s):
+        """Build a plane info based on the given string.
+
+        The string consists of three, space-separated fields.
+        The first field is the tail number, the second field is the gate
+        number, the third field is the plane's status as a character."""
+        try:
+            words = s.split(" ")
+            tailNumber = words[0]
+            self.tailNumber = tailNumber
+
+            status = words[2] if len(words)>2 else None
+            self.status = const.PLANE_HOME if status=="H" else \
+                          const.PLANE_AWAY if status=="A" else \
+                          const.PLANE_PARKING if status=="P" else \
+                          const.PLANE_UNKNOWN
+
+            gateNumber = words[1] if len(words)>1 else ""
+            self.gateNumber = gateNumber if gateNumber else None
+
+        except:
+            print >> sys.stderr, "Plane string is invalid: '" + s + "'"
+            self.tailNumber = None
+
+    def __repr__(self):
+        """Get the representation of the plane object."""
+        s = "<Plane: %s %s" % (self.tailNumber, 
+                               "home" if self.status==const.PLANE_HOME else \
+                               "away" if self.status==const.PLANE_AWAY else \
+                               "parking" if self.status==const.PLANE_PARKING \
+                               else "unknown")
+        if self.gateNumber is not None:
+            s += " (gate " + self.gateNumber + ")"
+        s += ">"
+        return s
+        
+
+#------------------------------------------------------------------------------
+
+class Fleet(object):
+    """Information about the whole fleet."""
+    def __init__(self, f):
+        """Construct the fleet information by reading the given file object."""
+        self._planes = {}
+        while True:
+            line = readline(f)
+            if not line or line == "#END": break
+
+            plane = Plane(line)
+            if plane.tailNumber is not None:
+                self._planes[plane.tailNumber] = plane        
+
+    def isGateConflicting(self, plane):
+        """Check if the gate of the given plane conflicts with another plane's
+        position."""
+        for p in self._planes.itervalues():
+            if p.tailNumber!=plane.tailNumber and \
+               p.status==const.PLANE_HOME and \
+               p.gateNumber==plane.gateNumber:
+                return True
+
+        return False
+
+    def getOccupiedGateNumbers(self):
+        """Get a set containing the numbers of the gates occupied by planes."""
+        gateNumbers = set()
+        for p in self._planes.itervalues():
+            if p.status==const.PLANE_HOME and p.gateNumber:
+                gateNumbers.add(p.gateNumber)
+        return gateNumbers
+        
+    def __getitem__(self, tailNumber):
+        """Get the plane with the given tail number.
+
+        If the plane is not in the fleet, None is returned."""
+        return self._planes[tailNumber] if tailNumber in self._planes else None
+
+    def __repr__(self):
+        """Get the representation of the fleet object."""
+        return self._planes.__repr__()
+        
+#------------------------------------------------------------------------------
+
 class Result(object):
     """A result object.
@@ -161,5 +247,5 @@
     iso88592decoder = codecs.getdecoder("iso-8859-2")
     
-    def __init__(self, pilotID, password, callback):
+    def __init__(self, callback, pilotID, password):
         """Construct the login request with the given pilot ID and
         password."""
@@ -205,6 +291,61 @@
                                     flight2.departureTime))
 
+        f.close()
+
         return result
         
+#------------------------------------------------------------------------------
+
+class GetFleet(Request):
+    """Request to get the fleet from the website."""
+    
+    def __init__(self, callback):
+        """Construct the fleet request."""
+        super(GetFleet, self).__init__(callback)
+
+    def run(self):
+        """Perform the login request."""
+        url = "http://www.virtualairlines.hu/onlinegates_get.php"
+
+        f = urllib2.urlopen(url)
+        result = Result()
+        result.fleet = Fleet(f)
+        f.close()
+        
+        return result
+
+#------------------------------------------------------------------------------
+
+class UpdatePlane(Request):
+    """Update the status of one of the planes in the fleet."""
+    def __init__(self, callback, tailNumber, status, gateNumber = None):
+        """Construct the request."""
+        super(UpdatePlane, self).__init__(callback)
+        self._tailNumber = tailNumber
+        self._status = status
+        self._gateNumber = gateNumber
+
+    def run(self):
+        """Perform the plane update."""
+        url = "http://www.virtualairlines.hu/onlinegates_set.php"
+
+        status = "H" if self._status==const.PLANE_HOME else \
+                 "A" if self._status==const.PLANE_AWAY else \
+                 "P" if self._status==const.PLANE_PARKING else ""
+
+        gateNumber = self._gateNumber if self._gateNumber else ""
+
+        data = urllib.urlencode([("lajstrom", self._tailNumber),
+                                 ("status", status),
+                                 ("kapu", gateNumber)])
+        
+        f = urllib2.urlopen(url, data)
+        line = readline(f)
+        
+        result = Result()
+        result.success = line == "OK"
+
+        return result
+            
 #------------------------------------------------------------------------------
 
@@ -223,8 +364,16 @@
         self.daemon = True
 
-    def login(self, pilotID, password, callback):
+    def login(self, callback, pilotID, password):
         """Enqueue a login request."""
-        self._addRequest(Login(pilotID, password, callback))
-
+        self._addRequest(Login(callback, pilotID, password))
+
+    def getFleet(self, callback):
+        """Enqueue a fleet retrieval request."""
+        self._addRequest(GetFleet(callback))
+        
+    def updatePlane(self, callback, tailNumber, status, gateNumber = None):
+        """Update the status of the given plane."""        
+        self._addRequest(UpdatePlane(callback, tailNumber, status, gateNumber))
+        
     def run(self):
         """Process the requests."""
@@ -255,6 +404,11 @@
     handler.start()
 
-    handler.login("P096", "V5fwj", callback)
+    #handler.login(callback, "P096", "V5fwj")
+    #handler.getFleet(callback)
+    # Plane: HA-LEG home (gate 67)
+    handler.updatePlane(callback, "HA-LQC", const.PLANE_AWAY, "72")
     time.sleep(3)    
-
-#------------------------------------------------------------------------------
+    handler.getFleet(callback)
+    time.sleep(3)    
+
+#------------------------------------------------------------------------------
