From bd52e3537ecbeb11024be02a7e74ef843c88e9fb Mon Sep 17 00:00:00 2001
From: MarkusKrug <markus.krug@uni-wuerzburg.de>
Date: Mon, 3 Jul 2017 08:12:26 +0200
Subject: [PATCH] mapping should now also be configurable with the span
 matching. Currently there are 2 span matching modes -strict and ignore
 Whitespace

---
 .../view/widget/TreeHierarchyComposite.java   |   1 +
 .../struct/ESpanMatching.java                 |   5 +
 .../util/AnnotationComparisonUtil.java        | 130 ++++--
 .../util/GoldMappingConfig.java               |  14 +
 .../util/MappingConverter.java                |  88 +++--
 .../util/XmlMappingConfig.java                | 153 ++++----
 .../wizard/FeatureMappingPage.java            | 222 +++++------
 .../wizard/InitialTypeSelectionPage.java      | 245 ++++++------
 .../wizard/MappingWizard.java                 | 370 +++++++++---------
 .../kall/coreferenceview/part/CorefView.java  |  23 ++
 10 files changed, 690 insertions(+), 561 deletions(-)
 create mode 100644 de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/struct/ESpanMatching.java

diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.athen.medie.owl.view/src/de/uniwue/mk/athen/medie/owl/view/widget/TreeHierarchyComposite.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.athen.medie.owl.view/src/de/uniwue/mk/athen/medie/owl/view/widget/TreeHierarchyComposite.java
index 83ca71c6..34510704 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.athen.medie.owl.view/src/de/uniwue/mk/athen/medie/owl/view/widget/TreeHierarchyComposite.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.athen.medie.owl.view/src/de/uniwue/mk/athen/medie/owl/view/widget/TreeHierarchyComposite.java
@@ -963,6 +963,7 @@ public class TreeHierarchyComposite extends Composite {
 
 			OWLOntologyClassWrapper wrapper = (OWLOntologyClassWrapper) sel.getFirstElement();
 			// editClass(wrapper);
+			
 		}
 	}
 
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/struct/ESpanMatching.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/struct/ESpanMatching.java
new file mode 100644
index 00000000..e53be457
--- /dev/null
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/struct/ESpanMatching.java
@@ -0,0 +1,5 @@
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct;
+
+public enum ESpanMatching {STRICT,IGNORE_WHITESPACE;
+
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/AnnotationComparisonUtil.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/AnnotationComparisonUtil.java
index e96891e4..cb71217b 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/AnnotationComparisonUtil.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/AnnotationComparisonUtil.java
@@ -13,13 +13,14 @@ import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.text.AnnotationFS;
+import org.eclipse.swt.graphics.Point;
 
 import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.BinaryTupelMapping;
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
 
 public class AnnotationComparisonUtil {
 
-	public static BinaryTupelMapping compareAnnotations(CAS cas, 
-			GoldMappingConfig config) {
+	public static BinaryTupelMapping compareAnnotations(CAS cas, GoldMappingConfig config) {
 		ArrayList<Pair<AnnotationFS, AnnotationFS>> list = new ArrayList<>();
 
 		List<AnnotationFS> goldList = new ArrayList<>();
@@ -28,7 +29,7 @@ public class AnnotationComparisonUtil {
 		cas.getAnnotationIndex(config.getSystemType()).forEach(anno -> systemRemaining.add(anno));
 
 		/*
-		 * Sorting is not necessary but should cause a speed-up in case of TPs. 
+		 * Sorting is not necessary but should cause a speed-up in case of TPs.
 		 */
 		Comparator<AnnotationFS> comparator = (anno1, anno2) -> {
 			if (anno1.getBegin() != anno2.getBegin()) {
@@ -46,7 +47,8 @@ public class AnnotationComparisonUtil {
 			AnnotationFS foundAnno = null;
 			for (AnnotationFS systemAnno : systemRemaining) {
 				if (goldAnno.getBegin() < systemAnno.getBegin()) {
-					// lists sorted => systemAnnotations after this cannot be equal
+					// lists sorted => systemAnnotations after this cannot be
+					// equal
 					break;
 				} else if (areEqual(goldAnno, systemAnno, config)) {
 					foundAnno = systemAnno;
@@ -60,7 +62,8 @@ public class AnnotationComparisonUtil {
 		});
 
 		/*
-		 * Add remaining System Annotations (there is no equal Gold Annotation for these)
+		 * Add remaining System Annotations (there is no equal Gold Annotation
+		 * for these)
 		 */
 		systemRemaining.forEach(systemAnno -> {
 			list.add(new Pair<AnnotationFS, AnnotationFS>(null, systemAnno));
@@ -71,18 +74,19 @@ public class AnnotationComparisonUtil {
 
 	/**
 	 * Checks whether the two given Annotations have the same Features. <br/>
-	 * If at least one of the Annotations is <code>null</code> the method will return false. 
+	 * If at least one of the Annotations is <code>null</code> the method will
+	 * return false.
+	 * 
 	 * @param goldAnno
 	 * @param systemAnno
 	 * @return
 	 */
-	public static boolean areEqual(AnnotationFS goldAnno, AnnotationFS systemAnno, 
-			GoldMappingConfig config) {
+	public static boolean areEqual(AnnotationFS goldAnno, AnnotationFS systemAnno, GoldMappingConfig config) {
 		if (goldAnno == null || systemAnno == null) {
 			return false;
 		}
 		// check spans
-		if (!haveEqualSpans(goldAnno, systemAnno)) {
+		if (!haveEqualSpans(goldAnno, systemAnno, config.getSpanMatchingMode())) {
 			return false;
 		}
 		// check whether the Types of the Annotations are mapped to each other
@@ -94,20 +98,21 @@ public class AnnotationComparisonUtil {
 	}
 
 	/**
-	 * Checks whether the Features of the two given Annotations are equal. Features that are 
-	 * Annotations themselves are compared using {@link #areEqual()}.
+	 * Checks whether the Features of the two given Annotations are equal.
+	 * Features that are Annotations themselves are compared using
+	 * {@link #areEqual()}.
+	 * 
 	 * @param goldAnno
 	 * @param systemAnno
 	 * @return
 	 */
-	public static boolean haveEqualFeatures(AnnotationFS goldAnno, AnnotationFS systemAnno, 
-			GoldMappingConfig config) {
+	public static boolean haveEqualFeatures(AnnotationFS goldAnno, AnnotationFS systemAnno, GoldMappingConfig config) {
 		List<Feature> goldFeatures = goldAnno.getType().getFeatures();
 		for (Feature goldFeat : goldFeatures) {
 			/*
-			 *  Find the Feature that is mapped to goldFeat. 
-			 *  If there is no Feature found then goldFeat has not been mapped and 
-			 *  therefore does not need to be compared. 
+			 * Find the Feature that is mapped to goldFeat. If there is no
+			 * Feature found then goldFeat has not been mapped and therefore
+			 * does not need to be compared.
 			 */
 			Feature systemFeat = findMappedFeature(goldFeat, config);
 			if (systemFeat == null) {
@@ -117,8 +122,7 @@ public class AnnotationComparisonUtil {
 			if (goldFeat.getRange().isPrimitive() || systemFeat.getRange().isPrimitive()) {
 				String goldFvs = goldAnno.getFeatureValueAsString(goldFeat);
 				String systemFvs = systemAnno.getFeatureValueAsString(systemFeat);
-				if ((goldFvs == null && systemFvs != null) || 
-						(goldFvs != null && !goldFvs.equals(systemFvs))) {
+				if ((goldFvs == null && systemFvs != null) || (goldFvs != null && !goldFvs.equals(systemFvs))) {
 					return false;
 				}
 				continue;
@@ -141,7 +145,8 @@ public class AnnotationComparisonUtil {
 				}
 			}
 
-			// Compare both features depending on whether they are both Annotations
+			// Compare both features depending on whether they are both
+			// Annotations
 			if (goldFS instanceof AnnotationFS && systemFS instanceof AnnotationFS) {
 				if (!areEqual((AnnotationFS) goldFS, (AnnotationFS) systemFS, config)) {
 					return false;
@@ -154,7 +159,9 @@ public class AnnotationComparisonUtil {
 	}
 
 	/**
-	 * Checks whether the GoldMappingConfig contains a mapping between the two given Types.
+	 * Checks whether the GoldMappingConfig contains a mapping between the two
+	 * given Types.
+	 * 
 	 * @param firstType
 	 * @param secondType
 	 * @param config
@@ -165,12 +172,10 @@ public class AnnotationComparisonUtil {
 			return true;
 		}
 		for (Pair<Type, Type> mapping : config.getTypeMapping()) {
-			if (firstType.equals(mapping.getFirstElement()) && 
-					secondType.equals(mapping.getSecondElement())) {
+			if (firstType.equals(mapping.getFirstElement()) && secondType.equals(mapping.getSecondElement())) {
 				return true;
 			}
-			if (firstType.equals(mapping.getSecondElement()) && 
-					secondType.equals(mapping.getFirstElement())) {
+			if (firstType.equals(mapping.getSecondElement()) && secondType.equals(mapping.getFirstElement())) {
 				return true;
 			}
 		}
@@ -178,19 +183,65 @@ public class AnnotationComparisonUtil {
 	}
 
 	/**
-	 * Checks whether the given Annotations possess the same span (begin and end Features)
+	 * Checks whether the given Annotations possess the same span (begin and end
+	 * Features)
+	 * 
 	 * @param firstAnno
 	 * @param secondAnno
+	 * @param eSpanMatching
 	 * @return
 	 */
-	public static boolean haveEqualSpans(AnnotationFS firstAnno, AnnotationFS secondAnno) {
-		return firstAnno.getBegin() == secondAnno.getBegin() && 
-				firstAnno.getEnd() == secondAnno.getEnd();
+	public static boolean haveEqualSpans(AnnotationFS firstAnno, AnnotationFS secondAnno, ESpanMatching eSpanMatching) {
+
+		//default
+		if(eSpanMatching==null){
+			eSpanMatching =ESpanMatching.STRICT;
+		}
+		
+		if (eSpanMatching == ESpanMatching.STRICT) {
+			return firstAnno.getBegin() == secondAnno.getBegin() && firstAnno.getEnd() == secondAnno.getEnd();
+		} else if (eSpanMatching == ESpanMatching.IGNORE_WHITESPACE) {
+			Point annoTrimmedFirst = trimAnno(firstAnno);
+			Point annoTrimmedsecond = trimAnno(secondAnno);
+
+			return (annoTrimmedFirst.x == annoTrimmedsecond.x && annoTrimmedFirst.y == annoTrimmedsecond.y);
+		}
+
+		return false;
+	}
+
+	private static Point trimAnno(AnnotationFS firstAnno) {
+
+		int beg = firstAnno.getBegin();
+
+		// trim beg
+		for (int i = 0; i < firstAnno.getCoveredText().length(); i++) {
+
+			if (Character.isWhitespace(firstAnno.getCoveredText().charAt(i))) {
+				beg++;
+			} else {
+				break;
+			}
+		}
+
+		// trim end
+		int end = firstAnno.getEnd();
+		for (int i = firstAnno.getCoveredText().length() - 1; i >= 0; i--) {
+
+			if (Character.isWhitespace(firstAnno.getCoveredText().charAt(i))) {
+				end--;
+			} else {
+				break;
+			}
+		}
+		return new Point(beg, end);
 	}
 
 	/**
-	 * Finds the Feature that is mapped to the given Feature in hte given GoldMappingConfig. <br/>
-	 * Returns <code>null</code> if there is no such Feature. 
+	 * Finds the Feature that is mapped to the given Feature in hte given
+	 * GoldMappingConfig. <br/>
+	 * Returns <code>null</code> if there is no such Feature.
+	 * 
 	 * @param feature
 	 * @param config
 	 * @return
@@ -207,7 +258,7 @@ public class AnnotationComparisonUtil {
 		return null;
 	}
 
-	public static boolean haveEqualElements(CommonArrayFS goldArray, CommonArrayFS systemArray, 
+	public static boolean haveEqualElements(CommonArrayFS goldArray, CommonArrayFS systemArray,
 			GoldMappingConfig config) {
 		if (goldArray instanceof ArrayFS || systemArray instanceof ArrayFS) {
 			return haveEqualElements((ArrayFS) goldArray, (ArrayFS) systemArray, config);
@@ -227,8 +278,7 @@ public class AnnotationComparisonUtil {
 		return true;
 	}
 
-	public static boolean haveEqualElements(ArrayFS goldArray, ArrayFS systemArray,
-			GoldMappingConfig config) {
+	public static boolean haveEqualElements(ArrayFS goldArray, ArrayFS systemArray, GoldMappingConfig config) {
 		for (int i = 0; i < goldArray.size(); i++) {
 			if (!arrayContains(systemArray, goldArray.get(i), config)) {
 				return false;
@@ -242,23 +292,19 @@ public class AnnotationComparisonUtil {
 		return true;
 	}
 
-	public static boolean arrayContains(ArrayFS array, FeatureStructure featureStructure,
-			GoldMappingConfig config) {
+	public static boolean arrayContains(ArrayFS array, FeatureStructure featureStructure, GoldMappingConfig config) {
 		for (int i = 0; i < array.size(); i++) {
 			FeatureStructure fs2 = array.get(i);
 			/*
-			 * Compare the two FeatureStructures
-			 * 1. both are Annotations
-			 * 2. both are arrays
-			 * 3. all other cases
+			 * Compare the two FeatureStructures 1. both are Annotations 2. both
+			 * are arrays 3. all other cases
 			 */
 			if (featureStructure instanceof AnnotationFS && fs2 instanceof AnnotationFS) {
 				if (areEqual((AnnotationFS) featureStructure, (AnnotationFS) fs2, config)) {
 					return true;
 				}
-			}  else if (featureStructure instanceof CommonArrayFS && fs2 instanceof CommonArrayFS) {
-				if (haveEqualElements((CommonArrayFS) featureStructure, 
-						(CommonArrayFS) fs2, config)) {
+			} else if (featureStructure instanceof CommonArrayFS && fs2 instanceof CommonArrayFS) {
+				if (haveEqualElements((CommonArrayFS) featureStructure, (CommonArrayFS) fs2, config)) {
 					return true;
 				}
 			} else if (featureStructure != null && featureStructure.equals(fs2)) {
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/GoldMappingConfig.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/GoldMappingConfig.java
index dd61d535..d36fb853 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/GoldMappingConfig.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/GoldMappingConfig.java
@@ -6,6 +6,8 @@ import java.util.Collection;
 import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.Type;
 
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
+
 public class GoldMappingConfig {
 	private Type goldType;
 	private Type systemType;
@@ -13,6 +15,7 @@ public class GoldMappingConfig {
 	private Collection<Pair<Type, Type>> typeMapping;
 
 	private Collection<Pair<Feature, Feature>> featureMapping;
+	private ESpanMatching spanMatchingMode;
 
 	public GoldMappingConfig(){
 		typeMapping = new ArrayList<>();
@@ -59,6 +62,17 @@ public class GoldMappingConfig {
 	public void setFeatureMapping(Collection<Pair<Feature, Feature>> featureMapping) {
 		this.featureMapping = featureMapping;
 	}
+
+
+	public ESpanMatching getSpanMatchingMode() {
+		return spanMatchingMode;
+	}
+
+	public void setSpanMatchingMode(ESpanMatching spanMatchingMode) {
+		this.spanMatchingMode = spanMatchingMode;
+	}
+	
+	
 	
 	
 
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/MappingConverter.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/MappingConverter.java
index 4fb9f102..fb1ee8ba 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/MappingConverter.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/MappingConverter.java
@@ -1,42 +1,46 @@
-package de.uniwue.mk.kall.athen.goldstandardAnalyzer.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.apache.uima.cas.Feature;
-import org.apache.uima.cas.Type;
-import org.apache.uima.cas.TypeSystem;
-
-public class MappingConverter {
-
-	public static XmlMappingConfig convertToXml(GoldMappingConfig config) {
-		String goldType = config.getGoldType().getName();
-		String systemType = config.getSystemType().getName();
-		List<Pair<String, String>> typeMapping = config.getTypeMapping().stream().map(pair -> 
-		new Pair<>(pair.getFirstElement().getName(), pair.getSecondElement().getName())).
-				collect(Collectors.toList());
-		List<Pair<String, String>> featureMapping = config.getFeatureMapping().stream().map(pair -> 
-		new Pair<>(pair.getFirstElement().getName(), pair.getSecondElement().getName())).
-				collect(Collectors.toList());
-		return new XmlMappingConfig(goldType, systemType, new ArrayList<>(typeMapping), 
-				new ArrayList<>(featureMapping));
-	}
-
-	public static GoldMappingConfig convert(XmlMappingConfig config, TypeSystem ts) {
-		Type goldType = ts.getType(config.getGoldType());
-		Type systemType = ts.getType(config.getSystemType());
-		List<Pair<Type, Type>> typeMapping = config.getTypeMapping().stream().map(pair -> {
-			Type firstType = ts.getType(pair.getFirstElement());
-			Type secondType = ts.getType(pair.getSecondElement());
-			return new Pair<>(firstType, secondType);
-		}).collect(Collectors.toList());
-		List<Pair<Feature, Feature>> featureMapping = config.getFeatureMapping().stream().map(pair -> {
-			Feature firstFeature = ts.getFeatureByFullName(pair.getFirstElement());
-			Feature secondFeature = ts.getFeatureByFullName(pair.getSecondElement());
-			return new Pair<>(firstFeature, secondFeature);
-		}).collect(Collectors.toList());
-		return new GoldMappingConfig(goldType, systemType, new ArrayList<>(typeMapping), 
-				new ArrayList<>(featureMapping));
-	}
-}
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+
+public class MappingConverter {
+
+	public static XmlMappingConfig convertToXml(GoldMappingConfig config) {
+		String goldType = config.getGoldType().getName();
+		String systemType = config.getSystemType().getName();
+		List<Pair<String, String>> typeMapping = config.getTypeMapping().stream().map(pair -> 
+		new Pair<>(pair.getFirstElement().getName(), pair.getSecondElement().getName())).
+				collect(Collectors.toList());
+		List<Pair<String, String>> featureMapping = config.getFeatureMapping().stream().map(pair -> 
+		new Pair<>(pair.getFirstElement().getName(), pair.getSecondElement().getName())).
+				collect(Collectors.toList());
+		XmlMappingConfig xmlMappingConfig = new XmlMappingConfig(goldType, systemType, new ArrayList<>(typeMapping), 
+				new ArrayList<>(featureMapping));
+		xmlMappingConfig.setSpanMatchingMode(config.getSpanMatchingMode());
+		return xmlMappingConfig;
+	}
+
+	public static GoldMappingConfig convert(XmlMappingConfig config, TypeSystem ts) {
+		Type goldType = ts.getType(config.getGoldType());
+		Type systemType = ts.getType(config.getSystemType());
+		List<Pair<Type, Type>> typeMapping = config.getTypeMapping().stream().map(pair -> {
+			Type firstType = ts.getType(pair.getFirstElement());
+			Type secondType = ts.getType(pair.getSecondElement());
+			return new Pair<>(firstType, secondType);
+		}).collect(Collectors.toList());
+		List<Pair<Feature, Feature>> featureMapping = config.getFeatureMapping().stream().map(pair -> {
+			Feature firstFeature = ts.getFeatureByFullName(pair.getFirstElement());
+			Feature secondFeature = ts.getFeatureByFullName(pair.getSecondElement());
+			return new Pair<>(firstFeature, secondFeature);
+		}).collect(Collectors.toList());
+		GoldMappingConfig goldMappingConfig = new GoldMappingConfig(goldType, systemType, new ArrayList<>(typeMapping), 
+				new ArrayList<>(featureMapping));
+		goldMappingConfig.setSpanMatchingMode(config.getSpanMatchingMode());
+		return goldMappingConfig;
+	}
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/XmlMappingConfig.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/XmlMappingConfig.java
index ac31cac5..ecf780d2 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/XmlMappingConfig.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/util/XmlMappingConfig.java
@@ -1,70 +1,83 @@
-package de.uniwue.mk.kall.athen.goldstandardAnalyzer.util;
-
-import java.util.ArrayList;
-
-import javax.xml.bind.annotation.XmlRootElement;
-
-@XmlRootElement
-public class XmlMappingConfig {
-	private String goldType;
-	private String systemType;
-
-	private ArrayList<Pair<String, String>> typeMapping;
-
-	private ArrayList<Pair<String, String>> featureMappings;
-
-
-	public XmlMappingConfig() {
-		typeMapping = new ArrayList<>();
-		featureMappings = new ArrayList<>();
-	}
-
-	public XmlMappingConfig(String goldType, String systemType, 
-			ArrayList<Pair<String, String>> typeMapping, 
-			ArrayList<Pair<String, String>> featureMapping) {
-		this.goldType = goldType;
-		this.systemType = systemType;
-		this.typeMapping = typeMapping;
-		this.featureMappings = featureMapping;
-	}
-
-	public String getGoldType() {
-		return goldType;
-	}
-
-	public void setGoldType(String goldType) {
-		if (this.goldType == null) {
-			this.goldType = goldType;
-		}
-	}
-
-	public String getSystemType() {
-		return systemType;
-	}
-
-	public void setSystemType(String systemType) {
-		if (this.systemType == null) {
-			this.systemType = systemType;
-		}
-	}
-
-	public ArrayList<Pair<String, String>> getTypeMapping() {
-		return typeMapping;
-	}
-
-	public void setTypeMapping(ArrayList<Pair<String, String>> typeMapping) {
-		if (this.typeMapping == null) {
-			this.typeMapping = typeMapping;
-		}
-	}
-
-	public ArrayList<Pair<String, String>> getFeatureMapping() {
-		return featureMappings;
-	}
-
-	public void setFeatureMapping(ArrayList<Pair<String, String>> featureMapping) {
-		if (this.featureMappings == null) {
-			this.featureMappings = featureMapping;
-		}
-	}
-}
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.util;
+
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
+
+@XmlRootElement
+public class XmlMappingConfig {
+	private String goldType;
+	private String systemType;
+
+	private ArrayList<Pair<String, String>> typeMapping;
+
+	private ArrayList<Pair<String, String>> featureMappings;
+	
+	private ESpanMatching spanMatchingMode;
+
+
+	public XmlMappingConfig() {
+		typeMapping = new ArrayList<>();
+		featureMappings = new ArrayList<>();
+	}
+
+	public XmlMappingConfig(String goldType, String systemType, 
+			ArrayList<Pair<String, String>> typeMapping, 
+			ArrayList<Pair<String, String>> featureMapping) {
+		this.goldType = goldType;
+		this.systemType = systemType;
+		this.typeMapping = typeMapping;
+		this.featureMappings = featureMapping;
+	}
+
+	
+	public ESpanMatching getSpanMatchingMode() {
+		return spanMatchingMode;
+	}
+
+	public void setSpanMatchingMode(ESpanMatching spanMatchingMode) {
+		this.spanMatchingMode = spanMatchingMode;
+	}
+
+	public String getGoldType() {
+		return goldType;
+	}
+
+	public void setGoldType(String goldType) {
+		if (this.goldType == null) {
+			this.goldType = goldType;
+		}
+	}
+
+	public String getSystemType() {
+		return systemType;
+	}
+
+	public void setSystemType(String systemType) {
+		if (this.systemType == null) {
+			this.systemType = systemType;
+		}
+	}
+
+	public ArrayList<Pair<String, String>> getTypeMapping() {
+		return typeMapping;
+	}
+
+	public void setTypeMapping(ArrayList<Pair<String, String>> typeMapping) {
+		if (this.typeMapping == null) {
+			this.typeMapping = typeMapping;
+		}
+	}
+
+	public ArrayList<Pair<String, String>> getFeatureMapping() {
+		return featureMappings;
+	}
+
+	public void setFeatureMapping(ArrayList<Pair<String, String>> featureMapping) {
+		if (this.featureMappings == null) {
+			this.featureMappings = featureMapping;
+		}
+	}
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/FeatureMappingPage.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/FeatureMappingPage.java
index b0507509..9395aac8 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/FeatureMappingPage.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/FeatureMappingPage.java
@@ -1,110 +1,112 @@
-package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.apache.uima.cas.Feature;
-import org.apache.uima.cas.Type;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-
-import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.Pair;
-import de.uniwue.mk.kall.athen.goldstandardAnalyzer.widgets.MappingWidget;
-
-public class FeatureMappingPage extends WizardPage {
-	private Type firstType;
-	private Type secondType;
-	private Collection<Pair<Feature, Feature>> mapping;
-	private boolean primitivesOnly;
-
-	private MappingWidget<Feature> widget;
-	private LabelProvider labelProvider;
-
-
-	protected FeatureMappingPage(Type firstType, Type secondType, boolean primitivesOnly, 
-			Collection<Pair<Feature, Feature>> mapping) {
-		super("Feature Mapping");
-		this.firstType = firstType;
-		this.secondType = secondType;
-		this.primitivesOnly = primitivesOnly;
-		this.mapping = mapping;
-	}
-
-
-	@Override
-	public void createControl(Composite parent) {
-		widget = new MappingWidget<>(parent, SWT.BORDER);
-		widget.addMappingChangedListener(ev -> checkPageCompletion());
-		labelProvider = new LabelProvider() {
-
-			@Override
-			public String getText(Object obj) {
-				if (obj instanceof Feature) {
-					return ((Feature) obj).getShortName();
-				}
-				return "";
-			}
-
-		};
-		
-		if (firstType == null || secondType == null) {
-			widget.setInput(new ArrayList<>(), new ArrayList<>(), labelProvider, mapping);
-		} else {
-			List<Feature> firstFeatures = firstType.getFeatures().stream().
-					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
-					collect(Collectors.toList());
-			List<Feature> secondFeatures = secondType.getFeatures().stream().
-					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
-					collect(Collectors.toList());
-			widget.setInput(firstFeatures, secondFeatures, labelProvider, mapping);
-			setMessage("Create mapping between the Features of " + firstType.getShortName() + 
-					" and " + secondType.getShortName());
-		}
-
-		setControl(widget);
-	}
-	
-	public void update(Type firstType, Type secondType) {
-		this.firstType = firstType;
-		this.secondType = secondType;
-		if (firstType == null || secondType == null) {
-			widget.setInput(new ArrayList<>(), new ArrayList<>(), labelProvider, mapping);
-		} else {
-			List<Feature> firstFeatures = firstType.getFeatures().stream().
-					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
-					filter(feature -> !isStandardFeature(feature)).
-					collect(Collectors.toList());
-			List<Feature> secondFeatures = secondType.getFeatures().stream().
-					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
-					filter(feature -> !isStandardFeature(feature)).
-					collect(Collectors.toList());
-			widget.setInput(firstFeatures, secondFeatures, labelProvider, mapping);
-			setMessage("Create mapping between the Features of " + firstType.getShortName() + 
-					" and " + secondType.getShortName());
-		}
-	}
-
-	public void checkPageCompletion() {
-		//TODO check whether non-primitive features are mapped to other non-primitive features
-		// set page as complete if no secondElement appears more than one time
-		boolean duplicateFree = mapping.stream().map(pair -> pair.getSecondElement()).
-				allMatch(new HashSet<>()::add);
-		if (!duplicateFree) {
-			setErrorMessage("Each Feature may only be mapped once!");
-		} else {
-			setErrorMessage(null);
-		}
-		setPageComplete(duplicateFree);
-	}
-	
-	private boolean isStandardFeature(Feature feature) {
-		String name = feature.getShortName();
-		return name.equals("sofa") || name.equals("begin") || name.equals("end");
-	}
-
-}
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.Pair;
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.widgets.MappingWidget;
+
+public class FeatureMappingPage extends WizardPage {
+	private Type firstType;
+	private Type secondType;
+	private Collection<Pair<Feature, Feature>> mapping;
+	private ESpanMatching spanMatching;
+	private boolean primitivesOnly;
+
+	private MappingWidget<Feature> widget;
+	private LabelProvider labelProvider;
+
+
+	protected FeatureMappingPage(Type firstType, Type secondType, boolean primitivesOnly, 
+			Collection<Pair<Feature, Feature>> mapping) {
+		super("Feature Mapping");
+		this.firstType = firstType;
+		this.secondType = secondType;
+		this.primitivesOnly = primitivesOnly;
+		this.mapping = mapping;
+	}
+
+
+	@Override
+	public void createControl(Composite parent) {
+		widget = new MappingWidget<>(parent, SWT.BORDER);
+		widget.addMappingChangedListener(ev -> checkPageCompletion());
+		labelProvider = new LabelProvider() {
+
+			@Override
+			public String getText(Object obj) {
+				if (obj instanceof Feature) {
+					return ((Feature) obj).getShortName();
+				}
+				return "";
+			}
+
+		};
+		
+		if (firstType == null || secondType == null) {
+			widget.setInput(new ArrayList<>(), new ArrayList<>(), labelProvider, mapping);
+		} else {
+			List<Feature> firstFeatures = firstType.getFeatures().stream().
+					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
+					collect(Collectors.toList());
+			List<Feature> secondFeatures = secondType.getFeatures().stream().
+					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
+					collect(Collectors.toList());
+			widget.setInput(firstFeatures, secondFeatures, labelProvider, mapping);
+			setMessage("Create mapping between the Features of " + firstType.getShortName() + 
+					" and " + secondType.getShortName());
+		}
+
+		setControl(widget);
+	}
+	
+	public void update(Type firstType, Type secondType) {
+		this.firstType = firstType;
+		this.secondType = secondType;
+		if (firstType == null || secondType == null) {
+			widget.setInput(new ArrayList<>(), new ArrayList<>(), labelProvider, mapping);
+		} else {
+			List<Feature> firstFeatures = firstType.getFeatures().stream().
+					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
+					filter(feature -> !isStandardFeature(feature)).
+					collect(Collectors.toList());
+			List<Feature> secondFeatures = secondType.getFeatures().stream().
+					filter(feature -> !primitivesOnly || feature.getRange().isPrimitive()).
+					filter(feature -> !isStandardFeature(feature)).
+					collect(Collectors.toList());
+			widget.setInput(firstFeatures, secondFeatures, labelProvider, mapping);
+			setMessage("Create mapping between the Features of " + firstType.getShortName() + 
+					" and " + secondType.getShortName());
+		}
+	}
+
+	public void checkPageCompletion() {
+		//TODO check whether non-primitive features are mapped to other non-primitive features
+		// set page as complete if no secondElement appears more than one time
+		boolean duplicateFree = mapping.stream().map(pair -> pair.getSecondElement()).
+				allMatch(new HashSet<>()::add);
+		if (!duplicateFree) {
+			setErrorMessage("Each Feature may only be mapped once!");
+		} else {
+			setErrorMessage(null);
+		}
+		setPageComplete(duplicateFree);
+	}
+	
+	private boolean isStandardFeature(Feature feature) {
+		String name = feature.getShortName();
+		return name.equals("sofa") || name.equals("begin") || name.equals("end");
+	}
+
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/InitialTypeSelectionPage.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/InitialTypeSelectionPage.java
index aa28c6a4..842b12ac 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/InitialTypeSelectionPage.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/InitialTypeSelectionPage.java
@@ -1,114 +1,131 @@
-package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
-
-import org.apache.uima.cas.Type;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-import de.uniwue.mk.kall.athen.part.editor.dialog.AnnotationStyleEditingDialog;
-import de.uniwue.mk.kall.athen.widget.editor.AnnotationEditorWidget;
-
-public class InitialTypeSelectionPage extends WizardPage {
-	private AnnotationEditorWidget editor;
-
-	private Type goldType;
-	private Type systemType;
-
-
-	public InitialTypeSelectionPage(AnnotationEditorWidget editor) {
-		super("Gold- and System-Type Selection");
-		setMessage("Select the Types of the Annotations that should be compared");
-
-		this.editor = editor;
-	}
-
-	@Override
-	public void createControl(Composite parent) {
-		Composite composite = new Composite(parent, SWT.NULL);
-		composite.setLayout(new GridLayout(3, false));
-		setControl(composite);
-
-		Label lbGoldDesc = new Label(composite, SWT.NULL);
-		lbGoldDesc.setText("Gold Annotation Type:");
-
-		Label lbGoldValue = new Label(composite, SWT.NULL);
-		lbGoldValue.setText(" - ");
-		lbGoldValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-
-		Button btGold = new Button(composite, SWT.PUSH);
-		btGold.setText("Choose...");
-
-		Label lbSystemDesc = new Label(composite, SWT.NULL);
-		lbSystemDesc.setText("System Annotation Type:");
-
-		Label lbSystemValue = new Label(composite, SWT.NULL);
-		lbSystemValue.setText(" - ");
-		lbSystemValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-
-		Button btSystem = new Button(composite, SWT.PUSH);
-		btSystem.setText("Choose...");
-
-
-		btGold.addSelectionListener(new SelectionListener() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				AnnotationStyleEditingDialog dialog = new AnnotationStyleEditingDialog(getShell(), 
-						editor);
-				int open = dialog.open();
-				if (open == Dialog.OK) {
-					Type type = dialog.getSelectedType();
-					if (type != null) {
-						lbGoldValue.setText(type.getShortName());
-						lbGoldValue.setToolTipText(type.getName());
-						goldType = type;
-					}
-					setPageComplete(goldType != null && systemType != null);
-				}
-			}
-
-			@Override
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-
-		btSystem.addSelectionListener(new SelectionListener() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				AnnotationStyleEditingDialog dialog = new AnnotationStyleEditingDialog(getShell(), 
-						editor);
-				int open = dialog.open();
-				if (open == Dialog.OK) {
-					Type type = dialog.getSelectedType();
-					if (type != null) {
-						lbSystemValue.setText(type.getShortName());
-						lbSystemValue.setToolTipText(type.getName());
-						systemType = type;
-					}
-					setPageComplete(goldType != null && systemType != null);
-				}
-			}
-
-			@Override
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-	}
-
-	public Type getGoldType() {
-		return goldType;
-	}
-
-	public Type getSystemType() {
-		return systemType;
-	}
-
-}
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
+
+import org.apache.uima.cas.Type;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
+import de.uniwue.mk.kall.athen.part.editor.dialog.AnnotationStyleEditingDialog;
+import de.uniwue.mk.kall.athen.widget.editor.AnnotationEditorWidget;
+
+public class InitialTypeSelectionPage extends WizardPage {
+	private AnnotationEditorWidget editor;
+
+	private Type goldType;
+	private Type systemType;
+	private ESpanMatching spanMatchingMode = ESpanMatching.STRICT;
+
+	public InitialTypeSelectionPage(AnnotationEditorWidget editor) {
+		super("Gold- and System-Type Selection");
+		setMessage("Select the Types of the Annotations that should be compared");
+
+		this.editor = editor;
+	}
+
+	@Override
+	public void createControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout(3, false));
+		setControl(composite);
+
+		Label lbGoldDesc = new Label(composite, SWT.NULL);
+		lbGoldDesc.setText("Gold Annotation Type:");
+
+		Label lbGoldValue = new Label(composite, SWT.NULL);
+		lbGoldValue.setText(" - ");
+		lbGoldValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+		Button btGold = new Button(composite, SWT.PUSH);
+		btGold.setText("Choose...");
+
+		Label lbSystemDesc = new Label(composite, SWT.NULL);
+		lbSystemDesc.setText("System Annotation Type:");
+
+		Label lbSystemValue = new Label(composite, SWT.NULL);
+		lbSystemValue.setText(" - ");
+		lbSystemValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+		Button btSystem = new Button(composite, SWT.PUSH);
+		btSystem.setText("Choose...");
+
+		btGold.addSelectionListener(new SelectionListener() {
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				AnnotationStyleEditingDialog dialog = new AnnotationStyleEditingDialog(getShell(), editor);
+				int open = dialog.open();
+				if (open == Dialog.OK) {
+					Type type = dialog.getSelectedType();
+					if (type != null) {
+						lbGoldValue.setText(type.getShortName());
+						lbGoldValue.setToolTipText(type.getName());
+						goldType = type;
+					}
+					setPageComplete(goldType != null && systemType != null);
+				}
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		btSystem.addSelectionListener(new SelectionListener() {
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				AnnotationStyleEditingDialog dialog = new AnnotationStyleEditingDialog(getShell(), editor);
+				int open = dialog.open();
+				if (open == Dialog.OK) {
+					Type type = dialog.getSelectedType();
+					if (type != null) {
+						lbSystemValue.setText(type.getShortName());
+						lbSystemValue.setToolTipText(type.getName());
+						systemType = type;
+					}
+					setPageComplete(goldType != null && systemType != null);
+				}
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		Label lbSpanMatchingMode = new Label(composite, SWT.NULL);
+		lbSpanMatchingMode.setText("Select Span Matching Mode:");
+		lbSpanMatchingMode.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+		ComboViewer comboViewer = new ComboViewer(composite);
+		comboViewer.setContentProvider(ArrayContentProvider.getInstance());
+		comboViewer.setInput(ESpanMatching.values());
+		comboViewer.setSelection(new StructuredSelection(ESpanMatching.STRICT));
+
+		comboViewer.addSelectionChangedListener((SelectionChangedEvent e) -> {
+			spanMatchingMode = (ESpanMatching) comboViewer.getStructuredSelection().getFirstElement();
+		});
+	}
+
+	public Type getGoldType() {
+		return goldType;
+	}
+
+	public Type getSystemType() {
+		return systemType;
+	}
+	public ESpanMatching getSpanMatchingMode(){
+		return spanMatchingMode;
+	}
+
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/MappingWizard.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/MappingWizard.java
index 0570a0a3..4dd95615 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/MappingWizard.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.athen.goldstandardAnalyzer/src/de/uniwue/mk/kall/athen/goldstandardAnalyzer/wizard/MappingWizard.java
@@ -1,183 +1,187 @@
-package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.uima.cas.Feature;
-import org.apache.uima.cas.Type;
-import org.apache.uima.cas.TypeSystem;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.Wizard;
-
-import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.GoldMappingConfig;
-import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.Pair;
-import de.uniwue.mk.kall.athen.widget.editor.AnnotationEditorWidget;
-
-public class MappingWizard extends Wizard {
-	public static final String MESSAGE_TITLE_COMPLETE = "Mapping Complete";
-
-
-	private Type goldType;
-	private Type systemType;
-	private TypeSystem typeSystem;
-
-	private GoldMappingConfig config;
-
-	private InitialTypeSelectionPage pageInitialTypeSelection;
-	private FeatureMappingPage pageInitialMapping;
-	private MessagePage pageMessageAdditionalTypes;
-	private TypeSelectionPage pageTypeSelection;
-	private TypeMappingPage pageTypeMapping;
-	private MessagePage pageMessageFeatureMapping;
-
-	private Collection<Pair<Feature, Feature>> featureMapping;
-	private Collection<Pair<Type, Type>> typeMapping;
-	private Map<Pair<Type, Type>, FeatureMappingPage> subPages;
-	private Map<Pair<Type, Type>, Collection<Pair<Feature, Feature>>> subMappings;
-	private List<FeatureMappingPage> subPageOrder;
-
-
-	public MappingWizard(AnnotationEditorWidget editor) {
-		setWindowTitle("Mapping Wizard");
-
-		this.typeSystem = editor.getCas().getTypeSystem();
-
-		pageInitialTypeSelection = new InitialTypeSelectionPage(editor);
-		featureMapping = new HashSet<>();
-		pageInitialMapping = new FeatureMappingPage(goldType, systemType, false, featureMapping);
-		pageMessageAdditionalTypes = new MessagePage();
-		addPage(pageInitialTypeSelection);
-		addPage(pageInitialMapping);
-		addPage(pageMessageAdditionalTypes);
-
-		typeMapping = new HashSet<>();
-		Collection<Type> types = new HashSet<>();
-		pageTypeSelection = new TypeSelectionPage(typeSystem, types);
-		pageTypeMapping = new TypeMappingPage(types, typeMapping);
-		pageMessageFeatureMapping = new MessagePage("", "Now that the Types have been selected and mapped "
-				+ "their Features need to be mapped as well.");
-		addPage(pageTypeSelection);
-		addPage(pageTypeMapping);
-		addPage(pageMessageFeatureMapping);
-
-		subPages = new HashMap<>();
-		subMappings = new HashMap<>();
-		subPageOrder = new ArrayList<>();
-	}
-
-
-	@Override
-	public IWizardPage getNextPage(IWizardPage currentPage) {
-		if (currentPage == null) {
-			return pageInitialTypeSelection;
-		}
-		if (currentPage == pageInitialTypeSelection) {
-			goldType = pageInitialTypeSelection.getGoldType();
-			systemType = pageInitialTypeSelection.getSystemType();
-			pageInitialMapping.update(goldType, systemType);
-			return pageInitialMapping;
-		}
-		if (currentPage == pageInitialMapping) {
-			boolean primitivesOnly = featureMapping.stream().
-					allMatch(pair -> pair.getFirstElement().getRange().isPrimitive());
-			if (primitivesOnly) {
-				pageMessageAdditionalTypes.setMessage(MESSAGE_TITLE_COMPLETE);
-				pageMessageAdditionalTypes.setText("The mapping is complete.");
-				return pageMessageAdditionalTypes;
-			} else {
-				pageMessageAdditionalTypes.setMessage("Mapping Incomplete");
-				pageMessageAdditionalTypes.setText("The mapping contains Features which are Annotations. \nThe "
-						+ "Annotation Types that can appear as these Features need to be "
-						+ "selected and mapped.");
-				return pageMessageAdditionalTypes;
-			}
-		}
-		if (currentPage == pageMessageAdditionalTypes) {
-			if (pageMessageAdditionalTypes.getMessage().equals(MESSAGE_TITLE_COMPLETE)) {
-				return null;
-			} else {
-				return pageTypeSelection;
-			}
-		}
-		if (currentPage == pageTypeSelection) {
-			pageTypeMapping.update();
-			return pageTypeMapping;
-		}
-		if (currentPage == pageTypeMapping) {
-			manageSubPages();
-			return pageMessageFeatureMapping;
-		}
-		if (currentPage == pageMessageFeatureMapping) {
-			return subPageOrder.size() > 0 ? subPageOrder.get(0) : null;
-		}
-		if (subPageOrder.contains(currentPage)) {
-			int index = subPageOrder.indexOf(currentPage);
-			if (index == subPageOrder.size() - 1) {
-				MessagePage page = new MessagePage(MESSAGE_TITLE_COMPLETE, 
-						"All mappings have been completed.");
-				addPage(page);
-				return page;
-			}
-			return subPageOrder.get(index + 1);
-		}
-		return null;
-	}
-
-	@Override
-	public boolean canFinish() {
-		IWizardPage currentPage = getContainer().getCurrentPage();
-		if (currentPage instanceof MessagePage) {
-			return currentPage.getMessage().equals(MESSAGE_TITLE_COMPLETE);
-		}
-		return false;
-	}
-
-	@Override
-	public boolean performFinish() {
-		subMappings.forEach((typePair, features) -> featureMapping.addAll(features));
-		config = new GoldMappingConfig(goldType, systemType, 
-				typeMapping, featureMapping);
-
-		return true;
-	}
-
-	private void manageSubPages() {
-		/*
-		 * Remove obsolete pages (in case the user was on a sub page, went back to the 
-		 * original mapping page and now wants to access the sub pages again)
-		 */
-		Set<Pair<Type, Type>> obsoletePages = subPages.keySet().stream().
-				filter(pair -> !typeMapping.contains(pair)).collect(Collectors.toSet());
-		obsoletePages.forEach(pair -> {
-			FeatureMappingPage page = subPages.remove(pair);
-			subMappings.remove(pair);
-			subPageOrder.remove(page);
-		});
-		/*
-		 * Create new pages
-		 */
-		typeMapping.stream().filter(pair -> !subPages.containsKey(pair)).forEach(
-				pair -> createMappingPage(pair));
-	}
-
-	private void createMappingPage(Pair<Type, Type> pair) {
-		HashSet<Pair<Feature, Feature>> mapping = new HashSet<>();
-		FeatureMappingPage page = new FeatureMappingPage(pair.getFirstElement(), 
-				pair.getSecondElement(), true, mapping);
-		subPages.put(pair, page);
-		subMappings.put(pair, mapping);
-		subPageOrder.add(page);
-		addPage(page);
-	}
-
-	public GoldMappingConfig getGoldMappingConfig() {
-		return config;
-	}
-
-}
+package de.uniwue.mk.kall.athen.goldstandardAnalyzer.wizard;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.struct.ESpanMatching;
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.GoldMappingConfig;
+import de.uniwue.mk.kall.athen.goldstandardAnalyzer.util.Pair;
+import de.uniwue.mk.kall.athen.widget.editor.AnnotationEditorWidget;
+
+public class MappingWizard extends Wizard {
+	public static final String MESSAGE_TITLE_COMPLETE = "Mapping Complete";
+
+
+	private Type goldType;
+	private Type systemType;
+	private TypeSystem typeSystem;
+	private ESpanMatching spanMatchingMode;
+
+	private GoldMappingConfig config;
+
+	private InitialTypeSelectionPage pageInitialTypeSelection;
+	private FeatureMappingPage pageInitialMapping;
+	private MessagePage pageMessageAdditionalTypes;
+	private TypeSelectionPage pageTypeSelection;
+	private TypeMappingPage pageTypeMapping;
+	private MessagePage pageMessageFeatureMapping;
+
+	private Collection<Pair<Feature, Feature>> featureMapping;
+	private Collection<Pair<Type, Type>> typeMapping;
+	private Map<Pair<Type, Type>, FeatureMappingPage> subPages;
+	private Map<Pair<Type, Type>, Collection<Pair<Feature, Feature>>> subMappings;
+	private List<FeatureMappingPage> subPageOrder;
+
+
+	public MappingWizard(AnnotationEditorWidget editor) {
+		setWindowTitle("Mapping Wizard");
+
+		this.typeSystem = editor.getCas().getTypeSystem();
+
+		pageInitialTypeSelection = new InitialTypeSelectionPage(editor);
+		featureMapping = new HashSet<>();
+		pageInitialMapping = new FeatureMappingPage(goldType, systemType, false, featureMapping);
+		pageMessageAdditionalTypes = new MessagePage();
+		addPage(pageInitialTypeSelection);
+		addPage(pageInitialMapping);
+		addPage(pageMessageAdditionalTypes);
+
+		typeMapping = new HashSet<>();
+		Collection<Type> types = new HashSet<>();
+		pageTypeSelection = new TypeSelectionPage(typeSystem, types);
+		pageTypeMapping = new TypeMappingPage(types, typeMapping);
+		pageMessageFeatureMapping = new MessagePage("", "Now that the Types have been selected and mapped "
+				+ "their Features need to be mapped as well.");
+		addPage(pageTypeSelection);
+		addPage(pageTypeMapping);
+		addPage(pageMessageFeatureMapping);
+
+		subPages = new HashMap<>();
+		subMappings = new HashMap<>();
+		subPageOrder = new ArrayList<>();
+	}
+
+
+	@Override
+	public IWizardPage getNextPage(IWizardPage currentPage) {
+		if (currentPage == null) {
+			return pageInitialTypeSelection;
+		}
+		if (currentPage == pageInitialTypeSelection) {
+			goldType = pageInitialTypeSelection.getGoldType();
+			systemType = pageInitialTypeSelection.getSystemType();
+			spanMatchingMode = pageInitialTypeSelection.getSpanMatchingMode();
+			pageInitialMapping.update(goldType, systemType);
+			return pageInitialMapping;
+		}
+		if (currentPage == pageInitialMapping) {
+			boolean primitivesOnly = featureMapping.stream().
+					allMatch(pair -> pair.getFirstElement().getRange().isPrimitive());
+			if (primitivesOnly) {
+				pageMessageAdditionalTypes.setMessage(MESSAGE_TITLE_COMPLETE);
+				pageMessageAdditionalTypes.setText("The mapping is complete.");
+				return pageMessageAdditionalTypes;
+			} else {
+				pageMessageAdditionalTypes.setMessage("Mapping Incomplete");
+				pageMessageAdditionalTypes.setText("The mapping contains Features which are Annotations. \nThe "
+						+ "Annotation Types that can appear as these Features need to be "
+						+ "selected and mapped.");
+				return pageMessageAdditionalTypes;
+			}
+		}
+		if (currentPage == pageMessageAdditionalTypes) {
+			if (pageMessageAdditionalTypes.getMessage().equals(MESSAGE_TITLE_COMPLETE)) {
+				return null;
+			} else {
+				return pageTypeSelection;
+			}
+		}
+		if (currentPage == pageTypeSelection) {
+			pageTypeMapping.update();
+			return pageTypeMapping;
+		}
+		if (currentPage == pageTypeMapping) {
+			manageSubPages();
+			return pageMessageFeatureMapping;
+		}
+		if (currentPage == pageMessageFeatureMapping) {
+			return subPageOrder.size() > 0 ? subPageOrder.get(0) : null;
+		}
+		if (subPageOrder.contains(currentPage)) {
+			int index = subPageOrder.indexOf(currentPage);
+			if (index == subPageOrder.size() - 1) {
+				MessagePage page = new MessagePage(MESSAGE_TITLE_COMPLETE, 
+						"All mappings have been completed.");
+				addPage(page);
+				return page;
+			}
+			return subPageOrder.get(index + 1);
+		}
+		return null;
+	}
+
+	@Override
+	public boolean canFinish() {
+		IWizardPage currentPage = getContainer().getCurrentPage();
+		if (currentPage instanceof MessagePage) {
+			return currentPage.getMessage().equals(MESSAGE_TITLE_COMPLETE);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean performFinish() {
+		subMappings.forEach((typePair, features) -> featureMapping.addAll(features));
+		config = new GoldMappingConfig(goldType, systemType, 
+				typeMapping, featureMapping);
+		config.setSpanMatchingMode(spanMatchingMode);
+
+		return true;
+	}
+
+	private void manageSubPages() {
+		/*
+		 * Remove obsolete pages (in case the user was on a sub page, went back to the 
+		 * original mapping page and now wants to access the sub pages again)
+		 */
+		Set<Pair<Type, Type>> obsoletePages = subPages.keySet().stream().
+				filter(pair -> !typeMapping.contains(pair)).collect(Collectors.toSet());
+		obsoletePages.forEach(pair -> {
+			FeatureMappingPage page = subPages.remove(pair);
+			subMappings.remove(pair);
+			subPageOrder.remove(page);
+		});
+		/*
+		 * Create new pages
+		 */
+		typeMapping.stream().filter(pair -> !subPages.containsKey(pair)).forEach(
+				pair -> createMappingPage(pair));
+	}
+
+	private void createMappingPage(Pair<Type, Type> pair) {
+		HashSet<Pair<Feature, Feature>> mapping = new HashSet<>();
+		FeatureMappingPage page = new FeatureMappingPage(pair.getFirstElement(), 
+				pair.getSecondElement(), true, mapping);
+		subPages.put(pair, page);
+		subMappings.put(pair, mapping);
+		subPageOrder.add(page);
+		addPage(page);
+	}
+
+	public GoldMappingConfig getGoldMappingConfig() {
+		return config;
+	}
+
+}
diff --git a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.coreferenceview/src/de/uniwue/mk/kall/coreferenceview/part/CorefView.java b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.coreferenceview/src/de/uniwue/mk/kall/coreferenceview/part/CorefView.java
index c6d7dc1b..223f843c 100644
--- a/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.coreferenceview/src/de/uniwue/mk/kall/coreferenceview/part/CorefView.java
+++ b/de.uniwue.mk.athen/bundles/de.uniwue.mk.kall.coreferenceview/src/de/uniwue/mk/kall/coreferenceview/part/CorefView.java
@@ -1183,6 +1183,29 @@ public class CorefView extends AEditorSubordinateViewPart {
 
 		// create and add an empty relation
 		Point selection = editor.getWidget().getSelection();
+		
+		//snap to the nearest persons
+		int beg=-1;
+		int end = -1;
+		int amount=0;
+		for(AnnotationFS a : editor.getCas().getAnnotationIndex(typNE)){
+			if(a.getBegin()>=selection.x && a.getEnd()<=selection.y){
+				amount++;
+				if(beg==-1){
+					beg = a.getBegin();
+				}
+				if(end==-1){
+					end = a.getEnd();
+				}
+				beg = a.getBegin()<=beg?a.getBegin():beg;
+				end = a.getEnd()>=end?a.getEnd():end;
+			}
+		}
+		if(amount>=2){
+			//SNAP!
+			selection.x = beg;
+			selection.y =end;
+		}
 		AnnotationFS anno = editor.getCas().createAnnotation(relationType, selection.x, selection.y);
 		editor.addAnnotation(anno);
 	}
-- 
GitLab