/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdi.internal.request;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jdi.internal.FieldImpl;
import org.eclipse.jdi.internal.LocationImpl;
import org.eclipse.jdi.internal.MirrorImpl;
import org.eclipse.jdi.internal.ReferenceTypeImpl;
import org.eclipse.jdi.internal.ThreadReferenceImpl;
import org.eclipse.jdi.internal.VirtualMachineImpl;
import org.eclipse.jdi.internal.event.AccessWatchpointEventImpl;
import org.eclipse.jdi.internal.event.BreakpointEventImpl;
import org.eclipse.jdi.internal.event.ClassPrepareEventImpl;
import org.eclipse.jdi.internal.event.ClassUnloadEventImpl;
import org.eclipse.jdi.internal.event.EventImpl;
import org.eclipse.jdi.internal.event.ExceptionEventImpl;
import org.eclipse.jdi.internal.event.MethodEntryEventImpl;
import org.eclipse.jdi.internal.event.MethodExitEventImpl;
import org.eclipse.jdi.internal.event.ModificationWatchpointEventImpl;
import org.eclipse.jdi.internal.event.MonitorContendedEnterEventImpl;
import org.eclipse.jdi.internal.event.MonitorContendedEnteredEventImpl;
import org.eclipse.jdi.internal.event.MonitorWaitEventImpl;
import org.eclipse.jdi.internal.event.MonitorWaitedEventImpl;
import org.eclipse.jdi.internal.event.StepEventImpl;
import org.eclipse.jdi.internal.event.ThreadDeathEventImpl;
import org.eclipse.jdi.internal.event.ThreadStartEventImpl;
import org.eclipse.jdi.internal.event.VMDeathEventImpl;
import org.eclipse.osgi.util.NLS;

import com.sun.jdi.Field;
import com.sun.jdi.Location;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMMismatchException;
import com.sun.jdi.request.AccessWatchpointRequest;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.ClassUnloadRequest;
import com.sun.jdi.request.DuplicateRequestException;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.ExceptionRequest;
import com.sun.jdi.request.InvalidRequestStateException;
import com.sun.jdi.request.MethodEntryRequest;
import com.sun.jdi.request.MethodExitRequest;
import com.sun.jdi.request.ModificationWatchpointRequest;
import com.sun.jdi.request.MonitorContendedEnterRequest;
import com.sun.jdi.request.MonitorContendedEnteredRequest;
import com.sun.jdi.request.MonitorWaitRequest;
import com.sun.jdi.request.MonitorWaitedRequest;
import com.sun.jdi.request.StepRequest;
import com.sun.jdi.request.ThreadDeathRequest;
import com.sun.jdi.request.ThreadStartRequest;
import com.sun.jdi.request.VMDeathRequest;

/**
 * this class implements the corresponding interfaces
 * declared by the JDI specification. See the com.sun.jdi package
 * for more information.
 */
public class EventRequestManagerImpl extends MirrorImpl implements EventRequestManager, org.eclipse.jdi.hcr.EventRequestManager {

	private static class EventRequestType<RT extends EventRequest> {

		private ArrayList<RT> requests;
		private Hashtable<RequestID, RT> enabledrequests;

		private EventRequestType() {
			requests= new ArrayList<>();
			enabledrequests= new Hashtable<>();
		}

		public List<RT> getUnmodifiableList() {
			return Collections.unmodifiableList(requests);
		}

		public void clear() {
			requests.clear();
			enabledrequests.clear();
		}
	}

	private EventRequestType<AccessWatchpointRequest> ACCESS_WATCHPOINT_TYPE= new EventRequestType<>();
	private EventRequestType<BreakpointRequest> BREAKPOINT_TYPE= new EventRequestType<>();
	private EventRequestType<ClassPrepareRequest> CLASS_PREPARE_TYPE= new EventRequestType<>();
	private EventRequestType<ClassUnloadRequest> CLASS_UNLOAD_TYPE= new EventRequestType<>();
	private EventRequestType<MethodEntryRequest> METHOD_ENTRY_TYPE= new EventRequestType<>();
	private EventRequestType<MethodExitRequest> METHOD_EXIT_TYPE= new EventRequestType<>();
	private EventRequestType<ExceptionRequest> EXCEPTION_TYPE= new EventRequestType<>();
	private EventRequestType<ModificationWatchpointRequest> MODIFICATION_WATCHPOINT_TYPE= new EventRequestType<>();
	private EventRequestType<StepRequest> STEP_TYPE= new EventRequestType<>();
	private EventRequestType<ThreadDeathRequest> THREAD_DEATH_TYPE= new EventRequestType<>();
	private EventRequestType<ThreadStartRequest> THREAD_START_TYPE= new EventRequestType<>();
	private EventRequestType<VMDeathRequest> VM_DEATH_TYPE= new EventRequestType<>();
	private EventRequestType<MonitorContendedEnteredRequest> MONITOR_CONTENDED_ENTERED_TYPE= new EventRequestType<>();
	private EventRequestType<MonitorContendedEnterRequest> MONITOR_CONTENDED_ENTER_TYPE= new EventRequestType<>();
	private EventRequestType<MonitorWaitedRequest> MONITOR_WAITED_TYPE= new EventRequestType<>();
	private EventRequestType<MonitorWaitRequest> MONITOR_WAIT_TYPE= new EventRequestType<>();

	/**
	 * Creates new EventRequestManager.
	 */
	public EventRequestManagerImpl(VirtualMachineImpl vmImpl) {
		super("EventRequestManager", vmImpl); //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createAccessWatchpointRequest(com.sun.jdi.Field)
	 */
	@Override
	public AccessWatchpointRequest createAccessWatchpointRequest(Field field) {
		FieldImpl fieldImpl = (FieldImpl)field;
		AccessWatchpointRequestImpl req = new AccessWatchpointRequestImpl(virtualMachineImpl());
		req.addFieldFilter(fieldImpl);
		ACCESS_WATCHPOINT_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createBreakpointRequest(com.sun.jdi.Location)
	 */
	@Override
	public BreakpointRequest createBreakpointRequest(Location location) throws VMMismatchException {
		LocationImpl locImpl = (LocationImpl)location;
		BreakpointRequestImpl req = new BreakpointRequestImpl(virtualMachineImpl());
		req.addLocationFilter(locImpl);
		BREAKPOINT_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createClassPrepareRequest()
	 */
	@Override
	public ClassPrepareRequest createClassPrepareRequest() {
		ClassPrepareRequestImpl req = new ClassPrepareRequestImpl(virtualMachineImpl());
		CLASS_PREPARE_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createClassUnloadRequest()
	 */
	@Override
	public ClassUnloadRequest createClassUnloadRequest() {
		ClassUnloadRequestImpl req = new ClassUnloadRequestImpl(virtualMachineImpl());
		CLASS_UNLOAD_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createExceptionRequest(com.sun.jdi.ReferenceType, boolean, boolean)
	 */
	@Override
	public ExceptionRequest createExceptionRequest(ReferenceType refType, boolean notifyCaught, boolean notifyUncaught) {
		ReferenceTypeImpl refTypeImpl = (ReferenceTypeImpl)refType;
		ExceptionRequestImpl req = new ExceptionRequestImpl(virtualMachineImpl());
		req.addExceptionFilter(refTypeImpl, notifyCaught, notifyUncaught);
		EXCEPTION_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMethodEntryRequest()
	 */
	@Override
	public MethodEntryRequest createMethodEntryRequest() {
		MethodEntryRequestImpl req = new MethodEntryRequestImpl(virtualMachineImpl());
		METHOD_ENTRY_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMethodExitRequest()
	 */
	@Override
	public MethodExitRequest createMethodExitRequest() {
		MethodExitRequestImpl req = new MethodExitRequestImpl(virtualMachineImpl());
		METHOD_EXIT_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMonitorContendedEnteredRequest()
	 */
	@Override
	public MonitorContendedEnteredRequest createMonitorContendedEnteredRequest() {
		MonitorContendedEnteredRequestImpl req = new MonitorContendedEnteredRequestImpl(virtualMachineImpl());
		MONITOR_CONTENDED_ENTERED_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMonitorContendedEnterRequest()
	 */
	@Override
	public MonitorContendedEnterRequest createMonitorContendedEnterRequest() {
		MonitorContendedEnterRequestImpl req = new MonitorContendedEnterRequestImpl(virtualMachineImpl());
		MONITOR_CONTENDED_ENTER_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMonitorWaitedRequest()
	 */
	@Override
	public MonitorWaitedRequest createMonitorWaitedRequest() {
		MonitorWaitedRequestImpl req = new MonitorWaitedRequestImpl(virtualMachineImpl());
		MONITOR_WAITED_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createMonitorWaitRequest()
	 */
	@Override
	public MonitorWaitRequest createMonitorWaitRequest() {
		MonitorWaitRequestImpl req = new MonitorWaitRequestImpl(virtualMachineImpl());
		MONITOR_WAIT_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createModificationWatchpointRequest(com.sun.jdi.Field)
	 */
	@Override
	public ModificationWatchpointRequest createModificationWatchpointRequest(Field field) {
		FieldImpl fieldImpl = (FieldImpl)field;
		ModificationWatchpointRequestImpl req = new ModificationWatchpointRequestImpl(virtualMachineImpl());
		req.addFieldFilter(fieldImpl);
		MODIFICATION_WATCHPOINT_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createStepRequest(com.sun.jdi.ThreadReference, int, int)
	 */
	@Override
	public StepRequest createStepRequest(ThreadReference thread, int size, int depth) throws DuplicateRequestException, ObjectCollectedException {
	   	ThreadReferenceImpl threadImpl = (ThreadReferenceImpl)thread;
		StepRequestImpl req = new StepRequestImpl(virtualMachineImpl());
		req.addStepFilter(threadImpl, size, depth);
		STEP_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createThreadDeathRequest()
	 */
	@Override
	public ThreadDeathRequest createThreadDeathRequest() {
		ThreadDeathRequestImpl req = new ThreadDeathRequestImpl(virtualMachineImpl());
		THREAD_DEATH_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#createThreadStartRequest()
	 */
	@Override
	public ThreadStartRequest createThreadStartRequest() {
		ThreadStartRequestImpl req = new ThreadStartRequestImpl(virtualMachineImpl());
		THREAD_START_TYPE.requests.add(req);
		return req;
	}

	/*
	 * @see EventRequestManager#createVMDeathRequest()
	 */
	@Override
	public VMDeathRequest createVMDeathRequest() {
		VMDeathRequestImpl req = new VMDeathRequestImpl(virtualMachineImpl());
		VM_DEATH_TYPE.requests.add(req);
		return req;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdi.hcr.EventRequestManager#createReenterStepRequest(com.sun.jdi.ThreadReference)
	 */
	@Override
	public org.eclipse.jdi.hcr.ReenterStepRequest createReenterStepRequest(ThreadReference thread) {
		virtualMachineImpl().checkHCRSupported();
	   	ThreadReferenceImpl threadImpl = (ThreadReferenceImpl)thread;
		ReenterStepRequestImpl req = new ReenterStepRequestImpl(virtualMachineImpl());
		// Note that the StepFilter is only used to specify the thread.
		// The size is ignored and the depth will always be written as HCR_STEP_DEPTH_REENTER_JDWP.
		req.addStepFilter(threadImpl, StepRequest.STEP_MIN, 0);
		// Since this is a special case of a step request, we use the same request list.
		STEP_TYPE.requests.add(req);
		return req;
	}

	/**
	 * Enables class prepare requests for all loaded classes.  This is
	 * necessary for current versions of the KVM to function correctly.
	 * This method is only called when the remote VM is determined to be
	 * the KVM.
	 */
	public void enableInternalClassPrepareEvent() {
		// Note that these requests are not stored in the set of outstanding requests because
		// they must be invisible from outside.
		ClassPrepareRequestImpl requestPrepare =
			new ClassPrepareRequestImpl(virtualMachineImpl());
		requestPrepare.setGeneratedInside();
		requestPrepare.setSuspendPolicy(EventRequest.SUSPEND_NONE);

		requestPrepare.enable();
	}

	/**
	 * Creates ClassUnloadRequest for maintaining class information for within JDI.
	 * Needed to known when to flush the cache.
	 */
	public void enableInternalClasUnloadEvent(/* TBD: ReferenceTypeImpl refType*/) {
		// Note that these requests are not stored in the set of outstanding requests because
		// they must be invisible from outside.
		ClassUnloadRequestImpl reqUnload = new ClassUnloadRequestImpl(virtualMachineImpl());
		reqUnload.setGeneratedInside();
		// TBD: It is now yet possible to only ask for unload events for
		// classes that we know of due to a limitation in the J9 VM.
		// reqUnload.addClassFilter(refType);
		reqUnload.setSuspendPolicy(EventRequest.SUSPEND_NONE);
		reqUnload.enable();
	}

	/**
	 * Checks if a steprequest is for the given thread is already enabled.
	 */
	boolean existsEnabledStepRequest(ThreadReferenceImpl threadImpl) {
		Enumeration<StepRequest> enumeration = STEP_TYPE.enabledrequests.elements();
		StepRequestImpl step;
		while (enumeration.hasMoreElements()) {
			step = (StepRequestImpl)enumeration.nextElement();
			if (step.thread() == threadImpl)
				return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#deleteAllBreakpoints()
	 */
	@Override
	public void deleteAllBreakpoints() {
		EventRequestImpl.clearAllBreakpoints(this);
		BREAKPOINT_TYPE.clear();
	}

	/**
	 * Deletes an EventRequest.
	 */
	private void deleteEventRequest(EventRequestType<? extends EventRequest> type, EventRequestImpl req) throws VMMismatchException {
		// Remove request from list of requests and from the mapping of requestIDs to requests.
		checkVM(req);
		type.requests.remove(req);
		RequestID id = req.requestID();
		if(id != null) {
			type.enabledrequests.remove(id);
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#deleteEventRequest(com.sun.jdi.request.EventRequest)
	 */
	@Override
	public void deleteEventRequest(EventRequest req) {
		// Disable request, note that this also causes the event request to be removed from fEnabledRequests.
		try {
			req.disable();
		} catch (InvalidRequestStateException exception) {
			// The event has already been removed from the VM.
		}
		if (req instanceof AccessWatchpointRequestImpl) {
			deleteEventRequest(ACCESS_WATCHPOINT_TYPE, (AccessWatchpointRequestImpl) req);
		} else if (req instanceof BreakpointRequestImpl) {
			deleteEventRequest(BREAKPOINT_TYPE, (BreakpointRequestImpl)req);
		} else if (req instanceof ClassPrepareRequestImpl) {
			deleteEventRequest(CLASS_PREPARE_TYPE, (ClassPrepareRequestImpl)req);
		} else if (req instanceof ClassUnloadRequestImpl) {
			deleteEventRequest(CLASS_UNLOAD_TYPE, (ClassUnloadRequestImpl)req);
		} else if (req instanceof ExceptionRequestImpl) {
			deleteEventRequest(EXCEPTION_TYPE, (ExceptionRequestImpl)req);
		} else if (req instanceof MethodEntryRequestImpl) {
			deleteEventRequest(METHOD_ENTRY_TYPE, (MethodEntryRequestImpl)req);
		} else if (req instanceof MethodExitRequestImpl) {
			deleteEventRequest(METHOD_EXIT_TYPE, (MethodExitRequestImpl)req);
		} else if (req instanceof ModificationWatchpointRequestImpl) {
			deleteEventRequest(MODIFICATION_WATCHPOINT_TYPE, (ModificationWatchpointRequestImpl)req);
		} else if (req instanceof StepRequestImpl) {
			deleteEventRequest(STEP_TYPE, (StepRequestImpl)req);
		} else if (req instanceof ThreadDeathRequestImpl) {
			deleteEventRequest(THREAD_DEATH_TYPE, (ThreadDeathRequestImpl)req);
		} else if (req instanceof ThreadStartRequestImpl) {
			deleteEventRequest(THREAD_START_TYPE, (ThreadStartRequestImpl)req);
		} else if(req instanceof MonitorContendedEnterRequestImpl) {
			deleteEventRequest(MONITOR_CONTENDED_ENTER_TYPE, (MonitorContendedEnterRequestImpl)req);
		} else if(req instanceof MonitorContendedEnteredRequestImpl) {
			deleteEventRequest(MONITOR_CONTENDED_ENTERED_TYPE, (MonitorContendedEnteredRequestImpl)req);
		} else if(req instanceof MonitorWaitRequestImpl) {
			deleteEventRequest(MONITOR_WAIT_TYPE, (MonitorWaitRequestImpl)req);
		} else if(req instanceof MonitorWaitedRequestImpl) {
			deleteEventRequest(MONITOR_WAITED_TYPE, (MonitorWaitedRequestImpl)req);
		} else {
			throw new InternalError(NLS.bind(RequestMessages.EventRequestManagerImpl_EventRequest_type_of__0__is_unknown_1, new String[]{req.toString()}));
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#deleteEventRequests(java.util.List)
	 */
	@Override
	public void deleteEventRequests(List<? extends EventRequest> requests) throws VMMismatchException {
		Iterator<? extends EventRequest> iter = requests.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			deleteEventRequest((EventRequest)obj);
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#accessWatchpointRequests()
	 */
	@Override
	public List<AccessWatchpointRequest> accessWatchpointRequests() {
		return ACCESS_WATCHPOINT_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#breakpointRequests()
	 */
	@Override
	public List<BreakpointRequest> breakpointRequests() {
		return BREAKPOINT_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#classPrepareRequests()
	 */
	@Override
	public List<ClassPrepareRequest> classPrepareRequests() {
		return CLASS_PREPARE_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#classUnloadRequests()
	 */
	@Override
	public List<ClassUnloadRequest> classUnloadRequests() {
		return CLASS_UNLOAD_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#exceptionRequests()
	 */
	@Override
	public List<ExceptionRequest> exceptionRequests() {
		return EXCEPTION_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#methodEntryRequests()
	 */
	@Override
	public List<MethodEntryRequest> methodEntryRequests() {
		return METHOD_ENTRY_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#methodExitRequests()
	 */
	@Override
	public List<MethodExitRequest> methodExitRequests() {
		return METHOD_EXIT_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#modificationWatchpointRequests()
	 */
	@Override
	public List<ModificationWatchpointRequest> modificationWatchpointRequests() {
		return MODIFICATION_WATCHPOINT_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#stepRequests()
	 */
	@Override
	public List<StepRequest> stepRequests() {
		return STEP_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#threadDeathRequests()
	 */
	@Override
	public List<ThreadDeathRequest> threadDeathRequests() {
		return THREAD_DEATH_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#threadStartRequests()
	 */
	@Override
	public List<ThreadStartRequest> threadStartRequests() {
		return THREAD_START_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#vmDeathRequests()
	 */
	@Override
	public List<VMDeathRequest> vmDeathRequests() {
		return VM_DEATH_TYPE.getUnmodifiableList();
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.request.EventRequestManager#monitorContendedEnterRequests()
	 */
	@Override
	public List<MonitorContendedEnterRequest> monitorContendedEnterRequests() {
		return MONITOR_CONTENDED_ENTER_TYPE.getUnmodifiableList();
	}

    /* (non-Javadoc)
     * @see com.sun.jdi.request.EventRequestManager#monitorContendedEnteredRequests()
     */
    @Override
	public List<MonitorContendedEnteredRequest> monitorContendedEnteredRequests() {
    	return MONITOR_CONTENDED_ENTERED_TYPE.getUnmodifiableList();
    }

    /* (non-Javadoc)
     * @see com.sun.jdi.request.EventRequestManager#monitorWaitRequests()
     */
    @Override
	public List<MonitorWaitRequest> monitorWaitRequests() {
    	return MONITOR_WAIT_TYPE.getUnmodifiableList();
    }

    /* (non-Javadoc)
     * @see com.sun.jdi.request.EventRequestManager#monitorWaitedRequests()
     */
    @Override
	public List<MonitorWaitedRequest> monitorWaitedRequests() {
    	return MONITOR_WAITED_TYPE.getUnmodifiableList();
    }

	public void removeRequestIDMapping(EventRequestImpl req) {
		if (req instanceof AccessWatchpointRequestImpl) {
			ACCESS_WATCHPOINT_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof BreakpointRequestImpl) {
			BREAKPOINT_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ClassPrepareRequestImpl) {
			CLASS_PREPARE_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ClassUnloadRequestImpl) {
			CLASS_UNLOAD_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ExceptionRequestImpl) {
			EXCEPTION_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof MethodEntryRequestImpl) {
			METHOD_ENTRY_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof MethodExitRequestImpl) {
			METHOD_EXIT_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ModificationWatchpointRequestImpl) {
			MODIFICATION_WATCHPOINT_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof StepRequestImpl) {
			STEP_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ThreadDeathRequestImpl) {
			THREAD_DEATH_TYPE.enabledrequests.remove(req.requestID());
		} else if (req instanceof ThreadStartRequestImpl) {
			THREAD_START_TYPE.enabledrequests.remove(req.requestID());
		} else if(req instanceof MonitorContendedEnterRequestImpl) {
			MONITOR_CONTENDED_ENTER_TYPE.enabledrequests.remove(req.requestID());
		} else if(req instanceof MonitorContendedEnteredRequestImpl) {
			MONITOR_CONTENDED_ENTERED_TYPE.enabledrequests.remove(req.requestID());
		} else if(req instanceof MonitorWaitRequestImpl) {
			MONITOR_WAIT_TYPE.enabledrequests.remove(req.requestID());
		} else if(req instanceof MonitorWaitedRequestImpl) {
			MONITOR_WAITED_TYPE.enabledrequests.remove(req.requestID());
		} else if(req instanceof VMDeathRequestImpl) {
			VM_DEATH_TYPE.enabledrequests.remove(req.requestID());
		}
	}

	/**
	 * Maps a request ID to requests.
	 */
	public void addRequestIDMapping(EventRequestImpl req) {
		if (req instanceof AccessWatchpointRequestImpl) {
			ACCESS_WATCHPOINT_TYPE.enabledrequests.put(req.requestID(), (AccessWatchpointRequestImpl) req);
		} else if (req instanceof BreakpointRequestImpl) {
			BREAKPOINT_TYPE.enabledrequests.put(req.requestID(), (BreakpointRequestImpl)req);
		} else if (req instanceof ClassPrepareRequestImpl) {
			CLASS_PREPARE_TYPE.enabledrequests.put(req.requestID(), (ClassPrepareRequestImpl)req);
		} else if (req instanceof ClassUnloadRequestImpl) {
			CLASS_UNLOAD_TYPE.enabledrequests.put(req.requestID(), (ClassUnloadRequestImpl)req);
		} else if (req instanceof ExceptionRequestImpl) {
			EXCEPTION_TYPE.enabledrequests.put(req.requestID(), (ExceptionRequestImpl)req);
		} else if (req instanceof MethodEntryRequestImpl) {
			METHOD_ENTRY_TYPE.enabledrequests.put(req.requestID(), (MethodEntryRequestImpl)req);
		} else if (req instanceof MethodExitRequestImpl) {
			METHOD_EXIT_TYPE.enabledrequests.put(req.requestID(), (MethodExitRequestImpl)req);
		} else if (req instanceof ModificationWatchpointRequestImpl) {
			MODIFICATION_WATCHPOINT_TYPE.enabledrequests.put(req.requestID(), (ModificationWatchpointRequestImpl)req);
		} else if (req instanceof StepRequestImpl) {
			STEP_TYPE.enabledrequests.put(req.requestID(), (StepRequestImpl)req);
		} else if (req instanceof ThreadDeathRequestImpl) {
			THREAD_DEATH_TYPE.enabledrequests.put(req.requestID(), (ThreadDeathRequestImpl)req);
		} else if (req instanceof ThreadStartRequestImpl) {
			THREAD_START_TYPE.enabledrequests.put(req.requestID(), (ThreadStartRequestImpl)req);
		} else if(req instanceof MonitorWaitRequestImpl) {
			MONITOR_WAIT_TYPE.enabledrequests.put(req.requestID(), (MonitorWaitRequestImpl)req);
		} else if(req instanceof MonitorWaitedRequestImpl) {
			MONITOR_WAITED_TYPE.enabledrequests.put(req.requestID(), (MonitorWaitedRequestImpl)req);
		} else if(req instanceof MonitorContendedEnterRequestImpl) {
			MONITOR_CONTENDED_ENTER_TYPE.enabledrequests.put(req.requestID(), (MonitorContendedEnterRequestImpl)req);
		} else if(req instanceof MonitorContendedEnteredRequestImpl) {
			MONITOR_CONTENDED_ENTERED_TYPE.enabledrequests.put(req.requestID(), (MonitorContendedEnteredRequestImpl)req);
		} else if(req instanceof VMDeathRequestImpl) {
			VM_DEATH_TYPE.enabledrequests.put(req.requestID(), (VMDeathRequest) req);
		}
	}

	/**
	 * Find Request that matches event.
	 */
	public EventRequest findRequest(EventImpl event) {
		if (event instanceof AccessWatchpointEventImpl) {
			return ACCESS_WATCHPOINT_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof BreakpointEventImpl) {
			return BREAKPOINT_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ClassPrepareEventImpl) {
			return CLASS_PREPARE_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ClassUnloadEventImpl) {
			return CLASS_UNLOAD_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ExceptionEventImpl) {
			return EXCEPTION_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof MethodEntryEventImpl) {
			return METHOD_ENTRY_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof MethodExitEventImpl) {
			return METHOD_EXIT_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ModificationWatchpointEventImpl) {
			return MODIFICATION_WATCHPOINT_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof StepEventImpl) {
			return STEP_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ThreadDeathEventImpl) {
			return THREAD_DEATH_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof ThreadStartEventImpl) {
			return THREAD_START_TYPE.enabledrequests.get(event.requestID());
		} else if (event instanceof VMDeathEventImpl) {
			return VM_DEATH_TYPE.enabledrequests.get(event.requestID());
		} else if(event instanceof MonitorWaitEventImpl) {
			return MONITOR_WAIT_TYPE.enabledrequests.get(event.requestID());
		} else if(event instanceof MonitorWaitedEventImpl) {
			return MONITOR_WAITED_TYPE.enabledrequests.get(event.requestID());
		} else if(event instanceof MonitorContendedEnterEventImpl) {
			return MONITOR_CONTENDED_ENTER_TYPE.enabledrequests.get(event.requestID());
		} else if(event instanceof MonitorContendedEnteredEventImpl) {
			return MONITOR_CONTENDED_ENTERED_TYPE.enabledrequests.get(event.requestID());
		}
		throw new InternalError(RequestMessages.EventRequestManagerImpl_Got_event_of_unknown_type_2);
	}
}
