Index: vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationService.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationService.java	(revision 6728)
+++ vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationService.java	(revision 6728)
@@ -0,0 +1,30 @@
+package eu.clarin.cmdi.vlo.normalization;
+
+import java.util.Map;
+
+public interface NormalizationService {
+
+	
+	/*
+	 * returns normalized value from vocabulary map or specified value in case of mismatch
+	 * 
+	 * @param input - value from record
+	 * @param fallbackOutput - specified returned value in case of mismatch 
+	 * @return normalized value if there is a match otherwise input value
+	 * 
+	 */
+	
+	public String normalize(String input, String fallbackOutput);	
+	
+	
+	/*
+	 * returns returns cross map for given input value in form of facet/value map or null if cross map doesn't exist for specified value or in case of mismatch 
+	 * 
+	 * @param input - value from record
+	 * @return facet/value Map or null
+	 * 
+	 */
+	
+	public Map<String, String> getCrossMappings(String input);
+	
+}
Index: vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationVocabulary.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationVocabulary.java	(revision 6728)
+++ vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/NormalizationVocabulary.java	(revision 6728)
@@ -0,0 +1,85 @@
+package eu.clarin.cmdi.vlo.normalization;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class NormalizationVocabulary implements NormalizationService {
+
+	private Map<String, Integer> normalizationMap = null;
+	private List<Integer> regExEntries = null;
+	private VocabularyEntry[] entries = null;
+
+	// false is default because it is a special case when patterns are used in maps
+	private boolean searchInRegExes = false; 
+
+	public NormalizationVocabulary(VocabularyEntry[] entries, boolean searchInRegExes) {
+		this(entries);
+		this.searchInRegExes = searchInRegExes;
+	}
+
+	public NormalizationVocabulary(VocabularyEntry[] entries) {
+		this.entries = entries;
+
+		for (int i = 0; i < entries.length; i++) {
+			if (entries[i].isRegEx()) {
+				if (regExEntries == null)
+					regExEntries = new LinkedList<Integer>();
+				regExEntries.add(i);
+			} else {
+				if (normalizationMap == null)
+					normalizationMap = new HashMap<String, Integer>();
+				normalizationMap.put(entries[i].getOriginalVal(), i);
+			}
+		}
+	}
+
+	public String normalize(String value) {
+		return normalize(value, value);
+	}
+
+	public String normalize(String value, String fallbackResult) {
+		VocabularyEntry hit = getEntry(value);
+		return (hit != null) ? hit.getNormalizedValue() : fallbackResult;
+
+	}
+
+	public Map<String, String> getCrossMappings(String value) {
+		VocabularyEntry hit = getEntry(value);
+		return (hit != null) ? hit.getCrossMap() : null;
+	}
+
+	public VocabularyEntry getEntry(String value) {
+		Integer index = null;
+
+		index = normalizationMap.get(value);
+
+		// no hit -> check in patterns if option set
+		if (index == null && searchInRegExes)
+			for (Integer regExIndex : regExEntries) {
+				if (Pattern.compile(entries[regExIndex].getOriginalVal()).matcher(value).find()) {
+					index = regExIndex;
+					break;
+				}
+			}
+
+		return (index != null) ? entries[index] : null;
+	}
+
+	private boolean exists(VocabularyEntry entry) {
+		for (int i = 0; i < entries.length; i++) {
+			if (entries[i].getOriginalVal().equals(entry.getOriginalVal()))
+				return true;
+		}
+
+		return false;
+	}
+	
+
+	public VocabularyEntry[] getEntries(){
+		return entries;
+	}
+
+}
Index: vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/VocabularyEntry.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/VocabularyEntry.java	(revision 6728)
+++ vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/normalization/VocabularyEntry.java	(revision 6728)
@@ -0,0 +1,71 @@
+package eu.clarin.cmdi.vlo.normalization;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import eu.clarin.cmdi.vlo.pojo.CrossMapping;
+
+public class VocabularyEntry {
+	
+	private String originalVal;
+	private String normalizedValue;
+	private boolean isRegEx;
+	private Map<String, String> crossMap;
+	
+	
+	
+	
+	
+	public VocabularyEntry(String originalVal, String normalizedValue, boolean isRegEx, List<CrossMapping> crossMap) {
+		this.originalVal = originalVal;
+		this.normalizedValue = normalizedValue;
+		this.isRegEx = isRegEx;
+		this.crossMap = new HashMap<String, String>();
+		if(crossMap != null)
+			for(CrossMapping cm: crossMap){
+				this.crossMap.put(cm.getFacet(), cm.getValue());
+			}
+	}
+
+	public String getOriginalVal() {
+		return originalVal;
+	}
+	
+	public void setOriginalVal(String val) {
+		this.originalVal = val;
+	}
+	
+	public String getNormalizedValue() {
+		return normalizedValue;
+	}
+	
+	public void setNormalizedValue(String normalizedValue) {
+		this.normalizedValue = normalizedValue;
+	}
+	
+	public boolean isRegEx() {
+		return isRegEx;
+	}
+	
+	public void setRegEx(boolean isRegEx) {
+		this.isRegEx = isRegEx;
+	}
+	
+	public Map<String, String> getCrossMap() {
+		return crossMap;
+	}
+	
+	public void setCrossMap(Map<String, String> crossMap) {
+		this.crossMap = crossMap;
+	}
+	
+	
+	@Override
+	public String toString() {
+		return originalVal + " -> " + normalizedValue + ", isRegEx=" + isRegEx + ", " + crossMap.toString(); 
+	}
+
+}
Index: vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/pojo/VariantsMap.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/pojo/VariantsMap.java	(revision 6727)
+++ vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/pojo/VariantsMap.java	(revision 6728)
@@ -1,5 +1,5 @@
 package eu.clarin.cmdi.vlo.pojo;
 
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -11,4 +11,7 @@
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+
+import eu.clarin.cmdi.vlo.normalization.NormalizationVocabulary;
+import eu.clarin.cmdi.vlo.normalization.VocabularyEntry;
 
 /**
@@ -46,5 +49,5 @@
 	
 	 /**
-     * returns inverted map variant-normalizedVal
+     * returns inverted map: variant-normalizedVal
      *
      */
@@ -63,14 +66,17 @@
 	
 	
-	public List<VocabularyEntry> getMap(){
-		List map = new LinkedList<VocabularyEntry>();
+	public NormalizationVocabulary getMap(){
+		List<VocabularyEntry> listOfEntries = new ArrayList<VocabularyEntry>();
+		boolean containsRegEx = false;
 		
 		for(Mapping m: mappings)
 			if(m.getVariants() != null)
 				for(Variant v: m.getVariants()){					
-					map.add(new VocabularyEntry(v.getValue().trim(), m.getValue().trim(), v.isRegExp(), v.getCrossMappings()));
+					listOfEntries.add(new VocabularyEntry(v.getValue().trim(), m.getValue().trim(), v.isRegExp(), v.getCrossMappings()));
+					if(v.isRegExp())
+						containsRegEx = true;
 				}
-		
-		return map;
+
+		return new NormalizationVocabulary(listOfEntries.toArray(new VocabularyEntry[0]), containsRegEx); 
 		
 	}
Index: vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/pojo/VocabularyEntry.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-vocabularies/src/main/java/eu/clarin/cmdi/vlo/pojo/VocabularyEntry.java	(revision 6727)
+++ 	(revision )
@@ -1,85 +1,0 @@
-package eu.clarin.cmdi.vlo.pojo;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class VocabularyEntry {
-	
-	private String originalVal;
-	private String normalizedValue;
-	private boolean isRegEx;
-	private Map<String, String> crossMap;
-	
-	
-	
-	
-	
-	public VocabularyEntry(String originalVal, String normalizedValue, boolean isRegEx, List<CrossMapping> crossMap) {
-		this.originalVal = originalVal;
-		this.normalizedValue = normalizedValue;
-		this.isRegEx = isRegEx;
-		this.crossMap = new HashMap<String, String>();
-		if(crossMap != null)
-			for(CrossMapping cm: crossMap){
-				this.crossMap.put(cm.getFacet(), cm.getValue());
-			}
-	}
-
-	public String getOriginalVal() {
-		return originalVal;
-	}
-	
-	public void setOriginalVal(String val) {
-		this.originalVal = val;
-	}
-	
-	public String getNormalizedValue() {
-		return normalizedValue;
-	}
-	
-	public void setNormalizedValue(String normalizedValue) {
-		this.normalizedValue = normalizedValue;
-	}
-	
-	public boolean isRegEx() {
-		return isRegEx;
-	}
-	
-	public void setRegEx(boolean isRegEx) {
-		this.isRegEx = isRegEx;
-	}
-	
-	public Map<String, String> getCrossMap() {
-		return crossMap;
-	}
-	
-	public void setCrossMap(Map<String, String> crossMap) {
-		this.crossMap = crossMap;
-	}
-	
-	
-	/*
-	 * Overridden for Collection.contains method
-	 */
-	
-	@Override
-	public boolean equals(Object obj) {
-		if(obj == null || !(obj instanceof String))
-			return false;
-		String val = (String) obj;
-		if(!isRegEx)
-			return this.originalVal.equals(val) || this.normalizedValue.equals(val);
-		
-		return Pattern.compile(this.getOriginalVal()).matcher(val).find();
-		
-	}
-	
-	@Override
-	public String toString() {
-		return originalVal + " -> " + normalizedValue + ", isRegEx=" + isRegEx + ", " + crossMap.toString(); 
-	}
-
-}
