src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts/PieceTreeBase/insert
class PieceTreeBase:	public insert(offset: number, value: string, eolNormalized: boolean = false): void {
		this._EOLNormalized = this._EOLNormalized && eolNormalized;
		this._lastVisitedLine.lineNumber = 0;
		this._lastVisitedLine.value = '';

		if (this.root !== SENTINEL) {
			const { node, remainder, nodeStartOffset } = this.nodeAt(offset);
			const piece = node.piece;
			const bufferIndex = piece.bufferIndex;
			const insertPosInBuffer = this.positionInBuffer(node, remainder);
			if (node.piece.bufferIndex === 0 &&
				piece.end.line === this._lastChangeBufferPos.line &&
				piece.end.column === this._lastChangeBufferPos.column &&
				(nodeStartOffset + piece.length === offset) &&
				value.length < AverageBufferSize
			) {
				// changed buffer
				this.appendToNode(node, value);
				this.computeBufferMetadata();
				return;
			}

			if (nodeStartOffset === offset) {
				this.insertContentToNodeLeft(value, node);
				this._searchCache.validate(offset);
			} else if (nodeStartOffset + node.piece.length > offset) {
				// we are inserting into the middle of a node.
				const nodesToDel: TreeNode[] = [];
				let newRightPiece = new Piece(
					piece.bufferIndex,
					insertPosInBuffer,
					piece.end,
					this.getLineFeedCnt(piece.bufferIndex, insertPosInBuffer, piece.end),
					this.offsetInBuffer(bufferIndex, piece.end) - this.offsetInBuffer(bufferIndex, insertPosInBuffer)
				);

				if (this.shouldCheckCRLF() && this.endWithCR(value)) {
					const headOfRight = this.nodeCharCodeAt(node, remainder);

					if (headOfRight === 10 /** \n */) {
						const newStart: BufferCursor = { line: newRightPiece.start.line + 1, column: 0 };
						newRightPiece = new Piece(
							newRightPiece.bufferIndex,
							newStart,
							newRightPiece.end,
							this.getLineFeedCnt(newRightPiece.bufferIndex, newStart, newRightPiece.end),
							newRightPiece.length - 1
						);

						value += '\n';
					}
				}

				// reuse node for content before insertion point.
				if (this.shouldCheckCRLF() && this.startWithLF(value)) {
					const tailOfLeft = this.nodeCharCodeAt(node, remainder - 1);
					if (tailOfLeft === 13 /** \r */) {
						const previousPos = this.positionInBuffer(node, remainder - 1);
						this.deleteNodeTail(node, previousPos);
						value = '\r' + value;

						if (node.piece.length === 0) {
							nodesToDel.push(node);
						}
					} else {
						this.deleteNodeTail(node, insertPosInBuffer);
					}
				} else {
					this.deleteNodeTail(node, insertPosInBuffer);
				}

				const newPieces = this.createNewPieces(value);
				if (newRightPiece.length > 0) {
					this.rbInsertRight(node, newRightPiece);
				}

				let tmpNode = node;
				for (let k = 0; k < newPieces.length; k++) {
					tmpNode = this.rbInsertRight(tmpNode, newPieces[k]);
				}
				this.deleteNodes(nodesToDel);
			} else {
				this.insertContentToNodeRight(value, node);
			}
		} else {
			// insert new node
			const pieces = this.createNewPieces(value);
			let node = this.rbInsertLeft(null, pieces[0]);

			for (let k = 1; k < pieces.length; k++) {
				node = this.rbInsertRight(node, pieces[k]);
			}
		}

		// todo, this is too brutal. Total line feed count should be updated the same way as lf_left.
		this.computeBufferMetadata();
	}