private <C extends Containerable> void serializeContainerValue(
      MapXNode xmap,
      PrismContainerValue<C> containerVal,
      PrismContainerDefinition<C> containerDefinition,
      SerializationContext ctx)
      throws SchemaException {
    Long id = containerVal.getId();
    if (id != null) {
      xmap.put(XNode.KEY_CONTAINER_ID, createPrimitiveXNodeAttr(id, DOMUtil.XSD_LONG));
    }
    if (containerVal.getConcreteType() != null) {
      xmap.setTypeQName(containerVal.getConcreteType());
      xmap.setExplicitTypeDeclaration(true);
    }

    Collection<QName> serializedItems = new ArrayList<>();
    if (containerDefinition != null) {
      // We have to serialize in the definition order. Some data formats (XML) are
      // ordering-sensitive. We need to keep that ordering otherwise the resulting
      // document won't pass schema validation
      for (ItemDefinition itemDef : containerDefinition.getDefinitions()) {
        QName elementName = itemDef.getName();
        Item<?, ?> item = containerVal.findItem(elementName);
        if (item != null) {
          XNode xsubnode = serializeItem(item, ctx);
          xmap.put(elementName, xsubnode);
          serializedItems.add(elementName);
        }
      }
    }
    // There are some cases when we do not have list of all elements in a container.
    // E.g. in run-time schema. Therefore we must also iterate over items and not just item
    // definitions.
    if (containerVal.getItems() != null) {
      for (Item<?, ?> item : containerVal.getItems()) {
        QName elementName = item.getElementName();
        if (serializedItems.contains(elementName)) {
          continue;
        }
        XNode xsubnode = serializeItem(item, ctx);
        xmap.put(elementName, xsubnode);
      }
    }
  }