diff --git a/openbis/dist/server/export-master-data.py b/openbis/dist/server/export-master-data.py
index 5b7de19ef0671857eb759b522a2538409f692bda..2dbb0b48415e00d16c994325427fc676bb1c192e 100644
--- a/openbis/dist/server/export-master-data.py
+++ b/openbis/dist/server/export-master-data.py
@@ -3,8 +3,16 @@
 #
 # To execute it, please run the ./export-master-data.sh 
 #
+import codecs
 import sys
 import re
+import os
+from datetime import datetime
+from java.lang import System
+
+ENCODING = "utf-8"
+
+OUTPUT_DIR_PROP_KEY = "master.data.output.dir"
 
 VARNAME_PREFIXES = {
   "EXPERIMENT" : "exp_type_",               
@@ -18,16 +26,31 @@ VARNAME_PREFIXES = {
   "VOCABULARY_TERM" : "vocabulary_term_"               
 }
 
+
 def getVarName(type, var):
     # remove minuses, dots and colons 
     # they are not valid characters for Python variables
     normalized =  re.sub("[\\-\\.:\\$]+", "", var)
     return VARNAME_PREFIXES[type] + normalized
+
+def is_ascii(str):
+    try:
+        str.decode('ascii')
+    except UnicodeDecodeError:
+        return False
+    
+    return True
     
 def strLiteral(var):
     if var:
-        return "'" + var + "'"
+        if is_ascii(var):
+            # ASCII string
+            return "'" + var + "'"
+        else:
+            # UNICODE string
+            return "u'" + var + "'"
     else: 
+        # NULL
         return 'None'
     
 def codeLiteral(code):
@@ -37,17 +60,18 @@ def codeLiteral(code):
     return strLiteral(normalized)
 
 
-def exportFileFormatType(fileType, out):
+def exportFileFormatType(fileType):
     var = getVarName("FILE_FORMAT", fileType.getCode())
     code = codeLiteral(fileType.getCode())
     description = strLiteral(fileType.getDescription())
-    snippet = """
+
+    return """
 %(var)s = tr.createNewFileFormatType(%(code)s)
 %(var)s.setDescription(%(description)s)
 """ % vars()
-    out.write(snippet)
 
-def exportVocabulary(vocabulary, out):
+
+def exportVocabulary(vocabulary):
     var = getVarName("VOCABULARY", vocabulary.getCode())
     code = codeLiteral(vocabulary.getCode())
     description = strLiteral(vocabulary.getDescription())
@@ -55,14 +79,15 @@ def exportVocabulary(vocabulary, out):
     isManagedInternally = vocabulary.isManagedInternally();
     isInternalNamespace = vocabulary.isInternalNamespace();
     isChosenFromList = vocabulary.isChosenFromList();
-    out.write("""
+    
+    result = """
 %(var)s = tr.createNewVocabulary(%(code)s)
 %(var)s.setDescription(%(description)s)
 %(var)s.setUrlTemplate(%(urlTemplate)s)
 %(var)s.setManagedInternally(%(isManagedInternally)s)
 %(var)s.setInternalNamespace(%(isInternalNamespace)s)
 %(var)s.setChosenFromList(%(isChosenFromList)s)
-""" % vars())
+""" % vars()
     
     for term in vocabulary.getTerms():
         term_var = getVarName("VOCABULARY_TERM", vocabulary.getCode() + "_" + term.getCode())
@@ -70,25 +95,27 @@ def exportVocabulary(vocabulary, out):
         term_description = strLiteral(term.getDescription())
         term_label = strLiteral(term.getLabel())
         term_ordinal = term.getOrdinal()
-        out.write("""
+        result = result + """
 %(term_var)s = tr.createNewVocabularyTerm(%(term_code)s)
 %(term_var)s.setDescription(%(term_description)s)
 %(term_var)s.setLabel(%(term_label)s)
 %(term_var)s.setOrdinal(%(term_ordinal)s)
 %(var)s.addTerm(%(term_var)s)
-""" % vars())
+""" % vars()
 
-def exportExperimentType(experimentType, out):
+    return result
+
+        
+def exportExperimentType(experimentType):
     var = getVarName("EXPERIMENT", experimentType.getCode())
     code = codeLiteral(experimentType.getCode())
     description = strLiteral(experimentType.getDescription())
-    snippet = """
+    return """
 %(var)s = tr.createNewExperimentType(%(code)s)
 %(var)s.setDescription(%(description)s)
 """ % vars()
-    out.write(snippet)
 
-def exportSampleType(sampleType, out):
+def exportSampleType(sampleType):
     var = getVarName("SAMPLE", sampleType.getCode())
     code = codeLiteral(sampleType.getCode())
     description = strLiteral(sampleType.getDescription())
@@ -96,7 +123,7 @@ def exportSampleType(sampleType, out):
     isSubcodeUnique = sampleType.isSubcodeUnique()
     isAutoGeneratedCode = sampleType.isAutoGeneratedCode()
     generatedCodePrefix = strLiteral(sampleType.getGeneratedCodePrefix())
-    snippet = """
+    return """
 %(var)s = tr.createNewSampleType(%(code)s)
 %(var)s.setDescription(%(description)s)
 %(var)s.setListable(%(listable)s)
@@ -104,31 +131,28 @@ def exportSampleType(sampleType, out):
 %(var)s.setAutoGeneratedCode(%(isAutoGeneratedCode)s)
 %(var)s.setGeneratedCodePrefix(%(generatedCodePrefix)s)
 """ % vars()
-    out.write(snippet)
 
-def exportDataSetType(dataSetType, out):
+def exportDataSetType(dataSetType):
     var = getVarName("DATA_SET", dataSetType.getCode())
     code = codeLiteral(dataSetType.getCode())
     description = strLiteral(dataSetType.getDescription())
     isContainerType = dataSetType.isContainerType()
-    snippet = """
+    return """
 %(var)s = tr.createNewDataSetType(%(code)s)
 %(var)s.setDescription(%(description)s)
 %(var)s.setContainerType(%(isContainerType)s)
 """ % vars()
-    out.write(snippet)
 
-def exportMaterialType(materialType, out):
+def exportMaterialType(materialType):
     var = getVarName("MATERIAL", materialType.getCode())
     code = codeLiteral(materialType.getCode())
     description = strLiteral(materialType.getDescription())
-    snippet = """
+    return """
 %(var)s = tr.createNewMaterialType(%(code)s)
 %(var)s.setDescription(%(description)s)
 """ % vars()
-    out.write(snippet)
     
-def exportPropertyType(propertyType, out):
+def exportPropertyType(propertyType):
     var = getVarName("PROPERTY", propertyType.getCode())
     code = codeLiteral(propertyType.getCode())
     label = strLiteral(propertyType.getLabel())
@@ -146,16 +170,15 @@ def exportPropertyType(propertyType, out):
     isManagedInternally = propertyType.isManagedInternally() 
     isInternalNamespace = propertyType.isInternalNamespace()
     
-    snippet = """
+    return """
 %(var)s = tr.createNewPropertyType(%(code)s, DataType.%(dataType)s)
 %(var)s.setLabel(%(label)s)
 %(var)s.setManagedInternally(%(isManagedInternally)s)
 %(var)s.setInternalNamespace(%(isInternalNamespace)s)
 %(specialSetters)s
 """ % vars()
-    out.write(snippet)
 
-def exportAssignment(assignment, out):
+def exportAssignment(assignment):
     
     var = getVarName("ASSIGNMENT", 
                      assignment.getEntityKind().name() + "_" + 
@@ -166,52 +189,53 @@ def exportAssignment(assignment, out):
     isMandatory = assignment.isMandatory()
     section = strLiteral(assignment.getSection())
     posInForms = assignment.getPositionInForms()
-    snippet = """
+    return """
 %(var)s = tr.assignPropertyType(%(entityVar)s, %(propertyVar)s)
 %(var)s.setMandatory(%(isMandatory)s)
 %(var)s.setSection(%(section)s)
 %(var)s.setPositionInForms(%(posInForms)s)
 """ % vars()
-    out.write(snippet)
 
 
-out = sys.stdout
+def defaultOutDirName():
+  now = datetime.now()
+  return "./exported-master-data-" + now.strftime("%y-%m-%d-%H-%M")
+
+
+#
+# Main script
+#
+
+outDir = System.getProperty(OUTPUT_DIR_PROP_KEY, defaultOutDirName())
+print "Exporting master data to ", outDir, "..."
 
-print "# "
-print "# Exporting master data to ", out.name, "..."
-print "# "
 
 tr = service.transaction()
 
-out.write("""
+exportedContent =  ( 
+  [exportFileFormatType(fileType) for fileType in tr.listFileFormatTypes()] + 
+  [exportVocabulary(vocabulary)   for vocabulary in tr.listVocabularies()] + 
+  [exportExperimentType(expType)  for expType in tr.listExperimentTypes()] + 
+  [exportSampleType(sampleType)   for sampleType in tr.listSampleTypes()] +
+  [exportDataSetType(dataSetType) for dataSetType in tr.listDataSetTypes()] +
+  [exportMaterialType(materialType) for materialType in tr.listMaterialTypes()] + 
+  [exportPropertyType(propertyType) for propertyType in tr.listPropertyTypes()] + 
+  [exportAssignment(assignment) for assignment in tr.listPropertyAssignments()] 
+);
+    
+if not os.path.exists(outDir):
+    os.makedirs(outDir)
+    
+out = codecs.open(outDir + "/master-data.py", "w", ENCODING)
+out.write("""# -*- coding: %(ENCODING)s -*-
 import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.DataType as DataType
 
 tr = service.transaction()
 
-""")
+""" % vars())
 
-for fileType in tr.listFileFormatTypes():
-    exportFileFormatType(fileType, out)
-    
-for vocabulary in tr.listVocabularies():
-    exportVocabulary(vocabulary, out)
-    
-for expType in tr.listExperimentTypes():
-    exportExperimentType(expType, out)
-    
-for sampleType in tr.listSampleTypes():
-    exportSampleType(sampleType, out)
-    
-for dataSetType in tr.listDataSetTypes():
-    exportDataSetType(dataSetType, out)
-    
-for materialType in tr.listMaterialTypes():
-    exportMaterialType(materialType, out)
-    
-for propertyType in tr.listPropertyTypes():
-    exportPropertyType(propertyType, out)
-    
-for assignment in tr.listPropertyAssignments():
-    exportAssignment(assignment, out)
-    
-out.close()
\ No newline at end of file
+exportedText = ''.join(exportedContent)
+out.write(exportedText.encode(ENCODING))
+out.close()
+
+print "DONE"
\ No newline at end of file