private final int deleteSelection(final KeyStroke[] keyStrokes,
			final boolean allowIncomplete, final KeyStroke[][] deletedKeyStrokes) {
		// Get the current selection.
		Point selection = text.getSelection();
		int start = selection.x;
		int end = selection.y;

		/*
		 * Using the key sequence format method, discover the point at which
		 * adding key strokes passes or equals the start of the selection. In
		 * other words, find the first stroke that is part of the selection.
		 * Keep track of the text range under which the stroke appears (i.e.,
		 * startTextIndex->string.length() is the first selected stroke).
		 */
		String string = new String();
		List currentStrokes = new ArrayList();
		int startTextIndex = 0; // keeps track of the start of the stroke
		final int keyStrokesLength = keyStrokes.length;
		int i;
		for (i = 0; (i < keyStrokesLength) && (string.length() < start); i++) {
			startTextIndex = string.length();
			currentStrokes.add(keyStrokes[i]);
			string = KeySequence.getInstance(currentStrokes).format();
		}

		/*
		 * If string.length() == start, then the cursor is positioned between
		 * strokes (i.e., selection is outside of a stroke).
		 */
		int startStrokeIndex;
		if (string.length() == start) {
			startStrokeIndex = currentStrokes.size();
		} else {
			startStrokeIndex = currentStrokes.size() - 1;
		}

		/*
		 * Check to see if the cursor is only positioned, rather than actually
		 * selecting something. We only need to compute the end if there is a
		 * selection.
		 */
		int endStrokeIndex;
		if (start == end) {
			// return the current keystrokes, nothing has to be deleted
			deletedKeyStrokes[0] = keyStrokes;
			return startStrokeIndex;
		}

		for (; (i < keyStrokesLength) && (string.length() < end); i++) {
			currentStrokes.add(keyStrokes[i]);
			string = KeySequence.getInstance(currentStrokes).format();
		}
		endStrokeIndex = currentStrokes.size() - 1;
		if (endStrokeIndex < 0) {
			endStrokeIndex = 0;
		}

		/*
		 * Remove the strokes that are touched by the selection. Keep track of
		 * the first stroke removed.
		 */
		final int newLength = keyStrokesLength
				- (endStrokeIndex - startStrokeIndex + 1);
		deletedKeyStrokes[0] = new KeyStroke[newLength];
		final KeyStroke startStroke = keyStrokes[startStrokeIndex];
		KeyStroke keyStrokeResult[] = new KeyStroke[newLength];
		System.arraycopy(keyStrokes, 0, keyStrokeResult, 0, startStrokeIndex);
		System.arraycopy(keyStrokes, endStrokeIndex + 1, keyStrokeResult,
				startStrokeIndex, keyStrokesLength - endStrokeIndex - 1);
		System.arraycopy(keyStrokeResult, 0, deletedKeyStrokes[0], 0, newLength);

		/*
		 * Allow the first stroke removed to be replaced by an incomplete
		 * stroke.
		 */
		if (allowIncomplete) {
			final int modifierKeys = startStroke.getModifierKeys();
			KeyStroke incompleteStroke = KeyStroke.getInstance(modifierKeys,
					KeyStroke.NO_KEY);
			int incompleteStrokeLength = incompleteStroke.format().length();
			if ((startTextIndex + incompleteStrokeLength) <= start) {
				final KeyStroke[] added = new KeyStroke[newLength + 1];
				System.arraycopy(deletedKeyStrokes[0], 0, added, 0,
						startStrokeIndex);
				added[startStrokeIndex] = incompleteStroke;
				System.arraycopy(deletedKeyStrokes[0], startStrokeIndex, added,
						startStrokeIndex + 1, newLength - startStrokeIndex);
				deletedKeyStrokes[0] = added;
			}
		}

		return startStrokeIndex;
	}