private IStatus doRedo(IProgressMonitor monitor, IAdaptable info,
			IUndoableOperation operation) throws ExecutionException {

		IStatus status = getRedoApproval(operation, info);
		if (status.isOK()) {
			notifyAboutToRedo(operation);
			try {
				status = operation.redo(monitor, info);
			} catch (OperationCanceledException e) {
				status = Status.CANCEL_STATUS;
			} catch (ExecutionException e) {
				notifyNotOK(operation);
				if (DEBUG_OPERATION_HISTORY_UNEXPECTED) {
					Tracing.printTrace("OPERATIONHISTORY", //$NON-NLS-1$
							"ExecutionException while redoing " + operation); //$NON-NLS-1$
				}
				throw e;
			} catch (Exception e) {
				notifyNotOK(operation);
				if (DEBUG_OPERATION_HISTORY_UNEXPECTED) {
					Tracing.printTrace("OPERATIONHISTORY", //$NON-NLS-1$
							"Exception while redoing " + operation); //$NON-NLS-1$
				}
				throw new ExecutionException(
						"While redoing the operation, an exception occurred", e); //$NON-NLS-1$
			}
		}

		// if successful, the operation is removed from the redo history and
		// placed back in the undo history.
		if (status.isOK()) {
			boolean addedToUndo = true;
			synchronized (undoRedoHistoryLock) {
				redoList.remove(operation);
				if (checkUndoLimit(operation)) {
					undoList.add(operation);
				} else {
					addedToUndo = false;
				}
			}
			// dispose the operation since we could not add it to the
			// stack and will no longer have a reference to it.
			if (!addedToUndo) {
				operation.dispose();
			}

			// notify listeners must happen after history is updated
			notifyRedone(operation);
		} else {
			notifyNotOK(operation, status);
		}

		return status;
	}