diff --git a/packages/roosterjs-content-model-core/lib/editor/Editor.ts b/packages/roosterjs-content-model-core/lib/editor/Editor.ts
index 3301ff252ee..6bad5976a24 100644
--- a/packages/roosterjs-content-model-core/lib/editor/Editor.ts
+++ b/packages/roosterjs-content-model-core/lib/editor/Editor.ts
@@ -32,6 +32,7 @@ import type {
     CachedElementHandler,
     DomToModelOptionForCreateModel,
     AnnounceData,
+    ExperimentalFeature,
 } from 'roosterjs-content-model-types';
 
 /**
@@ -406,6 +407,14 @@ export class Editor implements IEditor {
         core.api.announce(core, announceData);
     }
 
+    /**
+     * Check if a given feature is enabled
+     * @param featureName The name of feature to check
+     */
+    isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean {
+        return this.getCore().experimentalFeatures.indexOf(featureName) >= 0;
+    }
+
     /**
      * @returns the current EditorCore object
      * @throws a standard Error if there's no core object
diff --git a/packages/roosterjs-content-model-core/test/command/paste/pasteTest.ts b/packages/roosterjs-content-model-core/test/command/paste/pasteTest.ts
index 2446e2ee8c4..7a0f0cbe3dc 100644
--- a/packages/roosterjs-content-model-core/test/command/paste/pasteTest.ts
+++ b/packages/roosterjs-content-model-core/test/command/paste/pasteTest.ts
@@ -136,7 +136,7 @@ describe('paste with content model & paste plugin', () => {
         paste(editor!, clipboardData);
 
         expect(setProcessorF.setProcessor).toHaveBeenCalledTimes(1);
-        expect(addParserF.addParser).toHaveBeenCalledTimes(DEFAULT_TIMES_ADD_PARSER_CALLED + 4);
+        expect(addParserF.addParser).toHaveBeenCalledTimes(DEFAULT_TIMES_ADD_PARSER_CALLED + 5);
         expect(WordDesktopFile.processPastedContentFromWordDesktop).toHaveBeenCalledTimes(1);
     });
 
diff --git a/packages/roosterjs-content-model-core/test/editor/EditorTest.ts b/packages/roosterjs-content-model-core/test/editor/EditorTest.ts
index cb415755e7c..3db0c62136f 100644
--- a/packages/roosterjs-content-model-core/test/editor/EditorTest.ts
+++ b/packages/roosterjs-content-model-core/test/editor/EditorTest.ts
@@ -1116,4 +1116,36 @@ describe('Editor', () => {
         expect(resetSpy).toHaveBeenCalledWith();
         expect(() => editor.announce(mockedData)).toThrow();
     });
+
+    it('isExperimentalFeatureEnabled', () => {
+        const div = document.createElement('div');
+        const resetSpy = jasmine.createSpy('reset');
+        const mockedCore = {
+            plugins: [],
+            darkColorHandler: {
+                updateKnownColor: updateKnownColorSpy,
+                reset: resetSpy,
+            },
+            api: {
+                setContentModel: setContentModelSpy,
+            },
+            experimentalFeatures: ['Feature1', 'Feature2'],
+        } as any;
+
+        createEditorCoreSpy.and.returnValue(mockedCore);
+
+        const editor = new Editor(div);
+
+        const result1 = editor.isExperimentalFeatureEnabled('Feature1');
+        const result2 = editor.isExperimentalFeatureEnabled('Feature2');
+        const result3 = editor.isExperimentalFeatureEnabled('Feature3');
+
+        expect(result1).toBeTrue();
+        expect(result2).toBeTrue();
+        expect(result3).toBeFalse();
+
+        editor.dispose();
+        expect(resetSpy).toHaveBeenCalledWith();
+        expect(() => editor.isExperimentalFeatureEnabled('Feature4')).toThrow();
+    });
 });
diff --git a/packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts b/packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts
index 54bb520d0c7..131e7d68730 100644
--- a/packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts
+++ b/packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts
@@ -1,5 +1,6 @@
 import { isNodeOfType } from '../domUtils/isNodeOfType';
 import { toArray } from '../domUtils/toArray';
+import type { ContentModelDocumentWithPersistedCache } from '../modelApi/selection/iterateSelections';
 import type {
     ContentModelDocument,
     DOMSelection,
@@ -31,6 +32,10 @@ export function contentModelToDom(
         range.isReverted = true;
     }
 
+    if (context.domIndexer && context.allowCacheElement) {
+        (model as ContentModelDocumentWithPersistedCache).persistCache = true;
+    }
+
     root.normalize();
 
     return range;
diff --git a/packages/roosterjs-content-model-dom/test/modelApi/common/normalizeParagraphTest.ts b/packages/roosterjs-content-model-dom/test/modelApi/common/normalizeParagraphTest.ts
index a28e3aa5a38..ca033384432 100644
--- a/packages/roosterjs-content-model-dom/test/modelApi/common/normalizeParagraphTest.ts
+++ b/packages/roosterjs-content-model-dom/test/modelApi/common/normalizeParagraphTest.ts
@@ -509,3 +509,304 @@ describe('Normalize paragraph with segmentFormat', () => {
         });
     });
 });
+
+describe('Move up format', () => {
+    const mockedCache = {} as any;
+
+    it('No format', () => {
+        const para = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {},
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {},
+                },
+            ],
+            format: {},
+            cachedElement: mockedCache,
+        });
+    });
+
+    it('All segments have the same format', () => {
+        const para = createParagraph();
+        const text1 = createText('test1', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text2 = createText('test2', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: true,
+        });
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: false,
+                    },
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: true,
+                    },
+                },
+            ],
+            format: {},
+            segmentFormat: {
+                fontFamily: 'Calibri',
+                fontSize: '10pt',
+                textColor: 'red',
+            },
+        });
+    });
+
+    it('All segments have the same format, paragraph has different format', () => {
+        const para = createParagraph(false, undefined, {
+            fontFamily: 'Arial',
+            fontSize: '12pt',
+            textColor: 'green',
+        });
+        const text1 = createText('test1', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text2 = createText('test2', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: true,
+        });
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: false,
+                    },
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: true,
+                    },
+                },
+            ],
+            format: {},
+            segmentFormat: {
+                fontFamily: 'Calibri',
+                fontSize: '10pt',
+                textColor: 'red',
+            },
+        });
+    });
+
+    it('Some format are different', () => {
+        const para = createParagraph();
+        const text1 = createText('test1', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text2 = createText('test2', {
+            fontFamily: 'Calibri',
+            fontSize: '12pt',
+            textColor: 'red',
+            italic: true,
+        });
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: false,
+                    },
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '12pt',
+                        textColor: 'red',
+                        italic: true,
+                    },
+                },
+            ],
+            format: {},
+            segmentFormat: { fontFamily: 'Calibri', textColor: 'red' },
+        });
+    });
+
+    it('All formats are different', () => {
+        const para = createParagraph();
+        const text1 = createText('test1', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text2 = createText('test2', {
+            fontFamily: 'Arial',
+            fontSize: '12pt',
+            textColor: 'green',
+            italic: true,
+        });
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: false,
+                    },
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {
+                        fontFamily: 'Arial',
+                        fontSize: '12pt',
+                        textColor: 'green',
+                        italic: true,
+                    },
+                },
+            ],
+            format: {},
+            cachedElement: mockedCache,
+        });
+    });
+
+    it('Already has same format in paragraph', () => {
+        const para = createParagraph(false, undefined, {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text1 = createText('test1', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: false,
+        });
+        const text2 = createText('test2', {
+            fontFamily: 'Calibri',
+            fontSize: '10pt',
+            textColor: 'red',
+            italic: true,
+        });
+
+        para.segments.push(text1, text2);
+        para.cachedElement = mockedCache;
+
+        normalizeParagraph(para);
+
+        expect(para).toEqual({
+            blockType: 'Paragraph',
+            segments: [
+                {
+                    segmentType: 'Text',
+                    text: 'test1',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: false,
+                    },
+                },
+                {
+                    segmentType: 'Text',
+                    text: 'test2',
+                    format: {
+                        fontFamily: 'Calibri',
+                        fontSize: '10pt',
+                        textColor: 'red',
+                        italic: true,
+                    },
+                },
+            ],
+            format: {},
+            segmentFormat: {
+                fontFamily: 'Calibri',
+                fontSize: '10pt',
+                textColor: 'red',
+                italic: false,
+            },
+            cachedElement: mockedCache,
+        });
+    });
+});
diff --git a/packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts b/packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts
index 91c23a861e6..5ee5b9232c6 100644
--- a/packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts
+++ b/packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts
@@ -26,6 +26,7 @@ export class EditPlugin implements EditorPlugin {
     private disposer: (() => void) | null = null;
     private shouldHandleNextInputEvent = false;
     private selectionAfterDelete: DOMSelection | null = null;
+    private handleEnterKey = false;
 
     /**
      * Get name of this plugin
@@ -42,6 +43,8 @@ export class EditPlugin implements EditorPlugin {
      */
     initialize(editor: IEditor) {
         this.editor = editor;
+        this.handleEnterKey = this.editor.isExperimentalFeatureEnabled('PersistCache');
+
         if (editor.getEnvironment().isAndroid) {
             this.disposer = this.editor.attachDomEvent({
                 beforeinput: {
@@ -154,7 +157,11 @@ export class EditPlugin implements EditorPlugin {
                     break;
 
                 case 'Enter':
-                    keyboardEnter(editor, rawEvent);
+                    if (this.handleEnterKey) {
+                        keyboardEnter(editor, rawEvent);
+                    } else {
+                        keyboardInput(editor, rawEvent);
+                    }
                     break;
 
                 default:
diff --git a/packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts b/packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts
index 57abbb39218..b3a21c69d40 100644
--- a/packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts
+++ b/packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts
@@ -1,12 +1,10 @@
 import {
     unwrapBlock,
     getClosestAncestorBlockGroupIndex,
-    isBlockGroupOfType,
     createFormatContainer,
     mutateBlock,
 } from 'roosterjs-content-model-dom';
 import type {
-    ContentModelFormatContainer,
     DeleteSelectionStep,
     ReadonlyContentModelBlockGroup,
     ReadonlyContentModelFormatContainer,
@@ -21,66 +19,54 @@ import type {
 export const deleteEmptyQuote: DeleteSelectionStep = context => {
     const { deleteResult } = context;
 
-    if (deleteResult == 'nothingToDelete' || deleteResult == 'notDeleted') {
+    if (
+        deleteResult == 'nothingToDelete' ||
+        deleteResult == 'notDeleted' ||
+        deleteResult == 'range'
+    ) {
         const { insertPoint, formatContext } = context;
         const { path, paragraph } = insertPoint;
         const rawEvent = formatContext?.rawEvent as KeyboardEvent;
         const index = getClosestAncestorBlockGroupIndex(
             path,
-            ['FormatContainer', 'ListItem'],
-            ['TableCell']
+            ['FormatContainer'],
+            ['TableCell', 'ListItem']
         );
         const quote = path[index];
 
         if (quote && quote.blockGroupType === 'FormatContainer' && quote.tagName == 'blockquote') {
             const parent = path[index + 1];
             const quoteBlockIndex = parent.blocks.indexOf(quote);
-            const blockQuote = parent.blocks[quoteBlockIndex];
 
-            if (
-                isBlockGroupOfType<ContentModelFormatContainer>(blockQuote, 'FormatContainer') &&
-                blockQuote.tagName === 'blockquote'
+            if (isEmptyQuote(quote)) {
+                unwrapBlock(parent, quote);
+                rawEvent?.preventDefault();
+                context.deleteResult = 'range';
+            } else if (
+                rawEvent?.key === 'Enter' &&
+                quote.blocks.indexOf(paragraph) >= 0 &&
+                isEmptyParagraph(paragraph)
             ) {
-                if (isEmptyQuote(blockQuote)) {
-                    unwrapBlock(parent, blockQuote);
-                    rawEvent?.preventDefault();
-                    context.deleteResult = 'range';
-                } else if (
-                    isSelectionOnEmptyLine(blockQuote, paragraph) &&
-                    rawEvent?.key === 'Enter'
-                ) {
-                    insertNewLine(blockQuote, parent, quoteBlockIndex, paragraph);
-                    rawEvent?.preventDefault();
-                    context.deleteResult = 'range';
-                }
+                insertNewLine(mutateBlock(quote), parent, quoteBlockIndex, paragraph);
+                rawEvent?.preventDefault();
+                context.deleteResult = 'range';
             }
         }
     }
 };
 
-const isEmptyQuote = (quote: ContentModelFormatContainer) => {
+const isEmptyQuote = (quote: ReadonlyContentModelFormatContainer) => {
     return (
         quote.blocks.length === 1 &&
         quote.blocks[0].blockType === 'Paragraph' &&
-        quote.blocks[0].segments.every(
-            s => s.segmentType === 'SelectionMarker' || s.segmentType === 'Br'
-        )
+        isEmptyParagraph(quote.blocks[0])
     );
 };
 
-const isSelectionOnEmptyLine = (
-    quote: ReadonlyContentModelFormatContainer,
-    paragraph: ReadonlyContentModelParagraph
-) => {
-    const paraIndex = quote.blocks.indexOf(paragraph);
-
-    if (paraIndex >= 0) {
-        return paragraph.segments.every(
-            s => s.segmentType === 'SelectionMarker' || s.segmentType === 'Br'
-        );
-    } else {
-        return false;
-    }
+const isEmptyParagraph = (paragraph: ReadonlyContentModelParagraph) => {
+    return paragraph.segments.every(
+        s => s.segmentType === 'SelectionMarker' || s.segmentType === 'Br'
+    );
 };
 
 const insertNewLine = (
diff --git a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts
index ab091efbab4..5a7205a2700 100644
--- a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts
+++ b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts
@@ -24,7 +24,11 @@ export const handleEnterOnList: DeleteSelectionStep = context => {
 
     if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {
         const { path } = insertPoint;
-        const index = getClosestAncestorBlockGroupIndex(path, ['ListItem'], ['TableCell']);
+        const index = getClosestAncestorBlockGroupIndex(
+            path,
+            ['ListItem'],
+            ['TableCell', 'FormatContainer']
+        );
 
         const readonlyListItem = path[index];
         const listParent = path[index + 1];
@@ -84,6 +88,7 @@ const createNewListItem = (
     const { insertPoint } = context;
     const listIndex = listParent.blocks.indexOf(listItem);
     const currentPara = insertPoint.paragraph;
+    const paraIndex = listItem.blocks.indexOf(currentPara);
     const newParagraph = splitParagraph(insertPoint);
 
     const levels = createNewListLevel(listItem);
@@ -91,7 +96,17 @@ const createNewListItem = (
         levels,
         insertPoint.marker.format
     );
+
     newListItem.blocks.push(newParagraph);
+
+    const remainingBlockCount = listItem.blocks.length - paraIndex - 1;
+
+    if (paraIndex >= 0 && remainingBlockCount > 0) {
+        newListItem.blocks.push(
+            ...mutateBlock(listItem).blocks.splice(paraIndex + 1, remainingBlockCount)
+        );
+    }
+
     insertPoint.paragraph = newParagraph;
     mutateBlock(listParent).blocks.splice(listIndex + 1, 0, newListItem);
 
diff --git a/packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts b/packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts
index a3840002df5..403127175cf 100644
--- a/packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts
+++ b/packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts
@@ -8,6 +8,7 @@ import { setProcessor } from '../utils/setProcessor';
 import type { WordMetadata } from './WordMetadata';
 import type {
     BeforePasteEvent,
+    ContentModelBlockFormat,
     ContentModelListItemLevelFormat,
     ContentModelTableFormat,
     DomToModelContext,
@@ -15,6 +16,10 @@ import type {
     FormatParser,
 } from 'roosterjs-content-model-types';
 
+const PERCENTAGE_REGEX = /%/;
+// Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal
+const DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;
+
 /**
  * @internal
  * Handles Pasted content when source is Word Desktop
@@ -27,6 +32,7 @@ export function processPastedContentFromWordDesktop(
     const metadataMap: Map<string, WordMetadata> = getStyleMetadata(ev, trustedHTMLHandler);
 
     setProcessor(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
+    addParser(ev.domToModelOption, 'block', adjustPercentileLineHeight);
     addParser(ev.domToModelOption, 'block', removeNegativeTextIndentParser);
     addParser(ev.domToModelOption, 'listLevel', listLevelParser);
     addParser(ev.domToModelOption, 'container', wordTableParser);
@@ -50,6 +56,20 @@ const wordDesktopElementProcessor = (
     };
 };
 
+function adjustPercentileLineHeight(format: ContentModelBlockFormat, element: HTMLElement): void {
+    //If the line height is less than the browser default line height, line between the text is going to be too narrow
+    let parsedLineHeight: number;
+    if (
+        PERCENTAGE_REGEX.test(element.style.lineHeight) &&
+        !isNaN((parsedLineHeight = parseInt(element.style.lineHeight)))
+    ) {
+        format.lineHeight = (
+            DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE *
+            (parsedLineHeight / 100)
+        ).toString();
+    }
+}
+
 function listLevelParser(
     format: ContentModelListItemLevelFormat,
     element: HTMLElement,
diff --git a/packages/roosterjs-content-model-plugins/test/edit/EditPluginTest.ts b/packages/roosterjs-content-model-plugins/test/edit/EditPluginTest.ts
index 4ca88a12128..0c895000cbb 100644
--- a/packages/roosterjs-content-model-plugins/test/edit/EditPluginTest.ts
+++ b/packages/roosterjs-content-model-plugins/test/edit/EditPluginTest.ts
@@ -1,4 +1,5 @@
 import * as keyboardDelete from '../../lib/edit/keyboardDelete';
+import * as keyboardEnter from '../../lib/edit/keyboardEnter';
 import * as keyboardInput from '../../lib/edit/keyboardInput';
 import * as keyboardTab from '../../lib/edit/keyboardTab';
 import { DOMEventRecord, IEditor } from 'roosterjs-content-model-types';
@@ -10,6 +11,7 @@ describe('EditPlugin', () => {
     let eventMap: Record<string, any>;
     let attachDOMEventSpy: jasmine.Spy;
     let getEnvironmentSpy: jasmine.Spy;
+    let isExperimentalFeatureEnabledSpy: jasmine.Spy;
 
     beforeEach(() => {
         attachDOMEventSpy = jasmine
@@ -21,6 +23,9 @@ describe('EditPlugin', () => {
         getEnvironmentSpy = jasmine.createSpy('getEnvironment').and.returnValue({
             isAndroid: true,
         });
+        isExperimentalFeatureEnabledSpy = jasmine
+            .createSpy('isExperimentalFeatureEnabled')
+            .and.returnValue(false);
 
         editor = ({
             attachDomEvent: attachDOMEventSpy,
@@ -29,6 +34,7 @@ describe('EditPlugin', () => {
                 ({
                     type: -1,
                 } as any), // Force return invalid range to go through content model code
+            isExperimentalFeatureEnabled: isExperimentalFeatureEnabledSpy,
         } as any) as IEditor;
     });
 
@@ -40,11 +46,13 @@ describe('EditPlugin', () => {
         let keyboardDeleteSpy: jasmine.Spy;
         let keyboardInputSpy: jasmine.Spy;
         let keyboardTabSpy: jasmine.Spy;
+        let keyboardEnterSpy: jasmine.Spy;
 
         beforeEach(() => {
             keyboardDeleteSpy = spyOn(keyboardDelete, 'keyboardDelete');
             keyboardInputSpy = spyOn(keyboardInput, 'keyboardInput');
             keyboardTabSpy = spyOn(keyboardTab, 'keyboardTab');
+            keyboardEnterSpy = spyOn(keyboardEnter, 'keyboardEnter');
         });
 
         it('Backspace', () => {
@@ -60,6 +68,8 @@ describe('EditPlugin', () => {
 
             expect(keyboardDeleteSpy).toHaveBeenCalledWith(editor, rawEvent);
             expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Delete', () => {
@@ -75,6 +85,8 @@ describe('EditPlugin', () => {
 
             expect(keyboardDeleteSpy).toHaveBeenCalledWith(editor, rawEvent);
             expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Shift+Delete', () => {
@@ -90,6 +102,8 @@ describe('EditPlugin', () => {
 
             expect(keyboardDeleteSpy).not.toHaveBeenCalled();
             expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Tab', () => {
@@ -106,6 +120,50 @@ describe('EditPlugin', () => {
             expect(keyboardTabSpy).toHaveBeenCalledWith(editor, rawEvent);
             expect(keyboardInputSpy).not.toHaveBeenCalled();
             expect(keyboardDeleteSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+        });
+
+        it('Enter, keyboardEnter not enabled', () => {
+            plugin = new EditPlugin();
+            const rawEvent = { which: 13, key: 'Enter' } as any;
+            const addUndoSnapshotSpy = jasmine.createSpy('addUndoSnapshot');
+
+            editor.takeSnapshot = addUndoSnapshotSpy;
+
+            plugin.initialize(editor);
+
+            plugin.onPluginEvent({
+                eventType: 'keyDown',
+                rawEvent,
+            });
+
+            expect(keyboardDeleteSpy).not.toHaveBeenCalled();
+            expect(keyboardInputSpy).toHaveBeenCalledWith(editor, rawEvent);
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
+        });
+
+        it('Enter, keyboardEnter enabled', () => {
+            isExperimentalFeatureEnabledSpy.and.callFake(
+                (featureName: string) => featureName == 'PersistCache'
+            );
+            plugin = new EditPlugin();
+            const rawEvent = { which: 13, key: 'Enter' } as any;
+            const addUndoSnapshotSpy = jasmine.createSpy('addUndoSnapshot');
+
+            editor.takeSnapshot = addUndoSnapshotSpy;
+
+            plugin.initialize(editor);
+
+            plugin.onPluginEvent({
+                eventType: 'keyDown',
+                rawEvent,
+            });
+
+            expect(keyboardDeleteSpy).not.toHaveBeenCalled();
+            expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).toHaveBeenCalledWith(editor, rawEvent);
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Other key', () => {
@@ -124,6 +182,8 @@ describe('EditPlugin', () => {
 
             expect(keyboardDeleteSpy).not.toHaveBeenCalled();
             expect(keyboardInputSpy).toHaveBeenCalledWith(editor, rawEvent);
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Default prevented', () => {
@@ -138,6 +198,8 @@ describe('EditPlugin', () => {
 
             expect(keyboardDeleteSpy).not.toHaveBeenCalled();
             expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
 
         it('Trigger entity event first', () => {
@@ -174,6 +236,8 @@ describe('EditPlugin', () => {
                 key: 'Delete',
             } as any);
             expect(keyboardInputSpy).not.toHaveBeenCalled();
+            expect(keyboardEnterSpy).not.toHaveBeenCalled();
+            expect(keyboardTabSpy).not.toHaveBeenCalled();
         });
     });
 
diff --git a/packages/roosterjs-content-model-plugins/test/edit/deleteSteps/deleteEmptyQuoteTest.ts b/packages/roosterjs-content-model-plugins/test/edit/deleteSteps/deleteEmptyQuoteTest.ts
index 3494db5d813..ab1f69fe948 100644
--- a/packages/roosterjs-content-model-plugins/test/edit/deleteSteps/deleteEmptyQuoteTest.ts
+++ b/packages/roosterjs-content-model-plugins/test/edit/deleteSteps/deleteEmptyQuoteTest.ts
@@ -126,6 +126,218 @@ describe('deleteEmptyQuote', () => {
             ],
             format: {},
         };
-        runTest(model, model, 'notDeleted');
+        const expectedModel: ContentModelDocument = {
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'BlockGroup',
+                    blockGroupType: 'FormatContainer',
+                    tagName: 'blockquote',
+                    blocks: [
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'Text',
+                                    text: 'test',
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                                {
+                                    segmentType: 'SelectionMarker',
+                                    isSelected: true,
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                            segmentFormat: { textColor: 'rgb(102, 102, 102)' },
+                        },
+                    ],
+                    format: {
+                        marginTop: '1em',
+                        marginRight: '40px',
+                        marginBottom: '1em',
+                        marginLeft: '40px',
+                        paddingLeft: '10px',
+                        borderLeft: '3px solid rgb(200, 200, 200)',
+                    },
+                },
+            ],
+            format: {},
+        };
+        runTest(model, expectedModel, 'notDeleted');
+    });
+});
+
+describe('delete with Enter', () => {
+    it('Enter in empty paragraph in middle of quote', () => {
+        function runTest(
+            model: ContentModelDocument,
+            expectedModel: ContentModelDocument,
+            deleteResult: string
+        ) {
+            const result = deleteSelection(model, [deleteEmptyQuote], {
+                rawEvent: {
+                    key: 'Enter',
+                    preventDefault: () => {},
+                } as any,
+                newEntities: [],
+                deletedEntities: [],
+                newImages: [],
+            });
+            normalizeContentModel(model);
+            expect(result.deleteResult).toEqual(deleteResult);
+            expect(model).toEqual(expectedModel);
+        }
+
+        const model: ContentModelDocument = {
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'BlockGroup',
+                    blockGroupType: 'FormatContainer',
+                    tagName: 'blockquote',
+                    blocks: [
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'Text',
+                                    text: 'test',
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                        },
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'SelectionMarker',
+                                    isSelected: true,
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                        },
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'Text',
+                                    text: 'test',
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                        },
+                    ],
+                    format: {
+                        marginTop: '1em',
+                        marginRight: '40px',
+                        marginBottom: '1em',
+                        marginLeft: '40px',
+                        paddingLeft: '10px',
+                        borderLeft: '3px solid rgb(200, 200, 200)',
+                    },
+                },
+            ],
+            format: {},
+        };
+
+        const expectedModel: ContentModelDocument = {
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'BlockGroup',
+                    blockGroupType: 'FormatContainer',
+                    tagName: 'blockquote',
+                    blocks: [
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'Text',
+                                    text: 'test',
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                            segmentFormat: { textColor: 'rgb(102, 102, 102)' },
+                        },
+                    ],
+                    format: {
+                        marginTop: '1em',
+                        marginRight: '40px',
+                        marginBottom: '1em',
+                        marginLeft: '40px',
+                        paddingLeft: '10px',
+                        borderLeft: '3px solid rgb(200, 200, 200)',
+                    },
+                },
+                {
+                    blockType: 'Paragraph',
+                    segments: [
+                        {
+                            segmentType: 'SelectionMarker',
+                            isSelected: true,
+                            format: {
+                                textColor: 'rgb(102, 102, 102)',
+                            },
+                        },
+                        {
+                            segmentType: 'Br',
+                            format: {
+                                textColor: 'rgb(102, 102, 102)',
+                            },
+                        },
+                    ],
+                    format: {},
+                    segmentFormat: { textColor: 'rgb(102, 102, 102)' },
+                },
+                {
+                    blockType: 'BlockGroup',
+                    blockGroupType: 'FormatContainer',
+                    tagName: 'blockquote',
+                    blocks: [
+                        {
+                            blockType: 'Paragraph',
+                            segments: [
+                                {
+                                    segmentType: 'Text',
+                                    text: 'test',
+                                    format: {
+                                        textColor: 'rgb(102, 102, 102)',
+                                    },
+                                },
+                            ],
+                            format: {},
+                            segmentFormat: { textColor: 'rgb(102, 102, 102)' },
+                        },
+                    ],
+                    format: {
+                        marginTop: '1em',
+                        marginRight: '40px',
+                        marginBottom: '1em',
+                        marginLeft: '40px',
+                        paddingLeft: '10px',
+                        borderLeft: '3px solid rgb(200, 200, 200)',
+                    },
+                },
+            ],
+            format: {},
+        };
+        runTest(model, expectedModel, 'range');
     });
 });
diff --git a/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts
index 69616999988..34a9ddd18d9 100644
--- a/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts
+++ b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts
@@ -2438,4 +2438,222 @@ describe('handleEnterOnList - keyboardEnter', () => {
         };
         runTest(input, true, expected, false, 1);
     });
+
+    it('List item contains multiple blocks', () => {
+        const model: ContentModelDocument = {
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    formatHolder: {
+                        isSelected: false,
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                    },
+                    levels: [
+                        {
+                            listType: 'OL',
+                            format: {},
+                            dataset: {},
+                        },
+                    ],
+                    blockType: 'BlockGroup',
+                    format: {},
+                    blockGroupType: 'ListItem',
+                    blocks: [
+                        {
+                            segments: [
+                                {
+                                    text: 'test1',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                                {
+                                    isSelected: true,
+                                    segmentType: 'SelectionMarker',
+                                    format: {},
+                                },
+                                {
+                                    segmentType: 'Br',
+                                    format: {},
+                                },
+                                {
+                                    text: 'test2',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                        {
+                            segments: [
+                                {
+                                    text: 'test3',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                    ],
+                },
+                {
+                    formatHolder: {
+                        isSelected: false,
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                    },
+                    levels: [
+                        {
+                            listType: 'OL',
+                            format: {},
+                            dataset: {},
+                        },
+                    ],
+                    blockType: 'BlockGroup',
+                    format: {},
+                    blockGroupType: 'ListItem',
+                    blocks: [
+                        {
+                            isImplicit: true,
+                            segments: [
+                                {
+                                    text: 'test4',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                    ],
+                },
+            ],
+        };
+
+        const expectedModel: ContentModelDocument = {
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    formatHolder: {
+                        isSelected: false,
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                    },
+                    levels: [
+                        {
+                            listType: 'OL',
+                            format: {},
+                            dataset: {},
+                        },
+                    ],
+                    blockType: 'BlockGroup',
+                    format: {},
+                    blockGroupType: 'ListItem',
+                    blocks: [
+                        {
+                            segments: [
+                                {
+                                    text: 'test1',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                    ],
+                },
+                {
+                    formatHolder: {
+                        isSelected: false,
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                    },
+                    levels: [
+                        {
+                            listType: 'OL',
+                            format: {
+                                startNumberOverride: undefined,
+                                displayForDummyItem: undefined,
+                            },
+                            dataset: {},
+                        },
+                    ],
+                    blockType: 'BlockGroup',
+                    format: {},
+                    blockGroupType: 'ListItem',
+                    blocks: [
+                        {
+                            segments: [
+                                {
+                                    isSelected: true,
+                                    segmentType: 'SelectionMarker',
+                                    format: {},
+                                },
+                                {
+                                    segmentType: 'Br',
+                                    format: {},
+                                },
+                                {
+                                    text: 'test2',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                        {
+                            segments: [
+                                {
+                                    text: 'test3',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                    ],
+                },
+                {
+                    formatHolder: {
+                        isSelected: false,
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                    },
+                    levels: [
+                        {
+                            listType: 'OL',
+                            format: {
+                                startNumberOverride: undefined,
+                            },
+                            dataset: {},
+                        },
+                    ],
+                    blockType: 'BlockGroup',
+                    format: {},
+                    blockGroupType: 'ListItem',
+                    blocks: [
+                        {
+                            isImplicit: true,
+                            segments: [
+                                {
+                                    text: 'test4',
+                                    segmentType: 'Text',
+                                    format: {},
+                                },
+                            ],
+                            blockType: 'Paragraph',
+                            format: {},
+                        },
+                    ],
+                },
+            ],
+        };
+
+        runTest(model, false, expectedModel, false, 1);
+    });
 });
diff --git a/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnParagraphTest.ts b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnParagraphTest.ts
new file mode 100644
index 00000000000..cbab594af4e
--- /dev/null
+++ b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnParagraphTest.ts
@@ -0,0 +1,102 @@
+import { handleEnterOnParagraph } from '../../../lib/edit/inputSteps/handleEnterOnParagraph';
+import { ValidDeleteSelectionContext } from 'roosterjs-content-model-types';
+import {
+    createContentModelDocument,
+    createParagraph,
+    createSelectionMarker,
+    createText,
+} from 'roosterjs-content-model-dom';
+
+describe('handleEnterOnParagraph', () => {
+    it('Already deleted', () => {
+        const doc = createContentModelDocument();
+        const para = createParagraph();
+        const marker = createSelectionMarker();
+        const mockedCache = {} as any;
+
+        para.segments.push(marker);
+        doc.blocks.push(para);
+        doc.cachedElement = mockedCache;
+
+        const context: ValidDeleteSelectionContext = {
+            deleteResult: 'range',
+            insertPoint: {
+                paragraph: para,
+                marker: marker,
+                path: [doc],
+            },
+        };
+
+        handleEnterOnParagraph(context);
+
+        expect(doc).toEqual({
+            blockGroupType: 'Document',
+            blocks: [para],
+            cachedElement: mockedCache,
+        });
+    });
+
+    it('Not deleted, split current paragraph', () => {
+        const doc = createContentModelDocument();
+        const para = createParagraph();
+        const marker = createSelectionMarker();
+        const mockedCache = {} as any;
+        const text1 = createText('test1');
+        const text2 = createText('test1');
+
+        para.segments.push(text1, marker, text2);
+        doc.blocks.push(para);
+        doc.cachedElement = mockedCache;
+
+        const context: ValidDeleteSelectionContext = {
+            deleteResult: 'notDeleted',
+            insertPoint: {
+                paragraph: para,
+                marker: marker,
+                path: [doc],
+            },
+        };
+
+        handleEnterOnParagraph(context);
+
+        expect(doc).toEqual({
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'Paragraph',
+                    segments: [text1],
+                    format: {},
+                },
+                {
+                    blockType: 'Paragraph',
+                    segments: [
+                        {
+                            segmentType: 'SelectionMarker',
+                            format: {},
+                            isSelected: true,
+                        },
+                        text2,
+                    ],
+                    format: {},
+                },
+            ],
+        });
+
+        expect(context.insertPoint).toEqual({
+            paragraph: {
+                blockType: 'Paragraph',
+                segments: [
+                    {
+                        segmentType: 'SelectionMarker',
+                        format: {},
+                        isSelected: true,
+                    },
+                    text2,
+                ],
+                format: {},
+            },
+            marker: marker,
+            path: [doc],
+        });
+    });
+});
diff --git a/packages/roosterjs-content-model-plugins/test/edit/keyboardEnterTest.ts b/packages/roosterjs-content-model-plugins/test/edit/keyboardEnterTest.ts
new file mode 100644
index 00000000000..b18a6d0b6f6
--- /dev/null
+++ b/packages/roosterjs-content-model-plugins/test/edit/keyboardEnterTest.ts
@@ -0,0 +1,1418 @@
+import { keyboardEnter } from '../../lib/edit/keyboardEnter';
+import {
+    createBr,
+    createFormatContainer,
+    createListItem,
+    createListLevel,
+    createParagraph,
+    createSelectionMarker,
+    createTable,
+    createTableCell,
+    createText,
+} from 'roosterjs-content-model-dom';
+import {
+    ContentModelDocument,
+    ContentModelSegmentFormat,
+    FormatContentModelContext,
+    IEditor,
+} from 'roosterjs-content-model-types';
+
+describe('keyboardEnter', () => {
+    let getDOMSelectionSpy: jasmine.Spy;
+    let formatContentModelSpy: jasmine.Spy;
+    let preventDefaultSpy: jasmine.Spy;
+    let editor: IEditor;
+
+    beforeEach(() => {
+        getDOMSelectionSpy = jasmine.createSpy('getDOMSelection').and.returnValue({
+            type: 'range',
+        });
+        formatContentModelSpy = jasmine.createSpy('formatContentModel');
+        preventDefaultSpy = jasmine.createSpy('preventDefault');
+        editor = {
+            getDOMSelection: getDOMSelectionSpy,
+            formatContentModel: formatContentModelSpy,
+        } as any;
+    });
+
+    function runTest(
+        input: ContentModelDocument,
+        shift: boolean,
+        output: ContentModelDocument,
+        isChanged: boolean,
+        pendingFormat: ContentModelSegmentFormat | undefined
+    ) {
+        const rawEvent: KeyboardEvent = {
+            key: 'Enter',
+            shiftKey: shift,
+            preventDefault: preventDefaultSpy,
+        } as any;
+        const context: FormatContentModelContext = {
+            deletedEntities: [],
+            newEntities: [],
+            newImages: [],
+            rawEvent,
+        };
+        formatContentModelSpy.and.callFake((callback: Function) => {
+            const result = callback(input, context);
+
+            expect(result).toBe(isChanged);
+            expect();
+        });
+
+        keyboardEnter(editor, rawEvent);
+
+        expect(formatContentModelSpy).toHaveBeenCalledTimes(1);
+        expect(input).toEqual(output);
+        expect(context.newPendingFormat).toEqual(pendingFormat);
+    }
+
+    it('Empty model, no selection', () => {
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [],
+            },
+            false,
+            undefined
+        );
+    });
+
+    it('Single paragraph, only have selection marker', () => {
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'SelectionMarker',
+                                isSelected: true,
+                                format: { fontSize: '10pt' },
+                            },
+                            {
+                                segmentType: 'Br',
+                                format: {},
+                            },
+                        ],
+                    },
+                ],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'Br',
+                                format: { fontSize: '10pt' },
+                            },
+                        ],
+                        segmentFormat: { fontSize: '10pt' },
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'SelectionMarker',
+                                isSelected: true,
+                                format: { fontSize: '10pt' },
+                            },
+                            {
+                                segmentType: 'Br',
+                                format: {},
+                            },
+                        ],
+                    },
+                ],
+            },
+            true,
+            { fontSize: '10pt' }
+        );
+    });
+
+    it('Single paragraph, all text are selected', () => {
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'Text',
+                                isSelected: true,
+                                text: 'test',
+                                format: { fontSize: '10pt' },
+                            },
+                        ],
+                    },
+                ],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'Br',
+                                format: { fontSize: '10pt' },
+                            },
+                        ],
+                        segmentFormat: { fontSize: '10pt' },
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'SelectionMarker',
+                                isSelected: true,
+                                format: { fontSize: '10pt' },
+                            },
+                            {
+                                segmentType: 'Br',
+                                format: { fontSize: '10pt' },
+                            },
+                        ],
+                        segmentFormat: { fontSize: '10pt' },
+                    },
+                ],
+            },
+            true,
+            { fontSize: '10pt' }
+        );
+    });
+
+    it('Multiple paragraph, single selection', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+
+        para1.segments.push(createBr());
+        para2.segments.push(createBr());
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    para1,
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            text1,
+                            {
+                                segmentType: 'SelectionMarker',
+                                isSelected: true,
+                                format: {},
+                            },
+                            text2,
+                        ],
+                    },
+                    para2,
+                ],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    para1,
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [text1],
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'SelectionMarker',
+                                isSelected: true,
+                                format: {},
+                            },
+                            text2,
+                        ],
+                    },
+                    para2,
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Multiple paragraph, select from line end to line start', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const marker1 = createSelectionMarker();
+        const marker2 = createSelectionMarker();
+
+        para1.segments.push(text1, marker1);
+        para2.segments.push(marker2, text2);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, para2],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [text1],
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [marker1, text2],
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Multiple paragraph, select text across lines', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3, text4);
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, para2],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [text1],
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        format: {},
+                        segments: [
+                            {
+                                segmentType: 'SelectionMarker',
+                                format: {},
+                                isSelected: true,
+                            },
+                            text4,
+                        ],
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Empty paragraph in quote', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const quote = createFormatContainer('blockquote');
+        const marker = createSelectionMarker();
+        const br1 = createBr();
+        const br2 = createBr();
+        const br3 = createBr();
+
+        para1.segments.push(br1);
+        para2.segments.push(marker, br2);
+        para3.segments.push(br3);
+        quote.blocks.push(para2);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, quote, para3],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, para2, para3],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Empty paragraph in middle of quote', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const quote = createFormatContainer('blockquote');
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const br = createBr();
+        const text3 = createText('test3');
+
+        para1.segments.push(text1);
+        para2.segments.push(marker, br);
+        para3.segments.push(text3);
+        quote.blocks.push(para1, para2, para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [quote],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockGroupType: 'FormatContainer',
+                        blockType: 'BlockGroup',
+                        blocks: [para1],
+                        format: {},
+                        tagName: 'blockquote',
+                    },
+                    para2,
+                    {
+                        blockGroupType: 'FormatContainer',
+                        blockType: 'BlockGroup',
+                        blocks: [para3],
+                        format: {},
+                        tagName: 'blockquote',
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Empty paragraph in middle of quote, not empty', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const quote = createFormatContainer('blockquote');
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('text2');
+        const text3 = createText('test3');
+
+        para1.segments.push(text1);
+        para2.segments.push(marker, text2);
+        para3.segments.push(text3);
+        quote.blocks.push(para1, para2, para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [quote],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockGroupType: 'FormatContainer',
+                        blockType: 'BlockGroup',
+                        blocks: [
+                            para1,
+                            {
+                                blockType: 'Paragraph',
+                                format: {},
+                                segments: [
+                                    {
+                                        segmentType: 'Br',
+                                        format: {},
+                                    },
+                                ],
+                            },
+                            {
+                                blockType: 'Paragraph',
+                                format: {},
+                                segments: [marker, text2],
+                            },
+                            para3,
+                        ],
+                        format: {},
+                        tagName: 'blockquote',
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Empty paragraph in middle of quote, shift', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const quote = createFormatContainer('blockquote');
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const br = createBr();
+        const text3 = createText('test3');
+
+        para1.segments.push(text1);
+        para2.segments.push(marker, br);
+        para3.segments.push(text3);
+        quote.blocks.push(para1, para2, para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [quote],
+            },
+            true,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockGroupType: 'FormatContainer',
+                        blockType: 'BlockGroup',
+                        blocks: [
+                            para1,
+                            {
+                                blockType: 'Paragraph',
+                                segments: [
+                                    {
+                                        segmentType: 'Br',
+                                        format: {},
+                                    },
+                                ],
+                                format: {},
+                            },
+                            {
+                                blockType: 'Paragraph',
+                                segments: [marker, br],
+                                format: {},
+                            },
+                            para3,
+                        ],
+                        format: {},
+                        tagName: 'blockquote',
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Single empty list item', () => {
+        const para1 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const marker = createSelectionMarker();
+        const br = createBr();
+
+        para1.segments.push(marker, br);
+        list1.blocks.push(para1);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [para1],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Single empty list item, shift', () => {
+        const para1 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const marker = createSelectionMarker();
+        const br = createBr();
+
+        para1.segments.push(marker, br);
+        list1.blocks.push(para1);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1],
+            },
+            true,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockGroupType: 'ListItem',
+                        blockType: 'BlockGroup',
+                        format: {},
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                format: {},
+                                segments: [
+                                    {
+                                        segmentType: 'Br',
+                                        format: {},
+                                    },
+                                ],
+                            },
+                            {
+                                blockType: 'Paragraph',
+                                format: {},
+                                segments: [
+                                    marker,
+                                    {
+                                        segmentType: 'Br',
+                                        format: {},
+                                    },
+                                ],
+                            },
+                        ],
+                        levels: [listLevel],
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('First empty list item', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const list2 = createListItem([listLevel]);
+        const list3 = createListItem([listLevel]);
+        const marker = createSelectionMarker();
+        const br = createBr();
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+
+        para1.segments.push(marker, br);
+        para2.segments.push(text2);
+        para3.segments.push(text3);
+        list1.blocks.push(para1);
+        list2.blocks.push(para2);
+        list3.blocks.push(para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1, list2, list3],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, list2, list3],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('List item with text', () => {
+        const para1 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+
+        para1.segments.push(text1, marker, text2);
+        list1.blocks.push(para1);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text1],
+                                format: {},
+                            },
+                        ],
+                        levels: [listLevel],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [marker, text2],
+                                format: {},
+                            },
+                        ],
+                        levels: [
+                            {
+                                listType: 'OL',
+                                dataset: {},
+                                format: {
+                                    startNumberOverride: undefined,
+                                    displayForDummyItem: undefined,
+                                },
+                            },
+                        ],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Selection across list items', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const list3 = createListItem([listLevel]);
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+        const text5 = createText('test5');
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+        text4.isSelected = true;
+
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3);
+        para3.segments.push(text4, text5);
+        list1.blocks.push(para1);
+        list3.blocks.push(para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1, para2, list3],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text1],
+                                format: {},
+                            },
+                        ],
+                        levels: [listLevel],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [
+                                    {
+                                        segmentType: 'SelectionMarker',
+                                        isSelected: true,
+                                        format: {},
+                                    },
+                                    text5,
+                                ],
+                                format: {},
+                            },
+                        ],
+                        levels: [
+                            {
+                                listType: 'OL',
+                                format: {
+                                    startNumberOverride: undefined,
+                                    displayForDummyItem: undefined,
+                                },
+                                dataset: {},
+                            },
+                        ],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('Selection across list items, shift', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const list3 = createListItem([listLevel]);
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+        const text5 = createText('test5');
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+        text4.isSelected = true;
+
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3);
+        para3.segments.push(text4, text5);
+        list1.blocks.push(para1);
+        list3.blocks.push(para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1, para2, list3],
+            },
+            true,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text1],
+                                format: {},
+                            },
+                            {
+                                blockType: 'Paragraph',
+                                segments: [
+                                    {
+                                        segmentType: 'SelectionMarker',
+                                        isSelected: true,
+                                        format: {},
+                                    },
+                                    text5,
+                                ],
+                                format: {},
+                            },
+                        ],
+                        levels: [listLevel],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('multiple blocks under list item', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const listLevel = createListLevel('OL');
+        const list1 = createListItem([listLevel]);
+        const list2 = createListItem([listLevel]);
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+
+        para1.segments.push(text1, marker, text2);
+        para2.segments.push(text3);
+        para3.segments.push(text4);
+        list1.blocks.push(para1, para2);
+        list2.blocks.push(para3);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list1, list2],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text1],
+                                format: {},
+                            },
+                        ],
+                        levels: [listLevel],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [marker, text2],
+                                format: {},
+                            },
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text3],
+                                format: {},
+                            },
+                        ],
+                        levels: [
+                            {
+                                listType: 'OL',
+                                format: {
+                                    startNumberOverride: undefined,
+                                    displayForDummyItem: undefined,
+                                },
+                                dataset: {},
+                            },
+                        ],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Paragraph',
+                                segments: [text4],
+                                format: {},
+                            },
+                        ],
+                        levels: [
+                            {
+                                listType: 'OL',
+                                format: {
+                                    startNumberOverride: undefined,
+                                },
+                                dataset: {},
+                            },
+                        ],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection is in table', () => {
+        const para1 = createParagraph();
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para1);
+        para1.segments.push(text1, marker, text2);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [table],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Table',
+                        rows: [
+                            {
+                                height: 0,
+                                format: {},
+                                cells: [
+                                    {
+                                        blockGroupType: 'TableCell',
+                                        blocks: [
+                                            {
+                                                blockType: 'Paragraph',
+                                                segments: [text1],
+                                                format: {},
+                                            },
+                                            {
+                                                blockType: 'Paragraph',
+                                                segments: [marker, text2],
+                                                format: {},
+                                            },
+                                        ],
+                                        format: {},
+                                        spanLeft: false,
+                                        spanAbove: false,
+                                        isHeader: false,
+                                        dataset: {},
+                                    },
+                                ],
+                            },
+                        ],
+                        format: {},
+                        widths: [],
+                        dataset: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection is in table, under list', () => {
+        const para1 = createParagraph();
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        const listLevel = createListLevel('OL');
+        const list = createListItem([listLevel]);
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para1);
+        para1.segments.push(text1, marker, text2);
+        list.blocks.push(table);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [list],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'ListItem',
+                        blocks: [
+                            {
+                                blockType: 'Table',
+                                rows: [
+                                    {
+                                        height: 0,
+                                        format: {},
+                                        cells: [
+                                            {
+                                                blockGroupType: 'TableCell',
+                                                blocks: [
+                                                    {
+                                                        blockType: 'Paragraph',
+                                                        segments: [text1],
+                                                        format: {},
+                                                    },
+                                                    {
+                                                        blockType: 'Paragraph',
+                                                        segments: [marker, text2],
+                                                        format: {},
+                                                    },
+                                                ],
+                                                format: {},
+                                                spanLeft: false,
+                                                spanAbove: false,
+                                                isHeader: false,
+                                                dataset: {},
+                                            },
+                                        ],
+                                    },
+                                ],
+                                format: {},
+                                widths: [],
+                                dataset: {},
+                            },
+                        ],
+                        levels: [{ listType: 'OL', format: {}, dataset: {} }],
+                        formatHolder: {
+                            segmentType: 'SelectionMarker',
+                            isSelected: false,
+                            format: {},
+                        },
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection is in table, under quote', () => {
+        const para1 = createParagraph();
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        const quote = createFormatContainer('blockquote');
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para1);
+        para1.segments.push(text1, marker, text2);
+        quote.blocks.push(table);
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [quote],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'BlockGroup',
+                        blockGroupType: 'FormatContainer',
+                        blocks: [
+                            {
+                                blockType: 'Table',
+                                rows: [
+                                    {
+                                        height: 0,
+                                        format: {},
+                                        cells: [
+                                            {
+                                                blockGroupType: 'TableCell',
+                                                blocks: [
+                                                    {
+                                                        blockType: 'Paragraph',
+                                                        segments: [text1],
+                                                        format: {},
+                                                    },
+                                                    {
+                                                        blockType: 'Paragraph',
+                                                        segments: [marker, text2],
+                                                        format: {},
+                                                    },
+                                                ],
+                                                format: {},
+                                                spanLeft: false,
+                                                spanAbove: false,
+                                                isHeader: false,
+                                                dataset: {},
+                                            },
+                                        ],
+                                    },
+                                ],
+                                format: {},
+                                widths: [],
+                                dataset: {},
+                            },
+                        ],
+                        format: {},
+                        tagName: 'blockquote',
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection across table 1', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para2);
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3, text4);
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, table],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        segments: [text1],
+                        format: {},
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        segments: [
+                            { segmentType: 'SelectionMarker', isSelected: true, format: {} },
+                            { segmentType: 'Br', format: {} },
+                        ],
+                        format: {},
+                    },
+                    {
+                        blockType: 'Table',
+                        rows: [
+                            {
+                                height: 0,
+                                format: {},
+                                cells: [
+                                    {
+                                        blockGroupType: 'TableCell',
+                                        blocks: [
+                                            {
+                                                blockType: 'Paragraph',
+                                                segments: [text4],
+                                                format: {},
+                                            },
+                                        ],
+                                        format: {},
+                                        spanLeft: false,
+                                        spanAbove: false,
+                                        isHeader: false,
+                                        dataset: {},
+                                    },
+                                ],
+                            },
+                        ],
+                        format: {},
+                        widths: [],
+                        dataset: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection across table 2', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para1);
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3, text4);
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [table, para2],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Table',
+                        rows: [
+                            {
+                                height: 0,
+                                format: {},
+                                cells: [
+                                    {
+                                        blockGroupType: 'TableCell',
+                                        blocks: [
+                                            {
+                                                blockType: 'Paragraph',
+                                                segments: [text1],
+                                                format: {},
+                                            },
+                                            {
+                                                blockType: 'Paragraph',
+                                                segments: [
+                                                    {
+                                                        segmentType: 'SelectionMarker',
+                                                        isSelected: true,
+                                                        format: {},
+                                                    },
+                                                    { segmentType: 'Br', format: {} },
+                                                ],
+                                                format: {},
+                                            },
+                                        ],
+                                        format: {},
+                                        spanLeft: false,
+                                        spanAbove: false,
+                                        isHeader: false,
+                                        dataset: {},
+                                    },
+                                ],
+                            },
+                        ],
+                        format: {},
+                        widths: [],
+                        dataset: {},
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        segments: [text4],
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+
+    it('selection cover table', () => {
+        const para1 = createParagraph();
+        const para2 = createParagraph();
+        const para3 = createParagraph();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const text3 = createText('test3');
+        const text4 = createText('test4');
+        const text5 = createText('test5');
+        const td = createTableCell();
+        const table = createTable(1);
+
+        table.rows[0].cells.push(td);
+        td.blocks.push(para2);
+        para1.segments.push(text1, text2);
+        para2.segments.push(text3);
+        para3.segments.push(text4, text5);
+
+        text2.isSelected = true;
+        text3.isSelected = true;
+        text4.isSelected = true;
+        td.isSelected = true;
+
+        runTest(
+            {
+                blockGroupType: 'Document',
+                blocks: [para1, table, para3],
+            },
+            false,
+            {
+                blockGroupType: 'Document',
+                blocks: [
+                    {
+                        blockType: 'Paragraph',
+                        segments: [text1],
+                        format: {},
+                    },
+                    {
+                        blockType: 'Paragraph',
+                        segments: [
+                            { segmentType: 'SelectionMarker', isSelected: true, format: {} },
+                            text5,
+                        ],
+                        format: {},
+                    },
+                ],
+            },
+            true,
+            {}
+        );
+    });
+});
diff --git a/packages/roosterjs-content-model-plugins/test/edit/utils/splitParagraphTest.ts b/packages/roosterjs-content-model-plugins/test/edit/utils/splitParagraphTest.ts
new file mode 100644
index 00000000000..f810ee29904
--- /dev/null
+++ b/packages/roosterjs-content-model-plugins/test/edit/utils/splitParagraphTest.ts
@@ -0,0 +1,99 @@
+import { ContentModelParagraph, InsertPoint } from 'roosterjs-content-model-types';
+import { splitParagraph } from '../../../lib/edit/utils/splitParagraph';
+import {
+    createBr,
+    createContentModelDocument,
+    createParagraph,
+    createSelectionMarker,
+    createText,
+} from 'roosterjs-content-model-dom';
+
+describe('splitParagraph', () => {
+    it('empty paragraph with selection marker and BR', () => {
+        const doc = createContentModelDocument();
+        const marker = createSelectionMarker({ fontFamily: 'Arial' });
+        const br = createBr();
+        const para = createParagraph(false, { direction: 'ltr' }, { fontSize: '10pt' });
+        const ip: InsertPoint = {
+            marker: marker,
+            paragraph: para,
+            path: [doc],
+        };
+
+        para.segments.push(marker, br);
+        doc.blocks.push(para);
+
+        const result = splitParagraph(ip);
+
+        const expectedResult: ContentModelParagraph = {
+            blockType: 'Paragraph',
+            segments: [marker, br],
+            format: { direction: 'ltr' },
+            segmentFormat: { fontSize: '10pt' },
+        };
+
+        expect(result).toEqual(expectedResult);
+        expect(ip).toEqual({
+            marker: marker,
+            paragraph: expectedResult,
+            path: [doc],
+        });
+        expect(doc).toEqual({
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'Paragraph',
+                    segments: [
+                        {
+                            segmentType: 'Br',
+                            format: { fontFamily: 'Arial' },
+                        },
+                    ],
+                    format: { direction: 'ltr' },
+                    segmentFormat: { fontSize: '10pt', fontFamily: 'Arial' },
+                },
+            ],
+        });
+    });
+
+    it('Paragraph with more segments', () => {
+        const doc = createContentModelDocument();
+        const marker = createSelectionMarker();
+        const text1 = createText('test1');
+        const text2 = createText('test2');
+        const para = createParagraph(false);
+        const ip: InsertPoint = {
+            marker: marker,
+            paragraph: para,
+            path: [doc],
+        };
+
+        para.segments.push(text1, marker, text2);
+        doc.blocks.push(para);
+
+        const result = splitParagraph(ip);
+
+        const expectedResult: ContentModelParagraph = {
+            blockType: 'Paragraph',
+            segments: [marker, text2],
+            format: {},
+        };
+
+        expect(result).toEqual(expectedResult);
+        expect(ip).toEqual({
+            marker: marker,
+            paragraph: expectedResult,
+            path: [doc],
+        });
+        expect(doc).toEqual({
+            blockGroupType: 'Document',
+            blocks: [
+                {
+                    blockType: 'Paragraph',
+                    segments: [text1],
+                    format: {},
+                },
+            ],
+        });
+    });
+});
diff --git a/packages/roosterjs-content-model-plugins/test/paste/ContentModelPastePluginTest.ts b/packages/roosterjs-content-model-plugins/test/paste/ContentModelPastePluginTest.ts
index e6db9e6eca4..c7a175d4093 100644
--- a/packages/roosterjs-content-model-plugins/test/paste/ContentModelPastePluginTest.ts
+++ b/packages/roosterjs-content-model-plugins/test/paste/ContentModelPastePluginTest.ts
@@ -58,7 +58,7 @@ describe('Content Model Paste Plugin Test', () => {
             plugin.initialize(editor);
             plugin.onPluginEvent(event);
 
-            expect(addParser.addParser).toHaveBeenCalledTimes(DEFAULT_TIMES_ADD_PARSER_CALLED + 4);
+            expect(addParser.addParser).toHaveBeenCalledTimes(DEFAULT_TIMES_ADD_PARSER_CALLED + 5);
             expect(setProcessor.setProcessor).toHaveBeenCalledTimes(1);
         });
 
diff --git a/packages/roosterjs-content-model-plugins/test/paste/processPastedContentFromWordDesktopTest.ts b/packages/roosterjs-content-model-plugins/test/paste/processPastedContentFromWordDesktopTest.ts
index f14038afee5..07f17b4039d 100644
--- a/packages/roosterjs-content-model-plugins/test/paste/processPastedContentFromWordDesktopTest.ts
+++ b/packages/roosterjs-content-model-plugins/test/paste/processPastedContentFromWordDesktopTest.ts
@@ -144,7 +144,7 @@ describe('processPastedContentFromWordDesktopTest', () => {
         runTest(source, { blockGroupType: 'Document', blocks: [] }, true);
     });
 
-    it('Dont remove Line height less than default', () => {
+    it('adjust Line height less than default', () => {
         let source = '<p style="line-height:102%">Test</p>';
         runTest(
             source,
@@ -154,7 +154,7 @@ describe('processPastedContentFromWordDesktopTest', () => {
                     {
                         segments: [{ text: 'Test', segmentType: 'Text', format: {} }],
                         blockType: 'Paragraph',
-                        format: { marginTop: '1em', marginBottom: '1em', lineHeight: '102%' },
+                        format: { marginTop: '1em', marginBottom: '1em', lineHeight: '1.224' },
                         decorator: { tagName: 'p', format: {} },
                     },
                 ],
@@ -211,7 +211,7 @@ describe('processPastedContentFromWordDesktopTest', () => {
         });
     });
 
-    it('Remove Line height, percentage greater than default', () => {
+    it('Adjust Line height, percentage greater than default 2', () => {
         let source = '<p style="line-height:122%">Test</p>';
         runTest(source, {
             blockGroupType: 'Document',
@@ -222,7 +222,7 @@ describe('processPastedContentFromWordDesktopTest', () => {
                         format: {},
                         tagName: 'p',
                     },
-                    format: { marginTop: '1em', marginBottom: '1em', lineHeight: '122%' },
+                    format: { marginTop: '1em', marginBottom: '1em', lineHeight: '1.464' },
                     segments: [
                         {
                             segmentType: 'Text',
diff --git a/packages/roosterjs-content-model-types/lib/editor/IEditor.ts b/packages/roosterjs-content-model-types/lib/editor/IEditor.ts
index 2ff5e28bad0..39c5e08e7ae 100644
--- a/packages/roosterjs-content-model-types/lib/editor/IEditor.ts
+++ b/packages/roosterjs-content-model-types/lib/editor/IEditor.ts
@@ -18,6 +18,7 @@ import type { DarkColorHandler } from '../context/DarkColorHandler';
 import type { TrustedHTMLHandler } from '../parameter/TrustedHTMLHandler';
 import type { Rect } from '../parameter/Rect';
 import type { EntityState } from '../parameter/FormatContentModelContext';
+import type { ExperimentalFeature } from './ExperimentalFeature';
 
 /**
  * An interface of Editor, built on top of Content Model
@@ -227,4 +228,10 @@ export interface IEditor {
      * @param announceData Data to announce
      */
     announce(announceData: AnnounceData): void;
+
+    /**
+     * Check if a given feature is enabled
+     * @param featureName The name of feature to check
+     */
+    isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean;
 }