public static List<IO2Finding> join_WebLayer_traces_with_WebServices_traces(List<IO2Finding> sourceO2Findings, List<IO2Finding> webLayerFindingsWithUrl)
    	{
    		var bySink = webLayerFindingsWithUrl.indexBy_Sink();
			var bySource = sourceO2Findings.indexBy_Source();
			
			var jointFindings = new List<IO2Finding>();
			foreach(var source in bySource) 
			{
				var fixedSource = source.Key.replace("HacmeBank_v2_WS.WS_UserManagement", "WS_UserManagement");
				fixedSource = fixedSource.replace("HacmeBank_v2_WS.WS_AccountManagement", "WS_AccountManagement");
				fixedSource = fixedSource.replace("HacmeBank_v2_WS.WS_UsersCommunity", "WS_UsersCommunity");
				if (fixedSource.contains("Login"))
				{
					fixedSource.info();
					//source.Key.info();
				}
				if (bySink.hasKey(fixedSource))
				{
					foreach(var findingA in bySink[fixedSource]) 
						foreach(var findingB in source.Value) 			
						{
							var newFinding = OzasmtGlue.createCopyAndGlueTraceSinkWithTrace(findingA, findingB.o2Traces);
							jointFindings.add(newFinding);
						}
				}				
			}
			return jointFindings; 
    	}
    	public static List<IO2Finding> calculate_WebLayer_tracesInto_WebServices_with_URL_as_Source(List<IO2Finding> sourceO2Findings, List<IO2Finding> urlMappings)
    	{
    		var webLayerFindingsWithUrl = new List<IO2Finding>();

			var mappedFindings = sourceO2Findings.getFindingsWith_WebServicesInvoke()
												 .makeSinks_WebServicesInvokeTarget();
												 
			var indexedByRootMethod = mappedFindings.indexBy(
				(o2Finding)=>{
								if (o2Finding.o2Traces[0].childTraces.size() > 1)
									return o2Finding.o2Traces[0].childTraces[1].context;
								else
									return "no root method";
							 });
									
			 
			foreach(var sinkValue in urlMappings.indexBy_Sink())
			{
				if (indexedByRootMethod.hasKey(sinkValue.Key))
				{
					foreach(var findingA in sinkValue.Value)
						foreach(var findingB in indexedByRootMethod[sinkValue.Key])
						{				
							//var newFinding = findingA.copy();
							var newFinding = OzasmtGlue.createCopyAndGlueTraceSinkWithTrace(findingA, findingB.o2Traces);
							webLayerFindingsWithUrl.add(newFinding);
						}		
				} 
			//	sinkValue.Key.info(); 
			}
			webLayerFindingsWithUrl.removeFirstSource();
			return webLayerFindingsWithUrl;
    	}