Index: src/mlx/acft.py
===================================================================
--- src/mlx/acft.py	(revision 409)
+++ src/mlx/acft.py	(revision 447)
@@ -152,5 +152,5 @@
         self._checkers.append(checks.VSChecker())
 
-        timeout = 5.0 + config.realIASSmoothingLength - 1
+        timeout = 30.0 + config.realIASSmoothingLength - 1
         self._checkers.append(checks.OverspeedChecker(timeout = timeout))
 
@@ -1017,4 +1017,36 @@
 #---------------------------------------------------------------------------------------
 
+class B462(Aircraft):
+    """British Aerospace BAe-146 aircraft.
+
+    The aircraft type-specific values in the aircraft state have the following
+    structure:
+    - fuel: left, centre, right
+    - n1: left outer, left inner, right inner, right outer
+    - reverser: empty (the plane has no reversers)"""
+    def __init__(self, flight):
+        super(B462, self).__init__(flight)
+        self.dow = 25706
+        self.mtow = 43998
+        self.mlw = 38599
+        self.mzfw = 33792
+        self.gearSpeedLimit = 210
+        self.flapSpeedLimits = { 18 : 217,
+                                 24 : 180,
+                                 30 : 170,
+                                 33 : 150 }
+
+    @property
+    def derateLabels(self):
+        """Get the derate strings for this type."""
+        return (xstr("takeoff_derate_b462"), None)
+
+    @property
+    def derateTemplate(self):
+        """Get the derate template for this aicraft type."""
+        return "Derate enabled: %s"
+
+#---------------------------------------------------------------------------------------
+
 mostFuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_EXTERNAL1,
                  const.FUELTANK_LEFT_AUX,
@@ -1040,5 +1072,6 @@
              const.AIRCRAFT_T134  : T134,
              const.AIRCRAFT_T154  : T154,
-             const.AIRCRAFT_YK40  : YK40 }
+             const.AIRCRAFT_YK40  : YK40,
+             const.AIRCRAFT_B462  : B462 }
 
 #---------------------------------------------------------------------------------------
Index: src/mlx/checks.py
===================================================================
--- src/mlx/checks.py	(revision 416)
+++ src/mlx/checks.py	(revision 453)
@@ -940,5 +940,6 @@
             if n1>5: numEnginesRunning += 1
 
-        if flight.stage==const.STAGE_PARKING:
+        if flight.stage==const.STAGE_PARKING or \
+           (flight.stage==const.STAGE_TAXIAFTERLAND and state.parking):
             return numEnginesRunning<len(state.n1) \
                    and state.antiCollisionLightsOn
@@ -1050,6 +1051,6 @@
     def isCondition(self, flight, aircraft, oldState, state):
         """Check if the fault condition holds."""
-        return state.gLoad>2.0 and (flight.stage!=const.STAGE_LANDING or \
-                                    state.radioAltitude>=50)
+        return state.gLoad>2.0 and not state.onTheGround and \
+          (flight.stage!=const.STAGE_LANDING or state.radioAltitude>=50)
 
     def logFault(self, flight, aircraft, logger, oldState, state):
@@ -1118,5 +1119,7 @@
                  (flight.stage in
                   [const.STAGE_CRUISE, const.STAGE_DESCENT,
-                   const.STAGE_LANDING, const.STAGE_GOAROUND] or \
+                   const.STAGE_GOAROUND] or \
+                  (flight.stage==const.STAGE_LANDING  and
+                   state.groundSpeed>50.0) or \
                   ((not state.autoXPDR or \
                     (self._liftOffTime is not None and
@@ -1235,5 +1238,5 @@
 class OverspeedChecker(PatientFaultChecker):
     """Check if Vne has been exceeded."""
-    def __init__(self, timeout = 5.0):
+    def __init__(self, timeout = 30.0):
         """Construct the checker."""
         super(OverspeedChecker, self).__init__(timeout = timeout)
@@ -1304,4 +1307,5 @@
         return flight.stage in [const.STAGE_DESCENT, const.STAGE_LANDING,
                                 const.STAGE_TAXIAFTERLAND] and \
+            state.reverser and \
             state.groundSpeed<aircraft.reverseMinSpeed and max(state.reverser)
 
@@ -1350,9 +1354,9 @@
     If, during the PUSHANDTAXI stage the speed exceeds 50 knots, the state as
     saved as a provisional takeoff state. If the speed then decreases below 50
-    knots, or the plane remains on the ground for more than 20 seconds, a taxi
+    knots, or the plane remains on the ground for more than 40 seconds, a taxi
     speed error is logged with the highest ground speed detected. This state is
     also stored in the flight object as a possible
 
-    If the plane becomes airborne within 20 seconds, the stage becomes TAKEOFF,
+    If the plane becomes airborne within 40 seconds, the stage becomes TAKEOFF,
     and the previously saved takeoff state is logged.
 
@@ -1386,5 +1390,5 @@
                     aircraft.setStage(self._takeoffState, const.STAGE_TAKEOFF)
                     self._takeoffState = None
-                elif state.timestamp > (self._takeoffState.timestamp + 30):
+                elif state.timestamp > (self._takeoffState.timestamp + 40):
                     flight.setRTOState(self._highestSpeedState)
         elif self._takeoffState is not None:
Index: src/mlx/const.py
===================================================================
--- src/mlx/const.py	(revision 459)
+++ src/mlx/const.py	(revision 466)
@@ -11,5 +11,5 @@
 
 ## The version of the program
-VERSION="0.15.1"
+VERSION="0.17.1"
 
 #-------------------------------------------------------------------------------
@@ -95,4 +95,7 @@
 ## Aircraft type: Yakovlev Yak-40
 AIRCRAFT_YK40 = 15
+
+## Aircraft type: British Aerospace BAe-146
+AIRCRAFT_B462 = 17
 
 #-------------------------------------------------------------------------------
@@ -108,5 +111,6 @@
                  AIRCRAFT_B733, AIRCRAFT_B734, AIRCRAFT_B735,
                  AIRCRAFT_T154, AIRCRAFT_T134,
-                 AIRCRAFT_YK40, AIRCRAFT_DC3]
+                 AIRCRAFT_YK40, AIRCRAFT_DC3,
+                 AIRCRAFT_B462]
 
 #-------------------------------------------------------------------------------
@@ -129,5 +133,6 @@
               AIRCRAFT_T134  : "T134",
               AIRCRAFT_T154  : "T154",
-              AIRCRAFT_YK40  : "YK40" }
+              AIRCRAFT_YK40  : "YK40",
+              AIRCRAFT_B462  : "B462" }
 
 #-------------------------------------------------------------------------------
@@ -237,36 +242,4 @@
 #-------------------------------------------------------------------------------
 
-## Delay code: loading problems
-DELAYCODE_LOADING = 0
-
-## Delay code: VATSIM problem
-DELAYCODE_VATSIM = 1
-
-## Delay code: network problems
-DELAYCODE_NETWORK = 2
-
-## Delay code: controller's fault
-DELAYCODE_CONTROLLER = 3
-
-## Delay code: system crash or freeze
-DELAYCODE_SYSTEM = 4
-
-## Delay code: navigation problem
-DELAYCODE_NAVIGATION = 5
-
-## Delay code: traffic problems
-DELAYCODE_TRAFFIC = 6
-
-## Delay code: apron navigation
-DELAYCODE_APRON = 7
-
-## Delay code: weather problems
-DELAYCODE_WEATHER = 8
-
-## Delay code: personal reasons
-DELAYCODE_PERSONAL = 9
-
-#-------------------------------------------------------------------------------
-
 ## Message type: logger error
 # FIXME: cannot set the hotkey
Index: src/mlx/fsuipc.py
===================================================================
--- src/mlx/fsuipc.py	(revision 412)
+++ src/mlx/fsuipc.py	(revision 456)
@@ -1740,4 +1740,10 @@
         return "FSUIPC/Dreamwings Bombardier Dash 8-Q400"
 
+    def addMonitoringData(self, data, fsType):
+        """Add the model-specific monitoring data to the given array."""
+        super(DreamwingsDH8DModel, self).addMonitoringData(data, fsType)
+
+        self._addOffsetWithIndexMember(data, 0x132c, "d", "_dwdh8d_navgps")
+
     def getAircraftState(self, aircraft, timestamp, data):
         """Get the aircraft state.
@@ -1747,5 +1753,6 @@
                                                                   timestamp,
                                                                   data)
-        state.pitotHeatOn = not state.pitotHeatOn
+        if data[self._dwdh8d_navgps]==1:
+            state.apHeading = None
 
         return state
@@ -2043,4 +2050,31 @@
 #------------------------------------------------------------------------------
 
+class B462Model(GenericAircraftModel):
+    """Generic model for the British Aerospace BAe 146-200 aircraft."""
+    fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE,
+                 const.FUELTANK_RIGHT]
+
+    def __init__(self):
+        """Construct the model."""
+        super(B462Model, self). \
+            __init__(flapsNotches = [0, 18, 24, 30, 33],
+                     fuelTanks = B462Model.fuelTanks,
+                     numEngines = 4)
+
+    @property
+    def name(self):
+        """Get the name for this aircraft model."""
+        return "FSUIPC/Generic British Aerospace 146"
+
+    def getAircraftState(self, aircraft, timestamp, data):
+        """Get an aircraft state object for the given monitoring data.
+
+        This removes the reverser value for the middle engine."""
+        state = super(B462Model, self).getAircraftState(aircraft, timestamp, data)
+        state.reverser = []
+        return state
+
+#------------------------------------------------------------------------------
+
 _genericModels = { const.AIRCRAFT_B736  : B737Model,
                    const.AIRCRAFT_B737  : B737Model,
@@ -2058,5 +2092,6 @@
                    const.AIRCRAFT_T134  : T134Model,
                    const.AIRCRAFT_T154  : T154Model,
-                   const.AIRCRAFT_YK40  : YK40Model }
+                   const.AIRCRAFT_YK40  : YK40Model,
+                   const.AIRCRAFT_B462  : B462Model }
 
 #------------------------------------------------------------------------------
Index: src/mlx/gui/common.py
===================================================================
--- src/mlx/gui/common.py	(revision 401)
+++ src/mlx/gui/common.py	(revision 443)
@@ -73,4 +73,5 @@
 
     SHADOW_IN = gtk.SHADOW_IN
+    SHADOW_NONE = gtk.SHADOW_NONE
 
     POLICY_AUTOMATIC = gtk.POLICY_AUTOMATIC
@@ -86,4 +87,9 @@
 
     EVENT_BUTTON_PRESS = gdk.BUTTON_PRESS
+
+    TREE_VIEW_COLUMN_FIXED = gtk.TREE_VIEW_COLUMN_FIXED
+
+    FILL = gtk.FILL
+    EXPAND = gtk.EXPAND
 
     pixbuf_new_from_file = gdk.pixbuf_new_from_file
@@ -139,4 +145,5 @@
 
     SHADOW_IN = gtk.ShadowType.IN
+    SHADOW_NONE = gtk.ShadowType.NONE
 
     POLICY_AUTOMATIC = gtk.PolicyType.AUTOMATIC
@@ -152,4 +159,9 @@
 
     EVENT_BUTTON_PRESS = gdk.EventType.BUTTON_PRESS
+
+    TREE_VIEW_COLUMN_FIXED = gtk.TreeViewColumnSizing.FIXED
+
+    FILL = gtk.AttachOptions.FILL
+    EXPAND = gtk.AttachOptions.EXPAND
 
     pixbuf_new_from_file = gdkPixbuf.Pixbuf.new_from_file
@@ -286,5 +298,6 @@
                   _const.AIRCRAFT_T134  : xstr("aircraft_t134"),
                   _const.AIRCRAFT_T154  : xstr("aircraft_t154"),
-                  _const.AIRCRAFT_YK40  : xstr("aircraft_yk40") }
+                  _const.AIRCRAFT_YK40  : xstr("aircraft_yk40"),
+                  _const.AIRCRAFT_B462  : xstr("aircraft_b462") }
 
 #------------------------------------------------------------------------------
Index: src/mlx/gui/delaycodes.py
===================================================================
--- src/mlx/gui/delaycodes.py	(revision 439)
+++ src/mlx/gui/delaycodes.py	(revision 439)
@@ -0,0 +1,368 @@
+# Module to handle the GUI aspects of the table of the delay codes
+
+#------------------------------------------------------------------------------
+
+from dcdata import CAPTION, DELAYCODE, getTable
+
+from mlx.gui.common import *
+
+import mlx.const as const
+
+#------------------------------------------------------------------------------
+
+if pygobject:
+
+#------------------------------------------------------------------------------
+
+    class Viewport(gtk.Viewport):
+        """Viewport implementation that alleviates the problem with improper
+        resizing by the VBox."""
+        def __init__(self):
+            """Construct the viewport."""
+            gtk.Viewport.__init__(self)
+            self._recursive = False
+            self._vboxHeight = None
+
+        def setVBOXHeight(self, vboxHeight):
+            """Set the height of the VBox which will be used to calculate the
+            viewport's height."""
+            self._vboxHeight = vboxHeight
+
+        def do_size_allocate(self, allocation):
+            """Called when the viewport's size is allocated.
+
+            The height in the allocation object is modified so that it is only
+            so high to fit into the VBox."""
+            if self._vboxHeight is not None:
+                allocation.height = self._vboxHeight - allocation.y
+                self._vboxHeight = None
+            gtk.Viewport.do_size_allocate(self, allocation)
+
+    class DelayCodeTableBase(gtk.VBox, gtk.Scrollable):
+        """PyGObject-specific base class for the delay code table."""
+        __gproperties__ = {
+            "vscroll-policy" : ( gtk.ScrollablePolicy,
+                                 "vscroll-policy",
+                                 "The vertical scrolling policy",
+                                 gtk.ScrollablePolicy.MINIMUM,
+                                 gobject.PARAM_READWRITE ),
+            "vadjustment" : ( gtk.Adjustment,
+                              "vadjustment",
+                              "The vertical adjustment",
+                              gobject.PARAM_READWRITE ),
+            "hscroll-policy" : ( gtk.ScrollablePolicy,
+                                 "hscroll-policy",
+                                 "The horizontal scrolling policy",
+                                 gtk.ScrollablePolicy.MINIMUM,
+                                 gobject.PARAM_READWRITE ),
+            "hadjustment" : ( gtk.Adjustment,
+                              "hadjustment",
+                              "The horizontal adjustment",
+                              gobject.PARAM_READWRITE )  }
+
+
+        @staticmethod
+        def _createViewport():
+            """Create an instance of the viewport class used by this base class."""
+            return Viewport()
+
+        def __init__(self):
+            """Construct the delay code table."""
+            super(DelayCodeTableBase, self).__init__()
+
+        def do_size_allocate(self, allocation):
+            """Allocate the size for the table and its children.
+
+            This sets up the VBox height in the viewport and then calls the
+            do_size_allocate() function of VBox()."""
+            self._viewport.setVBOXHeight(allocation.height)
+            gtk.VBox.do_size_allocate(self, allocation)
+            self.allocate_column_sizes(allocation)
+
+        def do_get_property(self, prop):
+            """Get the value of one of the properties defined above.
+
+            The request is forwarded to the viewport."""
+            if prop.name=="vscroll-policy":
+                return self._viewport.get_vscroll_policy()
+            elif prop.name=="hscroll-policy":
+                return self._viewport.get_hscroll_policy()
+            elif prop.name=="vadjustment":
+                return self._viewport.get_vadjustment()
+            elif prop.name=="hadjustment":
+                return self._viewport.get_hadjustment()
+            else:
+                raise AttributeError("mlx.gui.delaycodes.DelayCodeTableBase: property %s is not handled in do_get_property" %
+                                     (prop.name,))
+
+        def do_set_property(self, prop, value):
+            """Set the value of the adjustment properties defined above.
+
+            The adjustments are forwarded to the viewport."""
+            if prop.name=="vadjustment":
+                self._viewport.set_vadjustment(value)
+            elif prop.name=="hadjustment":
+                self._viewport.set_hadjustment(value)
+                self._treeView.set_hadjustment(value)
+            else:
+                raise AttributeError("mlx.gui.delaycodes.DelayCodeTableBase: property %s is not handled in do_set_property" %
+                                     (prop.name,))
+
+        def setStyle(self):
+            """Set the style of the event box from the treeview."""
+
+    class Alignment(gtk.Alignment):
+        """An alignment that remembers the width it was given."""
+        def __init__(self, xalign = 0.0, yalign=0.0,
+                     xscale = 0.0, yscale = 0.0 ):
+            """Construct the alignment."""
+            super(Alignment, self).__init__(xalign = xalign, yalign = yalign,
+                                            xscale = xscale, yscale = yscale)
+            self.allocatedWidth = 0
+
+        def do_size_allocate(self, allocation):
+            """Called with the new size allocation."""
+            self.allocatedWidth = allocation.width
+            gtk.Alignment.do_size_allocate(self, allocation)
+
+#------------------------------------------------------------------------------
+
+else: # pygobject
+
+#------------------------------------------------------------------------------
+
+    class DelayCodeTableBase (gtk.VBox):
+        """Base class of the delay code table for PyGtk."""
+
+        __gsignals__ = {
+            "set-scroll-adjustments": (
+                gobject.SIGNAL_RUN_LAST,
+                gobject.TYPE_NONE, (gtk.Adjustment, gtk.Adjustment))
+                }
+
+        @staticmethod
+        def _createViewport():
+            """Create an instance of the viewport class used by this base class."""
+            return gtk.Viewport()
+
+        def __init__(self):
+            """Construct the base class."""
+            super(DelayCodeTableBase, self).__init__()
+            self.set_set_scroll_adjustments_signal("set-scroll-adjustments")
+            self.connect("size-allocate", self._do_size_allocate)
+
+        def do_set_scroll_adjustments(self, hAdjustment, vAdjustment):
+            """Set the adjustments on the viewport."""
+            self._viewport.set_hadjustment(hAdjustment)
+            self._viewport.set_vadjustment(vAdjustment)
+            self._treeView.set_hadjustment(hAdjustment)
+
+        def _do_size_allocate(self, widget, allocation):
+            """Handler of the size-allocate signal.
+
+            Calls allocate_column_sizes()."""
+            self.allocate_column_sizes(allocation)
+
+        def setStyle(self):
+            """Set the style of the event box from the treeview."""
+            if self._treeView is not None:
+                style = self._treeView.rc_get_style()
+                self._eventBox.modify_bg(0, style.bg[2])
+                self._eventBox.modify_fg(0, style.fg[2])
+
+    class Alignment(gtk.Alignment):
+        """An alignment that remembers the width it was given."""
+        def __init__(self, xalign = 0.0, yalign=0.0,
+                     xscale = 0.0, yscale = 0.0 ):
+            """Construct the alignment."""
+            super(Alignment, self).__init__(xalign = xalign, yalign = yalign,
+                                            xscale = xscale, yscale = yscale)
+            self.allocatedWidth = 0
+            self.connect("size-allocate", self._do_size_allocate)
+
+        def _do_size_allocate(self, widget, allocation):
+            """Called with the new size allocation."""
+            self.allocatedWidth = allocation.width
+
+#------------------------------------------------------------------------------
+
+class CheckButton(gtk.CheckButton):
+    """A check button that contains a reference to a row in the delay code
+    data table."""
+    def __init__(self, delayCodeRow):
+        """Construct the check button."""
+        super(CheckButton, self).__init__()
+        self.delayCodeRow = delayCodeRow
+
+#------------------------------------------------------------------------------
+
+# CAPTION = 1
+
+# DELAYCODE = 2
+
+# _data1 = ( lambda row: row[0].strip(),
+#            ["Num", "Code", "Title", "Description"],
+#            [ (CAPTION, "Others"),
+#              (DELAYCODE, ("        6", "OA     ", "NO GATES/STAND AVAILABLE",
+#                           "Due to own airline activity")),
+#              (DELAYCODE, ("9", "SG", "SCHEDULED GROUND TIME",
+#                           "Planned turnaround time less than declared minimum")),
+#              (CAPTION, "Passenger and baggage"),
+#              (DELAYCODE, ("11", "PD", "LATE CHECK-IN",
+#                           "Check-in reopened for late passengers")),
+#              (DELAYCODE, ("12", "PL", "LATE CHECK-IN",
+#                           "Check-in not completed by flight closure time")),
+#              (DELAYCODE, ("13", "PE", "CHECK-IN ERROR",
+#                           "Error with passenger or baggage details")) ] )
+
+# _data2 = ( lambda row: row[0].strip(),
+#            ["MA", "IATA", "Description"],
+#            [ (CAPTION, "Passenger and baggage"),
+#              (DELAYCODE, (" 012", "01   ",
+#                           "Late shipping of parts and/or materials")),
+#              (DELAYCODE, (" 111", "11",
+#                           "Check-in reopened for late passengers")),
+#              (DELAYCODE, (" 121", "12",
+#                           "Check-in not completed by flight closure time")),
+#              (DELAYCODE, (" 132", "13",
+#                           "Error with passenger or baggage details"))
+#             ])
+
+#------------------------------------------------------------------------------
+
+class DelayCodeTable(DelayCodeTableBase):
+    """The delay code table."""
+    def __init__(self):
+        """Construct the delay code table."""
+        super(DelayCodeTable, self).__init__()
+
+        self._delayCodeData = None
+
+        self._treeView = gtk.TreeView(gtk.ListStore(str, str))
+        self._treeView.set_rules_hint(True)
+
+        self.pack_start(self._treeView, False, False, 0)
+
+        self._alignments = []
+        self._checkButtons = []
+
+        self._eventBox = gtk.EventBox()
+
+        self._table = None
+
+        self._viewport = self._createViewport()
+        self._viewport.add(self._eventBox)
+        self._viewport.set_shadow_type(SHADOW_NONE)
+
+        self.pack_start(self._viewport, True, True, 0)
+
+        self._previousWidth = 0
+
+    @property
+    def delayCodes(self):
+        """Get a list of the delay codes checked by the user."""
+        codes = []
+
+        if self._delayCodeData is not None:
+            codeExtractor = self._delayCodeData[0]
+            for checkButton in self._checkButtons:
+                if checkButton.get_active():
+                    codes.append(codeExtractor(checkButton.delayCodeRow))
+
+        return codes
+
+    def allocate_column_sizes(self, allocation):
+        """Allocate the column sizes."""
+        if allocation.width!=self._previousWidth:
+            self._previousWidth = allocation.width
+            index = 0
+            lastIndex = len(self._alignments) - 1
+            for alignment in self._alignments:
+                column = self._treeView.get_column(index)
+                width = alignment.allocatedWidth
+                width += 8 if (index==0 or index==lastIndex) else 16
+                column.set_fixed_width(width)
+                index += 1
+
+    def setType(self, aircraftType):
+        """Setup the delay code table according to the given aircraft type."""
+        self._delayCodeData = data = getTable(aircraftType)
+        if data is None:
+            return
+
+        columns = self._treeView.get_columns()
+        for column in columns:
+            self._treeView.remove_column(column)
+
+        (_extractor, headers, rows) = data
+        numColumns = len(headers) + 1
+        numRows = len(rows)
+
+        column = gtk.TreeViewColumn("", gtk.CellRendererText())
+        column.set_sizing(TREE_VIEW_COLUMN_FIXED)
+        self._treeView.append_column(column)
+
+        for header in headers:
+            column = gtk.TreeViewColumn(header, gtk.CellRendererText())
+            column.set_sizing(TREE_VIEW_COLUMN_FIXED)
+            self._treeView.append_column(column)
+
+        self._table = gtk.Table(numRows, numColumns)
+        self._table.set_homogeneous(False)
+        self._table.set_col_spacings(16)
+        self._table.set_row_spacings(4)
+        self._eventBox.add(self._table)
+
+        self._alignments = []
+        self._checkButtons = []
+
+        firstDelayCodeRow = True
+        for i in range(0, numRows):
+            (type, elements) = rows[i]
+            if type==CAPTION:
+                alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
+                                          xscale = 1.0)
+                label = gtk.Label("<b>" + elements + "</b>")
+                label.set_use_markup(True)
+                label.set_alignment(0.0, 0.5)
+                alignment.add(label)
+                self._table.attach(alignment, 1, numColumns, i, i+1,
+                                   yoptions = FILL)
+                self._table.set_row_spacing(i, 8)
+            elif type==DELAYCODE:
+                checkButton = CheckButton(elements)
+                self._checkButtons.append(checkButton)
+                alignment = Alignment(xalign = 0.5, yalign = 0.5, xscale = 1.0)
+                alignment.add(checkButton)
+                self._table.attach(alignment, 0, 1, i, i+1,
+                                   xoptions = FILL, yoptions = FILL)
+                if firstDelayCodeRow:
+                    self._alignments.append(alignment)
+
+                for j in range(0, numColumns-1):
+                    label = gtk.Label(elements[j])
+                    label.set_alignment(0.0, 0.5)
+                    alignment = Alignment(xalign = 0.5, yalign = 0.5,
+                                          xscale = 1.0)
+                    alignment.add(label)
+                    xoptions = FILL
+                    if j==(numColumns-2): xoptions |= EXPAND
+                    self._table.attach(alignment, j+1, j+2, i, i+1,
+                                       xoptions = xoptions, yoptions = FILL)
+                    if firstDelayCodeRow:
+                        self._alignments.append(alignment)
+                firstDelayCodeRow = False
+
+        self._previousWidth = 0
+        self.show_all()
+
+    def reset(self):
+        """Reset the delay code table."""
+        columns = self._treeView.get_columns()
+        for column in columns:
+            self._treeView.remove_column(column)
+        self._eventBox.remove(self._table)
+        self._table = None
+        self.show_all()
+
+#------------------------------------------------------------------------------
Index: src/mlx/gui/flight.py
===================================================================
--- src/mlx/gui/flight.py	(revision 413)
+++ src/mlx/gui/flight.py	(revision 436)
@@ -368,5 +368,5 @@
     def _loginClicked(self, button):
         """Called when the login button was clicked."""
-        print "mlx.flight.LoginPage: logged in"
+        print "mlx.flight.LoginPage: logging in"
         self._wizard.login(self._handleLoginResult,
                            self._pilotID.get_text(),
@@ -591,5 +591,5 @@
         flight = self._getSelectedFlight()
         self._wizard._bookedFlight = flight
-        self._wizard.gui.enableFlightInfo()
+        self._wizard.gui.enableFlightInfo(flight.aircraftType)
 
         self._updateDepartureGate()
Index: src/mlx/gui/gui.py
===================================================================
--- src/mlx/gui/gui.py	(revision 393)
+++ src/mlx/gui/gui.py	(revision 436)
@@ -486,7 +486,7 @@
             self.reset()
 
-    def enableFlightInfo(self):
+    def enableFlightInfo(self, aircraftType):
         """Enable the flight info tab."""
-        self._flightInfo.enable()
+        self._flightInfo.enable(aircraftType)
 
     def cancelFlight(self):
Index: src/mlx/gui/info.py
===================================================================
--- src/mlx/gui/info.py	(revision 349)
+++ src/mlx/gui/info.py	(revision 441)
@@ -1,4 +1,6 @@
 
 from common import *
+
+from mlx.gui.delaycodes import DelayCodeTable
 
 from mlx.i18n import xstr
@@ -21,18 +23,4 @@
     """The flight info tab."""
     @staticmethod
-    def _delayCodes():
-        """Get an array of delay codes."""
-        return [ (const.DELAYCODE_LOADING, xstr("info_delay_loading")),
-                 (const.DELAYCODE_VATSIM, xstr("info_delay_vatsim")),
-                 (const.DELAYCODE_NETWORK, xstr("info_delay_net")),
-                 (const.DELAYCODE_CONTROLLER, xstr("info_delay_atc")),
-                 (const.DELAYCODE_SYSTEM, xstr("info_delay_system")),
-                 (const.DELAYCODE_NAVIGATION, xstr("info_delay_nav")),
-                 (const.DELAYCODE_TRAFFIC, xstr("info_delay_traffic")),
-                 (const.DELAYCODE_APRON, xstr("info_delay_apron")),
-                 (const.DELAYCODE_WEATHER, xstr("info_delay_weather")),
-                 (const.DELAYCODE_PERSONAL, xstr("info_delay_personal")) ]
-
-    @staticmethod
     def _createCommentArea(label):
         """Create a comment area.
@@ -52,11 +40,7 @@
 
         scroller = gtk.ScrolledWindow()
-        # FIXME: these should be constants
-        scroller.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
-                            else gtk.POLICY_AUTOMATIC,
-                            gtk.PolicyType.AUTOMATIC if pygobject
-                            else gtk.POLICY_AUTOMATIC)
-        scroller.set_shadow_type(gtk.ShadowType.IN if pygobject
-                                 else gtk.SHADOW_IN)
+        scroller.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+        scroller.set_shadow_type(SHADOW_IN)
+
         comments = gtk.TextView()
         comments.set_wrap_mode(WRAP_WORD)
@@ -94,32 +78,23 @@
 
         alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
-                                  xscale = 0.0, yscale = 0.0)
+                                  xscale = 1.0, yscale = 1.0)
         alignment.set_padding(padding_top = 4, padding_bottom = 4,
                               padding_left = 8, padding_right = 8)
 
-        self._delayTable = table = gtk.Table(5, 2)
-        table.set_col_spacings(16)
+        self._delayCodeTable = table = DelayCodeTable()
+        self._delayWindow = scrolledWindow = gtk.ScrolledWindow()
+        scrolledWindow.add(table)
+        scrolledWindow.set_size_request(-1, 185)
+        scrolledWindow.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+        scrolledWindow.set_shadow_type(SHADOW_IN)
 
-        row = 0
-        column = 0
-
-        self._delayCodeWidgets = []
-        for (_code, label) in FlightInfo._delayCodes():
-            button = gtk.CheckButton(label)
-            button.set_use_underline(True)
-            table.attach(button, column, column + 1, row, row + 1)
-            self._delayCodeWidgets.append(button)
-            if column==0:
-                column += 1
-            else:
-                row += 1
-                column = 0
-
-        alignment.add(table)
+        alignment.add(scrolledWindow)
         frame.add(alignment)
 
         self._delayAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
-                                             xscale = 0.0, yscale = 0.0)
+                                             xscale = 1.0, yscale = 1.0)
         self._delayAlignment.add(frame)
+        self._delayAlignment.set_padding(padding_top = 0, padding_bottom = 0,
+                                         padding_left = 8, padding_right = 8)
 
         self.pack_start(self._delayAlignment, False, False, 8)
@@ -147,16 +122,13 @@
     def delayCodes(self):
         """Get the list of delay codes checked by the user."""
-        codes =  []
-        delayCodes = FlightInfo._delayCodes()
-        for index in range(0, len(delayCodes)):
-            if self._delayCodeWidgets[index].get_active():
-                codes.append(delayCodes[index][0])
-        return codes
+        return self._delayCodeTable.delayCodes
 
-    def enable(self):
+    def enable(self, aircraftType):
         """Enable the flight info tab."""
         self._comments.set_sensitive(True)
         self._flightDefects.set_sensitive(True)
-        self._delayTable.set_sensitive(True)
+        self._delayCodeTable.setType(aircraftType)
+        self._delayWindow.set_sensitive(True)
+        self._delayCodeTable.setStyle()
 
     def disable(self):
@@ -164,5 +136,6 @@
         self._comments.set_sensitive(False)
         self._flightDefects.set_sensitive(False)
-        self._delayTable.set_sensitive(False)
+        self._delayWindow.set_sensitive(False)
+        self._delayCodeTable.setStyle()
 
     def reset(self):
@@ -170,7 +143,5 @@
         self._comments.get_buffer().set_text("")
         self._flightDefects.get_buffer().set_text("")
-
-        for widget in self._delayCodeWidgets:
-            widget.set_active(False)
+        self._delayCodeTable.reset()
 
     def _commentsChanged(self, textbuffer):
Index: src/mlx/gui/pirep.py
===================================================================
--- src/mlx/gui/pirep.py	(revision 303)
+++ src/mlx/gui/pirep.py	(revision 437)
@@ -241,5 +241,5 @@
         for code in pirep.delayCodes:
             if delayCodes: delayCodes += ", "
-            delayCodes += PIREP.delayCodeNames[code]
+            delayCodes += code
         
         self._delayCodes.get_buffer().set_text(delayCodes)        
Index: src/mlx/pirep.py
===================================================================
--- src/mlx/pirep.py	(revision 401)
+++ src/mlx/pirep.py	(revision 437)
@@ -19,15 +19,4 @@
 class PIREP(object):
     """A pilot's report of a flight."""
-    delayCodeNames = { const.DELAYCODE_LOADING : "Loading Problems",
-                       const.DELAYCODE_NETWORK : "Net Problems",
-                       const.DELAYCODE_SYSTEM : "System Crash/Freezing",
-                       const.DELAYCODE_TRAFFIC : "Traffic Problems",
-                       const.DELAYCODE_WEATHER : "Weather Problems",
-                       const.DELAYCODE_VATSIM : "VATSIM Problem",
-                       const.DELAYCODE_CONTROLLER : "Controller's Fault",
-                       const.DELAYCODE_NAVIGATION : "Navigation Problem",
-                       const.DELAYCODE_APRON : "Apron Navigation Problems",
-                       const.DELAYCODE_PERSONAL : "Personal Reasons" }
-
     @staticmethod
     def _formatLine(timeStr, line):
@@ -140,5 +129,5 @@
             for code in self.delayCodes:
                 if s: s += ", "
-                s += PIREP.delayCodeNames[code]
+                s += code
             return s
 
Index: src/mlx/pyuipc_sim.py
===================================================================
--- src/mlx/pyuipc_sim.py	(revision 408)
+++ src/mlx/pyuipc_sim.py	(revision 443)
@@ -158,4 +158,7 @@
     ENGINE_3 = 2
 
+    ## Engine index: engine #4
+    ENGINE_4 = 3
+
     ## The number of hotkey entries
     HOTKEY_SIZE = 56
@@ -295,6 +298,6 @@
         self.visibility = 10000
 
-        self.n1 = [0.0, 0.0, 0.0]
-        self.throttles = [0.0, 0.0, 0.0]
+        self.n1 = [0.0, 0.0, 0.0, 0.0]
+        self.throttles = [0.0, 0.0, 0.0, 0.0]
 
         self.payloadCount = 1
@@ -328,4 +331,5 @@
         self.eng2DeIce = False
         self.eng3DeIce = False
+        self.eng4DeIce = False
         self.propDeIce = False
         self.structDeIce = False
@@ -427,4 +431,8 @@
         elif offset==0x09e2:       # Engine #3 de-ice
             return 1 if self.eng3DeIce else 0
+        elif offset==0x0a54:       # Engine #4 throttle
+            return self._getThrottle(self.ENGINE_4)
+        elif offset==0x0a7a:       # Engine #4 de-ice
+            return 1 if self.eng4DeIce else 0
         elif offset==0x0af4:       # Fuel weight
             return int(self.fuelWeight * 256.0)
@@ -533,4 +541,6 @@
             return self.n1[self.ENGINE_2]
         elif offset==0x2200:       # Engine #3 N1
+            return self.n1[self.ENGINE_3]
+        elif offset==0x2300:       # Engine #4 N1
             return self.n1[self.ENGINE_3]
         elif offset==0x2ea0:       # Elevator trim
@@ -695,4 +705,8 @@
         elif offset==0x09e2:       # Engine #3 de-ice
             self.eng3DeIce = value!=0
+        elif offset==0x0a54:       # Engine #4 throttle
+            self._setThrottle(self.ENGINE_4, value)
+        elif offset==0x0a7a:       # Engine #4 de-ice
+            self.eng4DeIce = value!=0
         elif offset==0x0af4:       # Fuel weight
             self.fuelWeight = value / 256.0
@@ -796,4 +810,6 @@
         elif offset==0x2200:       # Engine #3 N1
             self.n1[self.ENGINE_3] = value
+        elif offset==0x2300:       # Engine #4 N1
+            self.n1[self.ENGINE_4] = value
         elif offset==0x2ea0:       # Elevator trim
             self.elevatorTrim = value * 180.0 / math.pi
@@ -1413,4 +1429,6 @@
         self._valueHandlers["n1_3"] = ([(0x2200, "f")], lambda value: value,
                                        lambda word: float(word))
+        self._valueHandlers["n1_4"] = ([(0x2300, "f")], lambda value: value,
+                                       lambda word: float(word))
 
         self._valueHandlers["throttle_1"] = ([(0x088c, "H")],
@@ -1421,4 +1439,7 @@
                                              CLI.throttle2pyuipc)
         self._valueHandlers["throttle_3"] = ([(0x09bc, "H")],
+                                             CLI.pyuipc2throttle,
+                                             CLI.throttle2pyuipc)
+        self._valueHandlers["throttle_4"] = ([(0x0a54, "H")],
                                              CLI.pyuipc2throttle,
                                              CLI.throttle2pyuipc)
@@ -1490,4 +1511,6 @@
                                             CLI.bool2str, CLI.str2bool)
         self._valueHandlers["eng3Deice"] = ([(0x09e2, "H")],
+                                            CLI.bool2str, CLI.str2bool)
+        self._valueHandlers["eng4Deice"] = ([(0x0a7a, "H")],
                                             CLI.bool2str, CLI.str2bool)
         self._valueHandlers["propDeice"] = ([(0x337c, "b")],
Index: src/mlx/web.py
===================================================================
--- src/mlx/web.py	(revision 401)
+++ src/mlx/web.py	(revision 443)
@@ -63,5 +63,6 @@
                       "TU3"  : const.AIRCRAFT_T134,
                       "TU5"  : const.AIRCRAFT_T154,
-                      "YK4"  : const.AIRCRAFT_YK40 }
+                      "YK4"  : const.AIRCRAFT_YK40,
+                      "146"  : const.AIRCRAFT_B462 }
 
     TYPE2TYPECODE = { const.AIRCRAFT_B736  : "736",
@@ -80,5 +81,6 @@
                       const.AIRCRAFT_T134  : "TU3",
                       const.AIRCRAFT_T154  : "TU5",
-                      const.AIRCRAFT_YK40  : "YK4" }
+                      const.AIRCRAFT_YK40  : "YK4",
+                      const.AIRCRAFT_B462  : "146" }
 
     @staticmethod
@@ -115,5 +117,5 @@
         departureTime = readline(f)
         self.departureTime = BookedFlight.getDateTime(date, departureTime)
-                                               
+
         arrivalTime = readline(f)
         self.arrivalTime = BookedFlight.getDateTime(date, arrivalTime)
@@ -130,11 +132,11 @@
         departureTime = None
         arrivalTime = None
-        
+
         line = f.readline()
-        lineNumber = 0    
+        lineNumber = 0
         while line:
             lineNumber += 1
             line = line.strip()
-            
+
             hashIndex = line.find("#")
             if hashIndex>=0: line = line[:hashIndex]
@@ -142,9 +144,9 @@
                 equalIndex = line.find("=")
                 lineOK = equalIndex>0
-                
+
                 if lineOK:
-                    key = line[:equalIndex].strip()                    
+                    key = line[:equalIndex].strip()
                     value = line[equalIndex+1:].strip().replace("\:", ":")
-                    
+
                     lineOK = key and value
 
@@ -196,5 +198,5 @@
             self.aircraftTypeName = \
                 BookedFlight.TYPE2TYPECODE[self.aircraftType]
-            
+
     def writeIntoFile(self, f):
         """Write the flight into a file."""
@@ -235,5 +237,5 @@
         else:
             raise Exception("Invalid aircraft type code: '" + typeCode + "'")
-        
+
     def __repr__(self):
         """Get a representation of the flight."""
@@ -248,5 +250,5 @@
         s += ">"
         return s
-        
+
 #------------------------------------------------------------------------------
 
@@ -279,5 +281,5 @@
     def __repr__(self):
         """Get the representation of the plane object."""
-        s = "<Plane: %s %s" % (self.tailNumber, 
+        s = "<Plane: %s %s" % (self.tailNumber,
                                "home" if self.status==const.PLANE_HOME else \
                                "away" if self.status==const.PLANE_AWAY else \
@@ -288,5 +290,5 @@
         s += ">"
         return s
-        
+
 
 #------------------------------------------------------------------------------
@@ -323,5 +325,5 @@
                 gateNumbers.add(p.gateNumber)
         return gateNumbers
-    
+
     def updatePlane(self, tailNumber, status, gateNumber = None):
         """Update the status of the given plane."""
@@ -330,10 +332,10 @@
             plane.status = status
             plane.gateNumber = gateNumber
-    
+
     def __iter__(self):
         """Get an iterator over the planes."""
         for plane in self._planes.itervalues():
             yield plane
-        
+
     def __getitem__(self, tailNumber):
         """Get the plane with the given tail number.
@@ -345,5 +347,5 @@
         """Get the representation of the fleet object."""
         return self._planes.__repr__()
-        
+
 #------------------------------------------------------------------------------
 
@@ -371,5 +373,5 @@
         s += ">"
         return s
-    
+
 #------------------------------------------------------------------------------
 
@@ -389,16 +391,16 @@
            "E" not in attrs or not attrs["E"]:
             return
-        
+
         icao = attrs["A"]
         if icao not in self._notams:
             return
-        
+
         begin = datetime.datetime.strptime(attrs["B"], "%Y-%m-%d %H:%M:%S")
 
         c = attrs["C"] if "C" in attrs else None
         end = datetime.datetime.strptime(c, "%Y-%m-%d %H:%M:%S") if c else None
-        
+
         permanent = attrs["C_flag"]=="PERM" if "C_flag" in attrs else False
-        
+
         repeatCycle = attrs["D"] if "D" in attrs else None
 
@@ -473,5 +475,5 @@
     """A login request."""
     iso88592decoder = codecs.getdecoder("iso-8859-2")
-    
+
     def __init__(self, callback, pilotID, password, entranceExam):
         """Construct the login request with the given pilot ID and
@@ -488,5 +490,5 @@
         md5.update(self._pilotID)
         pilotID = md5.hexdigest()
-        
+
         md5 = hashlib.md5()
         md5.update(self._password)
@@ -524,5 +526,5 @@
                 result.pilotName = self.iso88592decoder(readline(f))[0]
                 result.exams = readline(f)
-                
+
                 while True:
                     line = readline(f)
@@ -540,10 +542,10 @@
 
         return result
-        
+
 #------------------------------------------------------------------------------
 
 class GetFleet(Request):
     """Request to get the fleet from the website."""
-    
+
     def __init__(self, callback):
         """Construct the fleet request."""
@@ -558,5 +560,5 @@
         result.fleet = Fleet(f)
         f.close()
-        
+
         return result
 
@@ -585,13 +587,13 @@
                                  ("status", status),
                                  ("kapu", gateNumber)])
-        
+
         f = urllib2.urlopen(url, data, timeout = 10.0)
         line = readline(f)
-        
+
         result = Result()
         result.success = line == "OK"
 
         return result
-            
+
 #------------------------------------------------------------------------------
 
@@ -628,5 +630,5 @@
 
 class GetMETARs(Request):
-    """Get the METARs from the NOAA website for certain airport ICAOs."""    
+    """Get the METARs from the NOAA website for certain airport ICAOs."""
 
     def __init__(self, callback, airports):
@@ -639,5 +641,5 @@
         url = "http://www.aviationweather.gov/adds/dataserver_current/httpparam?"
         data = urllib.urlencode([ ("dataSource" , "metars"),
-                                  ("requestType",  "retrieve"), 
+                                  ("requestType",  "retrieve"),
                                   ("format", "csv"),
                                   ("stationString", " ".join(self._airports)),
@@ -652,5 +654,5 @@
                 if len(line)>5 and line[4]==' ':
                     icao = line[0:4]
-                    if icao in self._airports:                        
+                    if icao in self._airports:
                         result.metars[icao] = line.strip().split(",")[0]
         finally:
@@ -696,5 +698,5 @@
         data["bag"] = str(pirep.bagWeight)
         data["mail"] = str(pirep.mailWeight)
-        
+
         data["flttype"] = SendPIREP._flightTypes[pirep.flightType]
         data["onoff"] = "1" if pirep.online else "0"
@@ -742,5 +744,5 @@
             f.close()
 
-        return result    
+        return result
 #------------------------------------------------------------------------------
 
@@ -757,5 +759,5 @@
         """Perform the sending of the ACARS."""
         print "Sending the online ACARS"
-        
+
         url = "http://www.virtualairlines.hu/acars2/acarsonline.php"
 
@@ -766,10 +768,10 @@
         data["pid"] = acars.pid
         data["pilot"] = SendACARS._latin2Encoder(acars.pilotName)[0]
-    
+
         data["pass"] = str(bookedFlight.numPassengers)
         data["callsign"] = bookedFlight.callsign
         data["airplane"] = bookedFlight.aircraftTypeName
         data["from"] = bookedFlight.departureICAO
-        data["to"] = bookedFlight.arrivalICAO        
+        data["to"] = bookedFlight.arrivalICAO
         data["lajstrom"] = bookedFlight.tailNumber
 
@@ -779,5 +781,5 @@
         data["altitude"] = str(acars.state.altitude)
         data["speed"] = str(acars.state.groundSpeed)
-        
+
         data["event"] = acars.getEventText()
 
@@ -788,5 +790,5 @@
             f.close()
 
-        return result    
+        return result
 
 #------------------------------------------------------------------------------
@@ -813,7 +815,7 @@
         """Enqueue a fleet retrieval request."""
         self._addRequest(GetFleet(callback))
-        
+
     def updatePlane(self, callback, tailNumber, status, gateNumber = None):
-        """Update the status of the given plane."""        
+        """Update the status of the given plane."""
         self._addRequest(UpdatePlane(callback, tailNumber, status, gateNumber))
 
@@ -821,5 +823,5 @@
         """Get the NOTAMs for the given two airports."""
         self._addRequest(GetNOTAMs(callback, departureICAO, arrivalICAO))
-        
+
     def getMETARs(self, callback, airports):
         """Get the METARs for the given airports."""
@@ -833,5 +835,5 @@
         """Send the given ACARS"""
         self._addRequest(SendACARS(callback, acars))
-        
+
     def run(self):
         """Process the requests."""
@@ -844,5 +846,5 @@
 
             request.perform()
-    
+
     def _addRequest(self, request):
         """Add the given request to the queue."""
@@ -855,8 +857,8 @@
 if __name__ == "__main__":
     import time
-    
+
     def callback(returned, result):
         print returned, unicode(result)
-        
+
     handler = Handler()
     handler.start()
@@ -866,5 +868,5 @@
     # Plane: HA-LEG home (gate 67)
     #handler.updatePlane(callback, "HA-LQC", const.PLANE_AWAY, "72")
-    #time.sleep(3)    
+    #time.sleep(3)
     #handler.getFleet(callback)
     #time.sleep(3)
@@ -873,7 +875,7 @@
     #handler.getMETARs(callback, ["LHBP", "EPWA"])
     #time.sleep(5)
-    
+
     handler.updatePlane(callback, "HA-LON", const.PLANE_AWAY, "")
-    time.sleep(3)    
-
-#------------------------------------------------------------------------------
+    time.sleep(3)
+
+#------------------------------------------------------------------------------
