/*******************************************************************************
 * Copyright (c) 2000, 2012 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<RT>();
			enabledrequests= new Hashtable<RequestID, RT>();
		}
		
		public List<RT> getUnmodifiableList() {
			return Collections.unmodifiableList(requests);
		}
		
		public void clear() {
			requests.clear();
			enabledrequests.clear();
		}
	}
	
	private EventRequestType<AccessWatchpointRequest> ACCESS_WATCHPOINT_TYPE= new EventRequestType<AccessWatchpointRequest>();
	private EventRequestType<BreakpointRequest> BREAKPOINT_TYPE= new EventRequestType<BreakpointRequest>();
	private EventRequestType<ClassPrepareRequest> CLASS_PREPARE_TYPE= new EventRequestType<ClassPrepareRequest>();
	private EventRequestType<ClassUnloadRequest> CLASS_UNLOAD_TYPE= new EventRequestType<ClassUnloadRequest>();
	private EventRequestType<MethodEntryRequest> METHOD_ENTRY_TYPE= new EventRequestType<MethodEntryRequest>();
	private EventRequestType<MethodExitRequest> METHOD_EXIT_TYPE= new EventRequestType<MethodExitRequest>();
	private EventRequestType<ExceptionRequest> EXCEPTION_TYPE= new EventRequestType<ExceptionRequest>();
	private EventRequestType<ModificationWatchpointRequest> MODIFICATION_WATCHPOINT_TYPE= new EventRequestType<ModificationWatchpointRequest>();
	private EventRequestType<StepRequest> STEP_TYPE= new EventRequestType<StepRequest>();
	private EventRequestType<ThreadDeathRequest> THREAD_DEATH_TYPE= new EventRequestType<ThreadDeathRequest>();
	private EventRequestType<ThreadStartRequest> THREAD_START_TYPE= new EventRequestType<ThreadStartRequest>();
	private EventRequestType<VMDeathRequest> VM_DEATH_TYPE= new EventRequestType<VMDeathRequest>();
	private EventRequestType<MonitorContendedEnteredRequest> MONITOR_CONTENDED_ENTERED_TYPE= new EventRequestType<MonitorContendedEnteredRequest>();
	private EventRequestType<MonitorContendedEnterRequest> MONITOR_CONTENDED_ENTER_TYPE= new EventRequestType<MonitorContendedEnterRequest>();
	private EventRequestType<MonitorWaitedRequest> MONITOR_WAITED_TYPE= new EventRequestType<MonitorWaitedRequest>();
	private EventRequestType<MonitorWaitRequest> MONITOR_WAIT_TYPE= new EventRequestType<MonitorWaitRequest>();

	/**
	 * 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)
	 */
	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)
	 */
	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()
	 */
	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()
	 */
	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)
	 */
	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()
	 */
	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()
	 */
	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()
	 */
	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()
	 */
	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()
	 */
	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()
	 */
	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)
	 */
	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)
	 */
	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()
	 */
	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()
	 */
	public ThreadStartRequest createThreadStartRequest() {
		ThreadStartRequestImpl req = new ThreadStartRequestImpl(virtualMachineImpl());
		THREAD_START_TYPE.requests.add(req);
		return req;
	}
	
	/*
	 * @see EventRequestManager#createVMDeathRequest()
	 */
	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)
	 */
	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()
	 */
	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)
	 */
	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)
	 */
	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()
	 */
	public List<AccessWatchpointRequest> accessWatchpointRequests() {
		return ACCESS_WATCHPOINT_TYPE.getUnmodifiableList();
	}

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

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

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

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

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

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

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

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

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

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

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

    /* (non-Javadoc)
     * @see com.sun.jdi.request.EventRequestManager#monitorWaitedRequests()
     */
    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); 
	}
}
