diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 589ca68c798f4b572bdac199173ba575db311645..afa053012dab999cccd2b2d679745d3a48ec101d 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -86,7 +86,14 @@ void BKE_curve_translate(struct Curve *cu, float offset[3], int do_keys);
 void BKE_curve_material_index_remove(struct Curve *cu, int index);
 void BKE_curve_material_index_clear(struct Curve *cu);
 
-ListBase *BKE_curve_nurbs_get(struct Curve *cu);
+ListBase    *BKE_curve_nurbs_get(struct Curve *cu);
+
+void         BKE_curve_nurb_active_set(struct Curve *cu, struct Nurb *nu);
+struct Nurb *BKE_curve_nurb_active_get(struct Curve *cu);
+void        *BKE_curve_vert_active_get(struct Curve *cu);
+void         BKE_curve_nurb_vert_active_set(struct Curve *cu, struct Nurb *nu,    void *vert);
+bool         BKE_curve_nurb_vert_active_get(struct Curve *cu, struct Nurb **r_nu, void **r_vert);
+void         BKE_curve_nurb_vert_active_validate(struct Curve *cu);
 
 float (*BKE_curve_nurbs_vertexCos_get(struct ListBase *lb, int *numVerts_r))[3];
 void BK_curve_nurbs_vertexCos_apply(struct ListBase *lb, float (*vertexCos)[3]);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index dfcd8f6769852fdbd586100036621aae8a1bcb1f..cba4b7e1ea27d3604e422bb94014396d0d9ab19d 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -224,7 +224,6 @@ Curve *BKE_curve_copy(Curve *cu)
 
 	cun->editnurb = NULL;
 	cun->editfont = NULL;
-	cun->lastsel = NULL;
 
 #if 0   // XXX old animation system
 	/* single user ipo too */
@@ -3931,6 +3930,105 @@ ListBase *BKE_curve_nurbs_get(Curve *cu)
 	return &cu->nurb;
 }
 
+void BKE_curve_nurb_active_set(Curve *cu, Nurb *nu)
+{
+	if (nu == NULL) {
+		cu->actnu = -1;
+	}
+	else {
+		ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+		cu->actnu = BLI_findindex(nurbs, nu);
+	}
+}
+
+Nurb *BKE_curve_nurb_active_get(Curve *cu)
+{
+	ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+	return BLI_findlink(nurbs, cu->actnu);
+}
+
+/* Get active vert for curve */
+void *BKE_curve_vert_active_get(Curve *cu)
+{
+	Nurb *nu = NULL;
+	void *vert = NULL;
+
+	BKE_curve_nurb_vert_active_get(cu, &nu, &vert);
+	return vert;
+}
+
+/* Set active nurb and active vert for curve */
+void BKE_curve_nurb_vert_active_set(Curve *cu, Nurb *nu, void *vert)
+{
+	if (nu) {
+		BKE_curve_nurb_active_set(cu, nu);
+
+		if (nu->type == CU_BEZIER) {
+			BLI_assert(ARRAY_HAS_ITEM((BezTriple *)vert, nu->bezt, nu->pntsu));
+			cu->actvert = (BezTriple *)vert - nu->bezt;
+		}
+		else {
+			BLI_assert(ARRAY_HAS_ITEM((BPoint *)vert, nu->bp, nu->pntsu * nu->pntsv));
+			cu->actvert = (BPoint *)vert - nu->bp;
+		}
+	}
+	else {
+		cu->actnu = cu->actvert = CU_ACT_NONE;
+	}
+}
+
+/* Get points to active active nurb and active vert for curve */
+bool BKE_curve_nurb_vert_active_get(Curve *cu, Nurb **r_nu, void **r_vert)
+{
+	Nurb *nu = NULL;
+	void *vert = NULL;
+
+	if (cu->actvert != CU_ACT_NONE) {
+		ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+		nu = BLI_findlink(nurbs, cu->actnu);
+
+		if (nu) {
+			if (nu->type == CU_BEZIER) {
+				BLI_assert(nu->pntsu > cu->actvert);
+				vert = &nu->bezt[cu->actvert];
+			}
+			else {
+				BLI_assert((nu->pntsu * nu->pntsv) > cu->actvert);
+				vert = &nu->bp[cu->actvert];
+			}
+		}
+		/* get functions should never set! */
+#if 0
+		else {
+			cu->actnu = cu->actvert = CU_ACT_NONE;
+		}
+#endif
+	}
+
+	*r_nu = nu;
+	*r_vert = vert;
+
+	return (*r_vert != NULL);
+}
+
+void BKE_curve_nurb_vert_active_validate(Curve *cu)
+{
+	Nurb *nu;
+	void *vert;
+
+	if (BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
+		if (nu->type == CU_BEZIER) {
+			if ((((BezTriple *)vert)->f1 & SELECT) == 0) {
+				cu->actvert = CU_ACT_NONE;
+			}
+		}
+		else {
+			if ((((BPoint *)vert)->f1 & SELECT) == 0) {
+				cu->actvert = CU_ACT_NONE;
+			}
+		}
+	}
+}
 
 /* basic vertex data functions */
 bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 88e7f85a03d3e4ef0c6afb9ba40966f9e90e1a62..913bdfd1521bcee927af34b61d09a5b4241262c9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3388,7 +3388,6 @@ static void direct_link_curve(FileData *fd, Curve *cu)
 	}
 
 	cu->editnurb = NULL;
-	cu->lastsel = NULL;
 	cu->editfont = NULL;
 	
 	for (nu = cu->nurb.first; nu; nu = nu->next) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 6144c84f1ba5b895c9ed54d6bd92d24765ba98f1..f07d575ae5f6ec819bd2d155700ea5218ce3a160 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -80,7 +80,7 @@
 /* Undo stuff */
 typedef struct {
 	ListBase nubase;
-	void *lastsel;
+	int actvert;
 	GHash *undoIndex;
 	ListBase fcurves, drivers;
 	int actnu;
@@ -123,27 +123,6 @@ ListBase *object_editcurve_get(Object *ob)
 	return NULL;
 }
 
-/* this replaces the active flag used in uv/face mode */
-static void set_actNurb(Object *obedit, Nurb *nu)
-{
-	Curve *cu = obedit->data;
-	
-	if (nu == NULL)
-		cu->actnu = -1;
-	else {
-		ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-		cu->actnu = BLI_findindex(nurbs, nu);
-	}
-}
-
-static Nurb *get_actNurb(Object *obedit)
-{
-	Curve *cu = obedit->data;
-	ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-
-	return BLI_findlink(nurbs, cu->actnu);
-}
-
 /* ******************* SELECTION FUNCTIONS ********************* */
 
 
@@ -1217,11 +1196,9 @@ void make_editNurb(Object *obedit)
 {
 	Curve *cu = (Curve *)obedit->data;
 	EditNurb *editnurb = cu->editnurb;
-	Nurb *nu, *newnu, *nu_act = NULL;
+	Nurb *nu, *newnu;
 	KeyBlock *actkey;
 
-	set_actNurb(obedit, NULL);
-
 	if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
 		actkey = BKE_keyblock_from_object(obedit);
 
@@ -1242,18 +1219,10 @@ void make_editNurb(Object *obedit)
 		}
 
 		nu = cu->nurb.first;
-		cu->lastsel = NULL;   /* for select row */
-
 		while (nu) {
 			newnu = BKE_nurb_duplicate(nu);
 			BKE_nurb_test2D(newnu); // after join, or any other creation of curve
 			BLI_addtail(&editnurb->nurbs, newnu);
-
-			if (nu_act == NULL && isNurbsel(nu)) {
-				nu_act = newnu;
-				set_actNurb(obedit, newnu);
-			}
-
 			nu = nu->next;
 		}
 
@@ -1273,98 +1242,82 @@ void free_editNurb(Object *obedit)
 	BKE_curve_editNurb_free(cu);
 }
 
-void CU_deselect_all(Object *obedit)
+void ED_curve_deselect_all(EditNurb *editnurb)
 {
-	ListBase *editnurb = object_editcurve_get(obedit);
-
-	if (editnurb) {
-		Nurb *nu;
-		int a;
-		((Curve *)obedit->data)->lastsel = NULL;
+	Nurb *nu;
+	int a;
 
-		for (nu = editnurb->first; nu; nu = nu->next) {
-			if (nu->bezt) {
-				BezTriple *bezt;
-				for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
-					bezt->f1 &= ~SELECT;
-					bezt->f2 &= ~SELECT;
-					bezt->f3 &= ~SELECT;
-				}
+	for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+		if (nu->bezt) {
+			BezTriple *bezt;
+			for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+				bezt->f1 &= ~SELECT;
+				bezt->f2 &= ~SELECT;
+				bezt->f3 &= ~SELECT;
 			}
-			else if (nu->bp) {
-				BPoint *bp;
-				for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
-					bp->f1 &= ~SELECT;
-				}
+		}
+		else if (nu->bp) {
+			BPoint *bp;
+			for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+				bp->f1 &= ~SELECT;
 			}
 		}
 	}
 }
 
-void CU_select_all(Object *obedit)
+void ED_curve_select_all(EditNurb *editnurb)
 {
-	ListBase *editnurb = object_editcurve_get(obedit);
-
-	if (editnurb) {
-		Nurb *nu;
-		int a;
-		for (nu = editnurb->first; nu; nu = nu->next) {
-			if (nu->bezt) {
-				BezTriple *bezt;
-				for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
-					if (bezt->hide == 0) {
-						bezt->f1 |= SELECT;
-						bezt->f2 |= SELECT;
-						bezt->f3 |= SELECT;
-					}
+	Nurb *nu;
+	int a;
+	for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+		if (nu->bezt) {
+			BezTriple *bezt;
+			for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+				if (bezt->hide == 0) {
+					bezt->f1 |= SELECT;
+					bezt->f2 |= SELECT;
+					bezt->f3 |= SELECT;
 				}
 			}
-			else if (nu->bp) {
-				BPoint *bp;
-				for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
-					if (bp->hide == 0)
-						bp->f1 |= SELECT;
-				}
+		}
+		else if (nu->bp) {
+			BPoint *bp;
+			for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+				if (bp->hide == 0)
+					bp->f1 |= SELECT;
 			}
 		}
 	}
 }
 
-void CU_select_swap(Object *obedit)
+void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
 {
-	ListBase *editnurb = object_editcurve_get(obedit);
-
-	if (editnurb) {
-		Curve *cu = obedit->data;
-		Nurb *nu;
-		BPoint *bp;
-		BezTriple *bezt;
-		int a;
-
-		cu->lastsel = NULL;
+	Nurb *nu;
+	BPoint *bp;
+	BezTriple *bezt;
+	int a;
 
-		for (nu = editnurb->first; nu; nu = nu->next) {
-			if (nu->type == CU_BEZIER) {
-				bezt = nu->bezt;
-				a = nu->pntsu;
-				while (a--) {
-					if (bezt->hide == 0) {
-						bezt->f2 ^= SELECT; /* always do the center point */
-						if ((cu->drawflag & CU_HIDE_HANDLES) == 0) {
-							bezt->f1 ^= SELECT;
-							bezt->f3 ^= SELECT;
-						}
+	for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+		if (nu->type == CU_BEZIER) {
+			bezt = nu->bezt;
+			a = nu->pntsu;
+			while (a--) {
+				if (bezt->hide == 0) {
+					bezt->f2 ^= SELECT; /* always do the center point */
+					if (!hide_handles) {
+						bezt->f1 ^= SELECT;
+						bezt->f3 ^= SELECT;
 					}
-					bezt++;
 				}
+				bezt++;
 			}
-			else {
-				bp = nu->bp;
-				a = nu->pntsu * nu->pntsv;
-				while (a--) {
-					swap_selection_bpoint(bp);
-					bp++;
-				}
+		}
+		else {
+			bp = nu->bp;
+			a = nu->pntsu * nu->pntsv;
+			while (a--) {
+				swap_selection_bpoint(bp);
+				bp++;
 			}
 		}
 	}
@@ -1699,7 +1652,7 @@ static void weightflagNurb(ListBase *editnurb, short flag, float w)
 	}
 }
 
-static int deleteflagNurb(Object *obedit, short flag)
+static void ed_surf_delete_selected(Object *obedit)
 {
 	Curve *cu = obedit->data;
 	ListBase *editnurb = object_editcurve_get(obedit);
@@ -1707,11 +1660,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 	BPoint *bp, *bpn, *newbp;
 	int a, b, newu, newv;
 
-	if (obedit->type != OB_SURF) {
-		return OPERATOR_CANCELLED;
-	}
-
-	cu->lastsel = NULL;
+	BLI_assert(obedit->type != OB_SURF);
 
 	nu = editnurb->first;
 	while (nu) {
@@ -1722,7 +1671,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 		a = nu->pntsu * nu->pntsv;
 		while (a) {
 			a--;
-			if (bp->f1 & flag) {
+			if (bp->f1 & SELECT) {
 				/* pass */
 			}
 			else {
@@ -1736,7 +1685,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 			BKE_nurb_free(nu); nu = NULL;
 		}
 		else {
-			if (isNurbselU(nu, &newv, flag)) {
+			if (isNurbselU(nu, &newv, SELECT)) {
 				/* U direction selected */
 				newv = nu->pntsv - newv;
 				if (newv != nu->pntsv) {
@@ -1744,7 +1693,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 					bp = nu->bp;
 					bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb");
 					for (b = 0; b < nu->pntsv; b++) {
-						if ((bp->f1 & flag) == 0) {
+						if ((bp->f1 & SELECT) == 0) {
 							memcpy(bpn, bp, nu->pntsu * sizeof(BPoint));
 							keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu);
 							bpn += nu->pntsu;
@@ -1762,7 +1711,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 					BKE_nurb_knot_calc_v(nu);
 				}
 			}
-			else if (isNurbselV(nu, &newu, flag)) {
+			else if (isNurbselV(nu, &newu, SELECT)) {
 				/* V direction selected */
 				newu = nu->pntsu - newu;
 				if (newu != nu->pntsu) {
@@ -1771,7 +1720,7 @@ static int deleteflagNurb(Object *obedit, short flag)
 					bpn = newbp = (BPoint *)MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb");
 					for (b = 0; b < nu->pntsv; b++) {
 						for (a = 0; a < nu->pntsu; a++, bp++) {
-							if ((bp->f1 & flag) == 0) {
+							if ((bp->f1 & SELECT) == 0) {
 								*bpn = *bp;
 								keyIndex_updateBP(cu->editnurb, bp, bpn, 1);
 								bpn++;
@@ -1801,8 +1750,150 @@ static int deleteflagNurb(Object *obedit, short flag)
 		}
 		nu = next;
 	}
+}
 
-	return OPERATOR_FINISHED;
+static void ed_curve_delete_selected(Object *obedit)
+{
+	Curve *cu = obedit->data;
+	EditNurb *editnurb = cu->editnurb;
+	ListBase *nubase = &editnurb->nurbs;
+	Nurb *nu, *next;
+	BezTriple *bezt, *bezt1;
+	BPoint *bp, *bp1;
+	int a, type, nuindex = 0;
+
+	/* first loop, can we remove entire pieces? */
+	nu = nubase->first;
+	while (nu) {
+		next = nu->next;
+		if (nu->type == CU_BEZIER) {
+			bezt = nu->bezt;
+			a = nu->pntsu;
+			if (a) {
+				while (a) {
+					if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+						/* pass */
+					}
+					else {
+						break;
+					}
+					a--;
+					bezt++;
+				}
+				if (a == 0) {
+					if (cu->actnu == nuindex)
+						cu->actnu = -1;
+
+					BLI_remlink(nubase, nu);
+					keyIndex_delNurb(editnurb, nu);
+					BKE_nurb_free(nu); nu = NULL;
+				}
+			}
+		}
+		else {
+			bp = nu->bp;
+			a = nu->pntsu * nu->pntsv;
+			if (a) {
+				while (a) {
+					if (bp->f1 & SELECT) {
+						/* pass */
+					}
+					else {
+						break;
+					}
+					a--;
+					bp++;
+				}
+				if (a == 0) {
+					if (cu->actnu == nuindex)
+						cu->actnu = -1;
+
+					BLI_remlink(nubase, nu);
+					keyIndex_delNurb(editnurb, nu);
+					BKE_nurb_free(nu); nu = NULL;
+				}
+			}
+		}
+
+		/* Never allow the order to exceed the number of points
+		 * - note, this is ok but changes unselected nurbs, disable for now */
+#if 0
+		if ((nu != NULL) && (nu->type == CU_NURBS)) {
+			clamp_nurb_order_u(nu);
+		}
+#endif
+		nu = next;
+		nuindex++;
+	}
+	/* 2nd loop, delete small pieces: just for curves */
+	nu = nubase->first;
+	while (nu) {
+		next = nu->next;
+		type = 0;
+		if (nu->type == CU_BEZIER) {
+			int delta = 0;
+			bezt = nu->bezt;
+			for (a = 0; a < nu->pntsu; a++) {
+				if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+					memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
+					keyIndex_delBezt(editnurb, bezt + delta);
+					keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
+					nu->pntsu--;
+					a--;
+					type = 1;
+					delta++;
+				}
+				else {
+					bezt++;
+				}
+			}
+			if (type) {
+				bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
+				memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple));
+				keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu);
+				MEM_freeN(nu->bezt);
+				nu->bezt = bezt1;
+				BKE_nurb_handles_calc(nu);
+			}
+		}
+		else if (nu->pntsv == 1) {
+			int delta = 0;
+			bp = nu->bp;
+
+			for (a = 0; a < nu->pntsu; a++) {
+				if (bp->f1 & SELECT) {
+					memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint));
+					keyIndex_delBP(editnurb, bp + delta);
+					keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1);
+					nu->pntsu--;
+					a--;
+					type = 1;
+					delta++;
+				}
+				else {
+					bp++;
+				}
+			}
+			if (type) {
+				bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
+				memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint));
+				keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu);
+				MEM_freeN(nu->bp);
+				nu->bp = bp1;
+
+				/* Never allow the order to exceed the number of points
+				 * - note, this is ok but changes unselected nurbs, disable for now */
+#if 0
+				if (nu->type == CU_NURBS) {
+					clamp_nurb_order_u(nu);
+				}
+#endif
+			}
+			BKE_nurb_order_clamp_u(nu);
+			BKE_nurb_knot_calc_u(nu);
+		}
+		nu = next;
+	}
 }
 
 /* only for OB_SURF */
@@ -2155,8 +2246,7 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
 	}
 
 	if (newnurb->first != NULL) {
-		cu->lastsel = NULL;
-		cu->actnu = -1;
+		cu->actnu = cu->actvert = CU_ACT_NONE;
 
 		for (nu = newnurb->first; nu; nu = nu->next) {
 			if (nu->type == CU_BEZIER) {
@@ -2734,7 +2824,7 @@ void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool
 	if (obedit == NULL) return;
 
 	cu = (Curve *)obedit->data;
-	cu->lastsel = NULL;
+	cu->actvert = CU_ACT_NONE;
 
 	for (nu = editnurb->first; nu; nu = nu->next) {
 		if (nu->type == CU_BEZIER) {
@@ -2786,6 +2876,7 @@ static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op))
 
 	selectend_nurb(obedit, FIRST, true, DESELECT);
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	BKE_curve_nurb_vert_active_validate(obedit->data);
 
 	return OPERATOR_FINISHED;
 }
@@ -2811,6 +2902,7 @@ static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op))
 
 	selectend_nurb(obedit, LAST, true, DESELECT);
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	BKE_curve_nurb_vert_active_validate(obedit->data);
 
 	return OPERATOR_FINISHED;
 }
@@ -2871,6 +2963,7 @@ static short nurb_has_selected_cps(ListBase *editnurb)
 static int de_select_all_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
+	Curve *cu = obedit->data;
 	ListBase *editnurb = object_editcurve_get(obedit);
 	int action = RNA_enum_get(op->ptr, "action");
 
@@ -2882,17 +2975,18 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
 
 	switch (action) {
 		case SEL_SELECT:
-			CU_select_all(obedit);
+			ED_curve_select_all(cu->editnurb);
 			break;
 		case SEL_DESELECT:
-			CU_deselect_all(obedit);
+			ED_curve_deselect_all(cu->editnurb);
 			break;
 		case SEL_INVERT:
-			CU_select_swap(obedit);
+			ED_curve_select_swap(cu->editnurb, (cu->drawflag & CU_HIDE_HANDLES) != 0);
 			break;
 	}
 	
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	BKE_curve_nurb_vert_active_validate(cu);
 
 	return OPERATOR_FINISHED;
 }
@@ -2968,6 +3062,7 @@ static int hide_exec(bContext *C, wmOperator *op)
 
 	DAG_id_tag_update(obedit->data, 0);
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	BKE_curve_nurb_vert_active_validate(obedit->data);
 
 	return OPERATOR_FINISHED;
 }
@@ -4098,7 +4193,7 @@ static int merge_nurb(bContext *C, wmOperator *op)
 	
 	BLI_freelistN(&nsortbase);
 	
-	set_actNurb(obedit, NULL);
+	BKE_curve_nurb_active_set(obedit->data, NULL);
 
 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
 	DAG_id_tag_update(obedit->data, 0);
@@ -4266,7 +4361,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
 				BKE_nurb_free(nu2); nu2 = NULL;
 			}
 
-			set_actNurb(obedit, nu1);   /* for selected */
+			BKE_curve_nurb_active_set(cu, nu1);   /* for selected */
 			ok = 1;
 		}
 	}
@@ -4327,6 +4422,7 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 	Nurb *nu;
 	BezTriple *bezt = NULL;
 	BPoint *bp = NULL;
+	const void *vert = BKE_curve_vert_active_get(cu);
 	int location[2];
 	short hand;
 	
@@ -4342,17 +4438,17 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 			if (bezt) {
 				if (hand == 1) {
 					select_beztriple(bezt, SELECT, SELECT, HIDDEN);
-					cu->lastsel = bezt;
+					BKE_curve_nurb_vert_active_set(cu, nu, bezt);
 				}
 				else {
 					if (hand == 0) bezt->f1 |= SELECT;
 					else bezt->f3 |= SELECT;
 
-					cu->lastsel = NULL;
+					cu->actvert = CU_ACT_NONE;
 				}
 			}
 			else {
-				cu->lastsel = bp;
+				BKE_curve_nurb_vert_active_set(cu, nu, bp);
 				select_bpoint(bp, SELECT, SELECT, HIDDEN);
 			}
 		}
@@ -4360,7 +4456,7 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 			if (bezt) {
 				if (hand == 1) {
 					select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
-					if (bezt == cu->lastsel) cu->lastsel = NULL;
+					if (bezt == vert) cu->actvert = CU_ACT_NONE;
 				}
 				else if (hand == 0) {
 					bezt->f1 &= ~SELECT;
@@ -4371,7 +4467,7 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 			}
 			else {
 				select_bpoint(bp, DESELECT, SELECT, HIDDEN);
-				if (cu->lastsel == bp) cu->lastsel = NULL;
+				if (bp == vert) cu->actvert = CU_ACT_NONE;
 			}
 		}
 		else if (toggle) {
@@ -4379,11 +4475,11 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 				if (hand == 1) {
 					if (bezt->f2 & SELECT) {
 						select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
-						if (bezt == cu->lastsel) cu->lastsel = NULL;
+						if (bezt == vert) cu->actvert = CU_ACT_NONE;
 					}
 					else {
 						select_beztriple(bezt, SELECT, SELECT, HIDDEN);
-						cu->lastsel = bezt;
+						BKE_curve_nurb_vert_active_set(cu, nu, bezt);
 					}
 				}
 				else if (hand == 0) {
@@ -4396,11 +4492,11 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 			else {
 				if (bp->f1 & SELECT) {
 					select_bpoint(bp, DESELECT, SELECT, HIDDEN);
-					if (cu->lastsel == bp) cu->lastsel = NULL;
+					if (bp == vert) cu->actvert = CU_ACT_NONE;
 				}
 				else {
 					select_bpoint(bp, SELECT, SELECT, HIDDEN);
-					cu->lastsel = bp;
+					BKE_curve_nurb_vert_active_set(cu, nu, bp);
 				}
 			}
 		}
@@ -4411,23 +4507,25 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool
 
 				if (hand == 1) {
 					select_beztriple(bezt, SELECT, SELECT, HIDDEN);
-					cu->lastsel = bezt;
+					BKE_curve_nurb_vert_active_set(cu, nu, bezt);
 				}
 				else {
 					if (hand == 0) bezt->f1 |= SELECT;
 					else bezt->f3 |= SELECT;
 
-					cu->lastsel = NULL;
+					cu->actvert = CU_ACT_NONE;
 				}
 			}
 			else {
-				cu->lastsel = bp;
+				BKE_curve_nurb_vert_active_set(cu, nu, bp);
 				select_bpoint(bp, SELECT, SELECT, HIDDEN);
 			}
 		}
 
-		if (nu != get_actNurb(obedit))
-			set_actNurb(obedit, nu);
+		if (nu != BKE_curve_nurb_active_get(cu)) {
+			cu->actvert = CU_ACT_NONE;
+			BKE_curve_nurb_active_set(cu, nu);
+		}
 
 		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
 
@@ -4626,7 +4724,6 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 				}
 
 				BLI_addtail(&editnurb->nurbs, newnu);
-				set_actNurb(obedit, newnu);
 				newnu->bezt = newbezt;
 				newnu->pntsu = 1;
 
@@ -4650,12 +4747,10 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 				newbp->radius = 1;
 				newbp->alfa = 0;
 				newbp->f1 |= SELECT;
-				cu->lastsel = newbp;
 
 				newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
 				memcpy(newnu, nu, sizeof(Nurb));
 				BLI_addtail(&editnurb->nurbs, newnu);
-				set_actNurb(obedit, newnu);
 				newnu->bp = newbp;
 				newnu->orderu = 2;
 				newnu->pntsu = 1;
@@ -4688,7 +4783,6 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			nu->bezt = newbezt;
 			newbezt += nu->pntsu;
 			BEZ_SEL(newbezt);
-			cu->lastsel = newbezt;
 			newbezt->h1 = newbezt->h2;
 			bezt = &nu->bezt[nu->pntsu - 1];
 			ok = 1;
@@ -4704,7 +4798,6 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			ED_curve_beztcpy(editnurb, newbezt + 1, bezt, nu->pntsu);
 			*newbezt = *bezt;
 			BEZ_SEL(newbezt);
-			cu->lastsel = newbezt;
 			newbezt->h2 = newbezt->h1;
 			copy_v3_v3(temp, bezt->vec[1]);
 			MEM_freeN(nu->bezt);
@@ -4728,12 +4821,10 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
 			memcpy(newnu, nu, sizeof(Nurb));
 			BLI_addtail(&editnurb->nurbs, newnu);
-			set_actNurb(obedit, newnu);
 			newnu->bezt = newbezt;
 			newnu->pntsu = 1;
 
-			cu->lastsel = newbezt;
-
+			nu = newnu;
 			bezt = newbezt;
 			ok = 1;
 		}
@@ -4782,7 +4873,6 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			nu->bp = newbp;
 			newbp += nu->pntsu;
 			newbp->f1 |= SELECT;
-			cu->lastsel = newbp;
 			bp = newbp - 1;
 			ok = 1;
 		}
@@ -4792,7 +4882,6 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			ED_curve_bpcpy(editnurb, newbp + 1, bp, nu->pntsu);
 			*newbp = *bp;
 			newbp->f1 |= SELECT;
-			cu->lastsel = newbp;
 			MEM_freeN(nu->bp);
 			nu->bp = newbp;
 			bp = newbp + 1;
@@ -4803,17 +4892,16 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 			newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
 			*newbp = *bp;
 			newbp->f1 |= SELECT;
-			cu->lastsel = newbp;
 
 			newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
 			memcpy(newnu, nu, sizeof(Nurb));
 			BLI_addtail(&editnurb->nurbs, newnu);
-			set_actNurb(obedit, newnu);
 			newnu->bp = newbp;
 			newnu->orderu = 2;
 			newnu->pntsu = 1;
 			newnu->knotsu = newnu->knotsv = NULL;
 
+			nu = newnu;
 			bp = newbp;
 			ok = 1;
 		}
@@ -4844,6 +4932,13 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
 	}
 
 	if (ok) {
+		if (nu->bezt) {
+			BKE_curve_nurb_vert_active_set(cu, nu, newbezt);
+		}
+		else {
+			BKE_curve_nurb_vert_active_set(cu, nu, newbp);
+		}
+
 		BKE_nurb_test2D(nu);
 
 		if (ED_curve_updateAnimPaths(obedit->data))
@@ -5194,9 +5289,8 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent
 	Nurb *nu;
 	BezTriple *bezt;
 	BPoint *bp;
-	int a, deselect;
-
-	deselect = RNA_boolean_get(op->ptr, "deselect");
+	int a;
+	const bool select = !RNA_boolean_get(op->ptr, "deselect");
 
 	view3d_operator_needs_opengl(C);
 	view3d_set_viewcontext(C, &vc);
@@ -5207,8 +5301,7 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent
 		a = nu->pntsu;
 		bezt = nu->bezt;
 		while (a--) {
-			if (deselect) select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
-			else select_beztriple(bezt, SELECT, SELECT, VISIBLE);
+			select_beztriple(bezt, select, SELECT, VISIBLE);
 			bezt++;
 		}
 	}
@@ -5216,13 +5309,15 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent
 		a = nu->pntsu * nu->pntsv;
 		bp = nu->bp;
 		while (a--) {
-			if (deselect) select_bpoint(bp, DESELECT, SELECT, VISIBLE);
-			else select_bpoint(bp, SELECT, SELECT, VISIBLE);
+			select_bpoint(bp, select, SELECT, VISIBLE);
 			bp++;
 		}
 	}
 
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	if (!select) {
+		BKE_curve_nurb_vert_active_validate(obedit->data);
+	}
 
 	return OPERATOR_FINISHED;
 }
@@ -5254,50 +5349,30 @@ static int select_row_exec(bContext *C, wmOperator *UNUSED(op))
 	ListBase *editnurb = object_editcurve_get(obedit);
 	static BPoint *last = NULL;
 	static int direction = 0;
-	Nurb *nu;
-	BPoint *bp;
-	int u = 0, v = 0, a, b, ok = 0;
+	Nurb *nu = NULL;
+	BPoint *bp = NULL;
+	int u = 0, v = 0, a, b;
 
-	if (editnurb->first == NULL)
-		return OPERATOR_CANCELLED;
-	if (cu->lastsel == NULL)
+	if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp))
 		return OPERATOR_CANCELLED;
 
-	/* find the correct nurb and toggle with u of v */
-	for (nu = editnurb->first; nu; nu = nu->next) {
-		bp = nu->bp;
-		for (v = 0; v < nu->pntsv; v++) {
-			for (u = 0; u < nu->pntsu; u++, bp++) {
-				if (bp == cu->lastsel) {
-					if (bp->f1 & SELECT) {
-						ok = 1;
-						break;
-					}
-				}
-			}
-			if (ok) break;
-		}
+	if (last == bp) {
+		direction = 1 - direction;
+		BKE_nurbList_flag_set(editnurb, 0);
+	}
+	last = bp;
 
-		if (ok) {
-			if (last == cu->lastsel) {
-				direction = 1 - direction;
-				BKE_nurbList_flag_set(editnurb, 0);
+	u = cu->actvert % nu->pntsu;
+	v = cu->actvert / nu->pntsu;
+	bp = nu->bp;
+	for (a = 0; a < nu->pntsv; a++) {
+		for (b = 0; b < nu->pntsu; b++, bp++) {
+			if (direction) {
+				if (a == v) select_bpoint(bp, SELECT, SELECT, VISIBLE);
 			}
-			last = cu->lastsel;
-
-			bp = nu->bp;
-			for (a = 0; a < nu->pntsv; a++) {
-				for (b = 0; b < nu->pntsu; b++, bp++) {
-					if (direction) {
-						if (a == v) select_bpoint(bp, SELECT, SELECT, VISIBLE);
-					}
-					else {
-						if (b == u) select_bpoint(bp, SELECT, SELECT, VISIBLE);
-					}
-				}
+			else {
+				if (b == u) select_bpoint(bp, SELECT, SELECT, VISIBLE);
 			}
-
-			break;
 		}
 	}
 	
@@ -5634,6 +5709,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
 	}
 	
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	BKE_curve_nurb_vert_active_validate(obedit->data);
 
 	return OPERATOR_FINISHED;
 }
@@ -5699,6 +5775,7 @@ static int curve_select_random_exec(bContext *C, wmOperator *op)
 	const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
 
 	curve_select_random(editnurb, randfac, select);
+	BKE_curve_nurb_vert_active_validate(obedit->data);
 
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
 	
@@ -5726,34 +5803,6 @@ void CURVE_OT_select_random(wmOperatorType *ot)
 
 /********************* every nth number of point *******************/
 
-static bool point_in_nurb(Nurb *nu, void *point)
-{
-	if (nu->bezt) {
-		return ARRAY_HAS_ITEM((BezTriple *)point, nu->bezt, nu->pntsu);
-	}
-	else {
-		return ARRAY_HAS_ITEM((BPoint *)point, nu->bp, nu->pntsu);
-	}
-}
-
-static Nurb *get_lastsel_nurb(Curve *cu)
-{
-	ListBase *nubase = BKE_curve_editNurbs_get(cu);
-	Nurb *nu = nubase->first;
-
-	if (!cu->lastsel)
-		return NULL;
-
-	while (nu) {
-		if (point_in_nurb(nu, cu->lastsel))
-			return nu;
-
-		nu = nu->next;
-	}
-
-	return NULL;
-}
-
 static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth)
 {
 	int a, start;
@@ -5800,23 +5849,22 @@ static void select_nth_bp(Nurb *nu, BPoint *bp, int nth)
 	}
 }
 
-int CU_select_nth(Object *obedit, int nth)
+bool ED_curve_select_nth(Curve *cu, int nth)
 {
-	Curve *cu = (Curve *)obedit->data;
-	Nurb *nu;
+	Nurb *nu = NULL;
+	void *vert = NULL;
 
-	nu = get_lastsel_nurb(cu);
-	if (!nu)
-		return 0;
+	if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert))
+		return false;
 
 	if (nu->bezt) {
-		select_nth_bezt(nu, cu->lastsel, nth);
+		select_nth_bezt(nu, vert, nth);
 	}
 	else {
-		select_nth_bp(nu, cu->lastsel, nth);
+		select_nth_bp(nu, vert, nth);
 	}
 
-	return 1;
+	return true;
 }
 
 static int select_nth_exec(bContext *C, wmOperator *op)
@@ -5824,7 +5872,7 @@ static int select_nth_exec(bContext *C, wmOperator *op)
 	Object *obedit = CTX_data_edit_object(C);
 	int nth = RNA_int_get(op->ptr, "nth");
 
-	if (!CU_select_nth(obedit, nth)) {
+	if (!ED_curve_select_nth(obedit->data, nth)) {
 		if (obedit->type == OB_SURF) {
 			BKE_report(op->reports, RPT_ERROR, "Surface has not got active point");
 		}
@@ -5897,149 +5945,11 @@ void CURVE_OT_duplicate(wmOperatorType *ot)
 
 static int curve_delete_vertices(Object *obedit)
 {
-	Curve *cu = obedit->data;
-	EditNurb *editnurb = cu->editnurb;
-	ListBase *nubase = &editnurb->nurbs;
-	Nurb *nu, *next;
-	BezTriple *bezt, *bezt1;
-	BPoint *bp, *bp1;
-	int a, type, nuindex = 0;
-
 	if (obedit->type == OB_SURF) {
-		return deleteflagNurb(obedit, SELECT);
-	}
-
-	/* first loop, can we remove entire pieces? */
-	nu = nubase->first;
-	while (nu) {
-		next = nu->next;
-		if (nu->type == CU_BEZIER) {
-			bezt = nu->bezt;
-			a = nu->pntsu;
-			if (a) {
-				while (a) {
-					if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
-						/* pass */
-					}
-					else {
-						break;
-					}
-					a--;
-					bezt++;
-				}
-				if (a == 0) {
-					if (cu->actnu == nuindex)
-						cu->actnu = -1;
-
-					BLI_remlink(nubase, nu);
-					keyIndex_delNurb(editnurb, nu);
-					BKE_nurb_free(nu); nu = NULL;
-				}
-			}
-		}
-		else {
-			bp = nu->bp;
-			a = nu->pntsu * nu->pntsv;
-			if (a) {
-				while (a) {
-					if (bp->f1 & SELECT) {
-						/* pass */
-					}
-					else {
-						break;
-					}
-					a--;
-					bp++;
-				}
-				if (a == 0) {
-					if (cu->actnu == nuindex)
-						cu->actnu = -1;
-
-					BLI_remlink(nubase, nu);
-					keyIndex_delNurb(editnurb, nu);
-					BKE_nurb_free(nu); nu = NULL;
-				}
-			}
-		}
-
-		/* Never allow the order to exceed the number of points
-		 * - note, this is ok but changes unselected nurbs, disable for now */
-#if 0
-		if ((nu != NULL) && (nu->type == CU_NURBS)) {
-			clamp_nurb_order_u(nu);
-		}
-#endif
-		nu = next;
-		nuindex++;
+		ed_surf_delete_selected(obedit);
 	}
-	/* 2nd loop, delete small pieces: just for curves */
-	nu = nubase->first;
-	while (nu) {
-		next = nu->next;
-		type = 0;
-		if (nu->type == CU_BEZIER) {
-			int delta = 0;
-			bezt = nu->bezt;
-			for (a = 0; a < nu->pntsu; a++) {
-				if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
-					memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
-					keyIndex_delBezt(editnurb, bezt + delta);
-					keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
-					nu->pntsu--;
-					a--;
-					type = 1;
-					delta++;
-				}
-				else {
-					bezt++;
-				}
-			}
-			if (type) {
-				bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
-				memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple));
-				keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu);
-				MEM_freeN(nu->bezt);
-				nu->bezt = bezt1;
-				BKE_nurb_handles_calc(nu);
-			}
-		}
-		else if (nu->pntsv == 1) {
-			int delta = 0;
-			bp = nu->bp;
-
-			for (a = 0; a < nu->pntsu; a++) {
-				if (bp->f1 & SELECT) {
-					memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint));
-					keyIndex_delBP(editnurb, bp + delta);
-					keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1);
-					nu->pntsu--;
-					a--;
-					type = 1;
-					delta++;
-				}
-				else {
-					bp++;
-				}
-			}
-			if (type) {
-				bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
-				memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint));
-				keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu);
-				MEM_freeN(nu->bp);
-				nu->bp = bp1;
-
-				/* Never allow the order to exceed the number of points
-				 * - note, this is ok but changes unselected nurbs, disable for now */
-#if 0
-				if (nu->type == CU_NURBS) {
-					clamp_nurb_order_u(nu);
-				}
-#endif
-			}
-			BKE_nurb_order_clamp_u(nu);
-			BKE_nurb_knot_calc_u(nu);
-		}
-		nu = next;
+	else {
+		ed_curve_delete_selected(obedit);
 	}
 
 	return OPERATOR_FINISHED;
@@ -6454,8 +6364,7 @@ static int curve_delete_exec(bContext *C, wmOperator *op)
 	else BLI_assert(0);
 
 	if (retval == OPERATOR_FINISHED) {
-		cu->lastsel = NULL;
-		cu->actnu = -1;
+		cu->actnu = cu->actvert = CU_ACT_NONE;
 
 		if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
 
@@ -6723,24 +6632,6 @@ void CURVE_OT_tilt_clear(wmOperatorType *ot)
 
 /****************** undo for curves ****************/
 
-static void *undo_check_lastsel(void *lastsel, Nurb *nu, Nurb *newnu)
-{
-	if (nu->bezt) {
-		BezTriple *lastbezt = (BezTriple *)lastsel;
-		if (lastbezt >= nu->bezt && lastbezt < &nu->bezt[nu->pntsu]) {
-			return &newnu->bezt[lastbezt - nu->bezt];
-		}
-	}
-	else {
-		BPoint *lastbp = (BPoint *)lastsel;
-		if (lastbp >= nu->bp && lastbp < &nu->bp[nu->pntsu * nu->pntsv]) {
-			return &newnu->bp[lastbp - nu->bp];
-		}
-	}
-
-	return NULL;
-}
-
 static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
 {
 	Curve *cu = cu_v;
@@ -6749,7 +6640,6 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
 	ListBase *editbase = BKE_curve_editNurbs_get(cu);
 	Nurb *nu, *newnu;
 	EditNurb *editnurb = cu->editnurb;
-	void *lastsel = NULL;
 	AnimData *ad = BKE_animdata_from_id(&cu->id);
 
 	BKE_nurbList_free(editbase);
@@ -6773,10 +6663,6 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
 	for (nu = undobase->first; nu; nu = nu->next) {
 		newnu = BKE_nurb_duplicate(nu);
 
-		if (lastsel == NULL) {
-			lastsel = undo_check_lastsel(undoCurve->lastsel, nu, newnu);
-		}
-
 		if (editnurb->keyindex) {
 			keyIndex_updateNurb(editnurb, nu, newnu);
 		}
@@ -6784,7 +6670,7 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
 		BLI_addtail(editbase, newnu);
 	}
 
-	cu->lastsel = lastsel;
+	cu->actvert = undoCurve->actvert;
 	cu->actnu = undoCurve->actnu;
 	ED_curve_updateAnimPaths(cu);
 }
@@ -6796,7 +6682,6 @@ static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v)
 	UndoCurve *undoCurve;
 	EditNurb *editnurb = cu->editnurb, tmpEditnurb;
 	Nurb *nu, *newnu;
-	void *lastsel = NULL;
 	AnimData *ad = BKE_animdata_from_id(&cu->id);
 
 	undoCurve = MEM_callocN(sizeof(UndoCurve), "undoCurve");
@@ -6817,10 +6702,6 @@ static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v)
 	for (nu = nubase->first; nu; nu = nu->next) {
 		newnu = BKE_nurb_duplicate(nu);
 
-		if (lastsel == NULL) {
-			lastsel = undo_check_lastsel(cu->lastsel, nu, newnu);
-		}
-
 		if (undoCurve->undoIndex) {
 			keyIndex_updateNurb(&tmpEditnurb, nu, newnu);
 		}
@@ -6828,7 +6709,7 @@ static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v)
 		BLI_addtail(&undoCurve->nubase, newnu);
 	}
 
-	undoCurve->lastsel = lastsel;
+	undoCurve->actvert = cu->actvert;
 	undoCurve->actnu = cu->actnu;
 
 	return undoCurve;
@@ -6873,25 +6754,24 @@ void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count)
 	keyIndex_updateBP(editnurb, src, dst, count);
 }
 
-int ED_curve_actSelection(Curve *cu, float center[3])
+bool ED_curve_active_center(Curve *cu, float center[3])
 {
-	Nurb *nu = get_lastsel_nurb(cu);
-
-	if (!nu)
-		return 0;
+	Nurb *nu = NULL;
+	void *vert = NULL;
 
-	if (nu->bezt) {
-		BezTriple *bezt = cu->lastsel;
+	if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert))
+		return false;
 
+	if (nu->type == CU_BEZIER) {
+		BezTriple *bezt = (BezTriple *)vert;
 		copy_v3_v3(center, bezt->vec[1]);
 	}
 	else {
-		BPoint *bp = cu->lastsel;
-
+		BPoint *bp = (BPoint *)vert;
 		copy_v3_v3(center, bp->vec);
 	}
 
-	return 1;
+	return true;
 }
 
 /******************** Match texture space operator ***********************/
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index a1d144a92e9638042b0860e71a497f5a297f1bc4..c2a7a509fb3ab1d04c54a64fc44e3b840d5f4c52 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -459,7 +459,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type
 	if (nu) { /* should always be set */
 		nu->flag |= CU_SMOOTH;
 		cu->actnu = BLI_countlist(editnurb);
-		cu->lastsel = NULL;
+		cu->actvert = CU_ACT_NONE;
 
 		BKE_nurb_test2D(nu);
 	}
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index ce6c8f8354b2093b5914aa60d8ad7a66942dcc53..296d70959386d7e0765e777117c41ccec41b50fa 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -51,10 +51,10 @@ void    ED_operatormacros_curve(void);
 void    ED_keymap_curve(struct wmKeyConfig *keyconf);
 
 /* editcurve.c */
-void ED_curve_transform(struct Curve *cv, float mat[4][4]);
-void CU_deselect_all(struct Object *obedit);
-void CU_select_all(struct Object *obedit);
-void CU_select_swap(struct Object *obedit);
+void ED_curve_transform(struct Curve *cu, float mat[4][4]);
+void ED_curve_deselect_all(struct EditNurb *editnurb);
+void ED_curve_select_all(struct EditNurb *editnurb);
+void ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles);
 
 
 void    undo_push_curve(struct bContext *C, const char *name);
@@ -80,7 +80,7 @@ void    free_editText(struct Object *obedit);
 
 void    ED_text_to_object(struct bContext *C, struct Text *text, int split_lines);
 
-int CU_select_nth(struct Object *obedit, int nth);
+bool ED_curve_select_nth(struct Curve *cu, int nth);
 
 void ED_curve_beztcpy(struct EditNurb *editnurb, struct BezTriple *dst, struct BezTriple *src, int count);
 void ED_curve_bpcpy(struct EditNurb *editnurb, struct BPoint *dst, struct BPoint *src, int count);
@@ -88,10 +88,9 @@ struct Nurb *ED_curve_nurbcpy(struct Nurb *src, int count);
 
 int ED_curve_updateAnimPaths(struct Curve *cu);
 
-int ED_curve_actSelection(struct Curve *cu, float center[3]);
+bool ED_curve_active_center(struct Curve *cu, float center[3]);
 
 /* debug only */
 void printknots(struct Object *obedit);
 
 #endif /* __ED_CURVE_H__ */
-
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 4e353b18be87e5d3db1f02fc3b9497f6e3603bcf..1d4d61afef93bcfb59dfc551fc4b0755090fe7a5 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -124,7 +124,7 @@ enum {
 	TH_HANDLE_SEL_AUTOCLAMP,
 
 	TH_ACTIVE_SPLINE,
-	TH_LASTSEL_POINT,
+	TH_ACTIVE_VERT, /* equivalent of TH_EDITMESH_ACTIVE for splines */
 
 	TH_SYNTAX_B,
 	TH_SYNTAX_V,
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 63f4681c77909132d2acc9dc4445ad70f82e6f16..181e8de3f3d9f1ad473a8643306bf36f042bc3a9 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -372,7 +372,7 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
 					cp = ts->nurb_sel_vline; break;
 				case TH_ACTIVE_SPLINE:
 					cp = ts->act_spline; break;
-				case TH_LASTSEL_POINT:
+				case TH_ACTIVE_VERT:
 					cp = ts->lastsel_point; break;
 				case TH_HANDLE_FREE:
 					cp = ts->handle_free; break;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 8209d5db8cd04db2989987886ee273850e4f869c..924e88babf1828b410466c3e187aa6bbead91e86 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -498,15 +498,17 @@ static int effector_add_exec(bContext *C, wmOperator *op)
 	type = RNA_enum_get(op->ptr, "type");
 
 	if (type == PFIELD_GUIDE) {
+		Curve *cu;
 		ob = ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer);
 		if (!ob)
 			return OPERATOR_CANCELLED;
 
 		rename_id(&ob->id, CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "CurveGuide"));
-		((Curve *)ob->data)->flag |= CU_PATH | CU_3D;
+		cu = ob->data;
+		cu->flag |= CU_PATH | CU_3D;
 		ED_object_editmode_enter(C, 0);
 		ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE);
-		BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1));
+		BLI_addtail(&cu->editnurb->nurbs, add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1));
 		if (!enter_editmode)
 			ED_object_editmode_exit(C, EM_FREEDATA);
 	}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 05583f90ba362a407206ff998c251c6c729213ab..0caf679d775f8f900bfe895e246943425b7f39cb 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1854,7 +1854,7 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
 					if (bp->hide == 0) {
 						/* check for active BPoint and ensure selected */
 						if ((bp == actbp) && (bp->f1 & SELECT)) {
-							UI_ThemeColor(TH_LASTSEL_POINT);
+							UI_ThemeColor(TH_ACTIVE_VERT);
 							bglVertex3fv(dl ? co : bp->vec);
 							UI_ThemeColor(color);
 						}
@@ -5358,7 +5358,7 @@ static void drawhandlesN_active(Nurb *nu)
 	glLineWidth(1);
 }
 
-static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *lastsel)
+static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, const void *vert)
 {
 	BezTriple *bezt;
 	BPoint *bp;
@@ -5383,8 +5383,8 @@ static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *
 		a = nu->pntsu;
 		while (a--) {
 			if (bezt->hide == 0) {
-				if (sel == 1 && bezt == lastsel) {
-					UI_ThemeColor(TH_LASTSEL_POINT);
+				if (sel == 1 && bezt == vert) {
+					UI_ThemeColor(TH_ACTIVE_VERT);
 					bglVertex3fv(bezt->vec[1]);
 
 					if (!hide_handles) {
@@ -5411,8 +5411,8 @@ static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *
 		a = nu->pntsu * nu->pntsv;
 		while (a--) {
 			if (bp->hide == 0) {
-				if (bp == lastsel) {
-					UI_ThemeColor(TH_LASTSEL_POINT);
+				if (bp == vert) {
+					UI_ThemeColor(TH_ACTIVE_VERT);
 					bglVertex3fv(bp->vec);
 					UI_ThemeColor(color);
 				}
@@ -5621,6 +5621,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 	Curve *cu = ob->data;
 	Nurb *nu;
 	BevList *bl;
+	const void *vert = BKE_curve_vert_active_get(cu);
 	const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0;
 	int index;
 	unsigned char wire_col[3];
@@ -5700,7 +5701,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 	if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
 	
 	for (nu = nurb; nu; nu = nu->next) {
-		drawvertsN(nu, 1, hide_handles, cu->lastsel);
+		drawvertsN(nu, 1, hide_handles, vert);
 	}
 	
 	if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index d18fb452022976650c966901497221ef02f7863d..8dfb0e86ac2587f5c9f24a94a9e4ce4c482cf169 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -62,6 +62,7 @@
 
 #include "BKE_armature.h"
 #include "BKE_context.h"
+#include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
@@ -537,7 +538,6 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP
 	if (BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) {
 		if (bp) {
 			bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
-			if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL;
 		}
 		else {
 			if (cu->drawflag & CU_HIDE_HANDLES) {
@@ -555,8 +555,6 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP
 					bezt->f3 = data->select ? (bezt->f3 | SELECT) : (bezt->f3 & ~SELECT);
 				}
 			}
-
-			if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL;
 		}
 	}
 }
@@ -571,10 +569,11 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short
 	view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
 
 	if (extend == false && select)
-		CU_deselect_all(vc->obedit);
+		ED_curve_deselect_all(vc->obedit->data);
 
 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
 	nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+	BKE_curve_nurb_vert_active_validate(vc->obedit->data);
 }
 
 static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2])
@@ -1710,7 +1709,6 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoi
 	if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
 		if (bp) {
 			bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
-			if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL;
 		}
 		else {
 			if (cu->drawflag & CU_HIDE_HANDLES) {
@@ -1728,8 +1726,6 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoi
 					bezt->f3 = data->select ? (bezt->f3 | SELECT) : (bezt->f3 & ~SELECT);
 				}
 			}
-
-			if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL;
 		}
 	}
 }
@@ -1740,10 +1736,11 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, bool select, bool ex
 	view3d_userdata_boxselect_init(&data, vc, rect, select);
 
 	if (extend == false && select)
-		CU_deselect_all(vc->obedit);
+		ED_curve_deselect_all(vc->obedit->data);
 
 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
 	nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+	BKE_curve_nurb_vert_active_validate(vc->obedit->data);
 
 	return OPERATOR_FINISHED;
 }
@@ -2474,8 +2471,6 @@ static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint
 	if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
 		if (bp) {
 			bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
-
-			if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL;
 		}
 		else {
 			if (cu->drawflag & CU_HIDE_HANDLES) {
@@ -2493,8 +2488,6 @@ static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint
 					bezt->f3 = data->select ? (bezt->f3 | SELECT) : (bezt->f3 & ~SELECT);
 				}
 			}
-
-			if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL;
 		}
 	}
 }
@@ -2506,6 +2499,7 @@ static void nurbscurve_circle_select(ViewContext *vc, const bool select, const i
 
 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
 	nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+	BKE_curve_nurb_vert_active_validate(vc->obedit->data);
 }
 
 
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 85a2da10596bf145feabf94197a86afacbfcd4b4..55ecc53fd01cc1aa67877953ff09d5eaad91a836 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1667,7 +1667,7 @@ void calculateCenter(TransInfo *t)
 					float center[3];
 					Curve *cu = (Curve *)t->obedit->data;
 
-					if (ED_curve_actSelection(cu, center)) {
+					if (ED_curve_active_center(cu, center)) {
 						copy_v3_v3(t->center, center);
 						calculateCenter2D(t);
 						break;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index ddbb05f2536cfaf1b66f8a472dc9687a397b63de..fc4e5fcb8e57da90415c86ae46190f956810bbe4 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -397,7 +397,7 @@ int calc_manipulator_stats(const bContext *C)
 			Curve *cu = obedit->data;
 			float center[3];
 
-			if (v3d->around == V3D_ACTIVE && ED_curve_actSelection(cu, center)) {
+			if (v3d->around == V3D_ACTIVE && ED_curve_active_center(cu, center)) {
 				calc_tw_center(scene, center);
 				totsel++;
 			}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index be8bc460764d88a819577d2be468c2ed69610210..1cb441b5b163dad198413998ce2ebb166bee08ed 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -705,27 +705,15 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
 		} /* end editmesh */
 		else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
 			Curve *cu = obedit->data;
-			Nurb *nu;
-			BezTriple *bezt;
+			Nurb *nu = NULL;
+			BezTriple *bezt = NULL;
 			int a;
 			ListBase *nurbs = BKE_curve_editNurbs_get(cu);
 
-			if (activeOnly && cu->lastsel) {
-				for (nu = nurbs->first; nu; nu = nu->next) {
-					if (nu->type == CU_BEZIER) {
-						if (ARRAY_HAS_ITEM((BezTriple *)cu->lastsel, nu->bezt, nu->pntsu)) {
-							bezt = cu->lastsel;
-							BKE_nurb_bezt_calc_normal(nu, bezt, normal);
-							BKE_nurb_bezt_calc_plane(nu, bezt, plane);
-							break;
-						}
-					}
-					else {
-						if (ARRAY_HAS_ITEM((BPoint *)cu->lastsel, nu->bp, nu->pntsu)) {
-							/* do nothing */
-							break;
-						}
-					}
+			if (activeOnly && BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bezt)) {
+				if (nu->type == CU_BEZIER) {
+					BKE_nurb_bezt_calc_normal(nu, bezt, normal);
+					BKE_nurb_bezt_calc_plane(nu, bezt, plane);
 				}
 			}
 			else {
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 695df477e8b659290f9f00578052c3c18691c264..c7b6a8c43d34b65fd1f97155c3b29665d5a3a69f 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -209,9 +209,10 @@ typedef struct Curve {
 
 	/* edit, index in nurb list */
 	int actnu;
-	/* edit, last selected point */
-	void *lastsel;
+	/* edit, index in active nurb (BPoint or BezTriple) */
+	int actvert;
 
+	char pad[4];
 
 	/* font part */
 	short lines;
@@ -248,7 +249,7 @@ typedef struct Curve {
 	float ctime;			/* current evaltime - for use by Objects parented to curves */
 	float bevfac1, bevfac2;
 
-	char pad[4];
+	char pad2[4];
 } Curve;
 
 /* **************** CURVE ********************* */
@@ -325,6 +326,8 @@ typedef struct Curve {
 #define CU_NURB_ENDPOINT	2
 #define CU_NURB_BEZIER		4
 
+#define CU_ACT_NONE		-1
+
 /* *************** BEZTRIPLE **************** */
 
 /* h1 h2 (beztriple) */