Index: branches/CodeEditor/HeuristicLab.CodeEditor/3.4/CodeEditor.cs
===================================================================
--- branches/CodeEditor/HeuristicLab.CodeEditor/3.4/CodeEditor.cs	(revision 11738)
+++ branches/CodeEditor/HeuristicLab.CodeEditor/3.4/CodeEditor.cs	(revision 11741)
@@ -24,4 +24,5 @@
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Linq;
 using System.Reflection;
 using System.Threading.Tasks;
@@ -32,4 +33,5 @@
 using ICSharpCode.AvalonEdit.CodeCompletion;
 using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Editing;
 using ICSharpCode.AvalonEdit.Highlighting;
 using ICSharpCode.AvalonEdit.Search;
@@ -212,4 +214,18 @@
       #endregion
 
+      #region MoveLinesUpCommand
+      var moveLinesUpCommand = new Input.RoutedCommand();
+      moveLinesUpCommand.InputGestures.Add(new Input.KeyGesture(Input.Key.Up, Input.ModifierKeys.Alt));
+      var moveLinesUpCommandBinding = new Input.CommandBinding(moveLinesUpCommand, (sender, args) => MoveLines(MovementDirection.Up));
+      TextEditor.CommandBindings.Add(moveLinesUpCommandBinding);
+      #endregion
+
+      #region MoveLinesDownCommand
+      var moveLinesDownCommand = new Input.RoutedCommand();
+      moveLinesDownCommand.InputGestures.Add(new Input.KeyGesture(Input.Key.Down, Input.ModifierKeys.Alt));
+      var moveLinesDownCommandBinding = new Input.CommandBinding(moveLinesDownCommand, (sender, args) => MoveLines(MovementDirection.Down));
+      TextEditor.CommandBindings.Add(moveLinesDownCommandBinding);
+      #endregion
+
       TextEditorSyntaxHighlighting = DefaultTextEditorSyntaxHighlighting;
       TextEditorShowLineNumbers = DefaultTextEditorShowLineNumbers;
@@ -261,4 +277,70 @@
     }
 
+    private enum MovementDirection { Up, Down }
+    private void MoveLines(MovementDirection movementDirection) {
+      var textArea = TextEditor.TextArea;
+      var selection = textArea.Selection;
+
+      int selectionStart, selectionEnd;
+      if (!(selection is RectangleSelection) && selection.IsEmpty) {
+        selectionStart = selectionEnd = TextEditor.SelectionStart;
+      } else {
+        selectionStart = Doc.GetOffset(selection.StartPosition.Location);
+        selectionEnd = Doc.GetOffset(selection.EndPosition.Location);
+        if (selectionStart > selectionEnd) {
+          int temp = selectionStart;
+          selectionStart = selectionEnd;
+          selectionEnd = temp;
+        }
+      }
+
+      int selectionLength = selection.Length;
+      var selectionSegments = selection.Segments;
+      int caretOffset = TextEditor.CaretOffset;
+
+      var startLine = Doc.GetLineByOffset(selectionStart);
+      var endLine = Doc.GetLineByOffset(selectionEnd);
+
+      if (movementDirection == MovementDirection.Up && startLine.LineNumber == 1) return;
+      if (movementDirection == MovementDirection.Down && endLine.LineNumber == Doc.LineCount) return;
+
+      int startOffset = startLine.Offset;
+      string primaryText = Doc.GetText(startOffset, endLine.EndOffset - startOffset);
+      string primaryDelimiter = Doc.GetText(endLine.EndOffset, endLine.DelimiterLength);
+
+      var secondaryLine = movementDirection == MovementDirection.Up ? startLine.PreviousLine : endLine.NextLine;
+      string secondaryText = Doc.GetText(secondaryLine.Offset, secondaryLine.Length);
+      string secondaryDelimiter = Doc.GetText(secondaryLine.EndOffset, secondaryLine.DelimiterLength);
+
+      if (movementDirection == MovementDirection.Up) {
+        string replacementText = primaryText + secondaryDelimiter + secondaryText + primaryDelimiter;
+        Doc.Replace(secondaryLine.Offset, replacementText.Length, replacementText);
+        int correctionLength = secondaryText.Length + secondaryDelimiter.Length;
+        selectionStart -= correctionLength;
+        caretOffset -= correctionLength;
+      } else {
+        string replacementText = secondaryText + primaryDelimiter + primaryText + secondaryDelimiter;
+        Doc.Replace(startLine.Offset, replacementText.Length, replacementText);
+        int correctionLength = secondaryText.Length + primaryDelimiter.Length;
+        selectionStart += correctionLength;
+        caretOffset += correctionLength;
+      }
+
+      if (textArea.Selection is RectangleSelection) {
+        textArea.ClearSelection();
+        int lowestOffset = selectionSegments.Min(x => x.StartOffset);
+        int highestOffset = selectionSegments.Max(x => x.EndOffset);
+        selectionLength = highestOffset - lowestOffset;
+        var startPosition = new TextViewPosition(Doc.GetLocation(selectionStart));
+        var endPosition = new TextViewPosition(Doc.GetLocation(selectionStart + selectionLength));
+        textArea.Selection = new RectangleSelection(textArea, startPosition, endPosition);
+      } else {
+        TextEditor.SelectionStart = selectionStart;
+        TextEditor.SelectionLength = selectionLength;
+      }
+
+      TextEditor.CaretOffset = caretOffset;
+    }
+
     #region Compiler Errors
     public void ShowCompileErrors(CompilerErrorCollection compilerErrors) {
