paramTypeList.add(thisJoinPointVar.getType());
    public void weaveAroundInline(    	BcelAdvice munger,    	boolean hasDynamicTest)	{		/* Implementation notes:		 * 		 * AroundInline still extracts the instructions of the original shadow into 		 * an extracted method.  This allows inlining of even that advice that doesn't		 * call proceed or calls proceed more than once. 		 * 		 * It extracts the instructions of the original shadow into a method.		 * 		 * Then it inlines the instructions of the advice in its place, taking care		 * to treat the closure argument specially (it doesn't exist).		 * 		 * Then it searches in the instructions of the advice for any call to the		 * proceed method.		 * 		 *   At such a call, there is stuff on the stack representing the arguments to		 *   proceed.  Pop these into the frame.		 * 		 *   Now build the stack for the call to the extracted method, taking values 		 *   either from the join point state or from the new frame locs from proceed.		 *   Now call the extracted method.  The right return value should be on the		 *   stack, so no cast is necessary.		 *		 * If only one call to proceed is made, we can re-inline the original shadow.		 * We are not doing that presently.		 */		 		// !!! THIS BLOCK OF CODE SHOULD BE IN A METHOD CALLED weaveAround(...);        Member mungerSig = munger.getSignature();        ResolvedTypeX declaringType = world.resolve(mungerSig.getDeclaringType());        //??? might want some checks here to give better errors        BcelObjectType ot = BcelWorld.getBcelObjectType(declaringType);         		LazyMethodGen adviceMethod = ot.getLazyClassGen().getLazyMethodGen(mungerSig);		if (!adviceMethod.getCanInline())		{			weaveAroundClosure(munger, hasDynamicTest);			return;		}				// We can't inline around methods if they have around advice on them, this		// is because the weaving will extract the body and hence the proceed call.		//??? should consider optimizations to recognize simple cases that don't require body extraction		enclosingMethod.setCanInline(false);				// start by exposing various useful things into the frame		final InstructionFactory fact = getFactory();				// now generate the aroundBody method        LazyMethodGen extractedMethod =         	extractMethod(        		NameMangler.aroundCallbackMethodName(        			getSignature(),        			getEnclosingClass()));        			        			        // now extract the advice into its own method        String adviceMethodName =			NameMangler.aroundCallbackMethodName(							getSignature(),							getEnclosingClass()) + "$advice";        		List paramTypeList = new ArrayList();		List argVarList = new ArrayList();		List proceedVarList = new ArrayList();		int extraParamOffset = 0;				//TODO paramTypeList not needed any more				// start w/ stuff		if (thisVar != null) {			paramTypeList.add(thisVar.getType());			argVarList.add(thisVar);			proceedVarList.add(new BcelVar(thisVar.getType(), extraParamOffset));			extraParamOffset += thisVar.getType().getSize();		}				if (targetVar != null && targetVar != thisVar) {			paramTypeList.add(targetVar.getType());			argVarList.add(targetVar);			proceedVarList.add(new BcelVar(targetVar.getType(), extraParamOffset));			extraParamOffset += targetVar.getType().getSize();		}		for (int i = 0, len = getArgCount(); i < len; i++) {			paramTypeList.add(argVars[i].getType());			argVarList.add(argVars[i]);			proceedVarList.add(new BcelVar(argVars[i].getType(), extraParamOffset));			extraParamOffset += argVars[i].getType().getSize();		}		if (thisJoinPointVar != null) {			paramTypeList.add(thisJoinPointVar.getType());			argVarList.add(thisJoinPointVar);			proceedVarList.add(new BcelVar(thisJoinPointVar.getType(), extraParamOffset));			extraParamOffset += thisJoinPointVar.getType().getSize();		}                Type[] adviceParameterTypes = adviceMethod.getArgumentTypes();        Type[] extractedMethodParameterTypes = extractedMethod.getArgumentTypes();		Type[] parameterTypes = new Type[extractedMethodParameterTypes.length + adviceParameterTypes.length + 1];		int parameterIndex = 0;		System.arraycopy(extractedMethodParameterTypes, 0, parameterTypes, parameterIndex, extractedMethodParameterTypes.length);		parameterIndex += extractedMethodParameterTypes.length;//        for (Iterator i = paramTypeList.iterator(); i.hasNext(); ) {//        	ResolvedTypeX t = (ResolvedTypeX)i.next();//        	parameterTypes[parameterIndex++] = BcelWorld.makeBcelType(t);//        }        parameterTypes[parameterIndex++] =        	BcelWorld.makeBcelType(adviceMethod.getEnclosingClass().getType());		System.arraycopy(adviceParameterTypes, 0, parameterTypes, parameterIndex, adviceParameterTypes.length);        LazyMethodGen localAdviceMethod =					new LazyMethodGen(						Modifier.FINAL | Modifier.STATIC, 						adviceMethod.getReturnType(), 						adviceMethodName,						parameterTypes,						new String[0],						getEnclosingClass());    		getEnclosingClass().addMethodGen(localAdviceMethod);				int nVars = adviceMethod.getMaxLocals() + extraParamOffset;		IntMap varMap = IntMap.idMap(nVars);		for (int i=extraParamOffset; i < nVars; i++) {			varMap.put(i-extraParamOffset, i);		}				localAdviceMethod.getBody().insert(			BcelClassWeaver.genInlineInstructions(adviceMethod, 					localAdviceMethod, varMap, fact, true));							localAdviceMethod.setMaxLocals(nVars);							//System.err.println(localAdviceMethod);		        	// the shadow is now empty.  First, create a correct call    	// to the around advice.  This includes both the call (which may involve     	// value conversion of the advice arguments) and the return    	// (which may involve value conversion of the return value).  Right now    	// we push a null for the unused closure.  It's sad, but there it is.    	    	    	InstructionList advice = new InstructionList();        InstructionHandle adviceMethodInvocation;        {			for (Iterator i = argVarList.iterator(); i.hasNext(); ) {				BcelVar var = (BcelVar)i.next();				var.appendLoad(advice, fact);			}       	        	// ??? we don't actually need to push NULL for the closure if we take care		    advice.append(munger.getAdviceArgSetup(this, null, new InstructionList(fact.ACONST_NULL)));		    adviceMethodInvocation =		        advice.append(		        	Utility.createInvoke(fact, localAdviceMethod)); //(fact, getWorld(), munger.getSignature()));			advice.append(		        Utility.createConversion(		            getFactory(), 		            world.makeBcelType(munger.getSignature().getReturnType()), 		            extractedMethod.getReturnType()));		    if (! isFallsThrough()) {		        advice.append(fact.createReturn(extractedMethod.getReturnType()));		    }        }        		// now, situate the call inside the possible dynamic tests,		// and actually add the whole mess to the shadow        if (! hasDynamicTest) {            range.append(advice);        } else {        	InstructionList afterThingie = new InstructionList(fact.NOP);            InstructionList callback = makeCallToCallback(extractedMethod);            if (terminatesWithReturn()) {                callback.append(fact.createReturn(extractedMethod.getReturnType()));            } else {            	//InstructionHandle endNop = range.insert(fact.NOP, Range.InsideAfter);                advice.append(fact.createBranchInstruction(Constants.GOTO, afterThingie.getStart()));            }            range.append(munger.getTestInstructions(this, advice.getStart(), callback.getStart(), advice.getStart()));            range.append(advice);            range.append(callback);            range.append(afterThingie);                  }                        // now the range contains everything we need.  We now inline the advice method.				        //BcelClassWeaver.inlineMethod(adviceMethod, enclosingMethod, adviceMethodInvocation);        // now search through the advice, looking for a call to PROCEED.          // Then we replace the call to proceed with some argument setup, and a         // call to the extracted method.        String proceedName =         	NameMangler.proceedMethodName(munger.getSignature().getName());        InstructionHandle curr = localAdviceMethod.getBody().getStart();        InstructionHandle end = localAdviceMethod.getBody().getEnd();        ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen();        while (curr != end) {			InstructionHandle next = curr.getNext();			Instruction inst = curr.getInstruction();			if ((inst instanceof INVOKESTATIC)					&& proceedName.equals(((INVOKESTATIC) inst).getMethodName(cpg))) {									localAdviceMethod.getBody().append(curr, getRedoneProceedCall(fact, extractedMethod, munger, localAdviceMethod, proceedVarList));				Utility.deleteInstruction(curr, localAdviceMethod);			}			curr = next;        }        // and that's it.	}