docs: public I_CmsXmlContentValue addValue(CmsObject cms, String path, Locale locale, int index)
      throws CmsIllegalArgumentException, CmsRuntimeException {
  
          // get the schema type of the requested path
          I_CmsXmlSchemaType type = m_contentDefinition.getSchemaType(path);
          if (type == null) {
              throw new CmsIllegalArgumentException(
                  Messages.get().container(Messages.ERR_XMLCONTENT_UNKNOWN_ELEM_PATH_SCHEMA_1, path));
          }
  
          Element parentElement;
          String elementName;
          CmsXmlContentDefinition contentDefinition;
          if (CmsXmlUtils.isDeepXpath(path)) {
              // this is a nested content definition, so the parent element must be in the bookmarks
              String parentPath = CmsXmlUtils.createXpath(CmsXmlUtils.removeLastXpathElement(path), 1);
              Object o = getBookmark(parentPath, locale);
              if (o == null) {
                  throw new CmsIllegalArgumentException(
                      Messages.get().container(Messages.ERR_XMLCONTENT_UNKNOWN_ELEM_PATH_1, path));
              }
              CmsXmlNestedContentDefinition parentValue = (CmsXmlNestedContentDefinition)o;
              parentElement = parentValue.getElement();
              elementName = CmsXmlUtils.getLastXpathElement(path);
              contentDefinition = parentValue.getNestedContentDefinition();
          } else {
              // the parent element is the locale element
              parentElement = getLocaleNode(locale);
              elementName = CmsXmlUtils.removeXpathIndex(path);
              contentDefinition = m_contentDefinition;
          }
  
          int insertIndex;
  
          if (contentDefinition.getChoiceMaxOccurs() > 0) {
              // for a choice sequence with maxOccurs we do not check the index position, we rather check if maxOccurs has already been hit
              // additionally we ensure that the insert index is not too big
              List<?> choiceSiblings = parentElement.content();
              int numSiblings = choiceSiblings != null ? choiceSiblings.size() : 0;
  
              if ((numSiblings >= contentDefinition.getChoiceMaxOccurs()) || (index > numSiblings)) {
                  throw new CmsRuntimeException(
                      Messages.get().container(
                          Messages.ERR_XMLCONTENT_ADD_ELEM_INVALID_IDX_CHOICE_3,
                          new Integer(index),
                          elementName,
                          parentElement.getUniquePath()));
              }
              insertIndex = index;
  
          } else {
              // read the XML siblings from the parent node
              List<Element> siblings = CmsXmlGenericWrapper.elements(parentElement, elementName);
  
              if (siblings.size() > 0) {
                  // we want to add an element to a sequence, and there are elements already of the same type
  
                  if (siblings.size() >= type.getMaxOccurs()) {
                      // must not allow adding an element if max occurs would be violated
                      throw new CmsRuntimeException(
                          Messages.get().container(
                              Messages.ERR_XMLCONTENT_ELEM_MAXOCCURS_2,
                              elementName,
                              new Integer(type.getMaxOccurs())));
                  }
  
                  if (index > siblings.size()) {
                      // index position behind last element of the list
                      throw new CmsRuntimeException(
                          Messages.get().container(
                              Messages.ERR_XMLCONTENT_ADD_ELEM_INVALID_IDX_3,
                              new Integer(index),
                              new Integer(siblings.size())));
                  }
  
                  // check for offset required to append beyond last position
                  int offset = (index == siblings.size()) ? 1 : 0;
                  // get the element from the parent at the selected position
                  Element sibling = siblings.get(index - offset);
                  // check position of the node in the parent node content
                  insertIndex = sibling.getParent().content().indexOf(sibling) + offset;
              } else {
                  // we want to add an element to a sequence, but there are no elements of the same type yet
  
                  if (index > 0) {
                      // since the element does not occur, index must be 0
                      throw new CmsRuntimeException(
                          Messages.get().container(
                              Messages.ERR_XMLCONTENT_ADD_ELEM_INVALID_IDX_2,
                              new Integer(index),
                              elementName));
                  }
  
                  // check where in the type sequence the type should appear
                  int typeIndex = contentDefinition.getTypeSequence().indexOf(type);
                  if (typeIndex == 0) {
                      // this is the first type, so we just add at the very first position
                      insertIndex = 0;
                  } else {
  
                      // create a list of all element names that should occur before the selected type
                      List<String> previousTypeNames = new ArrayList<String>();
                      for (int i = 0; i < typeIndex; i++) {
                          I_CmsXmlSchemaType t = contentDefinition.getTypeSequence().get(i);
                          previousTypeNames.add(t.getName());
                      }
  
                      // iterate all elements of the parent node
                      Iterator<Node> i = CmsXmlGenericWrapper.content(parentElement).iterator();
                      int pos = 0;
                      while (i.hasNext()) {
                          Node node = i.next();
                          if (node instanceof Element) {
                              if (!previousTypeNames.contains(node.getName())) {
                                  // the element name is NOT in the list of names that occurs before the selected type,
                                  // so it must be an element that occurs AFTER the type
                                  break;
                              }
                          }
                          pos++;
                      }
                      insertIndex = pos;
                  }
              }
          }
  
          // just append the new element at the calculated position
          I_CmsXmlContentValue newValue = addValue(cms, parentElement, type, locale, insertIndex);
  
          // re-initialize this XML content
          initDocument(m_document, m_encoding, m_contentDefinition);
  
          // return the value instance that was stored in the bookmarks
          // just returning "newValue" isn't enough since this instance is NOT stored in the bookmarks
          return getBookmark(getBookmarkName(newValue.getPath(), locale));
      }