/** {@inheritDoc } */
 @Override
 public Geometry getDisplayGeometry() throws TransformException {
   if (displayGeometryISO == null) {
     displayGeometryISO = JTSUtils.toISO(getDisplayGeometryJTS(), params.displayCRS);
   }
   return displayGeometryISO;
 }
 /** {@inheritDoc } */
 @Override
 public Geometry getObjectiveGeometry() throws TransformException {
   if (objectiveGeometryISO == null) {
     objectiveGeometryISO = JTSUtils.toISO(getObjectiveGeometryJTS(), params.objectiveCRS);
   }
   return objectiveGeometryISO;
 }
  /**
   * Write the feature into the stream.
   *
   * @param feature The feature
   * @param root
   * @throws XMLStreamException
   */
  public Element writeFeature(final Feature feature, final Document rootDocument, boolean fragment)
      throws ParserConfigurationException {

    final Document document;
    if (rootDocument == null) {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      // then we have to create document-loader:
      factory.setNamespaceAware(false);
      DocumentBuilder loader = factory.newDocumentBuilder();

      // creating a new DOM-document...
      document = loader.newDocument();
    } else {
      document = rootDocument;
    }

    // the root element of the xml document (type of the feature)
    final FeatureType type = feature.getType();
    final Name typeName = type.getName();
    final String namespace = typeName.getNamespaceURI();
    final String localPart = typeName.getLocalPart();

    final Element rootElement;
    final Prefix prefix;
    if (namespace != null) {
      prefix = getPrefix(namespace);
      rootElement = document.createElementNS(namespace, localPart);
      rootElement.setPrefix(prefix.prefix);

    } else {
      rootElement = document.createElement(localPart);
      prefix = null;
    }
    // if main document set the xmlns
    if (!fragment) {
      rootElement.setAttributeNS(
          "http://www.w3.org/2000/xmlns/", "xmlns:gml", "http://www.opengis.net/gml");
    }
    final Attr idAttr = document.createAttributeNS(Namespaces.GML, "id");
    idAttr.setValue(feature.getIdentifier().getID());
    idAttr.setPrefix("gml");
    rootElement.setAttributeNodeNS(idAttr);

    if (rootDocument == null) {
      document.appendChild(rootElement);
    }
    // write properties in the type order
    for (final PropertyDescriptor desc : type.getDescriptors()) {
      final Collection<Property> props = feature.getProperties(desc.getName());
      for (Property a : props) {
        final Object valueA = a.getValue();
        final PropertyType typeA = a.getType();
        final Name nameA = a.getName();
        final String nameProperty = nameA.getLocalPart();
        String namespaceProperty = nameA.getNamespaceURI();
        if (valueA instanceof Collection && !(typeA instanceof GeometryType)) {
          for (Object value : (Collection) valueA) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            element.setTextContent(Utils.getStringValue(value));
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

        } else if (valueA instanceof Map && !(typeA instanceof GeometryType)) {
          final Map<?, ?> map = (Map) valueA;
          for (Entry<?, ?> entry : map.entrySet()) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            final Object key = entry.getKey();
            if (key != null) {
              element.setAttribute("name", (String) key);
            }
            element.setTextContent(Utils.getStringValue(entry.getValue()));
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

        } else if (!(typeA instanceof GeometryType)) {
          String value = Utils.getStringValue(valueA);
          if (value != null || (value == null && !a.isNillable())) {

            if ((nameProperty.equals("name") || nameProperty.equals("description"))
                && !Namespaces.GML.equals(namespaceProperty)) {
              namespaceProperty = Namespaces.GML;
              LOGGER.warning(
                  "the property name and description of a feature must have the GML namespace");
            }
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            if (value != null) {
              element.setTextContent(value);
            }
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

          // we add the geometry
        } else {

          if (valueA != null) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            Geometry isoGeometry =
                JTSUtils.toISO(
                    (com.vividsolutions.jts.geom.Geometry) valueA,
                    type.getCoordinateReferenceSystem());
            Marshaller marshaller = null;
            try {
              marshaller = POOL.acquireMarshaller();
              marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
              marshaller.marshal(OBJECT_FACTORY.buildAnyGeometry(isoGeometry), element);
            } catch (JAXBException ex) {
              LOGGER.log(
                  Level.WARNING,
                  "JAXB Exception while marshalling the iso geometry: " + ex.getMessage(),
                  ex);
            } finally {
              if (marshaller != null) {
                POOL.release(marshaller);
              }
            }
            rootElement.appendChild(element);
          }
        }
      }
    }

    // writer.writeEndElement();
    return rootElement;
  }