@Test
	public void canSeparteMultipleMultiThreadedRequests_threeEach() throws IntraceException {
		IRequestSeparator requestSeparator = DefaultFactory.getFactory().getRequestSeparator();
		IncludeThisEventFilterExt eventFilter = new IncludeThisEventFilterExt();
		eventFilter.setFilterCriteria(m_requestCompletionEvent);
		IncludeThisEventFilterExt eventFilter2 = new IncludeThisEventFilterExt();
		eventFilter2.setFilterCriteria(m_requestStartEvent);
		
		requestSeparator.setRequestCompletionFilter(eventFilter);
		requestSeparator.setRequestStartFilter(eventFilter2);
		
		//requestSeparator.setRequestCompletionEvent(m_requestCompletionEvent);//Whenever this particular event first, that marks the end of a thread/request.
		
		m_completedRequests.clear();
		ICompletedRequestCallback requestCallback = new ICompletedRequestCallback() {
			@Override
			public void requestCompleted(IRequest events) {
				m_completedRequests.add(events);
			}
		};
		requestSeparator.setCompletedRequestCallback(requestCallback);
		
		//Try some larger and arbitrary numbers
		int numThreads = 51;
		int iterations = 1013;		
	     CountDownLatch startSignal = new CountDownLatch(1);
	     CountDownLatch doneSignal = new CountDownLatch(numThreads);
		for (int i = 0; i < numThreads; i++) {
		       new Thread(new EventAndThreadIdGenerator(startSignal, doneSignal, requestSeparator,iterations, System.out)).start();
		}
	     startSignal.countDown();      // let all threads proceed
	     try {
	    	 //System.out.println("Waiting to finish");
			doneSignal.await();
			//System.out.println("Finished.");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}           // wait for all to finish

		assertEquals("Whoops, the test infrastructure didn't produce the right # of requests", numThreads*iterations, atomicRequestCount.get());
		assertEquals("Whoops, the test infrastructure didn't produce the right number of events.", numThreads*iterations*EventAndThreadIdGenerator.getEventCount(), atomicEventCount.get());

		assertEquals("Added a fixed number of java.lang.Thread.run EXIT events using multiple threads.", numThreads*iterations, m_completedRequests.size());
		assertEquals("Whoops.  The RequestSeparator should have evicted all the requests, but some were left",0,requestSeparator.size());
		//System.out.println("collected events [" + atomicEventCount.get() + "] ");
		ConcurrentHashMap<String, IRequest> mapInFlight = requestSeparator.getInFlightRequests();
		for(IRequest request : m_completedRequests) {
			if (request==null) {
				fail("Shouldn't have any nulls here.");
			} else {
				//System.out.println("#%#% Found non-null item in hash map");
				List<ITraceEvent> endEvents = request.getEvents();
//				for(ITraceEvent x : endEvents) {
//					System.out.println("parent thread [" + request.getThreadId() + "] simulated thread id [" + x.getThreadId() + "] Event [" + x.getValue() + "]");
//				}
				assertEquals("Expected 2 events for each request", 3, endEvents.size());
			}
		}
		
		assertEquals("All in-flight requests should have been complted",0, mapInFlight.size());
		//System.out.println("InFlight stuff###################################");
		Enumeration<IRequest> inFlightEnum =  mapInFlight.elements();
		while(inFlightEnum.hasMoreElements()) {
			IRequest req = inFlightEnum.nextElement();
			for(ITraceEvent e : req.getEvents()) {
				System.out.println("Parent [" + req.getThreadId() + "] child [" + e.getThreadId() + "][" + e.getAgentTimeMillis() + "]");
			}
		}
	}