class WFSFeatureStore extends ContentFeatureStore {

    @Override
    public void modifyFeatures(Name[] properties, Object[] values, Filter filter)
            throws IOException {
        if (filter == null) {
            throw new IllegalArgumentException("filter is null");
        }

        filter = resolvePropertyNames(filter);

        {
            QName typeName = getDataStore().getRemoteTypeName(getName());
            WFSClient wfsClient = getDataStore().getWfsClient();
            Filter[] splitFilters = wfsClient.splitFilters(typeName, filter);
            Filter unsupported = splitFilters[1];

            if (!Filter.INCLUDE.equals(unsupported)) {
                // Filter not fully supported, lets modify one by one
                super.modifyFeatures(properties, values, filter);
                return;
            }
        }

        // Filter fully supported, lets batch modify
        final ContentState contentState = getState();

        ReferencedEnvelope affectedBounds = new ReferencedEnvelope(getInfo().getCRS());
        if (contentState.hasListener()) {
            // gather bounds before modification
            ReferencedEnvelope before = getBounds(new Query(getSchema().getTypeName(), filter));
            if (before != null && !before.isEmpty()) {
                affectedBounds = before;
            }
        }
        final Transaction transaction = getTransaction();

        FeatureReader<SimpleFeatureType, SimpleFeature> oldFeatures = getReader(filter);
        try {
            if (!oldFeatures.hasNext()) {
                // don't bother
                oldFeatures.close();
                return;
            }
        } catch (IOException e) {
            oldFeatures.close();
            throw e;
        } catch (RuntimeException e) {
            oldFeatures.close();
            throw e;
        }

        if (Transaction.AUTO_COMMIT.equals(transaction)) {
            // we're in auto commit. Do a batch update and commit right away
            WFSLocalTransactionState localState = getState().getLocalTransactionState();
            WFSRemoteTransactionState committingState = new WFSRemoteTransactionState(
                    getDataStore());
            committingState.watch(localState.getState());

            WFSDiff diff = localState.getDiff();

            ReferencedEnvelope bounds;
            bounds = diff.batchModify(properties, values, filter, oldFeatures, contentState);
            affectedBounds.expandToInclude(bounds);
            committingState.commit();

        } else {
            // we're in a transaction, record to local state and wait for commit to be called
            WFSLocalTransactionState localState;
            localState = (WFSLocalTransactionState) transaction.getState(getEntry());
            WFSDiff diff = localState.getDiff();

            ReferencedEnvelope bounds;
            bounds = diff.batchModify(properties, values, filter, oldFeatures, contentState);
            affectedBounds.expandToInclude(bounds);
        }

        if (contentState.hasListener()) {
            // issue notificaiton
            FeatureEvent event = new FeatureEvent(this, Type.CHANGED, affectedBounds, filter);
            contentState.fireFeatureEvent(event);
        }

    }

    public  WFSFeatureStore(WFSFeatureSource source);

}