//Finding Base Implementation: mostly recently added implementation (not Advice)
public <T> DynamicType.Builder<T> apply(DynamicType.Builder<T> builder) {
		TypeDescription description = builder.toTypeDescription();
		List<MethodDescription> methods = getMethodDescriptionList(description);
		enhanceCasesByDynamicDefinitions(methods);
		builder = enhanceCasesByOverrides(builder, description, methods);
		if(cases.isEmpty()) return builder;
		Case[] cases = this.cases.toArray(new Case[this.cases.size()]);
		//Lets cache presence of methods per condition
		boolean[] hasMatchedMethods = new boolean[cases.length];
		boolean[] hasOpositeMatchedMethods = new boolean[cases.length];
		for (int i=0; i<cases.length; i++) {
			hasMatchedMethods[i] = hasMatch(methods, cases[i].getMatcher());
			hasOpositeMatchedMethods[i] = hasMatch(methods, not(cases[i].getMatcher()));
		}
		BigInteger permutationsTotal = BigInteger.ONE.shiftLeft(cases.length).subtract(BigInteger.ONE);
		for(BigInteger currentPermutation = BigInteger.ONE; 
				currentPermutation.compareTo(permutationsTotal)<=0;
				currentPermutation = currentPermutation.add(BigInteger.ONE)) {
			//Finding Base Implementation: mostly recently added implementation (not Advice)
			Implementation baseImplementation = null;
			for(int i=cases.length-1; i>=0; i--) {
				if(currentPermutation.testBit(i)) {
					Implementation impl = cases[i].getImplementation();
					if(baseImplementation==null) baseImplementation=cases[i].getImplementation();
					if(!(impl instanceof Advice)) {
						baseImplementation = impl;
						break;
					}
				}
			}
			ElementMatcher.Junction<? super MethodDescription> matcher = any();
			Implementation implementation = baseImplementation;
			int i = cases.length-1;
			for(; i>=0; i--) {
				Case c = cases[i];
				boolean caseIncluded = currentPermutation.testBit(i); // Included or excluded
				if(!caseIncluded) continue; //Advice will not be included in any case: moving forward
				if(!(caseIncluded?hasMatchedMethods[i]:hasOpositeMatchedMethods[i])) break; //No such methods at all
				matcher = matcher.and(caseIncluded?c.getMatcher():not(c.getMatcher()));
				if(caseIncluded 
						&& c.getImplementation() instanceof Advice
						&& c.getImplementation() != baseImplementation) {
					implementation = ((Advice)c.getImplementation()).wrap(implementation);
				}
			}
			if(i<0)
				builder = builder.method(matcher).intercept(implementation);
		}
		return builder;
	}
currentPermutation.compareTo(permutationsTotal)<=0;
currentPermutation = currentPermutation.add(BigInteger.ONE)) {
//Finding Base Implementation: mostly recently added implementation (not Advice)
Implementation baseImplementation = null;
for(int i=cases.length-1; i>=0; i--) {
boolean[] hasMatchedMethods = new boolean[cases.length];
boolean[] hasOpositeMatchedMethods = new boolean[cases.length];
for (int i=0; i<cases.length; i++) {
hasMatchedMethods[i] = hasMatch(methods, cases[i].getMatcher());
hasOpositeMatchedMethods[i] = hasMatch(methods, not(cases[i].getMatcher()));
}
BigInteger permutationsTotal = BigInteger.ONE.shiftLeft(cases.length).subtract(BigInteger.ONE);
for(BigInteger currentPermutation = BigInteger.ONE;
currentPermutation.compareTo(permutationsTotal)<=0;
currentPermutation = currentPermutation.add(BigInteger.ONE)) {
//Finding Base Implementation: mostly recently added implementation (not Advice)
Implementation baseImplementation = null;
for(int i=cases.length-1; i>=0; i--) {
if(currentPermutation.testBit(i)) {
Implementation impl = cases[i].getImplementation();
if(baseImplementation==null) baseImplementation=cases[i].getImplementation();
if(!(impl instanceof Advice)) {
baseImplementation = impl;
break;
}
}
public <T> DynamicType.Builder<T> apply(DynamicType.Builder<T> builder) {
TypeDescription description = builder.toTypeDescription();
List<MethodDescription> methods = getMethodDescriptionList(description);
enhanceCasesByDynamicDefinitions(methods);
builder = enhanceCasesByOverrides(builder, description, methods);
if(cases.isEmpty()) return builder;
Case[] cases = this.cases.toArray(new Case[this.cases.size()]);
//Lets cache presence of methods per condition
boolean[] hasMatchedMethods = new boolean[cases.length];
boolean[] hasOpositeMatchedMethods = new boolean[cases.length];
for (int i=0; i<cases.length; i++) {
hasMatchedMethods[i] = hasMatch(methods, cases[i].getMatcher());
hasOpositeMatchedMethods[i] = hasMatch(methods, not(cases[i].getMatcher()));
}
BigInteger permutationsTotal = BigInteger.ONE.shiftLeft(cases.length).subtract(BigInteger.ONE);
for(BigInteger currentPermutation = BigInteger.ONE;
currentPermutation.compareTo(permutationsTotal)<=0;
currentPermutation = currentPermutation.add(BigInteger.ONE)) {
//Finding Base Implementation: mostly recently added implementation (not Advice)
Implementation baseImplementation = null;
for(int i=cases.length-1; i>=0; i--) {
if(currentPermutation.testBit(i)) {
Implementation impl = cases[i].getImplementation();
if(baseImplementation==null) baseImplementation=cases[i].getImplementation();
if(!(impl instanceof Advice)) {
baseImplementation = impl;
break;
}
}
}
ElementMatcher.Junction<? super MethodDescription> matcher = any();
Implementation implementation = baseImplementation;
int i = cases.length-1;
for(; i>=0; i--) {
Case c = cases[i];
boolean caseIncluded = currentPermutation.testBit(i); // Included or excluded
if(!caseIncluded) continue; //Advice will not be included in any case: moving forward
if(!(caseIncluded?hasMatchedMethods[i]:hasOpositeMatchedMethods[i])) break; //No such methods at all
matcher = matcher.and(caseIncluded?c.getMatcher():not(c.getMatcher()));