public void executeAction(ActionListener listener, Object source,
		String actionCommand)
	{
		// create event
		ActionEvent evt = new ActionEvent(source,
			ActionEvent.ACTION_PERFORMED,
			actionCommand);

		// don't do anything if the action is a wrapper
		// (like EditAction.Wrapper)
		if(listener instanceof Wrapper)
		{
			listener.actionPerformed(evt);
			return;
		}

		// remember old values, in case action changes them
		boolean _repeat = repeat;
		int _repeatCount = getRepeatCount();

		// execute the action
		if(listener instanceof InputHandler.NonRepeatable)
			listener.actionPerformed(evt);
		else
		{
			for(int i = 0; i < Math.max(1,repeatCount); i++)
				listener.actionPerformed(evt);
		}

		// do recording. Notice that we do no recording whatsoever
		// for actions that grab keys
		if(grabAction == null)
		{
			if(recorder != null)
			{
				if(!(listener instanceof InputHandler.NonRecordable))
				{
					if(_repeatCount != 1)
						recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));

					recorder.actionPerformed(listener,actionCommand);
				}
			}

			// If repeat was true originally, clear it
			// Otherwise it might have been set by the action, etc
			if(_repeat)
			{
				repeat = false;
				repeatCount = 0;
			}
		}
	}