public function insertElement( $preposition, $refElement, Element $element, $void,
		$sourceStart, $sourceLength
	) {
		list( $parent, $refNode ) = $this->interpretPlacement( $preposition, $refElement );
		$children =& $parent->children;
		$lastChildIndex = count( $children ) - 1;
		$lastChild = $lastChildIndex >= 0 ? $children[$lastChildIndex] : null;

		if ( $element->userData ) {
			// This element has already been inserted, this is a reparenting operation
			$self = $element->userData;
			$oldParent = $this->nodes[$self->parentId];
			$oldChildren =& $oldParent->children;
			$oldChildIndex = array_search( $self, $oldChildren, true );
			if ( $oldChildIndex === false ) {
				throw new SerializerError( "cannot find node to reparent: " .
					$element->getDebugTag() );
			}
			// Remove from the old parent, update parent pointer
			$oldChildren[$oldChildIndex] = '';
			$self->parentId = $parent->id;
		} else {
			// Inserting an element which has not been seen before
			$id = $element->uid;
			$self = new SerializerNode( $id, $parent->id, $element->namespace,
				$element->name, $element->attrs, $void );
			$this->nodes[$id] = $element->userData = $self;
		}

		if ( $preposition === TreeBuilder::BEFORE ) {
			// Insert before element
			if ( $lastChild !== $refNode ) {
				$refIndex = array_search( $refNode, $children, true );
				throw new SerializerError( "invalid insert position $refIndex/$lastChildIndex" );
			}
			$children[$lastChildIndex] = $self;
			$children[$lastChildIndex + 1] = $refNode;
		} else {
			// Append to the list of children
			$children[] = $self;
		}
	}