/** @see org.geotools.data.FeatureStore#setFeatures(org.geotools.data.FeatureReader) */
  public void setFeatures(FeatureReader<SimpleFeatureType, SimpleFeature> reader)
      throws IOException {
    WFSTransactionState ts = null;

    if (trans == Transaction.AUTO_COMMIT) {
      ts = new WFSTransactionState(ds);
    } else {
      ts = (WFSTransactionState) trans.getState(ds);
    }

    ts.addAction(
        getSchema().getTypeName(), new DeleteAction(getSchema().getTypeName(), Filter.INCLUDE));

    ReferencedEnvelope bounds = null;
    while (reader.hasNext()) {

      try {
        SimpleFeature f = reader.next();
        List<AttributeDescriptor> atrs = f.getFeatureType().getAttributeDescriptors();
        for (int i = 0; i < atrs.size(); i++) {
          if (atrs.get(i) instanceof GeometryDescriptor) {
            Geometry g = (Geometry) f.getAttribute(i);
            CoordinateReferenceSystem cs =
                ((GeometryDescriptor) atrs.get(i)).getCoordinateReferenceSystem();
            if (cs != null && !cs.getIdentifiers().isEmpty())
              g.setUserData(cs.getIdentifiers().iterator().next().toString());
            if (g == null) continue;
            if (bounds == null) {
              bounds = new ReferencedEnvelope(g.getEnvelopeInternal(), cs);
            } else {
              bounds.expandToInclude(g.getEnvelopeInternal());
            }
          }
        }
        ts.addAction(getSchema().getTypeName(), new InsertAction(f));
      } catch (NoSuchElementException e) {
        WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
      } catch (IllegalAttributeException e) {
        WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
      }
    }

    // Fire a notification.
    // JE
    if (bounds == null) {
      // if bounds are null then send an envelope to say that features were added but
      // at an unknown location.
      bounds = new ReferencedEnvelope(getSchema().getCoordinateReferenceSystem());
      ((WFS_1_0_0_DataStore) getDataStore())
          .listenerManager.fireFeaturesRemoved(
              getSchema().getTypeName(), getTransaction(), bounds, false);
    } else {
      ((WFS_1_0_0_DataStore) getDataStore())
          .listenerManager.fireFeaturesRemoved(
              getSchema().getTypeName(), getTransaction(), bounds, false);
    }
    if (trans == Transaction.AUTO_COMMIT) {
      ts.commit();
    }
  }
  public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> collection)
      throws IOException {
    WFSTransactionState ts = null;

    if (trans == Transaction.AUTO_COMMIT) {
      ts = new WFSTransactionState(ds);
    } else {
      ts = (WFSTransactionState) trans.getState(ds);
    }
    List<FeatureId> r = new LinkedList<FeatureId>();

    SimpleFeatureType schema = getSchema();

    LenientBuilder build = new LenientBuilder(schema);

    boolean isLenient = true;
    if (schema.getUserData().containsKey("lenient")) {
      isLenient = (Boolean) schema.getUserData().get("lenient");
    }

    if (isLenient) {
      build.setFeatureFactory(new LenientFeatureFactory());
    }

    List<AttributeDescriptor> atrs = schema.getAttributeDescriptors();
    FeatureIterator<SimpleFeature> iter = collection.features();
    try {
      ReferencedEnvelope bounds = null;

      while (iter.hasNext()) {
        try {
          SimpleFeature newFeature;
          try {
            SimpleFeature f = iter.next();

            String nextFid = ts.nextFid(schema.getTypeName());
            Object[] values = f.getAttributes().toArray();

            build.addAll(values);
            newFeature = build.buildFeature(nextFid);

            r.add(newFeature.getIdentifier());
          } catch (IllegalAttributeException e) {
            throw (IOException) new IOException(e.getLocalizedMessage());
          }

          for (int i = 0; i < atrs.size(); i++) {
            AttributeDescriptor att = atrs.get(i);
            if (att instanceof GeometryDescriptor) {
              Object geom = newFeature.getAttribute(i);
              if (geom instanceof Geometry) {
                Geometry g = (Geometry) geom;
                CoordinateReferenceSystem cs =
                    ((GeometryDescriptor) att).getCoordinateReferenceSystem();
                if (g == null) continue;
                if (cs != null && !cs.getIdentifiers().isEmpty())
                  g.setUserData(cs.getIdentifiers().iterator().next().toString());
                if (bounds == null) {
                  bounds =
                      new ReferencedEnvelope(
                          g.getEnvelopeInternal(), schema.getCoordinateReferenceSystem());
                } else {
                  bounds.expandToInclude(g.getEnvelopeInternal());
                }
              }
            }
          }
          ts.addAction(schema.getTypeName(), new InsertAction(newFeature));

        } catch (NoSuchElementException e) {
          WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
          throw new IOException(e.toString());
        }
      }

      // Fire a notification.
      // JE
      if (bounds == null) {
        // if bounds are null then send an envelope to say that features were added but
        // at an unknown location.
        bounds = new ReferencedEnvelope(getSchema().getCoordinateReferenceSystem());
        ((WFS_1_0_0_DataStore) getDataStore())
            .listenerManager.fireFeaturesRemoved(
                schema.getTypeName(), getTransaction(), bounds, false);
      } else {
        ((WFS_1_0_0_DataStore) getDataStore())
            .listenerManager.fireFeaturesRemoved(
                schema.getTypeName(), getTransaction(), bounds, false);
      }

    } finally {
      iter.close();
    }
    if (trans == Transaction.AUTO_COMMIT) {
      ts.commit();

      String[] fids = ts.getFids(schema.getTypeName());
      int i = 0;
      for (String fid : fids) {
        FeatureId identifier = r.get(i);
        if (identifier instanceof FeatureIdImpl) {
          ((FeatureIdImpl) identifier).setID(fid);
        }
        i++;
      }
      return r;
    }
    return r;
  }