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;
			}
		}
	}