diff --git a/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js b/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js
index b2db244c25ca2825fed534f0e654f38842b3c929..53fe713f00a837c1931303dc011f49a4af4ee17c 100644
--- a/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js
+++ b/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js
@@ -20,6 +20,7 @@ var status = {
 
 for (var i = 0, l = files.length; i < l; i++) 
 {
+    vars.set("$field.INFO", translate.withArguments("processing %0/%1", [i.toString(), l.toString()]) + " . . .");
     switch (files[i].mimeType)
     {
         case "application/octet-stream"://.msg-files will not get any mimetype from the browser so let's use 
@@ -51,7 +52,7 @@ if (status.activitiesCreated > 0 || status.unlinkedMailsCreated > 0 || status.ot
 
 var messages = _getMessages(status);
 if (messages.length)
-    vars.set("$field.INFO", messages.join(", "));
+    vars.set("$field.INFO", translate.withArguments("processed %0/%1:", [i.toString(), l.toString()]) + "\n" + messages.join(", "));
 
 function _getMailObj(pDroppedFile)
 {
diff --git a/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js b/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js
index 1c866cce85e6ee96fb86a86ef55ea0b0503ba232..42654e03c0f48ffa67cc488dcada55d67653f704 100644
--- a/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js
+++ b/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js
@@ -33,9 +33,10 @@ if (changedRows.length > 0)
     var loadingConfig = entities.createConfigForLoadingRows().entity("AnyContact_entity")
                                                              .uids(contactIds)
                                                              .fields(["CONTACTID", "ORGANISATION_ID", "PERSON_ID", "STANDARD_EMAIL_COMMUNICATION"]);
+    //TODO: ignore grants when available since this is only for techincal decisions (like: does a standard-comm exist?)
     var contactRows = entities.getRows(loadingConfig);
-    //decide what to do with the data
     
+    //decide what to do with the data
     for (var i = 0, l = contactRows.length; i < l; i++) 
     {
         //first create a link
@@ -59,7 +60,7 @@ var mailObj = mail.parseRFC(vars.get("$param.MailAsText_param"));
 var unlinkedMailId = vars.get("$param.UnlinkedMailId_param");
 
 var incomingMailExec = new IncomingEmailExecutor(mailObj);
-incomingMailExec.setActivityEmployeeContactId(EmployeeUtils.getCurrentContactId());
+incomingMailExec.setActivityEmployeeContact(vars.get("$field.RESPONSIBLE_ID"));//TODO: language!
 var activityRes = incomingMailExec.createActivity(activityLinks);
 incomingMailExec.deleteUnlinkedMail(unlinkedMailId);
 
diff --git a/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js b/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js
index 38238664039762ee14eb60459947c46d3e12dd0c..773f204fd3e645dfc9e94e7e5b3f3bf3cdfd05a2 100644
--- a/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js
+++ b/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js
@@ -13,7 +13,7 @@ if (incomingMailExec.isUnlinkable())
 }
 else
 {
-    incomingMailExec.setActivityEmployeeContactId(EmployeeUtils.getCurrentContactId());
+    incomingMailExec.setActivityEmployeeContact(EmployeeUtils.getCurrentContactId());
     incomingMailExec.createActivity();
     incomingMailExec.deleteUnlinkedMail(vars.get("$sys.uid"));
     //refresh is needed for the dashboard: other elements are refreshed and display for example a new activity in the filter view while the own record (=ulinked mail) is removed
diff --git a/process/DataCaching_lib/process.js b/process/DataCaching_lib/process.js
index 62cb7b83ac50df30a5bb853943243e5540622bdb..3965f570fc041d2406b86f27110872a655ae242e 100644
--- a/process/DataCaching_lib/process.js
+++ b/process/DataCaching_lib/process.js
@@ -1,3 +1,4 @@
+import("system.db");
 import("system.vars");
 import("system.project");
 
@@ -11,11 +12,14 @@ import("system.project");
  * @param {String} pIdentifiyingName name to identify the DataCache. This MUST be unique for one data representation (e.g. key-value pair for all Languages with key ISO2-code and value the ISO3-Code). this will affect the storage-name (=name of the global variable on the client for example)
  * @param {bool} [pKeepPerLanguage=false] if true the data is kept per locale (different storing for each requested language), false when not (every language is sharing the same stoarge because only untranslated data is kept)
  * @param {String} [pLocaleOverride=current language] sometimes a special locale is required, use this parameter to specify it
+ * @param {String} [pAlias=none] sometimes you want to interact with the database and a specific alias. Whenever this is done you can specify an alias name
+ *                               the alias will be part of the storage variable name which means data is cached "per alias"
  * 
  * @class 
  */
-function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride)
+function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride, pAlias)
 {
+    this.alias = pAlias;
     this.identifyingName = pIdentifiyingName;
     this.keepPerLanguage = (pKeepPerLanguage == true);
 
@@ -42,7 +46,7 @@ function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride)
 CachedData.make = function(pIdentifiyingName, pKeepPerLanguage, pDataCallbackFunction)
 {
     return (new CachedData(pIdentifiyingName, pKeepPerLanguage, null)).load(pDataCallbackFunction);
-}
+};
 
 /**
  * loads data into a DataCache;
@@ -70,8 +74,10 @@ CachedData.prototype.load = function(pDataCallbackFunction)
             cachingEnabled = false;
     }
 
+    //always pass a aliasname to make it easier in the callback functions (you don't have to check if the alias set or not in the callback functions)
+    var dbAliasParam = this.alias || db.getCurrentAlias();
     if (!cachingEnabled)
-        return pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale);
+        return pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale, dbAliasParam);
     else
     {
         var varname = this.getVariableName();
@@ -83,7 +89,7 @@ CachedData.prototype.load = function(pDataCallbackFunction)
                 return data;
         }
         
-        data = pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale);
+        data = pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale, dbAliasParam);
         if (data == null)
         {
             this.unload();
@@ -131,6 +137,8 @@ CachedData.prototype.getVariableIdentifier = function()
 CachedData.prototype.getVariableName = function()
 {
     var res = this.getVariableIdentifier() + "." + this.locale;
+    if (this.alias)
+        res += "." + this.alias;
     return res;
 };
 
diff --git a/process/IncomingEmailExecutor_lib/process.js b/process/IncomingEmailExecutor_lib/process.js
index 096ef3111e2f05371f5de193cb0a165db89d412b..a00efeef474cdcddf7580fef63537cee8ef58119 100644
--- a/process/IncomingEmailExecutor_lib/process.js
+++ b/process/IncomingEmailExecutor_lib/process.js
@@ -1,3 +1,5 @@
+import("system.translate");
+import("Keyword_lib");
 import("EmailUtil_lib");
 import("Util_lib");
 import("system.question");
@@ -20,6 +22,7 @@ function IncomingEmailExecutor(pMail)
     //whenver this function is called it may not be in a context where a alias is given: the mail-importing-entity for example has no alias. 
     //therefore set it here manually
     this._alias = null;
+    this.locale = null;//this is maybe set later when determining an affected user for history
     this.setAlias();
     this.rawMail = pMail;
     this.mailSubject = this.rawMail[mail.MAIL_SUBJECT] || "";
@@ -47,9 +50,29 @@ function IncomingEmailExecutor(pMail)
     };
 }
 
-IncomingEmailExecutor.prototype.setActivityEmployeeContactId = function (pId)
+IncomingEmailExecutor.prototype.setActivityEmployeeContact = function (pContactId, pLanguageIso3, pSetAsFailback)
 {
-    this.activityData.employeeContactId = pId;
+    //autodetect language if not given
+    if (pLanguageIso3 == undefined)
+    {
+        var langSql = SqlCondition.begin(this._alias)
+                                  .andPrepare("CONTACT.CONTACTID", pContactId)
+                                  .buildSql("select CONTACT.ISOLANGUAGE from CONTACT");
+        var lang = db.cell(langSql, this._alias);
+        if (lang)
+            pLanguageIso3 = lang;
+    }
+
+    if (pSetAsFailback)
+    {
+        this.failbackActivityData.employeeContactId = pContactId;
+        this.failbackActivityData.employeeContactLanguage = pLanguageIso3;
+    }
+    else
+    {
+        this.activityData.employeeContactId = pContactId;
+        this.activityData.employeeContactLanguage = pLanguageIso3;
+    }
 };
 
 IncomingEmailExecutor.prototype.setAlias = function(pAlias)
@@ -59,15 +82,44 @@ IncomingEmailExecutor.prototype.setAlias = function(pAlias)
 
 IncomingEmailExecutor.prototype.getMailtextAsHtml = function()
 {
-    var htmlMailText = this.rawMail[mail.MAIL_ATTACHMENTCOUNT] + " Attachement(s)<br/><br/>\n";
+    var textInfos = [
+        translate.withArguments("Sender: %0", [this.rawMail[mail.MAIL_SENDER]], this.locale),
+        translate.withArguments("Recipients: %0", [this.mailRecipients.join(", ")], this.locale)
+    ]; 
+
+    var attachmentInfos = mail.getAttachmentInfos(this.rawMail);
+    var attachmentCount = attachmentInfos.length;
+    if (attachmentCount == 0)
+        textInfos.push(translate.text("no attachments", this.locale));
+    else
+    {
+        if (attachmentCount == 1)
+            textInfos.push(translate.withArguments("%0 attachment:", [attachmentCount], this.locale));
+        else
+            textInfos.push(translate.withArguments("%0 attachments:", [attachmentCount], this.locale));
+
+        var attachmentHtml = "";
+        var fileName;
+        for (var i = 0; i < attachmentCount; i++)
+        {
+            //don't use a <ul><li.......</ul> here since it does not look good in the client
+            [fileName] = text.decodeMS(attachmentInfos[i]);
+            attachmentHtml += "\n" + (i > 0 ? "<br/>" : "") + "&#x25CF; " + fileName;
+        }
+        textInfos.push(attachmentHtml);
+    }
+
     //since the activity has always and only a HTML-content-field we need to ensure that there will be always a HTML-content
     if (this.rawMail[mail.MAIL_HTMLTEXT])
-        htmlMailText += this.rawMail[mail.MAIL_HTMLTEXT];
+        textInfos.push("<br/>\n" + this.rawMail[mail.MAIL_HTMLTEXT]);
     else
-        htmlMailText += text.text2html(this.rawMail[mail.MAIL_TEXT], true);
-    return htmlMailText;
+        textInfos.push("<br/>\n" + text.text2html(this.rawMail[mail.MAIL_TEXT], true));
+    
+    var res = textInfos.join("<br/>\n");
+    return res;
 };
 
+
 IncomingEmailExecutor.prototype.getSenderInfo = function()
 {
     if (this._senderInfo == null)
@@ -97,7 +149,7 @@ IncomingEmailExecutor.getContactDataByEmail = function (pMailAddress, pAlias)
     var mailAddress = EmailUtils.extractAddress(pMailAddress).toUpperCase();
     var sql = SqlCondition.begin(pAlias)
     .andPrepare("COMMUNICATION.ADDR", mailAddress, "upper(#) = ?")
-    .buildSql("select CONTACT.CONTACTID, CONTACT.STATUS, CONTACT.PERSON_ID \n\
+    .buildSql("select CONTACT.CONTACTID, CONTACT.STATUS, CONTACT.PERSON_ID, CONTACT.ISOLANGUAGE \n\
                                                         from COMMUNICATION \n\
                                                         join CONTACT on (COMMUNICATION.CONTACT_ID = CONTACT.CONTACTID)");
     var res = db.table(sql, pAlias);
@@ -125,6 +177,15 @@ IncomingEmailExecutor.prototype.createActivity = function(pAdditionalLinks)
         this.activityData.links = this.activityData.links.concat(recipientContacts.prefered.length > 0 ? recipientContacts.prefered : recipientContacts.failback);
     }
 
+    var langIso3 = this.activityData.employeeContactLanguage || this.failbackActivityData.employeeContactLanguage;
+    var langIso2;
+    if (langIso3)
+    {
+        langIso2 = LanguageKeywordUtils.Iso2FromIso3(langIso3, this._alias);
+        if (langIso2)
+            this.locale = langIso2;
+    }
+
     //collecting all the information and combine it for the creation
     var activityDataForInsert = {
         subject: this.mailSubject,
@@ -171,8 +232,8 @@ IncomingEmailExecutor.prototype.autoProcess = function(pUnlinkedMailId)
 IncomingEmailExecutor.prototype._getProcessingFunction = function (pIsSender, pTargetArray)
 {
     return function(contactInfoRow) {
-        var contactId, contactStatus, contactPersonId;
-        [contactId, contactStatus, contactPersonId] = contactInfoRow;
+        var contactId, contactStatus, contactPersonId, languageIso3;
+        [contactId, contactStatus, contactPersonId, languageIso3] = contactInfoRow;
         
         //there *should* only exist no or one user per contactid, never two or more - so getUser (not getUsers) should be fine
         var user = tools.getUserByAttribute(tools.CONTACTID, [contactId]);
@@ -185,13 +246,13 @@ IncomingEmailExecutor.prototype._getProcessingFunction = function (pIsSender, pT
             var direction = pIsSender ? $KeywordRegistry.activityDirection$outgoing() : $KeywordRegistry.activityDirection$incoming();
             if (isContactActive)
             {
-                this.activityData.employeeContactId = contactId;
+                this.setActivityEmployeeContact(contactId, languageIso3);
                 this.activityData.direction = direction;
             }
             else
             {
                 //if the user is inactive, we may find a better (=active) user later
-                this.failbackActivityData.employeeContactId = contactId;
+                this.setActivityEmployeeContact(contactId, languageIso3, true);
                 this.failbackActivityData.direction = direction;
             }    
         }
diff --git a/process/KeywordData_lib/process.js b/process/KeywordData_lib/process.js
index 930d056393a8989f28842af3307d707754773264..3eb97115b302f01e8bbc722a9ad93bb8f19dc631 100644
--- a/process/KeywordData_lib/process.js
+++ b/process/KeywordData_lib/process.js
@@ -113,18 +113,20 @@ LanguageData.getData = function()
     });
 };
 
-LanguageData.getIso3Map = function(pLocale)
+LanguageData.getIso3Map = function(pLocale, pAlias)
 {
-    var cache = new CachedData("LanguagesISO3Map", true, pLocale);
-    return cache.load(function (pTranslationNecessary, pLocale){
-        var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE");
+    var dbAlias = pAlias || db.getCurrentAlias();
+    var cache = new CachedData("LanguagesISO3Map", true, pLocale, dbAlias);
+    var cachedData = cache.load(function (pTranslationNecessary, pLocale, pAlias){
+        var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.ISO2, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE", pAlias);
         var res = {};
-        var iso3, countryName;
+        var iso3, iso2, countryName;
         for (var i = 0, l = data.length; i < l; i++)
         {
-            [iso3, countryName] = data[i];
-            res[iso3] = translate.text(countryName, pLocale);
+            [iso3, iso2, countryName] = data[i];
+            res[iso3] = {name: translate.text(countryName, pLocale), iso2: iso2};
         }
         return res;
     });
+    return cachedData;
 };
\ No newline at end of file
diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js
index f0fd2438cb04e50991413362f85f97be8915c96f..ec1d8fbe077302645521473c27d39cb164efe8e7 100644
--- a/process/Keyword_lib/process.js
+++ b/process/Keyword_lib/process.js
@@ -323,8 +323,36 @@ LanguageKeywordUtils.getViewValue = function(key, locale)
         return "";
     
     var languageMap = LanguageData.getIso3Map(locale);
-    var title = languageMap[key];
+    var languageInfo = languageMap[key];
+    if (languageInfo == undefined)
+        return "";
+    var title = languageInfo.name;
     if (title == undefined)
         return "";
     return title;
+};
+
+/**
+ * deterines on server- and clientside the matching iso2-code to a iso3 by generating a map and then returning the matched result; 
+ * on clientside the map is cached
+ * 
+ * @param {String} key id value (iso3) of the language where the value shall be searched
+ * @param {String} [pAlias=the current alias] the database alias where the information shall be retrieved
+ *
+ * @return {String} iso2 or "" when nothing was found
+ * 
+ */
+LanguageKeywordUtils.Iso2FromIso3 = function(key, pAlias)
+{
+    if (!key)
+        return "";
+    //maybe this should be retrieved by a simple select on the serverside since LanguageData-methods are only cached on the client side
+    var languageMap = LanguageData.getIso3Map(null, pAlias);
+    var languageInfo = languageMap[key];
+    if (languageInfo == undefined)
+        return "";
+    var res = languageInfo.iso2;
+    if (res == undefined)
+        return "";
+    return res;
 };
\ No newline at end of file