diff --git a/Nasal/FMGC/flightplan-delegates.nas b/Nasal/FMGC/flightplan-delegates.nas
index 50859277..4938c00b 100644
--- a/Nasal/FMGC/flightplan-delegates.nas
+++ b/Nasal/FMGC/flightplan-delegates.nas
@@ -20,6 +20,127 @@
 # You can disable the default GPS behaviour *without* touching this delegate : they are
 # kept seperate since this first one is less likely to need changes
 
+
+var A320RouteManagerDelegate = {
+    new: func(fp) {
+        var m = { parents: [A320RouteManagerDelegate] };
+		
+        logprint(LOG_INFO, 'creating A320 Route Manager FPDelegate');
+		
+        m.flightplan = fp;
+        return m;
+    },
+
+    departureChanged: func
+    {
+        logprint(LOG_INFO, 'saw departure changed');
+        me.flightplan.clearWPType('sid');
+        if (me.flightplan.departure == nil)
+            return;
+
+        if (me.flightplan.departure_runway == nil) {
+        # no runway, only an airport, use that
+            var wp = createWPFrom(me.flightplan.departure);
+            wp.wp_role = 'sid';
+            me.flightplan.insertWP(wp, 0);
+            return;
+        }
+    # first, insert the runway itself
+        var wp = createWPFrom(me.flightplan.departure_runway);
+        wp.wp_role = 'sid';
+        me.flightplan.insertWP(wp, 0);
+        if (me.flightplan.sid == nil)
+            return;
+
+    # and we have a SID
+        var sid = me.flightplan.sid;
+        logprint(LOG_INFO, 'routing via SID ' ~ sid.id);
+        me.flightplan.insertWaypoints(sid.route(me.flightplan.departure_runway, me.flightplan.sid_trans), 1);
+		
+		for (var wpIdx = 0; wpIdx < me.flightplan.getPlanSize(); wpIdx = wpIdx + 1) {
+			if (me.flightplan.getWP(wpIdx).wp_type == "vectors" and (me.flightplan.getWP(wpIdx + 1) == nil or me.flightplan.getWP(wpIdx + 1).wp_type != "discontinuity")) {
+				me.flightplan.insertWP(createDiscontinuity(), wpIdx + 1);
+			}
+		}
+    },
+
+    arrivalChanged: func
+    {
+        me.flightplan.clearWPType('star');
+        me.flightplan.clearWPType('approach');
+        if (me.flightplan.destination == nil)
+            return;
+
+        if (me.flightplan.destination_runway == nil) {
+        # no runway, only an airport, use that
+            var wp = createWPFrom(me.flightplan.destination);
+            wp.wp_role = 'approach';
+            me.flightplan.appendWP(wp);
+            return;
+        }
+
+        var initialApproachFix = nil;
+        if (me.flightplan.star != nil) {
+            logprint(LOG_INFO, 'routing via STAR ' ~ me.flightplan.star.id);
+            var wps = me.flightplan.star.route(me.flightplan.destination_runway, me.flightplan.star_trans);
+            if (wps != nil) {
+                me.flightplan.insertWaypoints(wps, -1);
+                initialApproachFix = wps[-1]; # final waypoint of STAR
+            }
+        }
+
+        if (me.flightplan.approach != nil) {
+            var wps = nil;
+            var approachIdent = me.flightplan.approach.id;
+
+            if (me.flightplan.approach_trans != nil) {
+                # if an approach transition was specified, let's use it explicitly
+                wps = me.flightplan.approach.route(me.flightplan.destination_runway, me.flightplan.approach_trans);
+                if (wps == nil) {
+                    logprint(LOG_WARN, "couldn't route approach " ~ approachIdent ~ " based on specified transition:" ~ me.flightplan.approach_trans);
+                }
+            } else if (initialApproachFix != nil) {
+                # no explicit approach transition, let's use the IAF to guess one
+                wps = me.flightplan.approach.route(me.flightplan.destination_runway, initialApproachFix);
+                if (wps == nil) {
+                    logprint(LOG_INFO, "couldn't route approach " ~ approachIdent ~ " based on IAF:" ~ initialApproachFix.wp_name);
+                }
+            }
+
+            # depending on the order the user selects the approach or STAR, we might get into
+            # a mess here. If we failed to route so far, just try a direct to the approach
+            if (wps == nil) {
+                # route direct
+                 wps = me.flightplan.approach.route(me.flightplan.destination_runway);
+            }
+
+            if (wps == nil) {
+                logprint(LOG_WARN, 'routing via approach ' ~ approachIdent ~ ' failed entirely.');
+            } else {
+                me.flightplan.insertWaypoints(wps, -1);
+            }
+        } else {
+            # no approach, just use the runway waypoint
+            var wp = createWPFrom(me.flightplan.destination_runway);
+            wp.wp_role = 'approach';
+            me.flightplan.appendWP(wp);
+        }
+    },
+
+    cleared: func
+    {
+        logprint(LOG_INFO, "saw active flightplan cleared, deactivating");
+        # see http://https://code.google.com/p/flightgear-bugs/issues/detail?id=885
+        fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
+    },
+
+    endOfFlightPlan: func
+    {
+        logprint(LOG_INFO, "end of flight-plan, deactivating");
+        fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
+    }
+};
+
 var GPSPath = "/instrumentation/gps";
 
 # this delegate corresponds to the default behaviour of the built-in GPS.
@@ -129,13 +250,7 @@ var A320GPSDelegate = {
             if (me.flightplan.current + 1 >= me.flightplan.numWaypoints()) {
 				logprint(LOG_INFO, "default GPS sequencing, finishing flightplan");
 				me.flightplan.finish();
-            } elsif (me.flightplan.nextWP().wp_type == 'discontinuity') {
-				logprint(LOG_INFO, "default GPS sequencing DISCONTINUITY in flightplan, switching to HDG");
-				
-				me._captureCurrentCourse();
-				me._selectOBSMode();
-				# set HDG mode
-			} else {
+            } elsif (me.flightplan.nextWP().wp_type != 'discontinuity' and me.flightplan.nextWP().wp_type != 'vectors') {
 				logprint(LOG_INFO, "default GPS sequencing to next WP");
 				me.flightplan.current = me.flightplan.current + 1;
 			}
@@ -173,4 +288,5 @@ var A320GPSDelegate = {
 };
 
 registerFlightPlanDelegate(A320GPSDelegate.new);
+registerFlightPlanDelegate(A320RouteManagerDelegate.new);
 
diff --git a/Nasal/FMGC/flightplan.nas b/Nasal/FMGC/flightplan.nas
index 9fcc9309..f8d39444 100644
--- a/Nasal/FMGC/flightplan.nas
+++ b/Nasal/FMGC/flightplan.nas
@@ -229,6 +229,11 @@ var flightPlanController = {
 		if (me.flightplans[2].getWP(me.currentToWptIndexTemp + 1).wp_type == "discontinuity") {
 			fmgc.Input.lat.setValue(3);
 		} else {
+			if (me.flightplans[2].getWP(me.currentToWptIndexTemp + 1).wp_type == "vectors") {
+				fmgc.Input.lat.setValue(3);
+				me.flightplans[2].deleteWP(me.currentToWptIndexTemp + 2);
+			}
+			
 			me.currentToWptIndex.setValue(me.currentToWptIndexTemp + 1);
 			me.lastSequencedCurrentWP = me.currentToWptIndexTemp + 1;
 			
@@ -408,7 +413,7 @@ var flightPlanController = {
 					}
 				}
 			} else {
-				if (me.flightplans[n].getWP(index).id == "DISCONTINUITY" and index > 0 and me.flightplans[n].getWP(index - 1).id == "PPOS") {
+				if (me.flightplans[n].getWP(index).id == "DISCONTINUITY" and index > 0 and (me.flightplans[n].getWP(index - 1).id == "PPOS" or find(me.flightplans[n].getWP(index - 1).id, "VECTORS"))) {
 					return 1;
 				} else {
 					me.flightplans[n].deleteWP(index);
diff --git a/Nasal/Libraries/libraries.nas b/Nasal/Libraries/libraries.nas
index 3fe23fac..ca600559 100644
--- a/Nasal/Libraries/libraries.nas
+++ b/Nasal/Libraries/libraries.nas
@@ -7,7 +7,7 @@ print("------------------------------------------------");
 print("Copyright (c) 2016-2020 Josh Davidson (Octal450)");
 print("------------------------------------------------");
 
-# setprop("/autopilot/route-manager/disable-route-manager", 1);
+setprop("/autopilot/route-manager/disable-route-manager", 1);
 setprop("/autopilot/route-manager/disable-fms", 1);
 
 # Disable specific menubar items
diff --git a/Nasal/MCDU/F-PLN.nas b/Nasal/MCDU/F-PLN.nas
index 5ec16f8c..9b4d898d 100644
--- a/Nasal/MCDU/F-PLN.nas
+++ b/Nasal/MCDU/F-PLN.nas
@@ -120,10 +120,14 @@ var fplnItem = {
 	},
 	getBrg: func() {
 		var wp = fmgc.flightPlanController.flightplans[me.plan].getWP(me.index);
-		var courseDistanceFrom = courseAndDistance(wp);
-		me.brg = courseDistanceFrom[0] - magvar();
-		if (me.brg < 0) { me.brg += 360; }
-		if (me.brg > 360) { me.brg -= 360; }
+		if (wp.wp_type == "vectors") {
+			me.brg = pts.Orientation.heading.getValue();
+		} else {
+			var courseDistanceFrom = courseAndDistance(wp);
+			me.brg = courseDistanceFrom[0] - magvar();
+			if (me.brg < 0) { me.brg += 360; }
+			if (me.brg > 360) { me.brg -= 360; }
+		}
 		return sprintf("%03.0f", math.round(me.brg));
 	},
 	getTrack: func() {
@@ -174,7 +178,7 @@ var fplnItem = {
 		} else {
 			if (me.plan == 2 and decelShow and me.index == decelIndex and fmgc.flightPlanController.decelPoint != nil) {
 				return sprintf("%3.0f", courseAndDistance(fmgc.flightPlanController.decelPoint, me.wp)[1]);
-			} else if (prevwp != nil and prevwp.wp_name != "DISCONTINUITY") {
+			} else if (prevwp != nil and (prevwp.wp_name != "DISCONTINUITY" or find(prevwp.wp_name, "VECTORS"))) {
 				return sprintf("%3.0f", math.round(me.wp.leg_distance));
 			} else {
 				return " --";