Read CharacterRangeTableAttribute during analysis
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
index 623a1b6..29a0807 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
@@ -27,7 +27,9 @@
 import org.jacoco.core.internal.analysis.ClassAnalyzer;
 import org.jacoco.core.internal.analysis.StringPool;
 import org.jacoco.core.internal.data.CRC64;
+import org.jacoco.core.internal.flow.CharacterRangeTableAttribute;
 import org.jacoco.core.internal.flow.ClassProbesAdapter;
+import org.objectweb.asm.Attribute;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 
@@ -104,7 +106,7 @@
 	public void analyzeClass(final ClassReader reader) {
 		final ClassVisitor visitor = createAnalyzingVisitor(
 				CRC64.checksum(reader.b), reader.getClassName());
-		reader.accept(visitor, 0);
+		reader.accept(visitor, new Attribute[]{new CharacterRangeTableAttribute()}, 0);
 	}
 
 	/**
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
index 08deb5b..cb873ba 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
@@ -17,10 +17,12 @@
 import org.jacoco.core.analysis.ICounter;
 import org.jacoco.core.analysis.IMethodCoverage;
 import org.jacoco.core.analysis.ISourceNode;
+import org.jacoco.core.internal.flow.CharacterRangeTableAttribute;
 import org.jacoco.core.internal.flow.IFrame;
 import org.jacoco.core.internal.flow.Instruction;
 import org.jacoco.core.internal.flow.LabelInfo;
 import org.jacoco.core.internal.flow.MethodProbesVisitor;
+import org.objectweb.asm.Attribute;
 import org.objectweb.asm.Handle;
 import org.objectweb.asm.Label;
 
@@ -95,6 +97,19 @@
 	}
 
 	@Override
+	public void visitAttribute(Attribute attr) {
+		if (attr instanceof CharacterRangeTableAttribute) {
+			CharacterRangeTableAttribute characterRangeTableAttribute = (CharacterRangeTableAttribute) attr;
+			for (CharacterRangeTableAttribute.Entry entry : characterRangeTableAttribute.entries) {
+				if ((entry.flags & CharacterRangeTableAttribute.CRT_BRANCH_FLAGS) != 0) {
+					LabelInfo.setPos(entry.startLabel, entry.charStart,
+							entry.charEnd);
+				}
+			}
+		}
+	}
+
+	@Override
 	public void visitLineNumber(final int line, final Label start) {
 		currentLine = line;
 		if (firstLine > line || lastLine == ISourceNode.UNKNOWN_LINE) {
@@ -214,6 +229,25 @@
 	@Override
 	public void visitJumpInsnWithProbe(final int opcode, final Label label,
 			final int probeId, final IFrame frame) {
+
+		if (probes != null && !probes[probeId]) {
+			final int labelCount = currentLabel.size();
+			if (labelCount > 0) {
+				for (int i = labelCount; --i >= 0;) {
+					Label curLabel = currentLabel.get(i);
+					int charStart = LabelInfo.getCharStart(curLabel);
+					int charEnd = LabelInfo.getCharEnd(curLabel);
+					// TODO(Godin): not all branches are presented in
+					// CharacterRangeTableAttribute, for example "for-each"
+					// loops
+					System.out.println("branch not taken "
+							+ CharacterRangeTableAttribute.decodePos(charStart)
+							+ "-"
+							+ CharacterRangeTableAttribute.decodePos(charEnd));
+				}
+			}
+		}
+
 		visitInsn();
 		addProbe(probeId);
 	}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java
index c6f1b76..5dffa09 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java
@@ -41,10 +41,29 @@
 
 	private Instruction instruction = null;
 
+	private int charStart = 0;
+	private int charEnd = 0;
+
 	// instances are only created within this class
 	private LabelInfo() {
 	}
 
+	public static void setPos(final Label label, int charStart, int charEnd) {
+		LabelInfo info = create(label);
+		info.charStart = charStart;
+		info.charEnd = charEnd;
+	}
+
+	public static int getCharStart(final Label label) {
+		LabelInfo info = create(label);
+		return info.charStart;
+	}
+
+	public static int getCharEnd(final Label label) {
+		LabelInfo info = create(label);
+		return info.charEnd;
+	}
+
 	/**
 	 * Defines that the given label is a jump target.
 	 * 
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/MethodSanitizer.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/MethodSanitizer.java
index 1400b63..622a668 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/flow/MethodSanitizer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/MethodSanitizer.java
@@ -15,6 +15,7 @@
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.commons.JSRInlinerAdapter;
+import org.objectweb.asm.tree.LabelNode;
 
 /**
  * This method visitor fixes two potential issues with Java byte code:
@@ -37,6 +38,16 @@
 				exceptions);
 	}
 
+	// TODO(Godin):
+	// otherwise, if default implementation is used, labels will be changed
+	@Override
+	protected LabelNode getLabelNode(Label l) {
+		if (!(l.info instanceof LabelNode)) {
+			l.info = new LabelNode(l);
+		}
+		return (LabelNode) l.info;
+	}
+
 	@Override
 	public void visitLocalVariable(final String name, final String desc,
 			final String signature, final Label start, final Label end,