Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/AvailabilityPostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/AvailabilityPostProcessor.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/AvailabilityPostProcessor.java	(revision 6715)
@@ -10,7 +10,5 @@
  */
 public class AvailabilityPostProcessor extends PostProcessorsWithVocabularyMap {
-
-	private static Map<String, String> availabilityMap;
-    
+	
 	private static final Integer MAX_LENGTH = 20;
     private static final String OTHER_VALUE = "Other";
@@ -19,26 +17,15 @@
     @Override
     public List<String> process(final String value) {
-        String result = value;
         List<String> resultList = new ArrayList<String>();
-
-        if (getVocabularyMap().containsKey(value)) {
-            resultList.add(getVocabularyMap().get(value));
-        } else {
-            if (result.length() > MAX_LENGTH) {
-                resultList.add(OTHER_VALUE);
-            } else {
-                resultList.add(result.trim());
-            }
-        }
+        
+        resultList.add(normalize(value, value.length() > MAX_LENGTH? OTHER_VALUE : value.trim()));
 
         return resultList;
     }
-    
-    public Map<String, String> getVocabularyMap(){
-    	if(availabilityMap == null){
-    		availabilityMap = createControlledVocabularyMap(MetadataImporter.config.getLicenseAvailabilityMapUrl());
-		 }
-    	
-		 return availabilityMap;
-    }
+
+
+	@Override
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getLicenseAvailabilityMapUrl();
+	}
 }
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/CMDIParserVTDXML.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/CMDIParserVTDXML.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/CMDIParserVTDXML.java	(revision 6715)
@@ -1,3 +1,21 @@
 package eu.clarin.cmdi.vlo.importer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.ximpleware.AutoPilot;
@@ -8,17 +26,6 @@
 import com.ximpleware.XPathEvalException;
 import com.ximpleware.XPathParseException;
+
 import eu.clarin.cmdi.vlo.FacetConstants;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class CMDIParserVTDXML implements CMDIDataProcessor {
@@ -231,5 +238,6 @@
      */
     private void processFacets(CMDIData cmdiData, VTDNav nav, FacetMapping facetMapping) throws VTDException {
-        List<FacetConfiguration> facetList = facetMapping.getFacets();
+    	    	
+        List<FacetConfiguration> facetList = facetMapping.getFacets();    	
         for (FacetConfiguration config : facetList) {
             boolean matchedPattern = false;
@@ -289,7 +297,10 @@
                 continue;
             }
-
+            
             final List<String> values = postProcess(config.getName(), value);
-            insertFacetValues(config.getName(), values, cmdiData, languageCode, allowMultipleValues, config.isCaseInsensitive());
+            
+            insertFacetValues(config.getName(), values, cmdiData, languageCode, allowMultipleValues, config.isCaseInsensitive(), true);
+            
+            crossMap(config, value, cmdiData, languageCode);
             
             //add also non curated resource type
@@ -304,5 +315,5 @@
                     derivedValues.addAll(postProcess(derivedFacet, postProcessedValue));
                 }
-                insertFacetValues(derivedFacet, derivedValues, cmdiData, languageCode, allowMultipleValues, config.isCaseInsensitive());
+                insertFacetValues(derivedFacet, derivedValues, cmdiData, languageCode, allowMultipleValues, config.isCaseInsensitive(), true);
             }
 
@@ -330,5 +341,21 @@
     }
 
-    private void insertFacetValues(String name, List<String> valueList, CMDIData cmdiData, String languageCode, boolean allowMultipleValues, boolean caseInsensitive) {
+    
+    /*
+	 * Add values to facet either they come from MD fields either from cross mapping
+	 * Advantage is given to the values from MD fields. They will be always at the begging of the list and in case
+	 * when facet doesn't allow multiple values and we already had value from cross mapping this value will be overridden
+	 * 
+	 */
+    private void insertFacetValues(String name, List<String> valueList, CMDIData cmdiData, String languageCode, boolean allowMultipleValues, boolean caseInsensitive, boolean comesFromConceptMapping) {
+    	
+    	//keep only values from original concepts, not from cross mappings
+		if(comesFromConceptMapping && !allowMultipleValues && cmdiData.getSolrDocument().containsKey(name)){
+			cmdiData.getSolrDocument().remove(name);
+		}
+		
+		if(!comesFromConceptMapping && !allowMultipleValues && cmdiData.getSolrDocument().containsKey(name))
+			return;
+    	
         for (int i = 0; i < valueList.size(); i++) {
             if (!allowMultipleValues && i > 0) {
@@ -361,3 +388,26 @@
         return resultList;
     }
+    
+    private void crossMap(FacetConfiguration config, String extractedValue, CMDIData cmdiData, String languageCode){
+    	
+        if (postProcessors.containsKey(config.getName())){
+            PostProcessor processor = postProcessors.get(config.getName());
+            if(processor instanceof PostProcessorsWithVocabularyMap){
+            	
+            	List<String> facetNames = MetadataImporter.config.getAllFacetFields();
+            	
+            	Map<String, String> crossMap = ((PostProcessorsWithVocabularyMap) processor).getCrossMappings(extractedValue);
+            	for(Entry e: crossMap.entrySet()){
+            		String toFacet = (String) e.getKey();
+            		String value = (String) e.getValue();
+            		for(String facetName: facetNames){
+            			if(toFacet.toLowerCase().equals(facetName.toLowerCase())){//normalize facet name, map can contain it in any case
+            				insertFacetValues(facetName, Arrays.asList(value), cmdiData, languageCode, config.getAllowMultipleValues(), config.isCaseInsensitive(), false);
+            			}
+            		}
+            	}
+            }
+        }
+    }
+    
 }
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/LanguageCodePostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/LanguageCodePostProcessor.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/LanguageCodePostProcessor.java	(revision 6715)
@@ -43,12 +43,8 @@
     }
     
-    @Override
-	protected Map<String, String> getVocabularyMap() {
-		if(languageNameVariantsMap == null){
-			languageNameVariantsMap = createControlledVocabularyMap(MetadataImporter.config.getLanguageNameVariantsUrl());
-		}
-		return languageNameVariantsMap;
+	@Override
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getLanguageNameVariantsUrl();
 	}
-    
 
     protected String extractLanguageCode(String value) {
@@ -59,6 +55,5 @@
         
         // map known language name variants to their offical name
-        if(getVocabularyMap().containsKey(result))
-            result = getVocabularyMap().get(result);
+        result = normalize(result);
         
         // input is already ISO 639-3?
@@ -90,3 +85,4 @@
         return result;
     }
+
 }
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/MetadataImporter.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/MetadataImporter.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/MetadataImporter.java	(revision 6715)
@@ -89,4 +89,5 @@
         POST_PROCESSORS.put(FacetConstants.FIELD_CLARIN_PROFILE, new CMDIComponentProfileNamePostProcessor());
         POST_PROCESSORS.put(FacetConstants.FIELD_RESOURCE_CLASS, new ResourceClassPostProcessor());
+        POST_PROCESSORS.put(FacetConstants.FIELD_PROFILE, new ProfileNamePostProcessor());
     }
 
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/NationalProjectPostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/NationalProjectPostProcessor.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/NationalProjectPostProcessor.java	(revision 6715)
@@ -27,7 +27,4 @@
     private final static Logger LOG = LoggerFactory.getLogger(NationalProjectPostProcessor.class);
 
-    private static Map<String, String> nationalProjectMap = null;
-    private static Map<Pattern, String> nationalProjectRegExpMap = null;
-
     /**
      * Returns the national project based on the mapping in
@@ -39,75 +36,14 @@
     @Override
     public List<String> process(String value) {
-        String input = value.trim();
         List<String> resultList = new ArrayList<String>();
-
-        if (input != null && getVocabularyMap().containsKey(input)) {
-            resultList.add(getVocabularyMap().get(input));
-            return resultList;
-        }
-
-        for (Pattern pattern : getRegExpMapping().keySet()) {
-            Matcher matcher = pattern.matcher(input);
-            if (matcher.find()) {
-                resultList.add(getRegExpMapping().get(pattern));
-                return resultList;
-            }
-        }
-
-        resultList.add("");
+        resultList.add(normalize(value.trim(), ""));
+        
         return resultList;
     }
     
-    @Override
-	protected Map<String, String> getVocabularyMap() {
-		if(nationalProjectMap == null){
-			createControlledVocabularyMap(getMappingFileUrl());
-		}
-		
-		return nationalProjectMap;
-	}
-    
-    private Map<Pattern, String> getRegExpMapping() {
-    	if (nationalProjectRegExpMap == null) {
-        	createControlledVocabularyMap(getMappingFileUrl());
-        }
-        return nationalProjectRegExpMap;
-    }
-    
-    
-	protected String getMappingFileUrl() {
-    	String projectsMappingFile = MetadataImporter.config.getNationalProjectMapping();
 
-        if (projectsMappingFile.length() == 0) {
-            // use the packaged project mapping file
-            projectsMappingFile = "/nationalProjectsMapping.xml";
-        }
-        
-    	return projectsMappingFile;
-	}
-	
 	@Override
-	protected Map<String, String> createControlledVocabularyMap(String mapUrl) {
-		if(nationalProjectMap == null){
-    		nationalProjectMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
-    	}
-    	
-    	if(nationalProjectRegExpMap == null){
-    		nationalProjectRegExpMap = new HashMap<Pattern, String>();
-    	}
-    	
-    	VariantsMap map = getMappingFromFile(mapUrl);
-        	
-    	for(Entry<String, List<Variant>> entry: map.getMap().entrySet()){
-    		for(Variant variant: entry.getValue()){
-    			if(variant.isRegExp()){
-    				nationalProjectRegExpMap.put(Pattern.compile(variant.getValue()), entry.getKey());
-    			}else{
-    				nationalProjectMap.put(variant.getValue(), entry.getKey());
-    			}        			
-    		}
-        }
-    	
-    	return nationalProjectMap;
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getNationalProjectMapping();
 	}
     
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/OrganisationPostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/OrganisationPostProcessor.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/OrganisationPostProcessor.java	(revision 6715)
@@ -23,8 +23,7 @@
         String[] splitArray = normalizeInputString(value).split(";");
         for (int i = 0; i < splitArray.length; i++) {
-            String orgaName = splitArray[i];
-            if (getVocabularyMap().containsKey(normalizeVariant(orgaName))) {
-                splitArray[i] = getVocabularyMap().get(normalizeVariant(orgaName));
-            }
+            String normalizedVal = normalize(splitArray[i], null);
+            if(normalizedVal != null)
+               	splitArray[i] = normalizeVariant(normalizedVal);
         }
         
@@ -32,10 +31,7 @@
     }
     
-    @Override
-	protected Map<String, String> getVocabularyMap() {
-		if(organisationNamesMap == null){
-			organisationNamesMap = createControlledVocabularyMap(MetadataImporter.config.getOrganisationNamesUrl());
-		}
-		return organisationNamesMap;
+	@Override
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getOrganisationNamesUrl();
 	}
     
@@ -48,4 +44,5 @@
     }
 
+
 	
     
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/PostProcessorsWithVocabularyMap.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/PostProcessorsWithVocabularyMap.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/PostProcessorsWithVocabularyMap.java	(revision 6715)
@@ -2,4 +2,5 @@
 
 import java.io.InputStream;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -9,4 +10,5 @@
 
 import eu.clarin.cmdi.vlo.pojo.VariantsMap;
+import eu.clarin.cmdi.vlo.pojo.VocabularyEntry;
 import eu.clarin.cmdi.vlo.transformers.VariantsMapMarshaller;
 
@@ -23,11 +25,47 @@
 public abstract class PostProcessorsWithVocabularyMap implements PostProcessor{
 	
-	 private final static Logger LOG = LoggerFactory.getLogger(PostProcessorsWithVocabularyMap.class);
-	 	 
+	 private final static Logger _logger = LoggerFactory.getLogger(PostProcessorsWithVocabularyMap.class);
+	 
+	 private List<VocabularyEntry> map;
+	 
+	 public PostProcessorsWithVocabularyMap(){
+		 VariantsMap varinatsRawMap = getMappingFromFile(getNormalizationMapURL());
+		 map = varinatsRawMap.getMap();
+	 }
+	 
+	
+	 /*
+	  * This method is used for normalization of facet values based on normalization maps.
+	  * In case that value is not in the map, the input value is returned.
+	  * 
+	  * @param value - original value from record
+	  * @return normalized value if there is a match otherwise original value
+	  * 
+	  */
+	 public String normalize(String value){
+		 return normalize(value, value);
+	 }
+	 
 	 
 	 /*
-	  * returns specific static map and should call createControlledVocabularyMap 
+	  * This method is used for normalization of facet values based on normalization maps.
+	  * With second parameter user can specify what to return in case when value is not in normalization map (special case for NationalProject facet).
+	  *  
+	  * @param value - original value from record
+	  * @param fallBackValue - value to be returned in case of no match
+	  * @return normalized value if there is a match otherwise returns what is specified with 2nd parameter
+	  * 
 	  */
-	 protected abstract Map<String, String> getVocabularyMap();
+	 public String normalize(String value, String fallBackValue){
+		 int ind = map.indexOf(value);
+		 return (ind != -1)? map.get(ind).getNormalizedValue() : fallBackValue;
+	 }
+	 
+	 public  Map<String, String> getCrossMappings(String value){
+		 int ind = map.indexOf(value);
+		 return (ind != -1)? map.get(ind).getCrossMap() : null; 
+	 }
+	 
+	 public abstract String getNormalizationMapURL();
 	 
 	 	 
@@ -40,5 +78,5 @@
 		 try {
 	        	
-	        	LOG.info("Reading vocabulary file from: {}", mapUrl);
+	        	_logger.info("Reading vocabulary file from: {}", mapUrl);
 	            // load records from file
 	        	// in the future this should be loaded from CLAVAS directly and the file only used as fallback
@@ -52,28 +90,12 @@
 	 }
 	 
-	 // for debug purposes
+	 
+	 
+	 // for debug
 	 public void printMap(){
-		 LOG.info("map contains {} entries", getVocabularyMap().size());
-		 for(Entry<String, String> e: getVocabularyMap().entrySet()){
-			 byte bytes[] = e.getKey().getBytes();
-			 StringBuilder sb = new StringBuilder();
-			    for (byte b : bytes)
-			        sb.append(String.format("%02X ", b));
-			    
-			 LOG.info("Key <{} {}> will be mapped to <{}>", e.getKey(), sb.toString(), e.getValue());
-		 }
-		 
-		 String s = "TÃŒbingen Curated Resource";
-		 byte bytes[] = s.getBytes();
-		 StringBuilder sb = new StringBuilder();
-	     for (byte b : bytes)
-	    	 sb.append(String.format("%02X ", b));
-	     LOG.info("{} {}", s, sb.toString());
-		    
-		 
+		 _logger.info("map contains {} entries", map.size());
+		 for(VocabularyEntry entry: map)
+			 _logger.info(entry.toString());
+		
 	 }
-	 
-	
-
-
 }
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ProfileNamePostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ProfileNamePostProcessor.java	(revision 6715)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ProfileNamePostProcessor.java	(revision 6715)
@@ -0,0 +1,22 @@
+package eu.clarin.cmdi.vlo.importer;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.List;
+
+public class ProfileNamePostProcessor extends PostProcessorsWithVocabularyMap{
+
+	@Override
+	public List<String> process(String value) {
+		// doesnt do anything
+		return Arrays.asList(value);
+	}
+
+	
+	
+	@Override
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getProfileNameMapUrl();
+	}
+
+}
Index: vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ResourceClassPostProcessor.java
===================================================================
--- vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ResourceClassPostProcessor.java	(revision 6714)
+++ vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/ResourceClassPostProcessor.java	(revision 6715)
@@ -10,5 +10,4 @@
 
 public class ResourceClassPostProcessor extends PostProcessorsWithVocabularyMap {
-	private static Map<String, String> resourceTypeMap;
 	
 	/**
@@ -31,6 +30,5 @@
         }
 		
-        if (getVocabularyMap().containsKey(value))
-        	result = getVocabularyMap().get(value);
+        result = normalize(value);
             
 		return Arrays.asList(result);
@@ -38,10 +36,6 @@
 
 	@Override
-	protected Map<String, String> getVocabularyMap() {
-		if(resourceTypeMap == null){
-			resourceTypeMap = createControlledVocabularyMap(MetadataImporter.config.getResourceClassMapUrl());
-		 }
-    	
-		 return resourceTypeMap;
+	public String getNormalizationMapURL() {
+		return MetadataImporter.config.getResourceClassMapUrl();
 	}
 }
