public void add(int key, TreeNode lChild, TreeNode rChild) {
		int keyIndex = indexForKey(key);
		if (keyIndex == -1) {
			keyIndex = addKeySorted(key);

			if (lChild != null) {
				if (keyIndex < children.size())
					children.remove(keyIndex);
				children.add(keyIndex, lChild);
			}

			children.add(keyIndex + 1, rChild);
			size++;

			if (size > indexOrder) {
				int mid = size / 2;
				int parentKey = this.keyAtIndex(mid);

				IndexNode newIndexNode = new IndexNode(keyList.subList(mid + 1,
						size), children.subList(mid + 1, children.size()));

				for (int i = size - 1; i >= mid; i--) {
					keyList.remove(i);
					children.get(i + 1).parent = newIndexNode;
					children.remove(i + 1);
					size--;
				}

				newIndexNode.nextSibling = this.nextSibling;
				if (this.nextSibling != null)
					this.nextSibling.prevSibling = newIndexNode;

				this.nextSibling = newIndexNode;
				newIndexNode.prevSibling = this;
				newIndexNode.parent = this.parent;

				if (this.parent != null) {
					this.parent.add(parentKey, this, newIndexNode);

				} else {
					IndexNode newRoot = new IndexNode();
					this.parent = newIndexNode.parent = newRoot;
					newRoot.add(parentKey, this, newIndexNode);

					// An issue here for lock-free operation
					if (listener != null)
						listener.rootChanged(newRoot);
				}
			}
		}
	}