diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
index 82f21a4e4..fe93d938b 100644
--- a/src/AIModel/AIAircraft.cxx
+++ b/src/AIModel/AIAircraft.cxx
@@ -107,7 +107,7 @@ void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
 
     FGAIBase::readFromScenario(scFileNode);
 
-    setPerformance(scFileNode->getStringValue("class", "jet_transport"));
+    setPerformance("", scFileNode->getStringValue("class", "jet_transport"));
     setFlightPlan(scFileNode->getStringValue("flightplan"),
                   scFileNode->getBoolValue("repeat", false));
     setCallSign(scFileNode->getStringValue("callsign"));
@@ -131,16 +131,17 @@ void FGAIAircraft::update(double dt) {
     Transform();
 }
 
-void FGAIAircraft::setPerformance(const std::string& acclass) {
-     static PerformanceDB perfdb; //TODO make it a global service
-     setPerformance(perfdb.getDataFor(acclass));
-  }
-
+void FGAIAircraft::setPerformance(const std::string& acType, const std::string& acclass)
+{
+  static PerformanceDB perfdb; //TODO make it a global service
+  _performance = perfdb.getDataFor(acType, acclass);
+}
 
+#if 0
  void FGAIAircraft::setPerformance(PerformanceData *ps) {
      _performance = ps;
   }
-
+#endif
 
  void FGAIAircraft::Run(double dt) {
       FGAIAircraft::dt = dt;
diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx
index ea2d08e7c..73e98aeb3 100644
--- a/src/AIModel/AIAircraft.hxx
+++ b/src/AIModel/AIAircraft.hxx
@@ -44,8 +44,8 @@ public:
     virtual void bind();
     virtual void update(double dt);
 
-    void setPerformance(const std::string& perfString);
-    void setPerformance(PerformanceData *ps);
+    void setPerformance(const std::string& acType, const std::string& perfString);
+  //  void setPerformance(PerformanceData *ps);
 
     void setFlightPlan(const std::string& fp, bool repat = false);
     void SetFlightPlan(FGAIFlightPlan *f);
@@ -68,6 +68,8 @@ public:
     double getBearing(double crse);
 
     void setAcType(const std::string& ac) { acType = ac; };
+    std::string getAcType() const { return acType; }
+  
     void setCompany(const std::string& comp) { company = comp;};
 
     void announcePositionToController(); //TODO have to be public?
diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx
index c49b4abe8..47026b60e 100644
--- a/src/AIModel/AIFlightPlanCreate.cxx
+++ b/src/AIModel/AIFlightPlanCreate.cxx
@@ -145,6 +145,7 @@ FGAIWaypoint *    FGAIFlightPlan::createInAir(FGAIAircraft * ac,
     wpt->setGear_down  (false                   );
     wpt->setFlaps_down (false                   );
     wpt->setOn_ground  (false                   );
+    wpt->setCrossat    (aElev                   );
     return wpt;
 }
 
@@ -427,6 +428,22 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
     return true;
 }
 
+static double accelDistance(double v0, double v1, double accel)
+{
+  double t = fabs(v1 - v0) / accel; // time in seconds to change velocity
+  // area under the v/t graph: (t * v0) + (dV / 2t) where (dV = v1 - v0)
+  return t * 0.5 * (v1 + v0); 
+}
+
+// find the horizontal distance to gain the specific altiude, holding
+// a constant pitch angle. Used to compute distance based on standard FD/AP
+// PITCH mode prior to VS or CLIMB engaging. Visually, we want to avoid
+// a dip in the nose angle after rotation, during initial climb-out.
+static double pitchDistance(double pitchAngleDeg, double altGainM)
+{
+  return altGainM / tan(pitchAngleDeg * SG_DEGREES_TO_RADIANS);
+}
+
 /*******************************************************************
  * CreateTakeOff 
  * A note on units: 
@@ -442,27 +459,22 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
                                    FGAirport * apt, double speed,
                                    const string & fltType)
 {
+    const double ACCEL_POINT = 105.0;
+    const double KNOTS_HOUR_TO_MSEC = SG_NM_TO_METER / 3600.0;
+  // climb-out angle in degrees. could move this to the perf-db but this
+  // value is pretty sane
+    const double INITIAL_PITCH_ANGLE = 12.5;
+  
     double accel = ac->getPerformance()->acceleration();
     double vTaxi = ac->getPerformance()->vTaxi();
     double vRotate = ac->getPerformance()->vRotate();
     double vTakeoff = ac->getPerformance()->vTakeoff();
-    //double vClimb = ac->getPerformance()->vClimb();
 
-    double accelMetric = (accel * SG_NM_TO_METER) / 3600;
-    double vTaxiMetric = (vTaxi * SG_NM_TO_METER) / 3600;
-    double vRotateMetric = (vRotate * SG_NM_TO_METER) / 3600;
-    double vTakeoffMetric = (vTakeoff * SG_NM_TO_METER) / 3600;
-    //double vClimbMetric = (vClimb * SG_NM_TO_METER) / 3600;
-    // Acceleration = dV / dT
-    // Acceleration X dT = dV
-    // dT = dT / Acceleration
-    //d = (Vf^2 - Vo^2) / (2*a)
-    //double accelTime = (vRotate - vTaxi) / accel;
-    //cerr << "Using " << accelTime << " as total acceleration time" << endl;
-    double accelDistance =
-        (vRotateMetric * vRotateMetric -
-         vTaxiMetric * vTaxiMetric) / (2 * accelMetric);
-    //cerr << "Using " << accelDistance << " " << accelMetric << " " << vRotateMetric << endl;
+    double accelMetric = accel * KNOTS_HOUR_TO_MSEC;
+    double vTaxiMetric = vTaxi * KNOTS_HOUR_TO_MSEC;
+    double vRotateMetric = vRotate * KNOTS_HOUR_TO_MSEC;
+    double vTakeoffMetric = vTakeoff * KNOTS_HOUR_TO_MSEC;
+   
     FGAIWaypoint *wpt;
     // Get the current active runway, based on code from David Luff
     // This should actually be unified and extended to include 
@@ -475,41 +487,36 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
         apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
                                             heading);
     }
+  
     FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
     assert( rwy != NULL );
-
     double airportElev = apt->getElevation();
     
-
-    accelDistance =
-        (vTakeoffMetric * vTakeoffMetric -
-         vTaxiMetric * vTaxiMetric) / (2 * accelMetric);
-    //cerr << "Using " << accelDistance << " " << accelMetric << " " << vTakeoffMetric << endl;
-    SGGeod accelPoint = rwy->pointOnCenterline(105.0 + accelDistance);
+    double d = accelDistance(vTaxiMetric, vRotateMetric, accelMetric) + ACCEL_POINT;
+  
+    SGGeod accelPoint = rwy->pointOnCenterline(d);
     wpt = createOnGround(ac, "rotate", accelPoint, airportElev, vTakeoff);
     pushBackWaypoint(wpt);
 
-    accelDistance =
-        ((vTakeoffMetric * 1.1) * (vTakeoffMetric * 1.1) -
-         vTaxiMetric * vTaxiMetric) / (2 * accelMetric);
-    //cerr << "Using " << accelDistance << " " << accelMetric << " " << vTakeoffMetric << endl;
-    accelPoint = rwy->pointOnCenterline(105.0 + accelDistance);
-    wpt =
-        createOnGround(ac, "rotate", accelPoint, airportElev + 1000,
-                       vTakeoff * 1.1);
+    double vRef = vTakeoffMetric + 20; // climb-out at v2 + 20kts
+    double gearUpDist = d + pitchDistance(INITIAL_PITCH_ANGLE, 400 * SG_FEET_TO_METER);
+    accelPoint = rwy->pointOnCenterline(gearUpDist);
+    
+    wpt = cloneWithPos(ac, wpt, "gear-up", accelPoint);
+    wpt->setSpeed(vRef);
+    wpt->setCrossat(airportElev + 400);
     wpt->setOn_ground(false);
+    wpt->setGear_down(false);
+    pushBackWaypoint(wpt);
+  
+    double climbOut = d + pitchDistance(INITIAL_PITCH_ANGLE, 2000 * SG_FEET_TO_METER);
+    accelPoint = rwy->pointOnCenterline(climbOut);
+    wpt = createInAir(ac, "2000'", accelPoint, airportElev + 2000, vRef);
     pushBackWaypoint(wpt);
 
-    wpt = cloneWithPos(ac, wpt, "3000 ft", rwy->end());
-    wpt->setAltitude(airportElev + 3000);
-    pushBackWaypoint(wpt);
-
-    // Finally, add two more waypoints, so that aircraft will remain under
-    // Tower control until they have reached the 3000 ft climb point
-    SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
-    wpt = cloneWithPos(ac, wpt, "5000 ft", pt);
-    wpt->setAltitude(airportElev + 5000);
-    pushBackWaypoint(wpt);
+  // as soon as we pass 2000', hand off to departure so the next acft can line up
+  // ideally the next aircraft would be able to line-up + hold but that's tricky
+  // with the current design.
     return true;
 }
 
diff --git a/src/AIModel/performancedb.cxx b/src/AIModel/performancedb.cxx
index 37660e6a0..f218e851d 100644
--- a/src/AIModel/performancedb.cxx
+++ b/src/AIModel/performancedb.cxx
@@ -1,3 +1,11 @@
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "performancedb.hxx"
+
+#include <boost/foreach.hpp>
+
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/props/props_io.hxx>
@@ -7,7 +15,7 @@
 #include <iostream>
 #include <fstream>
 
-#include "performancedb.hxx"
+#include "performancedata.hxx"
 
 using std::string;
 using std::cerr;
@@ -36,14 +44,28 @@ void PerformanceDB::registerPerformanceData(const std::string& id, const std::st
     registerPerformanceData(id, new PerformanceData(filename));
 }
 
-PerformanceData* PerformanceDB::getDataFor(const std::string& id) {
-    if (_db.find(id) == _db.end()) // id not found -> return jet_transport data
+PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
+{
+  // first, try with the specific aircraft type, such as 738 or A322
+    if (_db.find(acType) != _db.end()) {
+        return _db[acType];
+    }
+    
+    string alias = findAlias(acType);
+    if (_db.find(alias) != _db.end()) {
+      return _db[alias];
+    }
+  
+    SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
+  
+    if (_db.find(acClass) == _db.end()) {
         return _db["jet_transport"];
-
-    return _db[id];
+    }
+  
+    return _db[acClass];
 }
 
-void PerformanceDB::load(SGPath filename) {
+void PerformanceDB::load(const SGPath& filename) {
     string name;
     double acceleration;
     double deceleration;
@@ -67,8 +89,9 @@ void PerformanceDB::load(SGPath filename) {
     }
 
     SGPropertyNode * node = root.getNode("performancedb");
-    for (int i = 0; i < node->nChildren(); i++) { 
+    for (int i = 0; i < node->nChildren(); i++) {
         SGPropertyNode * db_node = node->getChild(i);
+        if (!strcmp(db_node->getName(), "aircraft")) {
             name         = db_node->getStringValue("type", "heavy_jet");
             acceleration = db_node->getDoubleValue("acceleration-kts-hour", 4.0);
             deceleration = db_node->getDoubleValue("deceleration-kts-hour", 2.0);
@@ -85,6 +108,32 @@ void PerformanceDB::load(SGPath filename) {
 
             registerPerformanceData(name, new PerformanceData(
                 acceleration, deceleration, climbRate, descentRate, vRotate, vTakeOff, vClimb, vCruise, vDescent, vApproach, vTouchdown, vTaxi));
-    }
+        } else if (!strcmp(db_node->getName(), "alias")) {
+            string alias(db_node->getStringValue("alias"));
+            if (alias.empty()) {
+                SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
+                continue;
+            }
+          
+            BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
+                string match(matchNode->getStringValue());
+                _aliases.push_back(StringPair(match, alias));
+            }
+        } else {
+            SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
+        }
+    } // of nodes iteration
 }
 
+string PerformanceDB::findAlias(const string& acType) const
+{
+    BOOST_FOREACH(const StringPair& alias, _aliases) {
+        if (acType.find(alias.first) == 0) { // matched!
+            return alias.second;
+        }
+    } // of alias iteration
+  
+    return string();
+}
+
+
diff --git a/src/AIModel/performancedb.hxx b/src/AIModel/performancedb.hxx
index 61d040da0..ad3066cb8 100644
--- a/src/AIModel/performancedb.hxx
+++ b/src/AIModel/performancedb.hxx
@@ -2,10 +2,11 @@
 #define PERFORMANCEDB_HXX
 
 #include <string>
-#include <vector>
 #include <map>
+#include <vector>
 
-#include "performancedata.hxx"
+class PerformanceData;
+class SGPath;
 
 /**
  * Registry for performance data.
@@ -25,11 +26,23 @@ public:
     void registerPerformanceData(const std::string& id, PerformanceData* data);
     void registerPerformanceData(const std::string& id, const std::string& filename);
 
-    PerformanceData* getDataFor(const std::string& id);
-    void load(SGPath path);
+    /**
+     * get performance data for an aircraft type / class. Type is specific, eg
+     * '738' or 'A319'. Class is more generic, such as 'jet_transport'.
+     */
+    PerformanceData* getDataFor(const std::string& acType, const std::string& acClass);
+    void load(const SGPath& path);
 
 private:
     std::map<std::string, PerformanceData*> _db;
+    
+    std::string findAlias(const std::string& acType) const;
+  
+    typedef std::pair<std::string, std::string> StringPair;
+  /// alias list, to allow type/class names to share data. This is used to merge
+  /// related types together. Note it's ordered, and not a map since we permit
+  /// partial matches when merging - the first matching alias is used.
+    std::vector<StringPair> _aliases;
 };
 
 #endif
diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index c43721739..bbfc73311 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -74,7 +74,7 @@ void FGATCManager::init() {
     ai_ac.setLongitude( longitude );
     ai_ac.setLatitude ( latitude  );
     ai_ac.setAltitude ( altitude  );
-    ai_ac.setPerformance("jet_transport");
+    ai_ac.setPerformance("", "jet_transport");
 
     // NEXT UP: Create a traffic Schedule and fill that with appropriate information. This we can use to flight planning.
     // Note that these are currently only defaults. 
diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx
index 9af6a0c27..3d4db5cb7 100644
--- a/src/Traffic/Schedule.cxx
+++ b/src/Traffic/Schedule.cxx
@@ -346,7 +346,7 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots
   }
 
   FGAIAircraft *aircraft = new FGAIAircraft(this);
-  aircraft->setPerformance(m_class); //"jet_transport";
+  aircraft->setPerformance(acType, m_class); //"jet_transport";
   aircraft->setCompany(airline); //i->getAirline();
   aircraft->setAcType(acType); //i->getAcType();
   aircraft->setPath(modelPath.c_str());
diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx
index 2510b7a62..464dca5e0 100644
--- a/src/Traffic/TrafficMgr.cxx
+++ b/src/Traffic/TrafficMgr.cxx
@@ -782,8 +782,6 @@ void FGTrafficManager::endAircraft()
     acCounter++;
     requiredAircraft = "";
     homePort = "";
-    SG_LOG(SG_GENERAL, SG_BULK, "Reading aircraft : "
-           << registration << " with prioritization score " << score);
     score = 0;
 }