/** Sets the new handler and destroys the old one. */
  public void changeHandler(DrawFeatureHandler newHandler) {
    handler.deactivate();
    handler.destroy();

    handler = newHandler;
    handler.init(this);
    addObjModCode(
        new Stringer(
                getJSObjRef(),
                ".handler = new ",
                newHandler.jsClassName(),
                "(",
                getJSObjRef(),
                ",",
                getJSObjRef(),
                ".callbacks,",
                getJSObjRef(),
                ".handlerOptions);")
            .toString());
    handler.activate();
  }
  /**
   * @param layer
   * @param handler The handler to use to draw the feature.
   */
  public DrawFeatureControl(VectorLayer layer, DrawFeatureHandler handler) {
    super.create(
        new Stringer(
                "new OpenLayers.Control.DrawFeature(",
                layer.getJSObjRef(),
                ", ",
                handler.jsClassName(),
                // XXX FIX http://polymap.org/atlas/ticket/219
                // the event: this.events.triggerEvent('featureadded') is not fired for unknown
                // reason
                // -> do triggerEvent() in timeout which seems to disarm a race cond
                ",{drawFeature: function(geometry) {",
                "var self = this; var args = arguments;",
                "setTimeout( function() {",
                "OpenLayers.Control.DrawFeature.prototype.drawFeature.apply(self, args);",
                "}, 250 );",
                "}",
                "}",
                ");")
            .toString());

    addObjModCode(
        new Stringer(
                "OpenLayers.Util.extend(",
                getJSObjRef(),
                ", {",
                "activate: function() {",
                "OpenLayers.Control.DrawFeature.prototype.activate.apply(this, arguments);",
                "if (!this.keyboardHandler) {",
                "this.keyboardCallbacks = { keydown: this.handleKeyDown };",
                "this.keyboardHandler = new OpenLayers.Handler.Keyboard(this, this.keyboardCallbacks, {});",
                "}",
                "this.keyboardHandler.activate();",
                "},",
                "deactivate: function() {",
                "OpenLayers.Control.DrawFeature.prototype.deactivate.apply(this, arguments);",
                "this.keyboardHandler.deactivate();",
                "},",
                "destroy: function() {",
                "OpenLayers.Control.ModifyFeature.prototype.destroy.apply(this, arguments);",
                "if (this.keyboardHandler) {",
                "this.keyboardHandler.destroy();",
                "}",
                "},",
                "handleKeyDown: function (evt) {",
                "var handled = false;",
                "switch (evt.keyCode) {",
                "case 90:", // z
                "if (evt.metaKey || evt.ctrlKey) {",
                "this.undo();",
                "handled = true;",
                "}",
                "break;",
                "case 89:", // y
                "if (evt.metaKey || evt.ctrlKey) {",
                "this.redo();",
                "handled = true;",
                "}",
                "break;",
                "case 27:", // esc
                "this.cancel();",
                "handled = true;",
                "break;",
                "}",
                "if (handled) {",
                "OpenLayers.Event.stop(evt);",
                "}",
                "}",
                "});")
            .toString());

    handler.init(this);
    this.handler = handler;
  }