function cleanupStylesWhenDeleting() {
			var doc = editor.getDoc(), dom = editor.dom, selection = editor.selection;
			var MutationObserver = window.MutationObserver, olderWebKit, dragStartRng;

			// Add mini polyfill for older WebKits
			// TODO: Remove this when old Safari versions gets updated
			if (!MutationObserver) {
				olderWebKit = true;

				MutationObserver = function() {
					var records = [], target;

					function nodeInsert(e) {
						var target = e.relatedNode || e.target;
						records.push({target: target, addedNodes: [target]});
					}

					function attrModified(e) {
						var target = e.relatedNode || e.target;
						records.push({target: target, attributeName: e.attrName});
					}

					this.observe = function(node) {
						target = node;
						target.addEventListener('DOMSubtreeModified', nodeInsert, false);
						target.addEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
						target.addEventListener('DOMNodeInserted', nodeInsert, false);
						target.addEventListener('DOMAttrModified', attrModified, false);
					};

					this.disconnect = function() {
						target.removeEventListener('DOMSubtreeModified', nodeInsert, false);
						target.removeEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
						target.removeEventListener('DOMNodeInserted', nodeInsert, false);
						target.removeEventListener('DOMAttrModified', attrModified, false);
					};

					this.takeRecords = function() {
						return records;
					};
				};
			}

			function isTrailingBr(node) {
				var blockElements = dom.schema.getBlockElements(), rootNode = editor.getBody();

				if (node.nodeName != 'BR') {
					return false;
				}

				for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
					if (node.nextSibling) {
						return false;
					}
				}

				return true;
			}

			function isSiblingsIgnoreWhiteSpace(node1, node2) {
				var node;

				for (node = node1.nextSibling; node && node != node2; node = node.nextSibling) {
					if (node.nodeType == 3 && $.trim(node.data).length === 0) {
						continue;
					}

					if (node !== node2) {
						return false;
					}
				}

				return node === node2;
			}

			function findCaretNode(node, forward, startNode) {
				var walker, current, nonEmptyElements;

				nonEmptyElements = dom.schema.getNonEmptyElements();

				walker = new TreeWalker(startNode || node, node);

				while ((current = walker[forward ? 'next' : 'prev']())) {
					if (nonEmptyElements[current.nodeName] && !isTrailingBr(current)) {
						return current;
					}

					if (current.nodeType == 3 && current.data.length > 0) {
						return current;
					}
				}
			}

			function deleteRangeBetweenTextBlocks(rng) {
				var startBlock, endBlock, caretNodeBefore, caretNodeAfter, textBlockElements;

				if (rng.collapsed) {
					return;
				}

				startBlock = dom.getParent(RangeUtils.getNode(rng.startContainer, rng.startOffset), dom.isBlock);
				endBlock = dom.getParent(RangeUtils.getNode(rng.endContainer, rng.endOffset), dom.isBlock);
				textBlockElements = editor.schema.getTextBlockElements();

				if (startBlock == endBlock) {
					return;
				}

				if (!textBlockElements[startBlock.nodeName] || !textBlockElements[endBlock.nodeName]) {
					return;
				}

				if (dom.getContentEditable(startBlock) === "false" || dom.getContentEditable(endBlock) === "false") {
					return;
				}

				rng.deleteContents();

				caretNodeBefore = findCaretNode(startBlock, false);
				caretNodeAfter = findCaretNode(endBlock, true);

				if (!dom.isEmpty(endBlock)) {
					$(startBlock).append(endBlock.childNodes);
				}

				$(endBlock).remove();

				if (caretNodeBefore) {
					if (caretNodeBefore.nodeType == 1) {
						if (caretNodeBefore.nodeName == "BR") {
							rng.setStartBefore(caretNodeBefore);
							rng.setEndBefore(caretNodeBefore);
						} else {
							rng.setStartAfter(caretNodeBefore);
							rng.setEndAfter(caretNodeBefore);
						}
					} else {
						rng.setStart(caretNodeBefore, caretNodeBefore.data.length);
						rng.setEnd(caretNodeBefore, caretNodeBefore.data.length);
					}
				} else if (caretNodeAfter) {
					if (caretNodeAfter.nodeType == 1) {
						rng.setStartBefore(caretNodeAfter);
						rng.setEndBefore(caretNodeAfter);
					} else {
						rng.setStart(caretNodeAfter, 0);
						rng.setEnd(caretNodeAfter, 0);
					}
				}

				selection.setRng(rng);

				return true;
			}

			function expandBetweenBlocks(rng, isForward) {
				var caretNode, targetCaretNode, textBlock, targetTextBlock, container, offset;

				if (!rng.collapsed) {
					return rng;
				}

				container = rng.startContainer;
				offset = rng.startOffset;

				if (container.nodeType == 3) {
					if (isForward) {
						if (offset < container.data.length) {
							return rng;
						}
					} else {
						if (offset > 0) {
							return rng;
						}
					}
				}

				caretNode = RangeUtils.getNode(rng.startContainer, rng.startOffset);
				textBlock = dom.getParent(caretNode, dom.isBlock);
				targetCaretNode = findCaretNode(editor.getBody(), isForward, caretNode);
				targetTextBlock = dom.getParent(targetCaretNode, dom.isBlock);

				if (!caretNode || !targetCaretNode) {
					return rng;
				}

				if (targetTextBlock && textBlock != targetTextBlock) {
					if (!isForward) {
						if (!isSiblingsIgnoreWhiteSpace(targetTextBlock, textBlock)) {
							return rng;
						}

						if (targetCaretNode.nodeType == 1) {
							if (targetCaretNode.nodeName == "BR") {
								rng.setStartBefore(targetCaretNode);
							} else {
								rng.setStartAfter(targetCaretNode);
							}
						} else {
							rng.setStart(targetCaretNode, targetCaretNode.data.length);
						}

						if (caretNode.nodeType == 1) {
							rng.setEnd(caretNode, 0);
						} else {
							rng.setEndBefore(caretNode);
						}
					} else {
						if (!isSiblingsIgnoreWhiteSpace(textBlock, targetTextBlock)) {
							return rng;
						}

						if (caretNode.nodeType == 1) {
							if (caretNode.nodeName == "BR") {
								rng.setStartBefore(caretNode);
							} else {
								rng.setStartAfter(caretNode);
							}
						} else {
							rng.setStart(caretNode, caretNode.data.length);
						}

						if (targetCaretNode.nodeType == 1) {
							rng.setEnd(targetCaretNode, 0);
						} else {
							rng.setEndBefore(targetCaretNode);
						}
					}
				}

				return rng;
			}

			function handleTextBlockMergeDelete(isForward) {
				var rng = selection.getRng();

				rng = expandBetweenBlocks(rng, isForward);

				if (deleteRangeBetweenTextBlocks(rng)) {
					return true;
				}
			}

			/**
			 * This retains the formatting if the last character is to be deleted.
			 *
			 * Backspace on this: <p><b><i>a|</i></b></p> would become <p>|</p> in WebKit.
			 * With this patch: <p><b><i>|<br></i></b></p>
			 */
			function handleLastBlockCharacterDelete(isForward, rng) {
				var path, blockElm, newBlockElm, clonedBlockElm, sibling,
					container, offset, br, currentFormatNodes;

				function cloneTextBlockWithFormats(blockElm, node) {
					currentFormatNodes = $(node).parents().filter(function(idx, node) {
						return !!editor.schema.getTextInlineElements()[node.nodeName];
					});

					newBlockElm = blockElm.cloneNode(false);

					currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) {
						formatNode = formatNode.cloneNode(false);

						if (newBlockElm.hasChildNodes()) {
							formatNode.appendChild(newBlockElm.firstChild);
							newBlockElm.appendChild(formatNode);
						} else {
							newBlockElm.appendChild(formatNode);
						}

						newBlockElm.appendChild(formatNode);

						return formatNode;
					});

					if (currentFormatNodes.length) {
						br = dom.create('br');
						currentFormatNodes[0].appendChild(br);
						dom.replace(newBlockElm, blockElm);

						rng.setStartBefore(br);
						rng.setEndBefore(br);
						editor.selection.setRng(rng);

						return br;
					}

					return null;
				}

				function isTextBlock(node) {
					return node && editor.schema.getTextBlockElements()[node.tagName];
				}

				if (!rng.collapsed) {
					return;
				}

				container = rng.startContainer;
				offset = rng.startOffset;
				blockElm = dom.getParent(container, dom.isBlock);
				if (!isTextBlock(blockElm)) {
					return;
				}

				if (container.nodeType == 1) {
					container = container.childNodes[offset];
					if (container && container.tagName != 'BR') {
						return;
					}

					if (isForward) {
						sibling = blockElm.nextSibling;
					} else {
						sibling = blockElm.previousSibling;
					}

					if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) {
						if (cloneTextBlockWithFormats(blockElm, container)) {
							dom.remove(sibling);
							return true;
						}
					}
				} else if (container.nodeType == 3) {
					path = NodePath.create(blockElm, container);
					clonedBlockElm = blockElm.cloneNode(true);
					container = NodePath.resolve(clonedBlockElm, path);

					if (isForward) {
						if (offset >= container.data.length) {
							return;
						}

						container.deleteData(offset, 1);
					} else {
						if (offset <= 0) {
							return;
						}

						container.deleteData(offset - 1, 1);
					}

					if (dom.isEmpty(clonedBlockElm)) {
						return cloneTextBlockWithFormats(blockElm, container);
					}
				}
			}

			function customDelete(isForward) {
				var mutationObserver, rng, caretElement;

				if (handleTextBlockMergeDelete(isForward)) {
					return;
				}

				Tools.each(editor.getBody().getElementsByTagName('*'), function(elm) {
					// Mark existing spans
					if (elm.tagName == 'SPAN') {
						elm.setAttribute('mce-data-marked', 1);
					}

					// Make sure all elements has a data-mce-style attribute
					if (!elm.hasAttribute('data-mce-style') && elm.hasAttribute('style')) {
						editor.dom.setAttrib(elm, 'style', editor.dom.getAttrib(elm, 'style'));
					}
				});

				// Observe added nodes and style attribute changes
				mutationObserver = new MutationObserver(function() {});
				mutationObserver.observe(editor.getDoc(), {
					childList: true,
					attributes: true,
					subtree: true,
					attributeFilter: ['style']
				});

				editor.getDoc().execCommand(isForward ? 'ForwardDelete' : 'Delete', false, null);

				rng = editor.selection.getRng();
				caretElement = rng.startContainer.parentNode;

				Tools.each(mutationObserver.takeRecords(), function(record) {
					if (!dom.isChildOf(record.target, editor.getBody())) {
						return;
					}

					// Restore style attribute to previous value
					if (record.attributeName == "style") {
						var oldValue = record.target.getAttribute('data-mce-style');

						if (oldValue) {
							record.target.setAttribute("style", oldValue);
						} else {
							record.target.removeAttribute("style");
						}
					}

					// Remove all spans that aren't marked and retain selection
					Tools.each(record.addedNodes, function(node) {
						if (node.nodeName == "SPAN" && !node.getAttribute('mce-data-marked')) {
							var offset, container;

							if (node == caretElement) {
								offset = rng.startOffset;
								container = node.firstChild;
							}

							dom.remove(node, true);

							if (container) {
								rng.setStart(container, offset);
								rng.setEnd(container, offset);
								editor.selection.setRng(rng);
							}
						}
					});
				});

				mutationObserver.disconnect();

				// Remove any left over marks
				Tools.each(editor.dom.select('span[mce-data-marked]'), function(span) {
					span.removeAttribute('mce-data-marked');
				});
			}

			editor.on('keydown', function(e) {
				var isForward = e.keyCode == DELETE, isMetaOrCtrl = e.ctrlKey || e.metaKey;

				if (!isDefaultPrevented(e) && (isForward || e.keyCode == BACKSPACE)) {
					var rng = editor.selection.getRng(), container = rng.startContainer, offset = rng.startOffset;

					// Shift+Delete is cut
					if (isForward && e.shiftKey) {
						return;
					}

					if (handleLastBlockCharacterDelete(isForward, rng)) {
						e.preventDefault();
						return;
					}

					// Ignore non meta delete in the where there is text before/after the caret
					if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) {
						if (isForward ? offset < container.data.length : offset > 0) {
							return;
						}
					}

					e.preventDefault();

					if (isMetaOrCtrl) {
						editor.selection.getSel().modify("extend", isForward ? "forward" : "backward", e.metaKey ? "lineboundary" : "word");
					}

					customDelete(isForward);
				}
			});

			// Handle case where text is deleted by typing over
			editor.on('keypress', function(e) {
				if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) {
					var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText;

					rng = editor.selection.getRng();
					charText = String.fromCharCode(e.charCode);
					e.preventDefault();

					// Keep track of current format nodes
					currentFormatNodes = $(rng.startContainer).parents().filter(function(idx, node) {
						return !!editor.schema.getTextInlineElements()[node.nodeName];
					});

					customDelete(true);

					// Check if the browser removed them
					currentFormatNodes = currentFormatNodes.filter(function(idx, node) {
						return !$.contains(editor.getBody(), node);
					});

					// Then re-add them
					if (currentFormatNodes.length) {
						fragmentNode = dom.createFragment();

						currentFormatNodes.each(function(idx, formatNode) {
							formatNode = formatNode.cloneNode(false);

							if (fragmentNode.hasChildNodes()) {
								formatNode.appendChild(fragmentNode.firstChild);
								fragmentNode.appendChild(formatNode);
							} else {
								caretNode = formatNode;
								fragmentNode.appendChild(formatNode);
							}

							fragmentNode.appendChild(formatNode);
						});

						caretNode.appendChild(editor.getDoc().createTextNode(charText));

						// Prevent edge case where older WebKit would add an extra BR element
						blockParent = dom.getParent(rng.startContainer, dom.isBlock);
						if (dom.isEmpty(blockParent)) {
							$(blockParent).empty().append(fragmentNode);
						} else {
							rng.insertNode(fragmentNode);
						}

						rng.setStart(caretNode.firstChild, 1);
						rng.setEnd(caretNode.firstChild, 1);
						editor.selection.setRng(rng);
					} else {
						editor.selection.setContent(charText);
					}
				}
			});

			editor.addCommand('Delete', function() {
				customDelete();
			});

			editor.addCommand('ForwardDelete', function() {
				customDelete(true);
			});

			// Older WebKits doesn't properly handle the clipboard so we can't add the rest
			if (olderWebKit) {
				return;
			}

			editor.on('dragstart', function(e) {
				dragStartRng = selection.getRng();
				setMceInternalContent(e);
			});

			editor.on('drop', function(e) {
				if (!isDefaultPrevented(e)) {
					var internalContent = getMceInternalContent(e);

					if (internalContent) {
						e.preventDefault();

						// Safari has a weird issue where drag/dropping images sometimes
						// produces a green plus icon. When this happens the caretRangeFromPoint
						// will return "null" even though the x, y coordinate is correct.
						// But if we detach the insert from the drop event we will get a proper range
						Delay.setEditorTimeout(editor, function() {
							var pointRng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, doc);

							if (dragStartRng) {
								selection.setRng(dragStartRng);
								dragStartRng = null;
							}

							customDelete();
							selection.setRng(pointRng);
							insertClipboardContents(internalContent.html);
						});
					}
				}
			});

			editor.on('cut', function(e) {
				if (!isDefaultPrevented(e) && e.clipboardData && !editor.selection.isCollapsed()) {
					e.preventDefault();
					e.clipboardData.clearData();
					e.clipboardData.setData('text/html', editor.selection.getContent());
					e.clipboardData.setData('text/plain', editor.selection.getContent({format: 'text'}));

					// Needed delay for https://code.google.com/p/chromium/issues/detail?id=363288#c3
					// Nested delete/forwardDelete not allowed on execCommand("cut")
					// This is ugly but not sure how to work around it otherwise
					Delay.setEditorTimeout(editor, function() {
						customDelete(true);
					});
				}
			});
		}
Fixes a WebKit bug when deleting contents using backspace or delete key.
WebKit will produce a span element if you delete across two block elements.

Example:
<h1>a</h1><p>|b</p>

Will produce this on backspace:
<h1>a<span style="<all runtime styles>">b</span></p>

This fixes the backspace to produce:
<h1>a|b</p>

See bug: https://bugs.webkit.org/show_bug.cgi?id=45784

This fixes the following delete scenarios:
 1. Delete by pressing backspace key.
 2. Delete by pressing delete key.
 3. Delete by pressing backspace key with ctrl/cmd (Word delete).
 4. Delete by pressing delete key with ctrl/cmd (Word delete).
 5. Delete by drag/dropping contents inside the editor.
 6. Delete by using Cut Ctrl+X/Cmd+X.
 7. Delete by selecting contents and writing a character.

This code is a ugly hack since writing full custom delete logic for just this bug
fix seemed like a huge task. I hope we can remove this before the year 2030.