private void removeStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
    NodeImpl next = (NodeImpl) this.context.getNextNode();
    if (next != null) {
      short nodeType = next.getNodeType();
      if (nodeType != Node.ELEMENT_NODE) {
        IStructuredDocumentRegion flatNode = next.getStructuredDocumentRegion();
        if (flatNode == oldStructuredDocumentRegion) {
          removeNode(next);
          return;
        }
        if (nodeType != Node.TEXT_NODE) {
          throw new StructuredDocumentRegionManagementException();
        }
        if (flatNode == null) {
          // this is the case for empty Text
          // remove and continue
          removeNode(next);
          removeStructuredDocumentRegion(oldStructuredDocumentRegion);
          return;
        }
        TextImpl text = (TextImpl) next;
        boolean isShared = text.isSharingStructuredDocumentRegion(oldStructuredDocumentRegion);
        if (isShared) {
          // make sure there is next Text node sharing this
          TextImpl nextText = (TextImpl) this.context.findNextText();
          if (nextText == null || !nextText.hasStructuredDocumentRegion(oldStructuredDocumentRegion)) {
            isShared = false;
          }
        }
        oldStructuredDocumentRegion = text.removeStructuredDocumentRegion(oldStructuredDocumentRegion);
        if (oldStructuredDocumentRegion == null) {
          throw new StructuredDocumentRegionManagementException();
        }
        if (text.getStructuredDocumentRegion() == null) {
          // this is the case partial IStructuredDocumentRegion is
          // removed
          removeNode(text);
        }
        else {
          // notify the change
          text.notifyValueChanged();
        }
        // if shared, continue to remove IStructuredDocumentRegion
        // from them
        if (isShared)
          removeStructuredDocumentRegion(oldStructuredDocumentRegion);
        return;
      }
      ElementImpl element = (ElementImpl) next;
      if (element.hasStartTag()) {
        IStructuredDocumentRegion flatNode = element.getStartStructuredDocumentRegion();
        if (flatNode != oldStructuredDocumentRegion) {
          throw new StructuredDocumentRegionManagementException();
        }
        if (element.hasEndTag() || element.hasChildNodes()) {
          element.setStartStructuredDocumentRegion(null);
          removeStartTag(element);
        }
        else {
          removeNode(element);
        }
      }
      else {
        Node child = element.getFirstChild();
        if (child != null) {
          this.context.setNextNode(child);
          removeStructuredDocumentRegion(oldStructuredDocumentRegion);
          return;
        }
        if (!element.hasEndTag()) {
          // implicit element
          removeNode(element);
          removeStructuredDocumentRegion(oldStructuredDocumentRegion);
          return;
        }
        IStructuredDocumentRegion flatNode = element.getEndStructuredDocumentRegion();
        if (flatNode != oldStructuredDocumentRegion) {
          throw new StructuredDocumentRegionManagementException();
        }
        removeNode(element);
      }
      return;
    }
    Node parent = this.context.getParentNode();
    if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE) {
      throw new StructuredDocumentRegionManagementException();
    }
    ElementImpl end = (ElementImpl) parent;
    if (end.hasEndTag()) {
      IStructuredDocumentRegion flatNode = end.getEndStructuredDocumentRegion();
      if (flatNode != oldStructuredDocumentRegion) {
        throw new StructuredDocumentRegionManagementException();
      }
      if (!end.hasStartTag() && !end.hasChildNodes()) {
        this.context.setNextNode(end);