docs: @SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"})
  	public static Element writeMapElement(MapElement primitive, String primitiveNodeName,
  			XMLBuilder builder, XMLResources resources) throws IOException {
  		Element primitiveNode = null;
  		if (primitive instanceof MapPonctualElement) {
  			final MapPonctualElement mpe = (MapPonctualElement) primitive;
  			if (mpe instanceof MapPoint) {
  				final MapPoint mp = (MapPoint) mpe;
  				primitiveNode = builder.createElement(primitiveNodeName != null ? primitiveNodeName : NODE_POINT);
  				primitiveNode.setAttribute(ATTR_DOUBLEFRAME, Boolean.toString(mp.isDoubleFramed()));
  				primitiveNode.setAttribute(ATTR_SIZE, Double.toString(mp.getPointSize()));
  			} else if (mpe instanceof MapCircle) {
  				final MapCircle mc = (MapCircle) mpe;
  				primitiveNode = builder.createElement(primitiveNodeName != null ? primitiveNodeName : NODE_CIRCLE);
  				primitiveNode.setAttribute(ATTR_RADIUS, Double.toString(mc.getRadius()));
  			} else {
  				throw new IOException("unsupported MapElement type: " + mpe.getClass()); //$NON-NLS-1$
  			}
  			primitiveNode.setAttribute(ATTR_X, Double.toString(mpe.getX()));
  			primitiveNode.setAttribute(ATTR_Y, Double.toString(mpe.getY()));
  		} else if (primitive instanceof MapComposedElement) {
  			final MapComposedElement mce = (MapComposedElement) primitive;
  			if (mce instanceof MapPolyline) {
  				final MapPolyline mp = (MapPolyline) mce;
  				primitiveNode = builder.createElement(primitiveNodeName != null ? primitiveNodeName : NODE_POLYLINE);
  				primitiveNode.setAttribute(ATTR_WIDE, Boolean.toString(mp.isWidePolyline()));
  				primitiveNode.setAttribute(ATTR_WIDTH, Double.toString(mp.getWidth()));
  			} else if (mce instanceof MapMultiPoint) {
  				final MapMultiPoint mmp = (MapMultiPoint) mce;
  				primitiveNode = builder.createElement(primitiveNodeName != null ? primitiveNodeName : NODE_MULTIPOINT);
  				primitiveNode.setAttribute(ATTR_DOUBLEFRAME, Boolean.toString(mmp.isDoubleFramed()));
  				primitiveNode.setAttribute(ATTR_SIZE, Double.toString(mmp.getPointSize()));
  			} else if (mce instanceof MapPolygon) {
  				primitiveNode = builder.createElement(primitiveNodeName != null ? primitiveNodeName : NODE_POLYGON);
  			} else {
  				throw new IOException("unsupported MapElement type: " + mce.getClass()); //$NON-NLS-1$
  			}
  
  			final Element pointsNode = builder.createElement(NODE_POINTS);
  			for (int idxPoint = 0; idxPoint < mce.getPointCount(); ++idxPoint) {
  				final Element pointNode = builder.createElement(NODE_POINT);
  				final Point2d p = mce.getPointAt(idxPoint);
  				pointNode.setAttribute(ATTR_X, Double.toString(p.getX()));
  				pointNode.setAttribute(ATTR_Y, Double.toString(p.getY()));
  				pointsNode.appendChild(pointNode);
  			}
  			if (pointsNode.getChildNodes().getLength() > 0) {
  				primitiveNode.appendChild(pointsNode);
  			}
  			final Element groupsNode = builder.createElement(NODE_GROUPS);
  			for (int idxGroup = 0; idxGroup < mce.getGroupCount(); ++idxGroup) {
  				final Element groupNode = builder.createElement(NODE_GROUP);
  				final int idx1 = mce.getFirstPointIndexInGroup(idxGroup);
  				final int idx2 = mce.getLastPointIndexInGroup(idxGroup);
  				groupNode.setAttribute(ATTR_FIRSTPOINTINDEX, Integer.toString(idx1));
  				groupNode.setAttribute(ATTR_LASTPOINTINDEX, Integer.toString(idx2));
  				groupsNode.appendChild(groupNode);
  			}
  			if (groupsNode.getChildNodes().getLength() > 0) {
  				primitiveNode.appendChild(groupsNode);
  			}
  		}
  
  		assert primitiveNode != null;
  
  		writeGISElementAttributes(primitiveNode, primitive, builder, resources);
  		final Integer color = primitive.getRawColor();
  		if (color != null) {
  			primitive.setAttribute(XMLUtil.ATTR_COLOR, XMLUtil.toColor(color));
  		}
  
  		return primitiveNode;
  	}