diff -ur orig/unicode_far/editor.cpp new/unicode_far/editor.cpp
--- orig/unicode_far/editor.cpp	2013-06-01 05:47:05.226023900 +0200
+++ new/unicode_far/editor.cpp	2013-06-07 00:46:08.848669800 +0200
@@ -3188,35 +3188,6 @@
 		return;
 	}
 
-	std::for_each(RANGE(SavePos, i)
-	{
-		if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line))
-			--i.Line;
-	});
-
-	if (SessionPos)
-	{
-		InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new;
-
-		while (sb_temp->prev)
-			sb_temp=sb_temp->prev;
-
-		while (sb_temp)
-		{
-			sb_new = sb_temp->next;
-
-			if (UndoLine < static_cast<int>(sb_temp->Line))
-				sb_temp->Line--;
-			else
-			{
-				if (UndoLine == static_cast<int>(sb_temp->Line))
-					DeleteSessionBookmark(sb_temp);
-			}
-
-			sb_temp = sb_new;
-		}
-	}
-
 	NumLastLine--;
 
 	if(LastGetLine)
@@ -3289,6 +3260,40 @@
 	if (UndoLine!=-1)
 		AddUndoData(UNDO_DELSTR,DelPtr->GetStringAddr(),DelPtr->GetEOL(),UndoLine,0,DelPtr->GetLength());
 
+	std::for_each(RANGE(SavePos, i)
+	{
+		//FIXME: it would be better to add the bookmarks for deleted line to UndoData
+		if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line))
+			--i.Line;
+	});
+
+	if (SessionPos)
+	{
+		InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new;
+
+		while (sb_temp->prev)
+			sb_temp=sb_temp->prev;
+
+		while (sb_temp)
+		{
+			sb_new = sb_temp->next;
+
+			if (UndoLine < static_cast<int>(sb_temp->Line))
+				sb_temp->Line--;
+			else
+			{
+				if (UndoLine == static_cast<int>(sb_temp->Line))
+				{
+					if (UndoLine!=-1)
+						AddUndoData(sb_temp);
+					DeleteSessionBookmark(sb_temp);
+				}
+			}
+
+			sb_temp = sb_new;
+		}
+	}
+
 	delete DelPtr;
 
 	Change(ECTYPE_DELETED,UndoLine);
@@ -4998,6 +5003,16 @@
 	}
 }
 
+void Editor::AddUndoData(const InternalEditorSessionBookMark *BM)
+{
+	if (Flags.Check(FEDITOR_DISABLEUNDO))
+		return;
+	if (UndoPos->Type != UNDO_DELSTR)
+		return;
+
+	UndoPos->AddSessionBM(BM);
+}
+
 void Editor::Undo(int redo)
 {
 	auto ustart = UndoPos;
@@ -5082,6 +5097,16 @@
 
 				Pasting--;
 
+				{
+					InternalEditorSessionBookMark *BM = ud->BM;
+					while (BM)
+					{
+						InsertSessionBookmarkBack(BM);
+						BM = BM->next;
+					}
+					ud->DeleteAllSessionBM();
+				}
+
 				if (ud->Str)
 				{
 					CurLine->SetString(ud->Str.get(),ud->Length);
@@ -6497,6 +6522,7 @@
 	return FALSE;
 }
 
+//Set the numbered bookmark (CtrlShift-0..9)
 int Editor::SetBookmark(int Pos)
 {
 	if (Pos < static_cast<int>(SavePos.size()))
@@ -6512,6 +6538,7 @@
 	return FALSE;
 }
 
+//Restore the numbered bookmark (LeftCtrl-0..9)
 int Editor::GotoBookmark(int Pos)
 {
 	if (Pos < static_cast<int>(SavePos.size()))
@@ -6539,6 +6566,8 @@
 	return FALSE;
 }
 
+//Remove all session bookmarks;
+// SessionPos will be NULL
 int Editor::ClearSessionBookmarks()
 {
 	NewSessionPos = FALSE;
@@ -6550,7 +6579,7 @@
 		while (SessionPos)
 		{
 			sb_next = SessionPos->next;
-			xf_free(SessionPos);
+			delete SessionPos;
 			SessionPos = sb_next;
 		}
 
@@ -6559,7 +6588,7 @@
 		while (SessionPos)
 		{
 			sb_prev = SessionPos->prev;
-			xf_free(SessionPos);
+			delete SessionPos;
 			SessionPos = sb_prev;
 		}
 	}
@@ -6567,6 +6596,8 @@
 	return TRUE;
 }
 
+//Remove a particular session bookmark
+// adjusts SessionPos if deleting the current bookmark
 int Editor::DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete)
 {
 	NewSessionPos=FALSE;
@@ -6589,10 +6620,11 @@
 	return FALSE;
 }
 
+//Restore the current session bookmark
 int Editor::RestoreSessionBookmark()
 {
 	NewSessionPos=FALSE;
-
+	//only if the cursor is elsewhere
 	if (SessionPos && ((int)SessionPos->Line!=NumLine || (int)SessionPos->Cursor!=CurLine->GetCurPos()))
 	{
 		GoToLine(SessionPos->Line);
@@ -6613,10 +6645,13 @@
 	return FALSE;
 }
 
+//Add current cursor pos to session bookmarks, after the current bookmark,
+// and adjust SessionPos to it
 int Editor::AddSessionBookmark(BOOL blNewPos)
 {
 	InternalEditorSessionBookMark *sb_old=SessionPos;
 
+	//remove all subsequent bookmarks
 	if (SessionPos && SessionPos->next)
 	{
 		SessionPos=SessionPos->next;
@@ -6626,8 +6661,8 @@
 		SessionPos->next=0;
 	}
 
+	//append new bookmark
 	auto sb_new = new InternalEditorSessionBookMark;
-
 	if (sb_new)
 	{
 		if (SessionPos)
@@ -6647,6 +6682,69 @@
 	return FALSE;
 }
 
+//Insert the session bookmark on its original position in the list of session bookmarks, if it still exists,
+// otherwise do nothing; sb_ins->prev is hashed to better differentiate among session bookmarks
+int Editor::InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins)
+{
+	//Search for the bookmark referred in sb_ins->prev. But it needs not exist already...
+
+	//look up forward
+	InternalEditorSessionBookMark *sb_new = NULL, *sb_temp=SessionPos;
+	while (sb_temp && EditorUndoData::HashBM(sb_temp) != sb_ins->prev)
+		sb_temp=sb_temp->next;
+
+	if (sb_temp)
+	{
+		//found, insert sb_ins immediately after sb_temp
+		sb_new = new InternalEditorSessionBookMark(*sb_ins);
+		if (sb_new)
+		{
+			sb_new->prev = sb_temp;
+			sb_new->next = sb_temp->next;
+			sb_temp->next = sb_new;
+			if (sb_new->next)
+				sb_new->next->prev = sb_new;
+		}
+	}
+	else
+	{
+		//not found forward, look up backwards
+		sb_temp=SessionPos;
+		while (sb_temp && EditorUndoData::HashBM(sb_temp->prev) != sb_ins->prev)
+			sb_temp=sb_temp->prev;
+
+		if (sb_temp)
+		{
+			//found, insert sb_ins immediately before sb_temp
+			sb_new = new InternalEditorSessionBookMark(*sb_ins);
+			if (sb_new)
+			{
+				sb_new->prev = sb_temp->prev;
+				sb_new->next = sb_temp;
+				sb_temp->prev = sb_new;
+				if (sb_new->prev)
+					sb_new->prev->next = sb_new;
+			}
+		}
+		else if (!sb_ins->prev)
+		{
+			//SessionPos is NULL, but sb_ins was the first sb in the list
+			sb_new = new InternalEditorSessionBookMark(*sb_ins);
+			if (sb_new)
+			{
+				sb_new->next = NULL;
+				SessionPos = sb_new;
+			}
+		}
+		else
+			sb_new = sb_ins; //just to mark success
+	}
+
+	return sb_new?TRUE:FALSE;
+}
+
+//Return the first session bookmark (and do not change SessionPos);
+// On return, piCount will be set to the count of session bookmark preceding the current one
 InternalEditorSessionBookMark* Editor::PointerToFirstSessionBookmark(int *piCount)
 {
 	InternalEditorSessionBookMark *sb_temp=SessionPos;
@@ -6664,6 +6762,9 @@
 	return sb_temp;
 }
 
+//Return the last session bookmark (and do not change SessionPos);
+// piCount must be set to the count of session bookmarks preceding the current one
+// On return piCount will be set to the total count of session bookmarks
 InternalEditorSessionBookMark* Editor::PointerToLastSessionBookmark(int *piCount)
 {
 	InternalEditorSessionBookMark *sb_temp=SessionPos;
@@ -6682,6 +6783,8 @@
 	return sb_temp;
 }
 
+//Return the session bookmark of index iIdx (and do not change SessionPos); 
+// for iIdx==-1 the current bookmark is returned
 InternalEditorSessionBookMark* Editor::PointerToSessionBookmark(int iIdx) // Returns null_ptr if failed!
 {
 	InternalEditorSessionBookMark *sb_temp=SessionPos;
@@ -6717,6 +6820,7 @@
 	return FALSE;
 }
 
+//Restore the previous session bookmark, if there is any, the current one otherwise
 int Editor::PrevSessionBookmark()
 {
 	if (SessionPos)
@@ -6732,6 +6836,7 @@
 	return FALSE;
 }
 
+//Restore the next session bookmark, if there is any, the current one otherwise
 int Editor::NextSessionBookmark()
 {
 	if (SessionPos)
@@ -6747,6 +6852,7 @@
 	return FALSE;
 }
 
+//Restore the last session bookmark
 int Editor::LastSessionBookmark()
 {
 	if (SessionPos)
@@ -6758,6 +6864,8 @@
 	return FALSE;
 }
 
+//Restore the session bookmark at the specified index;
+// does nothing if there is no such index
 int Editor::GotoSessionBookmark(int iIdx)
 {
 	if (SessionPos)
@@ -6773,17 +6881,20 @@
 	return FALSE;
 }
 
+//Append new session bookmark as the last session bookmark, and move SessionPos to it
 int Editor::PushSessionBookMark()
 {
 	SessionPos=PointerToLastSessionBookmark();
 	return AddSessionBookmark(FALSE);
 }
 
+//Restore the last session bookmark and remove it
 int Editor::PopSessionBookMark()
 {
 	return (LastSessionBookmark() && DeleteSessionBookmark(SessionPos));
 }
 
+//Return index of the current session bookmark, -1 if there is none
 int Editor::CurrentSessionBookmarkIdx()
 {
 	int iIdx;
@@ -6792,6 +6903,7 @@
 	return -1;
 }
 
+//Get session bookmark at specified index into Param
 int Editor::GetSessionBookmark(int iIdx,InternalEditorBookmark *Param)
 {
 	InternalEditorSessionBookMark *sb_temp = PointerToSessionBookmark(iIdx);
@@ -6809,6 +6921,7 @@
 	return FALSE;
 }
 
+//Get all session bookmarks into the Param array
 int Editor::GetSessionBookmarks(EditorBookmarks *Param)
 {
 	int iCount=0;
diff -ur orig/unicode_far/editor.hpp new/unicode_far/editor.hpp
--- orig/unicode_far/editor.hpp	2013-06-01 05:47:04.599988100 +0200
+++ new/unicode_far/editor.hpp	2013-06-07 00:54:50.933531300 +0200
@@ -37,6 +37,7 @@
 #include "poscache.hpp"
 #include "bitflags.hpp"
 #include "config.hpp"
+#include <algorithm>
 
 class FileEditor;
 class KeyBar;
@@ -66,13 +67,15 @@
 	wchar_t EOL[10];
 	int Length;
 	wchar_t_ptr Str;
+	InternalEditorSessionBookMark *BM; //treat as uni-directional linked list
 	static size_t UndoDataSize;
 
 	EditorUndoData(int Type,const wchar_t *Str,const wchar_t *Eol,int StrNum,int StrPos,int Length=-1):
 		Type(0),
 		StrPos(0),
 		StrNum(0),
-		Length(0)
+		Length(0),
+		BM(0)
 	{
 		SetData(Type, Str, Eol, StrNum, StrPos, Length);
 	}
@@ -81,9 +84,11 @@
 	{
 		if (Length > 0)
 			UndoDataSize -= Length;
+		DeleteAllSessionBM();
 	}
 
-	EditorUndoData(EditorUndoData&& Right)
+	EditorUndoData(EditorUndoData&& Right):
+		BM(0)
 	{
 		*this = std::move(Right);
 		Right.Length = 0;
@@ -97,6 +102,7 @@
 		Length = Right.Length;
 		Str.swap(Right.Str);
 		wcscpy(EOL, Right.EOL);
+		std::swap(BM, Right.BM);
 		return *this;
 	}
 
@@ -124,6 +130,42 @@
 		}
 		else
 			this->Str.reset();
+		DeleteAllSessionBM();
+	}
+
+	void AddSessionBM(const InternalEditorSessionBookMark *BM)
+	{
+		InternalEditorSessionBookMark *BM_new = new InternalEditorSessionBookMark(*BM);
+		if (BM_new)
+		{
+			BM_new->prev = HashBM(BM->prev);
+			BM_new->next = this->BM;
+			this->BM = BM_new;
+		}
+	}
+
+	void DeleteAllSessionBM()
+	{
+		InternalEditorSessionBookMark *BM=this->BM, *BM_next;
+		this->BM = NULL;
+		while (BM)
+		{
+			BM_next = BM->next;
+			delete BM;
+			BM = BM_next;
+		}
+	}
+
+	static InternalEditorSessionBookMark *HashBM(InternalEditorSessionBookMark *BM)
+	{
+		if (BM)
+		{
+			size_t x = reinterpret_cast<size_t>(BM);
+			x = x ^ (BM->Line<<16) ^ (BM->Cursor);
+			return reinterpret_cast<InternalEditorSessionBookMark *>(x);
+		}
+		else
+			return NULL;
 	}
 };
 
@@ -232,8 +274,9 @@
 		int StartLine;
 		int StartChar;
 
+		//numbered bookmarks (accessible by Ctrl-0..9)
 		Bookmarks<editor_bookmark> SavePos;
-
+		//pointer to the current "session" bookmark (in the list of "session" bookmarks accessible through BM.Goto(n))
 		InternalEditorSessionBookMark *SessionPos;
 		BOOL NewSessionPos;
 
@@ -279,6 +322,7 @@
 		void UnmarkMacroBlock();
 
 		void AddUndoData(int Type,const wchar_t *Str=nullptr,const wchar_t *Eol=nullptr,int StrNum=0,int StrPos=0,int Length=-1);
+		void AddUndoData(const InternalEditorSessionBookMark *BM);
 		void Undo(int redo);
 		void SelectAll();
 		//void SetStringsTable();
@@ -298,6 +342,7 @@
 		int DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete);
 		int RestoreSessionBookmark();
 		int AddSessionBookmark(BOOL blNewPos=TRUE);
+		int InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins);
 		InternalEditorSessionBookMark* PointerToFirstSessionBookmark(int *piCount=nullptr);
 		InternalEditorSessionBookMark* PointerToLastSessionBookmark(int *piCount=nullptr);
 		InternalEditorSessionBookMark* PointerToSessionBookmark(int iIdx);
