text: 
  /**
   * Copyright (c) 2008
   * Willi Tscheschner
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   * and/or sell copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   * DEALINGS IN THE SOFTWARE.
   **/
  
  
  /**
   * This plugin offer the functionality of undo/redo
   * Therewith the command pattern is used.
   * 
   * A Plugin which want that the changes could get undo/redo has 
   * to implement a command-class (which implements the method .execute(), .rollback()).
   * Those instance of class must be execute thru the facade.executeCommands(). If so,
   * those command get stored here in the undo/redo stack and can get reset/restore.
   *
   **/
  
  if (!ORYX.Plugins) 
      ORYX.Plugins = new Object();
  
  ORYX.Plugins.Undo = Clazz.extend({
  	
  	// Defines the facade
      facade		: undefined,
      
  	// Defines the undo/redo Stack
  	undoStack	: [],
  	redoStack	: [],
  	
  	// Constructor 
      construct: function(facade){
      
          this.facade = facade;     
  		
  		// Offers the functionality of undo
          if(!(ORYX.READONLY == true || ORYX.VIEWLOCKED == true)) {
              this.facade.offer({
                  name			: ORYX.I18N.Undo.undo,
                  description		: ORYX.I18N.Undo.undoDesc,
                  icon			: ORYX.BASE_FILE_PATH + "images/arrow_undo.png",
                  keyCodes: [{
                          metaKeys: [ORYX.CONFIG.META_KEY_META_CTRL],
                          keyCode: 90,
                          keyAction: ORYX.CONFIG.KEY_ACTION_DOWN
                      }
                  ],
                  functionality	: this.doUndo.bind(this),
                  group			: ORYX.I18N.Undo.group,
                  isEnabled		: function(){ return this.undoStack.length > 0 }.bind(this),
                  index			: 0
              });
  
              // Offers the functionality of redo
              this.facade.offer({
                  name			: ORYX.I18N.Undo.redo,
                  description		: ORYX.I18N.Undo.redoDesc,
                  icon			: ORYX.BASE_FILE_PATH + "images/arrow_redo.png",
                  keyCodes: [{
                          metaKeys: [ORYX.CONFIG.META_KEY_META_CTRL],
                          keyCode: 89,
                          keyAction: ORYX.CONFIG.KEY_ACTION_DOWN
                      }
                  ],
                  functionality	: this.doRedo.bind(this),
                  group			: ORYX.I18N.Undo.group,
                  isEnabled		: function(){ return this.redoStack.length > 0 }.bind(this),
                  index			: 1
              });
          }
  		
  		// Register on event for executing commands --> store all commands in a stack		 
  		this.facade.registerOnEvent(ORYX.CONFIG.EVENT_EXECUTE_COMMANDS, this.handleExecuteCommands.bind(this) );
      	
  	},
  	
  	/**
  	 * Stores all executed commands in a stack
  	 * 
  	 * @param {Object} evt
  	 */
  	handleExecuteCommands: function( evt ){
  		
  		// If the event has commands
  		if( !evt.commands ){ return }
  		
  		// Add the commands to a undo stack ...
  		this.undoStack.push( evt.commands );
  		// ...and delete the redo stack
  		this.redoStack = [];
  		
  	},
  	
  	/**
  	 * Does the undo
  	 * 
  	 */
  	doUndo: function(){
  		// Get the last commands
  		var lastCommands = this.undoStack.pop();
  		
  		if( lastCommands ){
  			// Add the commands to the redo stack
  			this.redoStack.push( lastCommands );
  			
  			// Rollback every command
  			lastCommands.each(function(command){
  				command.rollback();
  			});
  		}
  		
  		// Update and refresh the canvas
  		//this.facade.getCanvas().update();
  		//this.facade.updateSelection();
  		this.facade.raiseEvent({
  			type 	: ORYX.CONFIG.EVENT_UNDO_ROLLBACK, 
  			commands: lastCommands
  		});
  	},
  	
  	/**
  	 * Does the redo
  	 * 
  	 */
  	doRedo: function(){
  		
  		// Get the last commands from the redo stack
  		var lastCommands = this.redoStack.pop();
  		
  		if( lastCommands ){
  			// Add this commands to the undo stack
  			this.undoStack.push( lastCommands );
  			
  			// Execute those commands
  			lastCommands.each(function(command){
  				command.execute();
  			});
  		}
  
  		// Update and refresh the canvas		
  		//this.facade.getCanvas().update();
  		//this.facade.updateSelection();
  		this.facade.raiseEvent({
  			type 	: ORYX.CONFIG.EVENT_UNDO_EXECUTE, 
  			commands: lastCommands
  		});
  	}
  	
  });
  