public void rollback(IProgressMonitor monitor) throws Exception {
    Layer editLayer = (Layer) handler.getEditLayer();
    editLayer.setFilter(oldFilter);

    EditBlackboard editBlackboard = handler.getEditBlackboard(editLayer);
    editBlackboard.startBatchingEvents();
    for (EditGeom geom : geoms) {
      copyFeature(editBlackboard, geom);
    }
    handler.setCurrentState(this.currentState);
    editBlackboard.fireBatchedEvents();
    handler.repaint();
  }
  public void run(IProgressMonitor monitor) throws Exception {
    Layer editLayer = (Layer) handler.getEditLayer();
    if (currentShape != null) {
      this.currentShape = handler.getCurrentShape();
      this.currentState = handler.getCurrentState();
      this.geoms = handler.getEditBlackboard(editLayer).getGeoms();
    }
    handler.setCurrentShape(null);
    handler.setCurrentState(EditState.NONE);

    oldFilter = (Filter) editLayer.getFilter();
    editLayer.setFilter(Filter.EXCLUDE);

    EditUtils.instance.cancelHideSelection(editLayer);

    EditBlackboard editBlackboard = handler.getEditBlackboard(editLayer);
    editBlackboard.startBatchingEvents();
    editBlackboard.clear();
    editBlackboard.fireBatchedEvents();

    handler.repaint();
  }
  @SuppressWarnings("unchecked")
  private void copyFeatures(
      ILayer sourceLayer, Filter filter, final Layer targetLayer, final IProgressMonitor monitor) {
    monitor.beginTask(Messages.CopyFeaturesCommand_name, 104);
    final int[] worked = new int[] {-3};
    monitor.worked(1);
    try {
      SubProgressMonitor subProgressMonitor = new SubProgressMonitor(monitor, 2);
      FeatureStore<SimpleFeatureType, SimpleFeature> destination =
          targetLayer.getResource(FeatureStore.class, subProgressMonitor);
      subProgressMonitor.done();
      worked[0] += 2;
      subProgressMonitor = new SubProgressMonitor(monitor, 2);
      FeatureSource<SimpleFeatureType, SimpleFeature> source =
          sourceLayer.getResource(FeatureSource.class, subProgressMonitor);
      subProgressMonitor.done();
      worked[0] += 2;
      // If no FeatureStore then features can't be copied
      // If no FeatureSource then features can't be copied
      if (destination == null || source == null) {
        targetLayer.setFilter(filter);
        return;
      }

      // Create a query that will get the attributes that are compatible
      // what is compatible? Do the attribute names and types have to be the same or
      // just the types.
      // Executive decision:
      // Match both name and type, the rest must be customized.
      final HashMap<String, String> attributeMap = new HashMap<String, String>();
      Query query = createQuery(sourceLayer, filter, targetLayer, attributeMap);
      if (attributeMap.isEmpty()) {
        targetLayer.setFilter(filter);
        return;
      }
      MathTransform mt = createMathTransform(sourceLayer, targetLayer);
      FeatureCollection<SimpleFeatureType, SimpleFeature> features = source.getFeatures(query);
      SimpleFeatureType schema = targetLayer.getSchema();

      CopyFeatureCollection c =
          new CopyFeatureCollection(
              schema,
              features,
              monitor,
              worked,
              mt,
              attributeMap,
              targetLayer.layerToMapTransform());
      Envelope env = c.env;
      targetLayer.eSetDeliver(false);
      try {
        List<FeatureId> fids = destination.addFeatures(c);

        displayCopiedFeatures(env);

        FilterFactory filterFactory =
            CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
        addedFeaturesFilter = filterFactory.id(new HashSet(fids));
      } finally {
        targetLayer.eSetDeliver(true);
      }
      getMap().getRenderManager().refresh(targetLayer, env);
    } catch (IOException e) {
      throw (RuntimeException) new RuntimeException().initCause(e);
    } finally {
      monitor.done();
    }
  }