diff --git a/.liquibase/_____SYSTEMALIAS/basic/2019.2/changelog.xml b/.liquibase/_____SYSTEMALIAS/basic/2019.2/changelog.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d389926043b6ea55c275f5074e7234d8874dc4cc
--- /dev/null
+++ b/.liquibase/_____SYSTEMALIAS/basic/2019.2/changelog.xml
@@ -0,0 +1,5 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <include relativeToChangelogFile="true" file="create_asys_notifications.xml"/>
+    <include relativeToChangelogFile="true" file="create_asys_notificationcontents.xml"/>
+</databaseChangeLog>
diff --git a/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notificationcontents.xml b/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notificationcontents.xml
new file mode 100644
index 0000000000000000000000000000000000000000..83818826decb7b62e72d42f34875cb823311b982
--- /dev/null
+++ b/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notificationcontents.xml
@@ -0,0 +1,22 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+<changeSet author="a.schindlbeck" id="6b25f062-fb39-4230-9348-b67ec5ec45a1">
+    <createTable tableName="ASYS_NOTIFICATIONCONTENTS">
+        <column name="CONTENTID" type="CHAR(36)">
+            <constraints primaryKey="true" primaryKeyName="PK_ASYS_NOTIFICATIONCONTENTS_CONTENTID"/>
+        </column>
+        <column name="BACKPACK" type="CLOB"/>
+        <column name="CAPTION" type="VARCHAR(512)"/>
+        <column name="CREATIONDATE" type="BIGINT"/>
+        <column name="DESCRIPTION" type="VARCHAR(1023)"/>
+        <column name="FORCEDPRIORITY" type="INTEGER"/>
+        <column name="ICON_INFO" type="VARCHAR(1023)"/>
+        <column name="LIFETIME" type="BIGINT"/>
+        <column name="LINK_INFO" type="VARCHAR(1023)"/>
+        <column name="ORIGINATORNAME" type="VARCHAR(63)"/>
+        <column name="RECIPIENTUSERIDS" type="CLOB"/>
+        <column name="TYPECODE" type="VARCHAR(63)"/>
+        <column name="VERSION" type="INTEGER"/>
+    </createTable>
+</changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notifications.xml b/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notifications.xml
new file mode 100644
index 0000000000000000000000000000000000000000..540cf0a19ee9c36c179b3f49a772afd8495473f7
--- /dev/null
+++ b/.liquibase/_____SYSTEMALIAS/basic/2019.2/create_asys_notifications.xml
@@ -0,0 +1,17 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+<changeSet author="a.schindlbeck" id="98f057b6-0140-4edd-b08d-9cc7cf178bab">
+    <!---
+	its ok to drop the old ASYS_NOTIFICATIONS due to new version
+    -->
+    <dropTable tableName="ASYS_NOTIFICATIONS"/>
+    <createTable tableName="ASYS_NOTIFICATIONS">
+        <column name="ID" type="CHAR(36)">
+            <constraints primaryKey="true" primaryKeyName="PK_ASYS_NOTIFICATIONS_ID"/>
+        </column>
+        <column name="CONTENTID" type="CHAR(36)"/>
+        <column name="STATE" type="VARCHAR(16)"/>
+        <column name="USERID" type="VARCHAR(63)"/>
+    </createTable>
+</changeSet>
+</databaseChangeLog>
diff --git a/.liquibase/_____SYSTEMALIAS/basic/init/struct/create_asys_notificationcontents.xml b/.liquibase/_____SYSTEMALIAS/basic/init/struct/create_asys_notificationcontents.xml
new file mode 100644
index 0000000000000000000000000000000000000000..83818826decb7b62e72d42f34875cb823311b982
--- /dev/null
+++ b/.liquibase/_____SYSTEMALIAS/basic/init/struct/create_asys_notificationcontents.xml
@@ -0,0 +1,22 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+<changeSet author="a.schindlbeck" id="6b25f062-fb39-4230-9348-b67ec5ec45a1">
+    <createTable tableName="ASYS_NOTIFICATIONCONTENTS">
+        <column name="CONTENTID" type="CHAR(36)">
+            <constraints primaryKey="true" primaryKeyName="PK_ASYS_NOTIFICATIONCONTENTS_CONTENTID"/>
+        </column>
+        <column name="BACKPACK" type="CLOB"/>
+        <column name="CAPTION" type="VARCHAR(512)"/>
+        <column name="CREATIONDATE" type="BIGINT"/>
+        <column name="DESCRIPTION" type="VARCHAR(1023)"/>
+        <column name="FORCEDPRIORITY" type="INTEGER"/>
+        <column name="ICON_INFO" type="VARCHAR(1023)"/>
+        <column name="LIFETIME" type="BIGINT"/>
+        <column name="LINK_INFO" type="VARCHAR(1023)"/>
+        <column name="ORIGINATORNAME" type="VARCHAR(63)"/>
+        <column name="RECIPIENTUSERIDS" type="CLOB"/>
+        <column name="TYPECODE" type="VARCHAR(63)"/>
+        <column name="VERSION" type="INTEGER"/>
+    </createTable>
+</changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/_____SYSTEMALIAS/changelog.xml b/.liquibase/_____SYSTEMALIAS/changelog.xml
index 5fea0f98a129af771181ebddc56030c59aa75c10..0754d5e05adc7a470dd86c988b58939825717e3d 100644
--- a/.liquibase/_____SYSTEMALIAS/changelog.xml
+++ b/.liquibase/_____SYSTEMALIAS/changelog.xml
@@ -1,4 +1,5 @@
 <?xml version="1.1" encoding="UTF-8" standalone="no"?>
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
     <include file="basic/init/init.xml"/>
+    <include file="basic/2019.2/changelog.xml"/>
 </databaseChangeLog>
diff --git a/entity/Analyses_entity/Analyses_entity.aod b/entity/Analyses_entity/Analyses_entity.aod
index 4a74b5723f30e1fa25db872e2b5f15de7ce5410f..5aeae376f2304ddae22c44736a846177419ffc5b 100644
--- a/entity/Analyses_entity/Analyses_entity.aod
+++ b/entity/Analyses_entity/Analyses_entity.aod
@@ -1,37 +1,37 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.1">
-  <name>Analyses_entity</name>
-  <title>Analyses</title>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <icon>VAADIN:GRID_BIG_O</icon>
-  <recordContainer>jdito</recordContainer>
-  <entityFields>
-    <entityProvider>
-      <name>#PROVIDER</name>
-    </entityProvider>
-    <entityField>
-      <name>NEW_TASKS</name>
-      <title>New tasks</title>
-      <contentType>NUMBER</contentType>
-      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js</valueProcess>
-    </entityField>
-    <entityField>
-      <name>OVERDUE_TASKS</name>
-      <title>Overdue tasks</title>
-      <contentType>NUMBER</contentType>
-      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js</valueProcess>
-    </entityField>
-    <entityField>
-      <name>IMMINENT_APPOINTMENTS</name>
-      <title>Imminent appointments for today</title>
-      <contentType>NUMBER</contentType>
-      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js</valueProcess>
-    </entityField>
-  </entityFields>
-  <recordContainers>
-    <jDitoRecordContainer>
-      <name>jdito</name>
-      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
-    </jDitoRecordContainer>
-  </recordContainers>
-</entity>
+<?xml version="1.0" encoding="UTF-8"?>
+<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.1">
+  <name>Analyses_entity</name>
+  <title>Analyses</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <icon>VAADIN:GRID_BIG_O</icon>
+  <recordContainer>jdito</recordContainer>
+  <entityFields>
+    <entityProvider>
+      <name>#PROVIDER</name>
+    </entityProvider>
+    <entityField>
+      <name>NEW_TASKS</name>
+      <title>New tasks</title>
+      <contentType>NUMBER</contentType>
+      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>OVERDUE_TASKS</name>
+      <title>Overdue tasks</title>
+      <contentType>NUMBER</contentType>
+      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>IMMINENT_APPOINTMENTS</name>
+      <title>Imminent appointments for today</title>
+      <contentType>NUMBER</contentType>
+      <valueProcess>%aditoprj%/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js</valueProcess>
+    </entityField>
+  </entityFields>
+  <recordContainers>
+    <jDitoRecordContainer>
+      <name>jdito</name>
+      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+    </jDitoRecordContainer>
+  </recordContainers>
+</entity>
diff --git a/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js b/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js
index 946744b43d4d64f0d1591aeedc090210abde57c7..47a1fc47f439997182d48840a09062d6777baad9 100644
--- a/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js
+++ b/entity/Analyses_entity/entityfields/imminent_appointments/valueProcess.js
@@ -1,55 +1,55 @@
-import("system.SQLTYPES");
-import("system.logging");
-import("system.db");
-import("system.datetime");
-import("system.result");
-import("system.vars");
-import("Date_lib");
-import("Sql_lib");
-import("system.calendars");
-import("Calendar_lib");
-
-var pFilter =  reset_filterEvent();
-var conditions = [];
-var conditioncount = 0;
-var user = undefined;
-var stati = [];
-var entries = [];
-
-var startnumber = Number(vars.get("$sys.date"));
-var endnumber = startnumber + 43200000 ;
-
-var start = startnumber + "";
-var end = endnumber + "";
-
-if ( pFilter.tentative == "true" )    
-    stati.push(calendars.STATUS_TENTATIVE);
-
-if ( pFilter.cancelled == "true" )    
-    stati.push(calendars.STATUS_CANCELLED);
-
-if ( pFilter.confirmed == "true" )
-    stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
-
-if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true")
-    stati.push(calendars.STATUS_FREE);
-
-if ( pFilter.user != "" )	
-    user = (pFilter.user).trim();
-
-for ( var z = 0; z < stati.length; z++ )
-    _addEntryCondition(conditions, ++conditioncount,
-    {
-        TYPE: calendars.VEVENT,
-        START: start,
-        END: end,
-        USER: user,
-        STATUS: stati[z]
-    });
-
-conditions["COUNT"] = String(conditioncount);
-entries = calendars.getEntries(conditions);
-
-logging.log("entries: " + entries.toSource());
-
+import("system.SQLTYPES");
+import("system.logging");
+import("system.db");
+import("system.datetime");
+import("system.result");
+import("system.vars");
+import("Date_lib");
+import("Sql_lib");
+import("system.calendars");
+import("Calendar_lib");
+
+var pFilter =  reset_filterEvent();
+var conditions = [];
+var conditioncount = 0;
+var user = undefined;
+var stati = [];
+var entries = [];
+
+var startnumber = Number(vars.get("$sys.date"));
+var endnumber = startnumber + 43200000 ;
+
+var start = startnumber + "";
+var end = endnumber + "";
+
+if ( pFilter.tentative == "true" )    
+    stati.push(calendars.STATUS_TENTATIVE);
+
+if ( pFilter.cancelled == "true" )    
+    stati.push(calendars.STATUS_CANCELLED);
+
+if ( pFilter.confirmed == "true" )
+    stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
+
+if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true")
+    stati.push(calendars.STATUS_FREE);
+
+if ( pFilter.user != "" )	
+    user = (pFilter.user).trim();
+
+for ( var z = 0; z < stati.length; z++ )
+    _addEntryCondition(conditions, ++conditioncount,
+    {
+        TYPE: calendars.VEVENT,
+        START: start,
+        END: end,
+        USER: user,
+        STATUS: stati[z]
+    });
+
+conditions["COUNT"] = String(conditioncount);
+entries = calendars.getEntries(conditions);
+
+logging.log("entries: " + entries.toSource());
+
 result.string(entries.length);
\ No newline at end of file
diff --git a/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js b/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js
index d139fcf5123f04e673e7ce07f2623849d73be9f7..497dffdbfa7ef331b91e5568df2ac738bc09477c 100644
--- a/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js
+++ b/entity/Analyses_entity/entityfields/new_tasks/valueProcess.js
@@ -1,11 +1,11 @@
-import("system.datetime");
-import("system.db");
-import("system.result");
-import("system.vars");
-import("Date_lib");
-import("Sql_lib");
-import("system.SQLTYPES")
-
-var opentask = db.cell("select count(STATUS) from TASK join AB_KEYWORD_ENTRY on KEYID = STATUS and CONTAINER  = 'TaskStatus' and TITLE = 'new' group by KEYID, AB_KEYWORD_ENTRY.TITLE");                             
-                                  
+import("system.datetime");
+import("system.db");
+import("system.result");
+import("system.vars");
+import("Date_lib");
+import("Sql_lib");
+import("system.SQLTYPES")
+
+var opentask = db.cell("select count(STATUS) from TASK join AB_KEYWORD_ENTRY on KEYID = STATUS and CONTAINER  = 'TaskStatus' and TITLE = 'new' group by KEYID, AB_KEYWORD_ENTRY.TITLE");                             
+                                  
 result.string(opentask);
\ No newline at end of file
diff --git a/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js b/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js
index 310743e11054a6f806f4a8c0810856072f76ca36..9708434347425c22451c1cf149c8e22e2c6034d2 100644
--- a/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js
+++ b/entity/Analyses_entity/entityfields/overdue_tasks/valueProcess.js
@@ -1,15 +1,15 @@
-import("system.db");
-import("system.datetime");
-import("system.result");
-import("system.vars");
-import("Date_lib");
-import("Sql_lib");
-
-
-var overduetask = db.cell(SqlCondition.begin()
-                                   .andPrepare("TASK.MATURITY_DATE", vars.get("$sys.date"), "# < ?")
-                                   .buildSql("select count(TASKID) from TASK", "1=2"));
-                                                                  
-result.string(overduetask);
-
-
+import("system.db");
+import("system.datetime");
+import("system.result");
+import("system.vars");
+import("Date_lib");
+import("Sql_lib");
+
+
+var overduetask = db.cell(SqlCondition.begin()
+                                   .andPrepare("TASK.MATURITY_DATE", vars.get("$sys.date"), "# < ?")
+                                   .buildSql("select count(TASKID) from TASK", "1=2"));
+                                                                  
+result.string(overduetask);
+
+
diff --git a/entity/SalesprojectAnalyses_entity/recordcontainers/jdito/contentProcess.js b/entity/SalesprojectAnalyses_entity/recordcontainers/jdito/contentProcess.js
index 443d47dfa6d3813e180e916b9c2d0328f6a4bd9d..0eb24b9e842ca3435a90aaf55a691acaa95586ba 100644
--- a/entity/SalesprojectAnalyses_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/SalesprojectAnalyses_entity/recordcontainers/jdito/contentProcess.js
@@ -1,34 +1,34 @@
-import("system.logging");
-import("system.vars");
-import("system.datetime");
-import("system.db");
-import("system.result");
-import("system.translate");
-import("Data_lib");
-import("Keyword_lib");
-import("Money_lib");
-import("KeywordRegistry_basic");
-    
-// load data
-
-var phases = db.table("select KEYID, AB_KEYWORD_ENTRY.TITLE, count(PHASE), AB_KEYWORD_ENTRY.SORTING \n\
-from SALESPROJECT join AB_KEYWORD_ENTRY on KEYID = PHASE and  CONTAINER  = 'SalesprojectPhase' and SORTING <> 7 \n\
-group by KEYID, AB_KEYWORD_ENTRY.TITLE, AB_KEYWORD_ENTRY.SORTING order by SORTING");
-
-for(i = 0; i < phases.length; i++){
-    if(phases[i][1] == "${SALESPROJECT_OFFER}"){
-        phases[i][1] = "Offer";
-    }   
-}
- 
-result.object(phases);
-
-
-
-
-
-
-
-
-
-
+import("system.logging");
+import("system.vars");
+import("system.datetime");
+import("system.db");
+import("system.result");
+import("system.translate");
+import("Data_lib");
+import("Keyword_lib");
+import("Money_lib");
+import("KeywordRegistry_basic");
+    
+// load data
+
+var phases = db.table("select KEYID, AB_KEYWORD_ENTRY.TITLE, count(PHASE), AB_KEYWORD_ENTRY.SORTING \n\
+from SALESPROJECT join AB_KEYWORD_ENTRY on KEYID = PHASE and  CONTAINER  = 'SalesprojectPhase' and SORTING <> 7 \n\
+group by KEYID, AB_KEYWORD_ENTRY.TITLE, AB_KEYWORD_ENTRY.SORTING order by SORTING");
+
+for(i = 0; i < phases.length; i++){
+    if(phases[i][1] == "${SALESPROJECT_OFFER}"){
+        phases[i][1] = "Offer";
+    }   
+}
+ 
+result.object(phases);
+
+
+
+
+
+
+
+
+
+
diff --git a/entity/SalesprojectCompetition_entity/entityfields/image/valueProcess.js b/entity/SalesprojectCompetition_entity/entityfields/image/valueProcess.js
index d071e384e95b26e1b3013d43ac5c4f45ae4cc579..dac257b091616b1d7320eec46615813728b6faf0 100644
--- a/entity/SalesprojectCompetition_entity/entityfields/image/valueProcess.js
+++ b/entity/SalesprojectCompetition_entity/entityfields/image/valueProcess.js
@@ -1,4 +1,4 @@
-import("system.vars");
-import("system.result");
-
+import("system.vars");
+import("system.result");
+
 result.string("TEXT:" + vars.getString("$field.ORGANISATION_NAME"));
\ No newline at end of file
diff --git a/neonContext/Analyses/Analyses.aod b/neonContext/Analyses/Analyses.aod
index ea8a1ab388a5dfea3efe36fa25c0ddbbe6bab0fb..f9466ef0070a184017d9a5ace7105ef623acd44f 100644
--- a/neonContext/Analyses/Analyses.aod
+++ b/neonContext/Analyses/Analyses.aod
@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.0">
-  <name>Analyses</name>
-  <title>Analyses</title>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <filterview>MyDashboardScoreCard_view</filterview>
-  <entity>Analyses_entity</entity>
-  <references>
-    <neonViewReference>
-      <name>f995b030-7b74-4513-89ca-57c6979ac06f</name>
-      <view>MyDashboardScoreCard_view</view>
-    </neonViewReference>
-  </references>
-</neonContext>
+<?xml version="1.0" encoding="UTF-8"?>
+<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.0">
+  <name>Analyses</name>
+  <title>Analyses</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <filterview>MyDashboardScoreCard_view</filterview>
+  <entity>Analyses_entity</entity>
+  <references>
+    <neonViewReference>
+      <name>f995b030-7b74-4513-89ca-57c6979ac06f</name>
+      <view>MyDashboardScoreCard_view</view>
+    </neonViewReference>
+  </references>
+</neonContext>
diff --git a/neonNotificationType/AndisNotification/AndisNotification.aod b/neonNotificationType/AndisNotification/AndisNotification.aod
new file mode 100644
index 0000000000000000000000000000000000000000..7aae24c40748d72225570cd8d6f72b9c81ba6c15
--- /dev/null
+++ b/neonNotificationType/AndisNotification/AndisNotification.aod
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonNotificationType xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonNotificationType/1.1.0">
+  <name>AndisNotification</name>
+  <title>Andis Noti</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <resultFrameNeon></resultFrameNeon>
+  <onResultOpen>%aditoprj%/neonNotificationType/AndisNotification/onResultOpen.js</onResultOpen>
+  <context>Contact</context>
+</neonNotificationType>
diff --git a/others/db_changes/Data_alias/basic/2019.2/AttributeKeyword.xml b/neonNotificationType/AndisNotification/onResultOpen.js
similarity index 100%
rename from others/db_changes/Data_alias/basic/2019.2/AttributeKeyword.xml
rename to neonNotificationType/AndisNotification/onResultOpen.js
diff --git a/neonView/MyDashboardScoreCard_view/MyDashboardScoreCard_view.aod b/neonView/MyDashboardScoreCard_view/MyDashboardScoreCard_view.aod
index c72f7535143b95cb61379886ac1b32b0be2994e3..1dda983c317269889fd41ecd94a1666364e88dae 100644
--- a/neonView/MyDashboardScoreCard_view/MyDashboardScoreCard_view.aod
+++ b/neonView/MyDashboardScoreCard_view/MyDashboardScoreCard_view.aod
@@ -1,49 +1,49 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
-  <name>MyDashboardScoreCard_view</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <dashletConfigurations>
-    <neonDashletConfiguration>
-      <name>Information</name>
-      <title>To-Do</title>
-      <fragment>Analyses/full</fragment>
-      <singleton v="true" />
-      <icon>VAADIN:CLIPBOARD_CHECK</icon>
-      <categories>
-        <neonDashletCategory>
-          <name>tasks</name>
-          <title>Tasks</title>
-        </neonDashletCategory>
-        <neonDashletCategory>
-          <name>calendar</name>
-          <title>Calendar</title>
-        </neonDashletCategory>
-      </categories>
-    </neonDashletConfiguration>
-  </dashletConfigurations>
-  <layout>
-    <boxLayout>
-      <name>layout</name>
-    </boxLayout>
-  </layout>
-  <children>
-    <scoreCardViewTemplate>
-      <name>Scorecard</name>
-      <entityField>#ENTITY</entityField>
-      <fields>
-        <entityFieldLink>
-          <name>158d3dd5-4de6-470b-b61d-6de1e9907264</name>
-          <entityField>OVERDUE_TASKS</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>5bbd7580-6fdd-4134-b33a-1082f4891c7c</name>
-          <entityField>NEW_TASKS</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>3631eda6-dfda-4c75-9caa-8b2c2e7c39e4</name>
-          <entityField>IMMINENT_APPOINTMENTS</entityField>
-        </entityFieldLink>
-      </fields>
-    </scoreCardViewTemplate>
-  </children>
-</neonView>
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
+  <name>MyDashboardScoreCard_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <dashletConfigurations>
+    <neonDashletConfiguration>
+      <name>Information</name>
+      <title>To-Do</title>
+      <fragment>Analyses/full</fragment>
+      <singleton v="true" />
+      <icon>VAADIN:CLIPBOARD_CHECK</icon>
+      <categories>
+        <neonDashletCategory>
+          <name>tasks</name>
+          <title>Tasks</title>
+        </neonDashletCategory>
+        <neonDashletCategory>
+          <name>calendar</name>
+          <title>Calendar</title>
+        </neonDashletCategory>
+      </categories>
+    </neonDashletConfiguration>
+  </dashletConfigurations>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <scoreCardViewTemplate>
+      <name>Scorecard</name>
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>158d3dd5-4de6-470b-b61d-6de1e9907264</name>
+          <entityField>OVERDUE_TASKS</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>5bbd7580-6fdd-4134-b33a-1082f4891c7c</name>
+          <entityField>NEW_TASKS</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>3631eda6-dfda-4c75-9caa-8b2c2e7c39e4</name>
+          <entityField>IMMINENT_APPOINTMENTS</entityField>
+        </entityFieldLink>
+      </fields>
+    </scoreCardViewTemplate>
+  </children>
+</neonView>
diff --git a/process/Calendar_lib/process.js b/process/Calendar_lib/process.js
index 5095c0e83d4d28cbb9be1dda09e274e143152668..d7e20bff690a2d93e1bd7270d1c8e224d07a7091 100644
--- a/process/Calendar_lib/process.js
+++ b/process/Calendar_lib/process.js
@@ -1,1907 +1,1907 @@
-import("system.neon");
-import("system.vars");
-import("system.db");
-import("system.translate");
-import("system.datetime");
-import("system.swing");
-import("system.eMath");
-import("system.calendars");
-import("system.logging");
-import("system.tools");
-import("system.text");
-import("system.question");
-import("system.SQLTYPES");
-import("system.result");
-import("Util_lib");
-import("system.util")
-
-
-/**
- *  @class
- **/
-function CalendarUtil(){}
-
-
-/*
- * Erzeugt und öffnet ein neues Aufgabenobjekt (mit einem Link).
- *
- * @param {String} pSummary opt die Zusammenfassung
- * @param {String} pDescription opt die Beschreibung
- * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
- * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
- *                                   pWithLink[1]: ID des angezeigten Datensatzes
- *                                   pWithLink[2]: Verknüpfungstitel
- * @param {String} pUser opt der Benutzer ( Login )
- * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
- * @param {date} pStart opt Beginn der Aufgabe
- * @param {date} pDuration opt Dauer
- * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
- * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
- * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten
- *
- * @return {void}
- */
-CalendarUtil.newTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh)
-{
-    var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus );
-    var prompts = [];
-    prompts["comp4refresh"] = [];
-
-    if (pComps4Refresh == undefined)
-        pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Aufgabe"];
-
-    for (var i = 0; i < pComps4Refresh.length; i++)
-    {
-        if ( vars.exists(pComps4Refresh[i]))    prompts["comp4refresh"].push(pComps4Refresh[i]);
-    }
-    if(vars.getString("$sys.scope") == "vaadin")
-        neon.openCalendarEntry([todo], null, neon.OPERATINGSTATE_NEW, null)
-    else
-    {
-        if (vars.exists("$sys.currentwindow"))
-            prompts["window"] = vars.getString("$sys.currentwindow");
-        if (vars.exists("$sys.currentimage"))
-            prompts["image"] = vars.getString("$sys.currentimage");
-
-        swing.openCalendarEntry([todo], null, false, prompts);
-    }
-}
-
-/*
- * Erzeugt eine neue Aufgabe (mit einem Link).
- *
- * @param {String} pSummary opt die Zusammenfassung
- * @param {String} pDescription opt die Beschreibung
- * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
- * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
- *                		     pWithLink[1]: ID des angezeigten Datensatzes
- *               		     pWithLink[2]: Verknüpfungstitel
- * @param {String} pUser opt der Benutzer ( Login )
- * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
- * @param {date} pStart opt Beginn der Aufagebe
- * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI )
- * @param {date} pDuration opt Dauer
- * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
- * @param {String} pStatus opt Status der Aufgabe ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
- * @param {String} pPriority opt Priorität der Aufgabe
- * @param {String} pReminder opt Erinnerung der Aufgabe
- *
- * @return {void}
- */
-
-CalendarUtil.newSilentTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pPriority, pReminder)
-{
-    if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE;
-    var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder );
-    
-    return calendars.insert([todo],calendars.GROUP_SINGLE);
-}
-
-/*
- * Erzeugt und öffnet ein neues Terminnobjekt mit einem Link.
- *
- * @param {String} pSummary opt die Zusammenfassung
- * @param {String} pDescription opt die Beschreibung
- * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
- * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
- *                		     pWithLink[1]: ID des angezeigten Datensatzes
- *               		     pWithLink[2]: Verknüpfungstitel
- * @param {String} pUser opt der Benutzer ( Login )
- * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
- * @param {date} pStart opt Beginn der Aufagebe
- * @param {date} pDuration opt Dauer
- * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
- * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
- * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten
- * 
- * @return {void}
- */
-CalendarUtil.newEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh, pWorklistId)
-{
-    var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus );
-
-    var prompts = [];
-    prompts["comp4refresh"] = [];
-    if (pComps4Refresh == undefined)
-        pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Termine"];
-    for (i = 0; i < pComps4Refresh.length; i++)
-    {
-        if ( vars.exists(pComps4Refresh[i]))    prompts["comp4refresh"].push(pComps4Refresh[i]);
-    }
-
-    if(vars.getString("$sys.scope") == "vaadin")
-        neon.openCalendarEntry([event],"", neon.OPERATINGSTATE_NEW, null)
-    else
-    {
-        prompts["window"] = vars.getString("$sys.currentwindow");
-        prompts["image"] = vars.getString("$sys.currentimage");
-        if (pWorklistId != undefined)
-            prompts["worklistId"]   = pWorklistId;
-        swing.openCalendarEntry([event], null, false, prompts);
-    }
-}
-
-
-/*
- * Erzeugt einen neuen Termineintrag (mit einem Link).
- *
- * @param {String} pSummary opt die Zusammenfassung
- * @param {String} pDescription opt die Beschreibung
- * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
- * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
- *                		     pWithLink[1]: ID des angezeigten Datensatzes
- *                		     pWithLink[2]: Verknüpfungstitel
- * @param {String} pUser opt der Benutzer ( Login )
- * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
- * @param {date} pStart opt Beginn des Termins
- * @param {date} pDuration opt Dauer
- * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI )
- * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
- * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
- * @param {String} pReminder opt Erinnerung des Termins
- *
- * @return {void}
- */
-CalendarUtil.newSilentEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pReminder)
-{
-    if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE;
-    var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, undefined, pReminder );
-    return calendars.insert( [event] , pGroupType );
-}
-
-/*
- * Erzeugt ein neues Aufgaben- / Termin-Objekt (mit einem Link).
- *
- * @param {date} pType req  Augabe oder Termin ( calendars.VTODO, calendars.VEVENT )
- * @param {String} pSummary opt die Zusammenfassung
- * @param {String} pDescription opt die Beschreibung
- * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
- * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
- *                		     pWithLink[1]: ID des angezeigten Datensatzes
- *                		     pWithLink[2]: Verknüpfungstitel
- * @param {String} pUser opt der Benutzer ( Login )
- * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( [ Login ] )
- * @param {date} pStart opt Beginn
- * @param {date} pDuration opt Dauer
- * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
- * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
- * @param {String} pPriority opt Priorität
- * @param {String} pReminder opt Erinnerung
- *
-@return {Object} das EntryObjekt
- */
-CalendarUtil.createEntry = function( pType, pSummary, pDescription, pWithLink, pAppLinkContext, pAppLinkId, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder )
-{
-    var Entry = {};
-    var framename;
-    var framdata;
-    var dbid;
-    var linktitle;
-    if ( pSummary == undefined || pSummary == null  ) pSummary = "";
-    if ( pDescription == undefined || pDescription == null )
-    {
-        if(vars.getString("$sys.scope") == "vaadin")
-            pDescription = neon.getImageContent(vars.getString("$sys.currententityname"));
-        else
-            pDescription = swing.getImageContent();
-    }
-    if ( pUser == undefined || pUser == null ) pUser = vars.getString("$sys.user");
-    //kein translate.key hier, weil es sich um einen rein technischen Wert handelt:
-    if ( pStart == undefined ) pStart = datetime.toLong(datetime.toDate(parseInt(vars.getString("$sys.date")) + datetime.ONE_HOUR, "dd.MM.yyyy HH:00"), "dd.MM.yyyy HH:mm");
-    if ( pCategory == undefined || pCategory == null  ) pCategory = "";
-
-    if (pAffectedUsers == null || pAffectedUsers == undefined )
-    {
-        Entry[calendars.AFFECTEDUSERS] = "";
-    }
-    else
-    {
-        Entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(pAffectedUsers));
-    }
-    Entry[calendars.TYPE] = pType;
-    Entry[calendars.DTSTART] = pStart;
-    if ( pType == calendars.VEVENT )
-    {
-        if ( pDuration == undefined )
-            pDuration = datetime.ONE_HOUR;
-
-        Entry[calendars.DTEND] = String ( eMath.addInt( pStart, pDuration) );
-
-        if ( pStatus == undefined )
-            pStatus = calendars.STATUS_CONFIRMED;
-
-        pStatus = mapCalendarStatus(pStatus, calendars.getBackendType() );
-    }
-    else if ( pType == calendars.VTODO )
-    {
-        //kein translate.key hier, weil es sich um einen rein technischen Wert handelt:
-        if ( pDuration != undefined )
-            Entry[calendars.DUE] = String ( eMath.addInt( pStart, pDuration) );
-        else
-            Entry[calendars.DUE] = datetime.toLong(datetime.toDate(pStart, "dd.MM.yyyy 23:59")
-                ,"dd.MM.yyyy HH:mm");
-
-        if ( pStatus == undefined )
-            pStatus = calendars.STATUS_NEEDSACTION;
-
-        pStatus = mapCalendarStatus(pStatus, calendars.getBackendTypeTasks() );
-        
-    }
-
-    Entry[calendars.USER] = calendars.getCalendarUser(pUser);
-    Entry[calendars.DESCRIPTION] = pDescription;
-    Entry[calendars.SUMMARY] = pSummary;
-    Entry[calendars.STATUS] = pStatus;
-    Entry[calendars.CLASSIFICATION] = calendars.CLASSIFICATION_PUBLIC;
-    Entry[calendars.CATEGORIES] = pCategory;
-   
-
-    if( pPriority != undefined )
-    {
-        Entry[calendars.PRIORITY] = pPriority;
-    }
-
-    if( pReminder != undefined)
-    {
-        Entry[calendars.HASREMINDER] = "true";
-        Entry[calendars.REMINDER_DURATION] = pReminder;
-    }
-    else
-        Entry[calendars.HASREMINDER] = "false";
-   
-
-    if (pWithLink == false)
-    {
-        Entry[calendars.LINKS] = "0";
-    }
-    else
-    {
-        var fd = new FrameData();
-        if ( typeof(pWithLink) == "object" )
-        {
-            for ( var li = 0; li < pWithLink.length; li++ )
-            {
-                framename = pWithLink[li][0];
-                framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0];
-                dbid = pWithLink[li][1];
-                linktitle = framdata[2] + " - " + pWithLink[li][2];
-
-                Entry["LINK_ALIAS_" + ( li + 1 )] = vars.getString("$sys.dbalias");
-                Entry["LINK_TABLE_" + ( li + 1 )] = framdata[0];
-                Entry["LINK_IDCOLUMN_" + ( li + 1 )] = framdata[1];
-                Entry["LINK_DBID_" + ( li + 1 )] = dbid;
-                Entry["LINK_FRAME_" + ( li + 1 )] = "comp." + framename;
-                Entry["LINK_TITLE_" + ( li + 1 )] = linktitle;
-            }
-            Entry[calendars.LINKS] = pWithLink.length.toString();
-        }
-        else
-        {
-            if ( pWithLink == true || pWithLink == undefined )
-            {
-                framename = vars.getString("$sys.currentimagename");
-                framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0];
-                dbid = vars.getString("$comp.idcolumn");
-                linktitle = framdata[2] + " - " + swing.getImageContent();
-            }
-            Entry[calendars.LINKS] = "1";
-            Entry["LINK_ALIAS_1"] = vars.getString("$sys.dbalias");
-            Entry["LINK_TABLE_1"] = framdata[0];
-            Entry["LINK_IDCOLUMN_1"] = framdata[1];
-            Entry["LINK_DBID_1"] = dbid;
-            Entry["LINK_FRAME_1"] = "comp." + framename;
-            Entry["LINK_TITLE_1"] = linktitle;
-        }
-    }
-    
-
-if(pAppLinkContext && pAppLinkId)
-{
-    Entry["AppLinkContext"] = pAppLinkContext;
-    Entry["AppLinkId"] = pAppLinkId;
-}
-    return Entry;
-}
-
-/*
- * Liefert den CalendarStatus übersetzt zurück.
- * @param {String} pStatus req Status
- * @param {String} pLanguage opt Sprache
- * @param {String} pKind opt ToDo oder Event
- *
- * @return {String} übersetzte Status
- */
-function getCalendarStatus( pStatus, pLanguage, pKind)
-{
-    //kein mappen des Status, da wirklich verschiedene Dinge angezeigt werden sollen
-    switch ( pStatus )
-    {
-        case calendars.STATUS_BUSY: 
-            return translate.text("Gebucht", pLanguage)
-        case calendars.STATUS_CANCELLED:
-            if(pKind == "ToDo" && pKind != undefined) return translate.text("Zurückgestellt", pLanguage)
-            return translate.text("Abgesagt", pLanguage)
-        case calendars.STATUS_COMPLETED:
-            return translate.text("Erledigt", pLanguage)
-        case calendars.STATUS_CONFIRMED:
-            return translate.text("Bestätigt", pLanguage)
-        case calendars.STATUS_FREE:
-            return translate.text("frei", pLanguage)
-        case calendars.STATUS_INPROCESS:
-            return translate.text("In Bearbeitung", pLanguage)
-        case calendars.STATUS_NEEDSACTION:
-            return translate.text("Nicht begonnen", pLanguage)
-        case calendars.STATUS_OOF:
-            return translate.text("Außer Haus", pLanguage)
-        case calendars.STATUS_TENTATIVE:
-            return translate.text("Vorläufig", pLanguage)
-        default:
-            return "";
-    }
-}
-
-/*
- * Zu einer übergebenen Priorität wird ihre Bedeutung übersetzt und zurückgegeben.
- *
- * @param {String} pPriority req Priorität
- * @param {String} pLanguage opt Sprache
- *
- * @return (String) übersetzte Bedeutung einer Priorität
- */
-function getCalendarPriority(pPriority, pLanguage)
-{
-    switch(pPriority)
-    {
-        case "9":
-            return translate.text("niedrig", pLanguage);
-            break;
-        case "5":
-            return translate.text("normal", pLanguage);
-            break;
-        case "1":
-            return translate.text("hoch", pLanguage);
-            break;
-        default:
-            return translate.text("keine", pLanguage);
-            break;
-    }
-}
-
-/*
- * Liefert zum Objekt verknüpfte Aufgaben aus dem Kalender.
- *
- * @param {String} pFrame req Name des Frames
- * @param {String} pDBID req ID des verknüpften Datensatzes
- * @param {String} pAlias opt
- * @param {String} pLanguage opt Sprache
- *
- * @return {[]} mit Aufgaben aus Kalender
- */
-function getLinkedToDos (pFrame, pDBID, pAlias, pLanguage )
-{
-    if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias");
-    var tab = [];
-    var status = " and STATUS in ('NEEDS-ACTION', 'IN-PROCESS')";
-    var exists = [];
-    var zustaendig = "";
-    var today = getDate(vars.getString("$sys.date"));
-    var filtervalues = ["", "false"];
-    if ( vars.exists("$image.FilterValuesT") )
-    {
-        filtervalues = vars.get("$image.FilterValuesT");
-        zustaendig = filtervalues[0]
-        if (filtervalues[1] == "true") status = " and STATUS in ('COMPLETED', 'CANCELLED')";
-    }
-
-    var entryids = db.table("select ENTRYID, OWNER from ASYS_CALENDARLINK "
-        + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." + pFrame + "' "
-        + "and ENTRYID is not null "
-        + "and ENTRYTYPE = " + calendars.VTODO + " "
-        + "and DBID = '" + pDBID + "' "
-        + status, pAlias);
-
-    for (var i = 0; i < entryids.length; i++)
-    {
-        if ( exists.indexOf(entryids[i][0]) == -1)
-        {
-            try
-                {
-                    var entry = calendars.getEntry(entryids[i][0], null, getTitleCalenderUser( entryids[i][1] ), calendars.VTODO);
-                    var entr = new Array;
-                    status = "";
-                    var user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
-                    if(user == null) user = entry[calendars.USER2]["cn"];
-                     else user = user[tools.TITLE]
-                    if ((user == zustaendig || zustaendig == ""))
-                    {
-                        entr[0] = text.encodeMS([entry[calendars.ID], user]);
-                        var due = getDate(entry[calendars.DUE]);
-                        if (due < today ) entr[1]	= "-1769402";
-                        else  if (due > today) entr[1]	= "-16777216"; else entr[1]	= "-16744020";
-                        entr[2] = "-1";  // Hintergrundfarbe
-                        entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length;
-                        entr[4] = entry[calendars.DUE]
-                        entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo");
-                        entr[6] = entry[calendars.SUMMARY]
-                        entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
-                        entr[8] = getRealName(entry[calendars.ATTENDEES]);
-                        entr[9] = entry[calendars.DESCRIPTION];
-                        entr[10] = entry[calendars.PRIORITY];
-                        tab.push(entr);
-                        exists.push(entryids[i][0]);
-                    }
-            }
-            catch (ex)
-            {
-                logging.log(ex);
-            }
-        }
-    }
-    array_mDimSort(tab, 4, false); //Sortierung nach Fälligkeitsdatum
-    return tab;
-}
-
-/*
- * Anzeige des Aufgaben-Filter
- *
- * @param {Object} pFilter req
- *
- * @return string Anzeige
- */
-function show_filterLinkedToDos(pFilter)
-{
-    var retstring = "";
-    if (pFilter[0] != "")
-    {
-        var userp = tools.getUser( pFilter[0] )[tools.PARAMS];
-        retstring = translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME];
-    }
-    if (pFilter[1] == "true") retstring += ", " + translate.text("erledigt / zurückgestellt");
-
-    return retstring
-}
-
-/*
- * Liefert zum Objekt verknüpfte Events aus dem Kalender.
- *
- * @param {String} pFrame req Name des Frames
- * @param {String} pDBID req ID des verknüpften Datensatzes
- * @param {Object} pFilter opt
- * @param {String} pAlias opt
- * @param {String} pUser opt Benutzer
- *
- * @return {[]} mit Events aus Kalender
- */
-function getLinkedEvents (pFrame, pDBID, pFilter, pAlias, pUser )
-{
-    if ( pFilter == "" || pFilter == undefined)
-        pFilter = reset_filterEvent();
-
-    var tab = [];
-    var exists = [];
-    var conditions = [];
-    var today = getDate(vars.getString("$sys.date"));
-    var conditioncount = 0;
-    var stati = [];
-
-    if ( pFilter.tentative == "true" )
-        stati.push(mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() ));
-
-    if ( pFilter.cancelled == "true" )
-        stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendType() ));
-
-    if ( pFilter.confirmed == "true" )
-        stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
-
-    if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS)
-        stati.push(calendars.STATUS_FREE);
-
-    if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias");
-
-    var entryids = db.table(["select ENTRYID, OWNER "
-        + "from ASYS_CALENDARLINK "
-        + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp."
-        + pFrame + "' and ENTRYID is not null and ENTRYTYPE = " + calendars.VEVENT
-        + " and DBID = '" + pDBID + "' and DTSTART >= ?",
-        [ [ String(pFilter.datefrom - datetime.ONE_WEEK), SQLTYPES.DATE ]]], pAlias );
-
-    /*
-     * Check for rights before constructing condition otherwise you'll get an error by opening linked Data
-     */
-    var userToRead = []
-    if(pUser != undefined)
-    {
-        userToRead = getCalendarUsers( calendars.RIGHT_READ_APPOINTMENT, pUser );
-    }
-    else
-    {
-        userToRead = calendars.getDisplayCalendarUsers(calendars.RIGHT_READ_APPOINTMENT);
-    }
-    var userMap = {};
-    for (let i = 0; i < userToRead.length; i++)
-    {
-        userMap[userToRead[i][1]] = true;
-    }
-
-    for ( var i = 0;i < entryids.length; i++)
-    {
-        var user = getTitleCalenderUser(entryids[i][1]);
-        if(userMap[user])
-        {
-            for ( var z = 0; z < stati.length; z++ )
-                _addEntryCondition(conditions, String(++conditioncount),
-                {
-                    TYPE: calendars.VEVENT,
-                    START: pFilter.datefrom,
-                    END: pFilter.dateto,
-                    USER: user,
-                    STATUS: stati[z],
-                    UID: entryids[i][0]
-                });
-        } else continue
-    }
-    conditions["COUNT"] = String(conditioncount);
-
-    var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto);
-    for ( let i = 0; i < entries.length; i++)
-    {
-        for (var j = 0; j < entries[i].length; j++)
-        {
-            var entry = entries[i][j];
-            if( exists.indexOf(entry[calendars.ID]) == -1 && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > 0))
-            {
-                var entr = new Array;
-                var start = getDate(entry[calendars.DTSTART]);
-                var end = getDate(entry[calendars.DTEND]);
-                user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
-                if(user == null) user = entry[calendars.USER2]["cn"];
-                 else user = user[tools.TITLE]
-                entr[0] = text.encodeMS([entry[calendars.ID], user , entry[calendars.RECURRENCEID]]);
-                if (end < today) entr[1]	= "-6710887" ;
-                else if (start <= today && end >= today )   entr[1] = "-16744020" ;
-                else entr[1] = "-16777216";
-                entr[2] = "-1"
-                entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length;
-                entr[4] = entry[calendars.DTSTART]
-                entr[5] = entry[calendars.DTEND]
-                entr[6] = entry[calendars.SUMMARY]
-                entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
-                entr[8] = getRealName(entry[calendars.ATTENDEES]);
-                entr[9] = entry[calendars.DESCRIPTION]
-                tab.push(entr);
-                exists.push(entry[calendars.ID]);
-            }
-        }
-    }
-    array_mDimSort(tab, 4, false);
-    return tab;
-}
-
-/*
- * Liefert Aufgaben aus dem Kalender.
- *
- * @param {Object} pFilter req
- * @param {String} pLanguage opt
- * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen
- *
- * @return {[]} mit allen aufgaben aus dem Kalender
- */
-function getTodos( pFilter, pLanguage, pShortForm )
-{
-    if ( pFilter == "" )    pFilter =  reset_filterToDo();
-    var tab = [];
-    var today = getDate (vars.getString("$sys.date"));
-    var conditions = [];
-    var conditioncount = 0;
-    var user = pFilter.user;
-    var stati = [];
-    var status = [];
-    var exists = [];
-    var entries = [];
-
-    if ( pFilter.needs_action == "true" )
-    {
-        stati.push(mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ));
-        status.push("NEEDS-ACTION");
-    }
-    if ( pFilter.in_process == "true" )
-    {
-        stati.push(mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ));
-        status.push("IN-PROCESS");
-    }
-    if ( pFilter.completed == "true" )
-    {
-        stati.push(mapCalendarStatus(calendars.STATUS_COMPLETED, calendars.getBackendTypeTasks() ));
-        status.push("COMPLETED");
-    }
-    if ( pFilter.cancelled == "true" )
-    {
-        stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendTypeTasks() ));
-        status.push("CANCELLED");
-    }
-    if (pFilter.delegated == "true" )
-    {
-        var from = [pFilter.datefrom, SQLTYPES.TIMESTAMP];
-        var to = [pFilter.dateto, SQLTYPES.TIMESTAMP];
-        setAllCalendarGrant();
-        user = calendars.getCalendarUser(user);
-        user = db.table(["select ELEMENTUID, OWNER from ASYS_CALENDARBACKEND where ENTRYTYPE = 2 and OWNER != '" + user + "' and ORGANIZER = '"
-            + user + "' and STATUS in ('" + status.join("', '") + "') and (( STARTTIME >= ? and STARTTIME <= ?) or "
-            + "( ENDTIME >= ? and ENDTIME <= ? ) or ( STARTTIME >= ? and ENDTIME <= ? ))", [from, to, from, to, from, to]] );
-
-        for (let i = 0; i < user.length; i++ )
-        {
-            try
-            {
-                entries.push([calendars.getEntry(user[i][0], null, getTitleCalenderUser(user[i][1]), calendars.VTODO)]);
-            }
-            catch(err){
-                logging.log(err);
-            }
-        }
-        setCalendarGrant();
-    }
-    else
-    {
-        if ( typeof( pFilter.user ) != "object" )  user = [user.trim()];
-        for (let i = 0; i < user.length; i++ )
-        for ( var z = 0; z < stati.length; z++ )
-            _addEntryCondition(conditions, ++conditioncount,
-            {
-                TYPE: calendars.VTODO,
-                START: pFilter.datefrom,
-                END: pFilter.dateto,
-                USER: user[i],
-                STATUS: stati[z]
-            });
-
-        conditions["COUNT"] = String(conditioncount);
-        entries = calendars.getEntries(conditions);
-    }
-
-    for (i = 0; i < entries.length; i++)
-    {
-        var entry = entries[i][0];
-        user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
-        if (user == null)  user = entry[calendars.USER2]["cn"];
-         else user = user[tools.TITLE]
-        if ( !(user != vars.getString("$sys.user") && entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) // no privat
-            && !( pFilter.delegated == "true" && ( isAffectedUser( entry, pFilter.user) || exists.indexOf(entry[calendars.ID]) > -1  ) ) // no duplicate
-            && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf( pFilter.category ) > -1 ) ) // Filter category
-            {
-            var entr = [];
-            var links =  entry[calendars.LINKS];
-            var due = entry[calendars.DUE] != "" ? getDate(entry[calendars.DUE]) : "";
-            entr[0] = text.encodeMS([entry[calendars.ID], user]);
-            if (due == today )      entr[1] = "-16744020" ;
-            else if(due == "")      entr[1] = "-13395712";
-            else if (due > today )  entr[1] = "-16777216";
-            else                    entr[1]	= "-1769402";
-            if (entry[calendars.PRIORITY] == "1") entr[2] = "-100";
-            entr[3] = entry[calendars.ATTENDEES].length;
-            entr[4] = entry[calendars.DUE];
-
-            if (pShortForm)
-            {
-                entr[5] = entry[calendars.SUMMARY];
-                entr[6] = entry[calendars.DESCRIPTION];
-            }
-            else
-            {
-                entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo");
-                entr[6] = getCalendarPriority( entry[calendars.PRIORITY], pLanguage);
-                entr[7] = entry[calendars.SUMMARY];
-                entr[8] = getRealName( [ entry[calendars.ORGANIZER2] ] );
-                entr[9] = getRealName( entry[calendars.ATTENDEES] );
-                if (links == undefined) entr[10] = "";	else entr[10] = links;
-                entr[11] = entry[calendars.DESCRIPTION];
-                entr[12] = entry[calendars.CREATED];
-            }
-
-            tab.push(entr);
-            if ( pFilter.delegated == "true" )  exists.push(entry[calendars.ID]);
-        }
-    }
-
-    if (pShortForm)
-        sortArray(tab, -1, 4, 1, 5);
-    else
-        sortArray(tab, -1, 4, 1, 12 );
-
-    return tab;
-}
-
-/*
- * Fügt eine Condition hinzu
- *
- * @param {[]} pConditions req die Conditions
- * @param {Integer} pIndex req Index der Condition
- * @param {Object} pValues req
- *
- * @return {void}
- */
-function _addEntryCondition(pConditions, pIndex, pValues)
-{
-    var params = ["TYPE", "START", "END", "USER", "STATUS", "UID"];
-
-    for (var i = 0; i < params.length; i++)
-        if (pValues[params[i]] != undefined)    pConditions[params[i] + "_" + pIndex] = pValues[params[i]];
-}
-
-CalendarUtil.addEntryCondition = function(pConditions, pIndex, pValues)
-{
-    _addEntryCondition(pConditions, pIndex, pValues);
-}
-/*
- * Liefert Events zu bestimmten Usern/Daten in einem Array.
- *
- * @param {Object} pFilter req
- * @param {String} pLanguage opt
- * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen
- *
- * @return {[]}
- *				[0] ID
- *				[1] Vordergrundfarbe
- *				[2] Hintergrundfarbe
- *				[3] Start
- *				[4] Ende
- *				[5] Betreff
- *				[6] Inhalt
- *				[7] User
- *				[8] Anzahl Verknüpfungen
- *				[9] Klassifikation (privat/öffentlich)
- */
-function getEvents( pFilter, pLanguage, pShortForm )
-{
-    if ( pFilter == "" )  pFilter = reset_filterEvent();
-    var tab = [];
-    var conditions = [];
-    var today = getDate(vars.getString("$sys.date"));
-    var conditioncount = 0;
-    var stati = [];
-    var user = undefined;
-    if ( pFilter.tentative == "true" )    stati.push(calendars.STATUS_TENTATIVE);
-    if ( pFilter.cancelled == "true" )    stati.push(calendars.STATUS_CANCELLED);
-    if ( pFilter.confirmed == "true" )
-        stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
-
-    if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true")
-        stati.push(calendars.STATUS_FREE);
-
-    if ( pFilter.user != "" )	user = (pFilter.user).trim();
-
-    for ( var z = 0; z < stati.length; z++ )
-        _addEntryCondition(conditions, String(++conditioncount),
-        {
-            TYPE: calendars.VEVENT,
-            START: pFilter.datefrom,
-            END: pFilter.dateto,
-            USER: user,
-            STATUS: stati[z]
-        });
-
-    conditions["COUNT"] = String(conditioncount);
-
-    var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto);
-    for ( var i = 0;i < entries.length; i++)
-    {
-        for (var j = 0; j < entries[i].length; j++)
-        {
-            var entry = entries[i][j];
-            if( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > -1 )
-            {
-                var entr = new Array;
-                var start = getDate(entry[calendars.DTSTART]);
-                var end = getDate(entry[calendars.DTEND]);
-
-                user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
-                if(user == null) user = entry[calendars.USER2]["cn"];
-                else user = user[tools.TITLE]
-                entr[0] = text.encodeMS([ entry[calendars.ID], user, entry[calendars.RECURRENCEID]]);
-                if (end < today ) entr[1]	="-6710887" ;
-                else if (start > today) entr[1]	= "-16777216";
-                else entr[1]	= "-16744020" ;
-                entr[2] = "-1"
-                entr[3] = entry[calendars.ATTENDEES].length;
-                entr[4] = entry[calendars.DTSTART];
-                entr[5] = entry[calendars.DTEND];
-                entr[6] = entry[calendars.SUMMARY];
-
-                if (!pShortForm)
-                {
-                    entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
-                    entr[8] = getRealName(entry[calendars.ATTENDEES]);
-                    entr[9] = getCalendarStatus( entry[calendars.STATUS], pLanguage );
-                    if (entry[calendars.LINKS] == undefined) entr[10] = "";
-                    else entr[10] = entry[calendars.LINKS];
-                    entr[11] = entry[calendars.DESCRIPTION];
-                }
-                tab.push( entr );
-            }
-        }
-    }
-    sortArray(tab, -1, 4, 1, 6 );
-    return tab;
-}
-
-/*
- * Liefert den echten Namen anhand des Logins zurück
- *
- * @param {Array}[]} pUserMap req pUserMap
- *
- * @return String
- */
-function getRealName(pUserMap)
-{
-    var resultName = [];
-    var RealNames = getRealNameObject(pUserMap);
-
-    for ( var realname in RealNames )   resultName.push(RealNames[realname]);
-    return resultName.join(", \n");
-}
-
-/*
- * Liefert den echten Namen anhand des Logins zurück
- *
- * @param {Array}[]} pUserMap req pUserMap
- *
- * @return Object
- */
-function getRealNameObject(pUserMap)
-{
-    var resultObject = {};
-    var realname = "";
-
-    for ( let i = 0; i < pUserMap.length; i++ )
-    {
-        let user = tools.getUserByAttribute(tools.CALENDARID, [pUserMap[i]["paramvalue"].substr("mailto:".length)])
-        if ( user != null )
-        {
-            if(vars.exists("$global.firstLastName") && vars.get("$global.firstLastName"))
-                realname = user[tools.PARAMS][tools.LASTNAME] + " " + user[tools.PARAMS][tools.FIRSTNAME];
-            else realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME];
-        }
-        else //Der User existiert nicht im System
-        {
-            realname = pUserMap[i]["cn"] + " " + pUserMap[i]["paramvalue"];
-        }
-        resultObject[pUserMap[i]["cn"]] = realname;
-    }
-    return resultObject;
-}
-
-
-/*
- * Gibt an ob der User im Calendarobject vorhanden ist
- *
- * @param {Object} pEntry req Calendarobject
- * @param {String} pUser req Title
- *
- * @return Object
- */
-function isAffectedUser( pEntry, pUser)
-{
-    var usermap = pEntry[calendars.ATTENDEES];
-
-    for ( var i = 0; i < usermap.length; i++ )
-        if( usermap[i]["cn"] == pUser )
-            return true;
-    return false;
-}
-
-/*
- * Liefert das Datum ohne Urzeit zurück
- *
- * @param {String} datetimeIn req DatumZeit
- *
- * @return {date}
- */
-function getDate( datetimeIn )
-{
-    if ( datetimeIn != "")
-        return datetime.clearTime(datetimeIn);
-    else return "";
-}
-
-/*
- * Setzt den Aufgaben-Filter
- *
- * @param {Object} pFilter req
- *
- * @return {image}
- */
-function filterToDo( pFilter )
-{
-    var error = true;
-    var von = pFilter.datefrom;
-    var bis = pFilter.dateto;
-    if ( pFilter == "" )	pFilter =  reset_filterToDo();
-    do
-    {
-        vars.set("$local.relation_id", pFilter.user);
-        vars.set("$local.edt_von", pFilter.datefrom);
-        vars.set("$local.edt_bis", pFilter.dateto);
-        vars.set("$local.category", pFilter.category);
-        vars.set("$local.delegated", pFilter.delegated);
-        vars.set("$local.needs_action", pFilter.needs_action);
-        vars.set("$local.in_process", pFilter.in_process);
-        vars.set("$local.completed", pFilter.completed);
-        vars.set("$local.cancelled", pFilter.cancelled);
-        var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_FILTER");
-        if( res != null )
-        {
-            pFilter.user =      res["DLG_TASK_FILTER.relation_id"];
-            pFilter.datefrom =  res["DLG_TASK_FILTER.edt_von"];
-            pFilter.dateto =    res["DLG_TASK_FILTER.edt_bis"];
-            pFilter.category =  res["DLG_TASK_FILTER.category"];
-            pFilter.delegated = res["DLG_TASK_FILTER.delegated"];
-            pFilter.needs_action = res["DLG_TASK_FILTER.needs_action"];
-            pFilter.in_process = res["DLG_TASK_FILTER.in_process"];
-            pFilter.completed = res["DLG_TASK_FILTER.completed"];
-            pFilter.cancelled = res["DLG_TASK_FILTER.cancelled"];
-            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
-            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
-        }
-        else
-        {
-            pFilter.datefrom = von;
-            pFilter.dateto = bis;
-            error = false;
-        }
-    }
-    while ( error )
-    return pFilter;
-}
-
-/*
- * Setzt den Aufgaben-Filter
- *
- * @param {Object} pFilter req
- *
- * @return {image}
- */
-function filterToDo_Neon( pFilter )
-{
-    var error = true;
-    var von = pFilter.datefrom;
-    var bis = pFilter.dateto;
-    if ( pFilter == "" )	pFilter =  reset_filterToDo();
-    do
-    {
-        var prompts = {
-            FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"),
-            RESPONSIBLE: pFilter.user,
-            DATE_FROM: pFilter.datefrom,
-            DATE_TO: pFilter.dateto,
-            CATEGORY_TODO: pFilter.category,
-            DELEGATED: pFilter.delegated,
-            NEEDS_ACTION: pFilter.needs_action,
-            IN_PROCESS: pFilter.in_process,
-            COMPLETED: pFilter.completed,
-            CANCELLED: pFilter.cancelled
-        }
-
-        var buttons = {
-            "ok" : translate.text("OK"),
-            "": translate.text("Abbrechen")
-            };
-        var defaultButton = "ok";
-
-        var res = question.openDialog("DLG_FILTER_TODO_Neon", prompts, buttons, defaultButton);
-
-        if( res.button != null )
-        {
-            pFilter.user =      res.RESPONSIBLE;
-            pFilter.datefrom =  res.DATE_FROM;
-            pFilter.dateto =    res.DATE_TO;
-            pFilter.category =  res.CATEGORY_TODO;
-            pFilter.delegated = res.DELEGATED;
-            pFilter.needs_action = res.NEEDS_ACTION;
-            pFilter.in_process = res.IN_PROCESS;
-            pFilter.completed = res.COMPLETED;
-            pFilter.cancelled = res.CANCELLED;
-            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
-            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
-        }
-        else
-        {
-            pFilter.datefrom = von;
-            pFilter.dateto = bis;
-            error = false;
-        }
-    }
-    while ( error )
-    return pFilter;
-}
-
-
-/*
- * Anzeige des Aufgaben-Filter
- *
- * @param {Object} pFilter req
- *
- * @return string Anzeige
- */
-function show_filterToDo(pFilter)
-{
-    var retstring = "";
-    var userp = tools.getUser( pFilter.user )[tools.PARAMS];
-    if (pFilter.user != "") retstring = (translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]);
-    if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy"));
-    if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy"));
-    if (pFilter.category != "") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category;
-    if (pFilter.delegated == "true") retstring += ", " + translate.text("delegiert");
-    if (pFilter.needs_action == "true") retstring += ", " + translate.text("Nicht begonnen");
-    if (pFilter.in_process == "true") retstring += ", " + translate.text("In Bearbeitung");
-    if (pFilter.completed == "true") retstring += ", " + translate.text("Erledigt");
-    if (pFilter.cancelled == "true") retstring += ", " + translate.text("Zurückgestellt");
-
-    return retstring
-}
-
-/*
- * Setzt den Aufgaben-Filter zurück
- *
- * @return {filter}
- */
-function reset_filterToDo()
-{
-    var today = getDate (vars.getString("$sys.date"));
-
-    return pFilter =  {
-        user: vars.getString("$sys.user"),
-        datefrom: String(eMath.subInt(today, 720 * datetime.ONE_DAY)),
-        dateto: String(eMath.addInt(eMath.addInt(today, 3 * datetime.ONE_DAY)
-            ,datetime.ONE_DAY - datetime.ONE_MINUTE)),
-        category: "",
-        delegated: "",
-        needs_action: "true",
-        in_process: "true",
-        completed: "",
-        cancelled: ""
-    };
-}
-
-/*
- * Setzt den Event-Filter
- *
- * @param {Object} pFilter req
- *
- * @return {image}
- */
-function filterEvent( pFilter )
-{
-    var error = true;
-    var von = pFilter.datefrom;
-    var bis = pFilter.dateto;
-    if ( pFilter == "" )	pFilter =  reset_filterEvent();
-    do
-    {
-        vars.set("$local.relation_id", pFilter.user);
-        vars.set("$local.edt_von", pFilter.datefrom);
-        vars.set("$local.edt_bis", pFilter.dateto);
-        vars.set("$local.category", pFilter.category);
-        vars.set("$local.tentative", pFilter.tentative);
-        vars.set("$local.confirmed", pFilter.confirmed);
-        vars.set("$local.cancelled", pFilter.cancelled);
-        vars.set("$local.free", pFilter.free);
-        var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_EVENT_FILTER");
-        if( res != null )
-        {
-            pFilter.user =      res["DLG_EVENT_FILTER.relation_id"];
-            pFilter.datefrom =  res["DLG_EVENT_FILTER.edt_von"];
-            pFilter.dateto =    res["DLG_EVENT_FILTER.edt_bis"];
-            pFilter.category =  res["DLG_EVENT_FILTER.category"];
-            pFilter.tentative = res["DLG_EVENT_FILTER.tentative"];
-            pFilter.confirmed = res["DLG_EVENT_FILTER.confirmed"];
-            pFilter.cancelled = res["DLG_EVENT_FILTER.cancelled"];
-            pFilter.free      = res["DLG_EVENT_FILTER.free"];
-            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
-            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
-        }
-        else
-        {
-            pFilter.datefrom = von;
-            pFilter.dateto = bis;
-            error = false;
-        }
-    }
-    while ( error )
-    return pFilter;
-}
-
-/*
- * Setzt den Event-Filter
- *
- * @param {Object} pFilter req
- *
- * @return {image}
- */
-function filterEvent_Neon( pFilter )
-{
-    var error = true;
-    var von = pFilter.datefrom;
-    var bis = pFilter.dateto;
-    if ( pFilter == "" )	pFilter =  reset_filterEvent();
-    do
-    {
-        var buttons = {
-            "ok" : translate.text("OK"),
-            "": translate.text("Abbrechen")
-        };
-        var defaultButton = "ok";
-
-        var prompts = {
-            FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"),
-            RESPONSIBLE_APPOINTMENT: pFilter.user,
-            DATE_FROM: pFilter.datefrom,
-            DATE_TO: pFilter.dateto,
-            CATEGORY_APPOINTMENT: pFilter.category,
-            TENTATIVE: pFilter.tentative,
-            CONFIRMED: pFilter.confirmed,
-            CANCELLED: pFilter.cancelled
-        }
-        var res = question.openDialog("DLG_FILTER_APPOINTMENT_Neon", prompts, buttons, defaultButton);
-        if( res.button != null )
-        {
-            pFilter.user =      res.RESPONSIBLE_APPOINTMENT;
-            pFilter.datefrom =  res.DATE_FROM;
-            pFilter.dateto =    res.DATE_TO;
-            pFilter.category =  res.CATEGORY_APPOINTMENT;
-            pFilter.tentative = res.TENTATIVE;
-            pFilter.confirmed = res.CONFIRMED;
-            pFilter.cancelled = res.CANCELLED;
-            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
-            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
-        }
-        else
-        {
-            pFilter.datefrom = von;
-            pFilter.dateto = bis;
-            error = false;
-        }
-    }
-    while ( error )
-    return pFilter;
-}
-
-/*
- * Anzeige des Event-Filter
- *
- * @param {Object} pFilter req
- *
- * @return string Anzeige
- */
-function show_filterEvent(pFilter)
-{
-    var retstring = "";
-
-    var userp = tools.getUser( pFilter.user )[tools.PARAMS];
-    if (pFilter.user != "") retstring = translate.text("Termine von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME];
-    if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy"));
-    if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy"));
-    if (pFilter.category == "true") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category;
-    if (pFilter.tentative == "true") retstring += ", " + translate.text("Vorläufig");
-    if (pFilter.confirmed == "true") retstring += ", " + translate.text("Bestätigt");
-    if (pFilter.cancelled == "true") retstring += ", " + translate.text("Abgesagt");
-
-    return retstring
-}
-
-/*
- * Setzt den Event-Filter zurück
- *
- * @return {filter}
- */
-function reset_filterEvent()
-{
-    var today = getDate (vars.getString("$sys.date"));
-
-    return pFilter =  {
-        user: vars.getString("$sys.user"),
-        datefrom: String(today), //nur die Termine ab heute anzeigen,
-        //die von vor einer Woche sind uninteressant
-        dateto: String(eMath.addInt(eMath.addInt(today, datetime.ONE_WEEK)
-            ,datetime.ONE_DAY - datetime.ONE_MINUTE)),
-        category: "",
-        tentative: "true",
-        confirmed: "true",
-        cancelled: "",
-        free: "true"
-    };
-}
-
-/*
- * Setzt den Aufgaben-Filter in Tab Aufgaben
- *
- * @return {image}
- */
-function filterLinkedToDo()
-{
-    var filtervalues = ["", "false"];
-    vars.set("$local.CalenderUser", getCalenderUser( calendars.RIGHT_READ_TASK ));
-
-    //Vorbelegen der Werte, wenn bereits gewählt wurde:
-    if(vars.exists("$image.FilterValuesT"))
-    {
-        filtervalues = vars.get("$image.FilterValuesT");
-        vars.set("$local.relation_id", filtervalues[0]);
-        vars.set("$local.done", filtervalues[1]);
-    }
-
-    var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_DATE_LINKED_FILTER");
-
-    if( res != null && res != undefined && res != "")
-    {
-        filtervalues[0] = res["DLG_TASK_DATE_LINKED_FILTER.relation_id"];
-        filtervalues[1] = res["DLG_TASK_DATE_LINKED_FILTER.done"]
-    }
-    vars.set("$image.FilterValuesT", filtervalues );
-
-    return(filtervalues);
-}
-
-/*
- * Setzt den Aufgabe-Filter zurück
- *
- * @return {image}
- */
-function resetfilterLinkedToDo()
-{
-    var filtervalues = ["", "false"];
-
-    vars.set("$image.FilterValuesT", filtervalues );
-
-}
-
-/*
- * setzt die Kalenderrechte
- *
- * @return {void}
- */
-function setCalendarGrant()
-{
-    calendars.resetCalendarUser();
-    var user_read_todo = [];
-    var user_write_todo = [];   // ["Admin"]
-    var user_read_event = [];
-    var user_write_event = [];
-    var tree = {};
-    var data = db.table("select THEMEID, THEME.THEME_ID, LOGIN, STATUS from THEME "
-        + " left join EMPLOYEE on EMPLOYEE.THEME_ID = THEMEID left join RELATION on RELATION_ID = RELATIONID and STATUS = 1"
-        +" where KIND = 2");
-    for ( let i = 0; i < data.length; i++)
-    {
-        if ( tree[data[i][0]] == undefined )    tree[data[i][0]] = {
-            pid: data[i][1],
-            isuser: false
-        };
-        if ( data[i][2] != "" && data[i][3] != "" )     tree[data[i][2]] = {
-            pid: data[i][0],
-            isuser: true
-        };
-    }
-
-    var user = vars.getString("$sys.user");
-    // Lese- und Schreibrechte auf Kalender aus Datentabelle holen
-    data = db.table("select HASRIGHTFOR, TODO_RIGHTS, EVENT_RIGHTS from AOSYS_CALENDAR_RIGHTS where LOGIN = '" + user + "'");
-    for ( var i = 0; i < data.length; i++ )
-        if(tree[data[i][0]] != undefined)
-            tree[data[i][0]].grants = data[i].slice(1);
-
-    for ( login in tree )
-    {
-        if( tree[login].isuser )
-        {
-            var grantstodo = __getGrants( login, 0 );
-            var grantsevent = __getGrants( login, 1 );
-            if ( grantstodo.length + grantsevent.length > 0 )
-            {
-                if ( grantstodo == "1" || grantstodo == "3")  user_read_todo.push(login);
-                if ( grantstodo == "2" || grantstodo == "3")  user_write_todo.push(login);
-                if ( grantsevent == "1" || grantsevent == "3")  user_read_event.push(login);
-                if ( grantsevent == "2" || grantsevent == "3")  user_write_event.push(login);
-            }
-        }
-    }
-    calendars.setCalendarUser(user_read_todo, calendars.RIGHT_READ_TASK, true, calendars.SORTSTRATEGY_NATURAL );
-    calendars.setCalendarUser(user_write_todo, calendars.RIGHT_WRITE_TASK, true, calendars.SORTSTRATEGY_NATURAL );
-    calendars.setCalendarUser(user_read_event, calendars.RIGHT_READ_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL );
-    calendars.setCalendarUser(user_write_event, calendars.RIGHT_WRITE_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL );
-
-    //********** Ressourcen in Kalender einfügen ************
-    var ressource = tools.getUsersWithRole("PROJECT_Ressource");
-    calendars.setCalendarUser(  ressource, calendars.RIGHT_READ_APPOINTMENT | calendars.RIGHT_WRITE_APPOINTMENT  );
-
-    //add all users from support-role since support-action-tasks (sp_supportAktionen) generates tasks for all support-role members
-    //and if you're a member you are allowed to edit these
-    if (tools.hasRole(user, "PROJECT_Support"))
-    {
-        var support = tools.getUsersWithRole("PROJECT_Support");
-        calendars.setCalendarUser(  support, calendars.RIGHT_WRITE_TASK | calendars.RIGHT_READ_TASK  );
-    }
-
-    function __getGrants( pKey, pIndex )
-    {
-        var grants = [];
-        if ( tree[pKey].grants != undefined && tree[pKey].grants[pIndex]) grants = tree[pKey].grants[pIndex];
-        else if ( tree[pKey].pid != "" )   grants = __getGrants( tree[pKey].pid, pIndex );
-        return grants;
-    }
-}
-
-/*
- * setzt Recht für alle Kalender
- *
- * @return {void}
- */
-function setAllCalendarGrant()
-{
-    calendars.resetCalendarUser();
-    var users = tools.getStoredUsers();
-    var calendar_user = [];
-    for ( var i = 0; i < users.length; i++ )    calendar_user.push( users[i][1] );
-    calendars.setCalendarUser(calendar_user, calendars.RIGHT_READ_TASK | calendars.RIGHT_WRITE_TASK, false, calendars.SORTSTRATEGY_NATURAL );
-}
-
-/*
- * gibt die Logins der user, die den übergebenen User als Attribute eingetragen haben, zurück
- *
- * @param {[]} pUsers req Logins
- * @param {String []} pAttrName req AttributeName für Employee
- * @param {String []} pFields opt
- *
- * @return {String []} Logins
- */
-function getUsersbyAttr( pUsers, pAttrName, pFields )
-{
-    if (typeof(pAttrName) == "string") pAttrName = [pAttrName]
-
-    if ( pFields == undefined )
-    {
-        pFields = ["LOGIN"];
-    }
-
-    var sqlstr = "select " + pFields.join(", ") + " from ATTRLINK join ATTR on ATTRLINK.ATTR_ID = ATTRID and OBJECT_ID = 12 "
-    + "and ATTRNAME in ('" + pAttrName.join("','") + "') "
-    + " join EMPLOYEE on EMPLOYEEID = ATTRLINK.ROW_ID join RELATION on RELATION_ID = RELATIONID join PERS on PERS_ID = PERSID"
-    + " where VALUE_ID in (select EMPLOYEEID from EMPLOYEE where LOGIN in ('" + pUsers.join("','") + "'))"
-    + "";
-
-    if(pFields.length == 1)
-        return db.array(db.COLUMN, sqlstr);
-    else
-        return db.table(sqlstr);
-}
-
-/*
- * Gibt die Anzahl der verknüpften Aufgaben und Termine zurück.
- *
- * @param {String} pID req
- * @param {String} pFrame req
- *
- * @return {String} text
- */
-function countLinkedTodoEvent(pID, pFrame)
-{
-    var today = getDate (vars.getString("$sys.date"));
-    var datefrom = String(today);
-    var dateto = String(eMath.addInt(today, datetime.ONE_WEEK));
-
-    var str = "select count(distinct ELEMENTUID) from ASYS_CALENDARLINK join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID "
-    + " where FRAME = 'comp." + pFrame + "' and ELEMENTUID is not null and DBID = '" + pID + "'";
-    var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO + " and STATUS in ('"
-        + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '"
-        + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')");
-
-    var eventStatusList = [
-         mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )
-        ,mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() )
-    ];
-
-    if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS)
-        eventStatusList.push(calendars.STATUS_FREE);
-
-    var retevent = db.cell([str + " and ENTRYTYPE = " + calendars.VEVENT + " and STATUS in ('" + eventStatusList.join("', '") + "')"
-            + " and DTSTART >= ? and DTEND <= ?",
-        [ [ String(datefrom), SQLTYPES.DATE ],  [String(dateto), SQLTYPES.DATE ] ]]);
-
-    result.string(translate.withArguments("&Aufg / Term (%0/%1)", [rettask, retevent]));
-}
-
-/*
- * Gibt die Anzahl der verknüpften Aufgaben zurück.
- *
- * @param {String} pID req
- * @param {String} pFrame req
- *
- * @return {String} text
- */
-function countLinkedTodo(pID, pFrame)
-{
-    var str = "select count(distinct ELEMENTUID) "
-    + "from ASYS_CALENDARLINK "
-    + "join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID "
-    + " where FRAME = 'comp." + pFrame + "' "
-    + "and ELEMENTUID is not null and DBID = '" + pID + "'";
-
-    var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO
-        + " and  STATUS in ('"
-        + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '"
-        + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')"
-        + "");
-
-    result.string(translate.withArguments("&Aufgaben (%0)", [rettask]));
-}
-
-/*
- * Gibt die Überschneidungen von Termine zurück.
- *
- * @param {Date} pStart req
- * @param {Date} pEnd req
- * @param {Array} pUsers req
- *
- * @return {String Array} Termine
- */
-function getOverlappingEvents(pStart, pEnd, pUsers  )
-{
-    var resultEvents = new Array();
-    var users = pUsers;
-    if (calendars.getBackendType() == calendars.BACKEND_DB && pStart != "" && pEnd != "" && users.length > 0)
-    {
-        calendars.clearCache();
-        for (var u = 0; u < users.length; u++)
-        {
-            var localuid = vars.get("$image.entry")[calendars.ID]
-            var condition = new Array();
-            condition["COUNT"] = "1";
-            condition["TYPE_1"] = calendars.VFREEBUSY;
-            condition["USER_1"] = users[u][0];
-            condition["START_1"] = pStart;
-            condition["END_1"] = pEnd;
-
-            var fbsall = calendars.getEntries(condition);
-            for (var j = 0; j < fbsall.length; j++)
-            {
-                var fbs = fbsall[j];
-                for (var i = 0; i < fbs.length; i++)
-                {
-                    var next = fbs[i];
-                    var uid = next[calendars.ID];
-                    var sum = next[calendars.SUMMARY];
-                    if (uid != localuid)
-                    {
-                        var freebusy = next[calendars.FREEBUSY];
-                        var freebusyDec = text.decodeMS(freebusy);
-                        var match = false;
-                        for (var k = 0; k < freebusyDec.length; k++)
-                        {
-                            var freebusyInstance = text.decodeMS(freebusyDec[k]);
-                            if (!freebusyInstance[0].equals("FREE"))
-                            {
-                                match = true;
-                            }
-                        }
-                        if (match)  resultEvents.push([users[u][2], sum != null && sum.length > 0 ? sum : "?", uid]);
-                    }
-                }
-            }
-        }
-    }
-    return resultEvents;
-}
-
-/*
- * Überprüft den Eintrag, wenn eine neue Aufgaben angelegt wird darauf, ob private Aufgaben für andere erstellt werden
- *
- * @param {String[]} pUser die Liste der User, denen die Aufgabe zugewiesen werden soll
- * @param {String} pClassification die Klassifizierung der Aufgabe - "PRIVATE"
- *
- * @return {Boolean} ob der Eintrag in der Konstellation möglich ist, wenn nicht wird eine Meldung ausgegeben
- */
-function checkEntry(pUser, pClassification )
-{
-    if( pClassification == "PRIVATE" &&
-        ( pUser.length > 1 || text.decodeMS(pUser[0][0])[1] != "CN:" + vars.getString("$sys.user")))
-        {
-        question.showMessage(translate.text("Eine private Aufgabe kann nicht jemand anderem zugewiesen werden."));
-        return false;
-    }
-    else
-    {
-        return true;
-    }
-}
-
-/*
- * Verschiebt ein Calendareintrag
- *
- * @param {String[]} pIDs req die zu verschiebenden Ids mit den Calenderinformationen (Multistring)
- * @param {String} pTblCompName  opt die Komponente die aktualisiert werden soll
- *
- * @return {void}
- */
-function shiftEntry(pIDs, pTblCompName)
-{
-    var datenew = swing.askUserQuestion(translate.text("Verschieben auf Datum?"), "DLG_DATE");
-    if (datenew != null )
-    {
-        var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK);
-        var usermap = {};
-        var granted = true;
-        for (let i = 0; i < grantedUsers.length; i++)
-        {
-            usermap[grantedUsers[i][1]] = true;
-        }
-
-        datenew = datetime.clearTime(datenew["DLG_DATE.Edit_date"]);
-        if (datenew <= vars.getString("$sys.today"))
-            question.showMessage(translate.text("nur Verschiebung in die Zukunft erlaubt!"));
-        else
-        {
-            for (var i = 0, j = pIDs.length; i < j; i++)
-            {
-                var id = text.decodeMS(pIDs[i]);
-                var entry = calendars.getEntry(id[0], null, id [1], calendars.VTODO);
-                var affectedUsers = entry[calendars.ATTENDEES];
-
-                granted =  hasGrantForEntryByObject(affectedUsers, usermap);
-                if(granted)
-                {
-                    //Zeitdifferenz von Aufgabenstart und -ende
-                    var dateDiff  = eMath.subInt(entry[calendars.DUE], entry[calendars.DTSTART]);
-
-                    //Startzeit der Aufgabe
-                    var startTime = eMath.subInt(entry[calendars.DTSTART]
-                        , datetime.clearTime(entry[calendars.DTSTART]));
-
-                    entry[calendars.DTSTART] = eMath.addInt(datenew, startTime);
-                    entry[calendars.DUE] = eMath.addInt(entry[calendars.DTSTART], dateDiff);
-                    calendars.update( [ entry ] );
-                }
-                else
-                    question.showMessage(translate.text("Keine Berechtigung zum Verschieben der Aufgabe"));
-            }
-        }
-    }
-}
-
-/*
- * Gibt eine Aufgabe weiter
- *
- * @param {String} pIDs die ID der Aufgabe, welche weitergegeben werden soll
- * @param {String} pTblCompName die Komponente der Aufgaben, die aktualisiert werden soll
- *
- * @return {void}
- */
-function handOverToDo(pIDs, pTblCompName)
-{
-    var calendar_user = "";
-    var users = getCalenderUser( calendars.RIGHT_WRITE_TASK );
-    var publicCount = 0;
-    var privateCount = 0;
-    var notGrantedCount = 0;
-
-    var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK);
-    var userMap = {};
-    var granted = true;
-    for (let i = 0; i < grantedUsers.length; i++)
-    {
-        userMap[grantedUsers[i][1]] = true;
-    }
-
-    if (pIDs.length == 1)  // only one todo and private
-    {
-        var id = text.decodeMS( pIDs[0] );
-        var entry = calendars.getEntry( id[0], null, id[1] );
-        if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE)
-        {
-            question.showMessage(translate.text("Kein Weitergeben von privaten Aufgaben möglich!"));
-            return;
-        }
-    }
-
-    for ( let i = 0; i < users.length; i++)  if (pIDs.length > 0 || users[i][0] != id[1])   calendar_user += "|" + users[i][1];
-    var selection = swing.askQuestion(translate.text("Benutzer auswählen"), swing.QUESTION_COMBOBOX, calendar_user);
-    if (selection != null)
-    {
-        for ( let i = 0; i < users.length; i++)
-        {
-            if ( selection == users[i][1] )
-            {
-                selection = users[i];
-                break;
-            }
-        }
-        for( let i = 0; i < pIDs.length; i++)
-        {
-            let id = text.decodeMS( pIDs[i] );
-            let entry = calendars.getEntry( id[0], null, id[1] );
-            if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE)  privateCount++;
-            else //Nur öffentliche Aufgabe kann weiter gegeben werden.
-            {
-                // User austauschen
-                var usermap = entry[calendars.ATTENDEES];
-                var affectedusers = [];
-
-                granted =  hasGrantForEntryByObject(usermap, userMap);
-
-                for (var ui = 0; ui < usermap.length; ui++)
-                {
-                    var login_cn = usermap[ui]["cn"];
-                    var user = tools.getUserByAttribute(tools.CALENDARID, usermap[ui]["paramvalue"].substr("mailto:".length))
-                    if (user == null)  user = login_cn;
-                    else user = user[tools.TITLE]
-
-                    if ( user == id[1] )   affectedusers.push(selection[0]);
-                    else  if ( user != selection[0] )  affectedusers.push(user);
-                }
-                if(granted)
-                {
-                    entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(affectedusers));
-                    calendars.update([entry]);
-                    publicCount++;
-                }
-                else notGrantedCount++
-            }
-        }
-        question.showMessage(translate.withArguments("%0 Aufgabe(n) erfolgreich weitergegeben an: %1"
-            + (privateCount == 0 ? "" : "\n%2 private Aufgabe(n) können nicht weitergegeben werden.")
-            +(notGrantedCount == 0 ? "" : "\n%3 Aufgabe(n) können aufgrund fehlender Berechtigung nicht weitergegeben werden."),
-            [publicCount, selection[1], privateCount, notGrantedCount]));
-
-    }
-}
-
-// ToDo prüfen !!
-/*
- * Verschiebt die Kalendereinträge bei Login-Änderung
- *
- * @param {String} pNewlogin req
- * @param {String} pOldlogin req
- * @param {String} pNewCalendarID req
- * @param {String} pOldCalendarID req
- *
- * @return {void}
- */
-function moveCalendarData ( pNewlogin, pOldlogin, pNewCalendarID, pOldCalendarID )
-{
-    var newcaluser = text.encodeMS(["mailto:" + pNewCalendarID, "CN:" + pNewlogin]);
-    var oldcaluser = text.encodeMS(["mailto:" + pOldCalendarID, "CN:" + pOldlogin]);
-    db.runStatement("update ASYS_CALENDARBACKEND set OWNER = '" + newcaluser + "' where OWNER = '" + oldcaluser + "'");
-    db.runStatement("update ASYS_CALENDARBACKEND set ORGANIZER = '" + newcaluser + "' where ORGANIZER = '" + oldcaluser + "'");
-
-    if(pNewCalendarID != pOldCalendarID) //Nur wenn sich die E-Mailadresse geändert hat
-    {
-        //Messenger-Historien
-        db.runStatement("update ASYS_XMPP_HISTORY set JID_FROM = '" + pNewCalendarID +"' where JID_FROM = '" + pOldCalendarID +"'", "_____SYSTEMALIAS");
-        db.runStatement("update ASYS_XMPP_HISTORY set JID_TO = '" + pNewCalendarID +"' where JID_TO = '" + pOldCalendarID +"'", "_____SYSTEMALIAS");
-    }
-}
-
-/*
- * Löst den CalenderUser in lesbarer From auf
- *
- * @param {String} pValue req
- *
- * @return {String} übersetzten Wert
- */
-function getCalUser( pValue )
-{
-    var realname = pValue;
-    var user = tools.getUser( text.decodeMS(pValue)[1].split(":")[1] );
-    if ( user != null )
-    {
-        realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME];
-    }
-    return realname;
-}
-
-/*
- * Gibt den Login eines CalenderUser zurück
- *
- * @param {String} pCalendarUser req
- *
- * @return {String} Title
- */
-function getTitleCalenderUser( pCalendarUser )
-{
-    var data = text.decodeMS(pCalendarUser)
-    for ( var i = 0; i < data.length; i++ )
-    {
-        //if login changes we have to check calendarid
-        if ( data[i].substr(0, "mailto:".length).toUpperCase() == "MAILTO:" )
-        {
-            var user = tools.getUserByAttribute(tools.CALENDARID, [data[i].substr("mailto:".length)]);
-            if (user != null )
-                return user[tools.TITLE];
-        }
-
-        if ( data[i].substr(0, 3).toUpperCase() == "CN:" )
-            return data[i].substr(3);
-    }
-    return "";
-}
-
-
-/*
- * Gibt den richtigen Status zum Prüfen je nach Backend zurück
- *
- *
- * @param {String} pStatus req die konstante für den zu prüfenden status,
- *                             z.B. calendars.STATUS_INPROCESS
- *
- * @param {String} pCalendarType req die konstante für den typen des Termin- oder Aufgabenbackends,
- *                             z.B. calendars.BACKEND_DB
- *
- * @return {String} Konstanten für den Kalender (Backend-Typen), gibt es den status im backend nicht
- *                  wird null geliefert
- */
-function mapCalendarStatus(pStatus, pCalendarType)
-{
-    switch (pCalendarType)
-    {
-        //case calendars.BACKEND_EXCHANGE:
-        case calendars.BACKEND_EXCHANGEWS:
-            if (pStatus == calendars.STATUS_CONFIRMED)
-                return calendars.STATUS_BUSY;
-            else
-                return pStatus;
-        default:
-            if (pStatus == calendars.STATUS_OOF)//nur bei exchange
-                return null;
-            else
-                return pStatus;
-    }
-}
-
-/*
- * Sets the imagevariable with affectedusers
- *
- * @param {Object} pEntry req the Entry of Tasks or Appointments
- *
- * @return {void}
- *
- */
-function setAffectedUsersImage(pEntry)
-{
-    var affectedUsers = [];
-    var usermap = pEntry[calendars.ATTENDEES];
-    var realnames = getRealNameObject(usermap);
-
-    for ( var i = 0; i < usermap.length; i++ )
-    {
-        affectedUsers.push([ text.encodeMS( [usermap[i]["paramvalue"], "CN:" + usermap[i]["cn"]] ), realnames[usermap[i]["cn"]] ]);
-    }
-
-    vars.set("$image.affectedusers", affectedUsers);
-    return affectedUsers;
-}
-
-/*
- * Opens calendar links
- *
- * @param {String} pEntryID req the ID of the link
- *
- * @return {void}
- *
- */
-function openCalendarLinks(pEntryID)
-{
-    var openFramesObj = {};
-    if (typeof(pEntryID) == "object")
-        openFramesObj = pEntryID;
-    else
-    {
-        var links = db.table("SELECT FRAME, DBIDCOLUMN, DBID FROM ASYS_CALENDARLINK WHERE ENTRYID = '" + pEntryID + "'");
-        for (var i = 0; i < links.length; i++)
-        {
-            var frame = links[i][0].substr( 5 );//remove comp. so the frame can be opened with openFrame
-            if ( openFramesObj[frame] == undefined ) openFramesObj[frame] = {
-                IDField: links[i][1],
-                IDs: []
-            };
-            openFramesObj[frame].IDs.push(links[i][2]);
-        }
-    }
-
-    for ( frame in openFramesObj)
-    {
-        var condition = openFramesObj[frame].IDField + " in ('" + openFramesObj[frame].IDs.join("', '") + "')";
-        var framemode = openFramesObj[frame].IDs.length > 1 ? swing.FRAMEMODE_TABLE_SELECTION : swing.FRAMEMODE_SHOW;
-
-        if ( vars.getString("$global.upwardLink") == "link")
-        {
-            swing.openLinkedFrame(frame, condition, swing.WINDOW_CURRENT, framemode, "", null, false, {
-                autoclose: true
-            } );
-        }
-        else
-        {
-            swing.openFrame(frame, condition, swing.WINDOW_CURRENT, framemode, null, false);
-        }
-    }
-}
-
-/**
- * Returns the "real" calendar system/backend type (BackendType & SyncBackendType)
- *
- * @param {Number} pScope - The needed scope (e.g. "calendars.VEVENT", "calendars.VTODO")
- * @return {Number} - The backend type (calendars.BACKEND_*)
- */
-function getCalendarSystemType (pScope)
-{
-    // Check sync backend type
-    if (calendars.getSyncBackendType() != calendars.BACKEND_NONE && calendars.getSyncBackendType() != 3)
-    {
-        var scope = calendars.getSyncBackendTypeScope();
-        if (scope.length == 1 && scope[0] == pScope) // Scope.length = 1 -> VEVENT *OR* VTODO
-            return calendars.getSyncBackendType();
-        else if (scope.length == 2) // Scope.length = 2 -> Both
-            return calendars.getSyncBackendType();
-       // Scope.length = 0 -> Nothing selected -> Skip this block
-    }
-
-    // Fallback to backend type (event)
-    if (calendars.getBackendType() != calendars.BACKEND_NONE && pScope === calendars.VEVENT)
-        return calendars.getBackendType();
-
-    // Second fallback to backend type (todo)
-    if (calendars.getBackendTypeTasks() != calendars.BACKEND_NONE && pScope === calendars.VTODO)
-        return calendars.getBackendTypeTasks();
-
-    // Everything is none
-    return calendars.BACKEND_NONE;
-}
-
-function hasGrantForEntryByMS(pAffectedUsers, pUserMap)
-{
-    for (let i = 0; i < pAffectedUsers.length; i++)
-    {
-        var calUser = getTitleCalenderUser( pAffectedUsers[i][0]);
-        if(pUserMap[calUser] == undefined)
-        {
-            return false;
-            break;
-        }
-        else
-            return true;
-    }
-}
-
-function hasGrantForEntryByObject(pAffectedUsers, pUserMap)
-{
-    for (let i = 0; i < pAffectedUsers.length; i++)
-    {
-        calUser = tools.getUserByAttribute(tools.CALENDARID, pAffectedUsers[i]["paramvalue"].substr("mailto:".length))
-        if (calUser == null)  calUser = pAffectedUsers[i]["cn"];
-        else calUser = calUser[tools.TITLE]
-        if(pUserMap[calUser] == undefined)
-        {
-            return false;
-            break;
-        }
-        else
-            return true;
-    }
-}
+import("system.neon");
+import("system.vars");
+import("system.db");
+import("system.translate");
+import("system.datetime");
+import("system.swing");
+import("system.eMath");
+import("system.calendars");
+import("system.logging");
+import("system.tools");
+import("system.text");
+import("system.question");
+import("system.SQLTYPES");
+import("system.result");
+import("Util_lib");
+import("system.util")
+
+
+/**
+ *  @class
+ **/
+function CalendarUtil(){}
+
+
+/*
+ * Erzeugt und öffnet ein neues Aufgabenobjekt (mit einem Link).
+ *
+ * @param {String} pSummary opt die Zusammenfassung
+ * @param {String} pDescription opt die Beschreibung
+ * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
+ * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
+ *                                   pWithLink[1]: ID des angezeigten Datensatzes
+ *                                   pWithLink[2]: Verknüpfungstitel
+ * @param {String} pUser opt der Benutzer ( Login )
+ * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
+ * @param {date} pStart opt Beginn der Aufgabe
+ * @param {date} pDuration opt Dauer
+ * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
+ * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
+ * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten
+ *
+ * @return {void}
+ */
+CalendarUtil.newTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh)
+{
+    var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus );
+    var prompts = [];
+    prompts["comp4refresh"] = [];
+
+    if (pComps4Refresh == undefined)
+        pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Aufgabe"];
+
+    for (var i = 0; i < pComps4Refresh.length; i++)
+    {
+        if ( vars.exists(pComps4Refresh[i]))    prompts["comp4refresh"].push(pComps4Refresh[i]);
+    }
+    if(vars.getString("$sys.scope") == "vaadin")
+        neon.openCalendarEntry([todo], null, neon.OPERATINGSTATE_NEW, null)
+    else
+    {
+        if (vars.exists("$sys.currentwindow"))
+            prompts["window"] = vars.getString("$sys.currentwindow");
+        if (vars.exists("$sys.currentimage"))
+            prompts["image"] = vars.getString("$sys.currentimage");
+
+        swing.openCalendarEntry([todo], null, false, prompts);
+    }
+}
+
+/*
+ * Erzeugt eine neue Aufgabe (mit einem Link).
+ *
+ * @param {String} pSummary opt die Zusammenfassung
+ * @param {String} pDescription opt die Beschreibung
+ * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
+ * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
+ *                		     pWithLink[1]: ID des angezeigten Datensatzes
+ *               		     pWithLink[2]: Verknüpfungstitel
+ * @param {String} pUser opt der Benutzer ( Login )
+ * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
+ * @param {date} pStart opt Beginn der Aufagebe
+ * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI )
+ * @param {date} pDuration opt Dauer
+ * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
+ * @param {String} pStatus opt Status der Aufgabe ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
+ * @param {String} pPriority opt Priorität der Aufgabe
+ * @param {String} pReminder opt Erinnerung der Aufgabe
+ *
+ * @return {void}
+ */
+
+CalendarUtil.newSilentTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pPriority, pReminder)
+{
+    if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE;
+    var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder );
+    
+    return calendars.insert([todo],calendars.GROUP_SINGLE);
+}
+
+/*
+ * Erzeugt und öffnet ein neues Terminnobjekt mit einem Link.
+ *
+ * @param {String} pSummary opt die Zusammenfassung
+ * @param {String} pDescription opt die Beschreibung
+ * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
+ * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
+ *                		     pWithLink[1]: ID des angezeigten Datensatzes
+ *               		     pWithLink[2]: Verknüpfungstitel
+ * @param {String} pUser opt der Benutzer ( Login )
+ * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
+ * @param {date} pStart opt Beginn der Aufagebe
+ * @param {date} pDuration opt Dauer
+ * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
+ * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
+ * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten
+ * 
+ * @return {void}
+ */
+CalendarUtil.newEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh, pWorklistId)
+{
+    var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus );
+
+    var prompts = [];
+    prompts["comp4refresh"] = [];
+    if (pComps4Refresh == undefined)
+        pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Termine"];
+    for (i = 0; i < pComps4Refresh.length; i++)
+    {
+        if ( vars.exists(pComps4Refresh[i]))    prompts["comp4refresh"].push(pComps4Refresh[i]);
+    }
+
+    if(vars.getString("$sys.scope") == "vaadin")
+        neon.openCalendarEntry([event],"", neon.OPERATINGSTATE_NEW, null)
+    else
+    {
+        prompts["window"] = vars.getString("$sys.currentwindow");
+        prompts["image"] = vars.getString("$sys.currentimage");
+        if (pWorklistId != undefined)
+            prompts["worklistId"]   = pWorklistId;
+        swing.openCalendarEntry([event], null, false, prompts);
+    }
+}
+
+
+/*
+ * Erzeugt einen neuen Termineintrag (mit einem Link).
+ *
+ * @param {String} pSummary opt die Zusammenfassung
+ * @param {String} pDescription opt die Beschreibung
+ * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
+ * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
+ *                		     pWithLink[1]: ID des angezeigten Datensatzes
+ *                		     pWithLink[2]: Verknüpfungstitel
+ * @param {String} pUser opt der Benutzer ( Login )
+ * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login )
+ * @param {date} pStart opt Beginn des Termins
+ * @param {date} pDuration opt Dauer
+ * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI )
+ * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
+ * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
+ * @param {String} pReminder opt Erinnerung des Termins
+ *
+ * @return {void}
+ */
+CalendarUtil.newSilentEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pReminder)
+{
+    if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE;
+    var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, undefined, pReminder );
+    return calendars.insert( [event] , pGroupType );
+}
+
+/*
+ * Erzeugt ein neues Aufgaben- / Termin-Objekt (mit einem Link).
+ *
+ * @param {date} pType req  Augabe oder Termin ( calendars.VTODO, calendars.VEVENT )
+ * @param {String} pSummary opt die Zusammenfassung
+ * @param {String} pDescription opt die Beschreibung
+ * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable
+ * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames
+ *                		     pWithLink[1]: ID des angezeigten Datensatzes
+ *                		     pWithLink[2]: Verknüpfungstitel
+ * @param {String} pUser opt der Benutzer ( Login )
+ * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( [ Login ] )
+ * @param {date} pStart opt Beginn
+ * @param {date} pDuration opt Dauer
+ * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) )
+ * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED )
+ * @param {String} pPriority opt Priorität
+ * @param {String} pReminder opt Erinnerung
+ *
+@return {Object} das EntryObjekt
+ */
+CalendarUtil.createEntry = function( pType, pSummary, pDescription, pWithLink, pAppLinkContext, pAppLinkId, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder )
+{
+    var Entry = {};
+    var framename;
+    var framdata;
+    var dbid;
+    var linktitle;
+    if ( pSummary == undefined || pSummary == null  ) pSummary = "";
+    if ( pDescription == undefined || pDescription == null )
+    {
+        if(vars.getString("$sys.scope") == "vaadin")
+            pDescription = neon.getImageContent(vars.getString("$sys.currententityname"));
+        else
+            pDescription = swing.getImageContent();
+    }
+    if ( pUser == undefined || pUser == null ) pUser = vars.getString("$sys.user");
+    //kein translate.key hier, weil es sich um einen rein technischen Wert handelt:
+    if ( pStart == undefined ) pStart = datetime.toLong(datetime.toDate(parseInt(vars.getString("$sys.date")) + datetime.ONE_HOUR, "dd.MM.yyyy HH:00"), "dd.MM.yyyy HH:mm");
+    if ( pCategory == undefined || pCategory == null  ) pCategory = "";
+
+    if (pAffectedUsers == null || pAffectedUsers == undefined )
+    {
+        Entry[calendars.AFFECTEDUSERS] = "";
+    }
+    else
+    {
+        Entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(pAffectedUsers));
+    }
+    Entry[calendars.TYPE] = pType;
+    Entry[calendars.DTSTART] = pStart;
+    if ( pType == calendars.VEVENT )
+    {
+        if ( pDuration == undefined )
+            pDuration = datetime.ONE_HOUR;
+
+        Entry[calendars.DTEND] = String ( eMath.addInt( pStart, pDuration) );
+
+        if ( pStatus == undefined )
+            pStatus = calendars.STATUS_CONFIRMED;
+
+        pStatus = mapCalendarStatus(pStatus, calendars.getBackendType() );
+    }
+    else if ( pType == calendars.VTODO )
+    {
+        //kein translate.key hier, weil es sich um einen rein technischen Wert handelt:
+        if ( pDuration != undefined )
+            Entry[calendars.DUE] = String ( eMath.addInt( pStart, pDuration) );
+        else
+            Entry[calendars.DUE] = datetime.toLong(datetime.toDate(pStart, "dd.MM.yyyy 23:59")
+                ,"dd.MM.yyyy HH:mm");
+
+        if ( pStatus == undefined )
+            pStatus = calendars.STATUS_NEEDSACTION;
+
+        pStatus = mapCalendarStatus(pStatus, calendars.getBackendTypeTasks() );
+        
+    }
+
+    Entry[calendars.USER] = calendars.getCalendarUser(pUser);
+    Entry[calendars.DESCRIPTION] = pDescription;
+    Entry[calendars.SUMMARY] = pSummary;
+    Entry[calendars.STATUS] = pStatus;
+    Entry[calendars.CLASSIFICATION] = calendars.CLASSIFICATION_PUBLIC;
+    Entry[calendars.CATEGORIES] = pCategory;
+   
+
+    if( pPriority != undefined )
+    {
+        Entry[calendars.PRIORITY] = pPriority;
+    }
+
+    if( pReminder != undefined)
+    {
+        Entry[calendars.HASREMINDER] = "true";
+        Entry[calendars.REMINDER_DURATION] = pReminder;
+    }
+    else
+        Entry[calendars.HASREMINDER] = "false";
+   
+
+    if (pWithLink == false)
+    {
+        Entry[calendars.LINKS] = "0";
+    }
+    else
+    {
+        var fd = new FrameData();
+        if ( typeof(pWithLink) == "object" )
+        {
+            for ( var li = 0; li < pWithLink.length; li++ )
+            {
+                framename = pWithLink[li][0];
+                framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0];
+                dbid = pWithLink[li][1];
+                linktitle = framdata[2] + " - " + pWithLink[li][2];
+
+                Entry["LINK_ALIAS_" + ( li + 1 )] = vars.getString("$sys.dbalias");
+                Entry["LINK_TABLE_" + ( li + 1 )] = framdata[0];
+                Entry["LINK_IDCOLUMN_" + ( li + 1 )] = framdata[1];
+                Entry["LINK_DBID_" + ( li + 1 )] = dbid;
+                Entry["LINK_FRAME_" + ( li + 1 )] = "comp." + framename;
+                Entry["LINK_TITLE_" + ( li + 1 )] = linktitle;
+            }
+            Entry[calendars.LINKS] = pWithLink.length.toString();
+        }
+        else
+        {
+            if ( pWithLink == true || pWithLink == undefined )
+            {
+                framename = vars.getString("$sys.currentimagename");
+                framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0];
+                dbid = vars.getString("$comp.idcolumn");
+                linktitle = framdata[2] + " - " + swing.getImageContent();
+            }
+            Entry[calendars.LINKS] = "1";
+            Entry["LINK_ALIAS_1"] = vars.getString("$sys.dbalias");
+            Entry["LINK_TABLE_1"] = framdata[0];
+            Entry["LINK_IDCOLUMN_1"] = framdata[1];
+            Entry["LINK_DBID_1"] = dbid;
+            Entry["LINK_FRAME_1"] = "comp." + framename;
+            Entry["LINK_TITLE_1"] = linktitle;
+        }
+    }
+    
+
+if(pAppLinkContext && pAppLinkId)
+{
+    Entry["AppLinkContext"] = pAppLinkContext;
+    Entry["AppLinkId"] = pAppLinkId;
+}
+    return Entry;
+}
+
+/*
+ * Liefert den CalendarStatus übersetzt zurück.
+ * @param {String} pStatus req Status
+ * @param {String} pLanguage opt Sprache
+ * @param {String} pKind opt ToDo oder Event
+ *
+ * @return {String} übersetzte Status
+ */
+function getCalendarStatus( pStatus, pLanguage, pKind)
+{
+    //kein mappen des Status, da wirklich verschiedene Dinge angezeigt werden sollen
+    switch ( pStatus )
+    {
+        case calendars.STATUS_BUSY: 
+            return translate.text("Gebucht", pLanguage)
+        case calendars.STATUS_CANCELLED:
+            if(pKind == "ToDo" && pKind != undefined) return translate.text("Zurückgestellt", pLanguage)
+            return translate.text("Abgesagt", pLanguage)
+        case calendars.STATUS_COMPLETED:
+            return translate.text("Erledigt", pLanguage)
+        case calendars.STATUS_CONFIRMED:
+            return translate.text("Bestätigt", pLanguage)
+        case calendars.STATUS_FREE:
+            return translate.text("frei", pLanguage)
+        case calendars.STATUS_INPROCESS:
+            return translate.text("In Bearbeitung", pLanguage)
+        case calendars.STATUS_NEEDSACTION:
+            return translate.text("Nicht begonnen", pLanguage)
+        case calendars.STATUS_OOF:
+            return translate.text("Außer Haus", pLanguage)
+        case calendars.STATUS_TENTATIVE:
+            return translate.text("Vorläufig", pLanguage)
+        default:
+            return "";
+    }
+}
+
+/*
+ * Zu einer übergebenen Priorität wird ihre Bedeutung übersetzt und zurückgegeben.
+ *
+ * @param {String} pPriority req Priorität
+ * @param {String} pLanguage opt Sprache
+ *
+ * @return (String) übersetzte Bedeutung einer Priorität
+ */
+function getCalendarPriority(pPriority, pLanguage)
+{
+    switch(pPriority)
+    {
+        case "9":
+            return translate.text("niedrig", pLanguage);
+            break;
+        case "5":
+            return translate.text("normal", pLanguage);
+            break;
+        case "1":
+            return translate.text("hoch", pLanguage);
+            break;
+        default:
+            return translate.text("keine", pLanguage);
+            break;
+    }
+}
+
+/*
+ * Liefert zum Objekt verknüpfte Aufgaben aus dem Kalender.
+ *
+ * @param {String} pFrame req Name des Frames
+ * @param {String} pDBID req ID des verknüpften Datensatzes
+ * @param {String} pAlias opt
+ * @param {String} pLanguage opt Sprache
+ *
+ * @return {[]} mit Aufgaben aus Kalender
+ */
+function getLinkedToDos (pFrame, pDBID, pAlias, pLanguage )
+{
+    if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias");
+    var tab = [];
+    var status = " and STATUS in ('NEEDS-ACTION', 'IN-PROCESS')";
+    var exists = [];
+    var zustaendig = "";
+    var today = getDate(vars.getString("$sys.date"));
+    var filtervalues = ["", "false"];
+    if ( vars.exists("$image.FilterValuesT") )
+    {
+        filtervalues = vars.get("$image.FilterValuesT");
+        zustaendig = filtervalues[0]
+        if (filtervalues[1] == "true") status = " and STATUS in ('COMPLETED', 'CANCELLED')";
+    }
+
+    var entryids = db.table("select ENTRYID, OWNER from ASYS_CALENDARLINK "
+        + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." + pFrame + "' "
+        + "and ENTRYID is not null "
+        + "and ENTRYTYPE = " + calendars.VTODO + " "
+        + "and DBID = '" + pDBID + "' "
+        + status, pAlias);
+
+    for (var i = 0; i < entryids.length; i++)
+    {
+        if ( exists.indexOf(entryids[i][0]) == -1)
+        {
+            try
+                {
+                    var entry = calendars.getEntry(entryids[i][0], null, getTitleCalenderUser( entryids[i][1] ), calendars.VTODO);
+                    var entr = new Array;
+                    status = "";
+                    var user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
+                    if(user == null) user = entry[calendars.USER2]["cn"];
+                     else user = user[tools.TITLE]
+                    if ((user == zustaendig || zustaendig == ""))
+                    {
+                        entr[0] = text.encodeMS([entry[calendars.ID], user]);
+                        var due = getDate(entry[calendars.DUE]);
+                        if (due < today ) entr[1]	= "-1769402";
+                        else  if (due > today) entr[1]	= "-16777216"; else entr[1]	= "-16744020";
+                        entr[2] = "-1";  // Hintergrundfarbe
+                        entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length;
+                        entr[4] = entry[calendars.DUE]
+                        entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo");
+                        entr[6] = entry[calendars.SUMMARY]
+                        entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
+                        entr[8] = getRealName(entry[calendars.ATTENDEES]);
+                        entr[9] = entry[calendars.DESCRIPTION];
+                        entr[10] = entry[calendars.PRIORITY];
+                        tab.push(entr);
+                        exists.push(entryids[i][0]);
+                    }
+            }
+            catch (ex)
+            {
+                logging.log(ex);
+            }
+        }
+    }
+    array_mDimSort(tab, 4, false); //Sortierung nach Fälligkeitsdatum
+    return tab;
+}
+
+/*
+ * Anzeige des Aufgaben-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return string Anzeige
+ */
+function show_filterLinkedToDos(pFilter)
+{
+    var retstring = "";
+    if (pFilter[0] != "")
+    {
+        var userp = tools.getUser( pFilter[0] )[tools.PARAMS];
+        retstring = translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME];
+    }
+    if (pFilter[1] == "true") retstring += ", " + translate.text("erledigt / zurückgestellt");
+
+    return retstring
+}
+
+/*
+ * Liefert zum Objekt verknüpfte Events aus dem Kalender.
+ *
+ * @param {String} pFrame req Name des Frames
+ * @param {String} pDBID req ID des verknüpften Datensatzes
+ * @param {Object} pFilter opt
+ * @param {String} pAlias opt
+ * @param {String} pUser opt Benutzer
+ *
+ * @return {[]} mit Events aus Kalender
+ */
+function getLinkedEvents (pFrame, pDBID, pFilter, pAlias, pUser )
+{
+    if ( pFilter == "" || pFilter == undefined)
+        pFilter = reset_filterEvent();
+
+    var tab = [];
+    var exists = [];
+    var conditions = [];
+    var today = getDate(vars.getString("$sys.date"));
+    var conditioncount = 0;
+    var stati = [];
+
+    if ( pFilter.tentative == "true" )
+        stati.push(mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() ));
+
+    if ( pFilter.cancelled == "true" )
+        stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendType() ));
+
+    if ( pFilter.confirmed == "true" )
+        stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
+
+    if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS)
+        stati.push(calendars.STATUS_FREE);
+
+    if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias");
+
+    var entryids = db.table(["select ENTRYID, OWNER "
+        + "from ASYS_CALENDARLINK "
+        + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp."
+        + pFrame + "' and ENTRYID is not null and ENTRYTYPE = " + calendars.VEVENT
+        + " and DBID = '" + pDBID + "' and DTSTART >= ?",
+        [ [ String(pFilter.datefrom - datetime.ONE_WEEK), SQLTYPES.DATE ]]], pAlias );
+
+    /*
+     * Check for rights before constructing condition otherwise you'll get an error by opening linked Data
+     */
+    var userToRead = []
+    if(pUser != undefined)
+    {
+        userToRead = getCalendarUsers( calendars.RIGHT_READ_APPOINTMENT, pUser );
+    }
+    else
+    {
+        userToRead = calendars.getDisplayCalendarUsers(calendars.RIGHT_READ_APPOINTMENT);
+    }
+    var userMap = {};
+    for (let i = 0; i < userToRead.length; i++)
+    {
+        userMap[userToRead[i][1]] = true;
+    }
+
+    for ( var i = 0;i < entryids.length; i++)
+    {
+        var user = getTitleCalenderUser(entryids[i][1]);
+        if(userMap[user])
+        {
+            for ( var z = 0; z < stati.length; z++ )
+                _addEntryCondition(conditions, String(++conditioncount),
+                {
+                    TYPE: calendars.VEVENT,
+                    START: pFilter.datefrom,
+                    END: pFilter.dateto,
+                    USER: user,
+                    STATUS: stati[z],
+                    UID: entryids[i][0]
+                });
+        } else continue
+    }
+    conditions["COUNT"] = String(conditioncount);
+
+    var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto);
+    for ( let i = 0; i < entries.length; i++)
+    {
+        for (var j = 0; j < entries[i].length; j++)
+        {
+            var entry = entries[i][j];
+            if( exists.indexOf(entry[calendars.ID]) == -1 && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > 0))
+            {
+                var entr = new Array;
+                var start = getDate(entry[calendars.DTSTART]);
+                var end = getDate(entry[calendars.DTEND]);
+                user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
+                if(user == null) user = entry[calendars.USER2]["cn"];
+                 else user = user[tools.TITLE]
+                entr[0] = text.encodeMS([entry[calendars.ID], user , entry[calendars.RECURRENCEID]]);
+                if (end < today) entr[1]	= "-6710887" ;
+                else if (start <= today && end >= today )   entr[1] = "-16744020" ;
+                else entr[1] = "-16777216";
+                entr[2] = "-1"
+                entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length;
+                entr[4] = entry[calendars.DTSTART]
+                entr[5] = entry[calendars.DTEND]
+                entr[6] = entry[calendars.SUMMARY]
+                entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
+                entr[8] = getRealName(entry[calendars.ATTENDEES]);
+                entr[9] = entry[calendars.DESCRIPTION]
+                tab.push(entr);
+                exists.push(entry[calendars.ID]);
+            }
+        }
+    }
+    array_mDimSort(tab, 4, false);
+    return tab;
+}
+
+/*
+ * Liefert Aufgaben aus dem Kalender.
+ *
+ * @param {Object} pFilter req
+ * @param {String} pLanguage opt
+ * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen
+ *
+ * @return {[]} mit allen aufgaben aus dem Kalender
+ */
+function getTodos( pFilter, pLanguage, pShortForm )
+{
+    if ( pFilter == "" )    pFilter =  reset_filterToDo();
+    var tab = [];
+    var today = getDate (vars.getString("$sys.date"));
+    var conditions = [];
+    var conditioncount = 0;
+    var user = pFilter.user;
+    var stati = [];
+    var status = [];
+    var exists = [];
+    var entries = [];
+
+    if ( pFilter.needs_action == "true" )
+    {
+        stati.push(mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ));
+        status.push("NEEDS-ACTION");
+    }
+    if ( pFilter.in_process == "true" )
+    {
+        stati.push(mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ));
+        status.push("IN-PROCESS");
+    }
+    if ( pFilter.completed == "true" )
+    {
+        stati.push(mapCalendarStatus(calendars.STATUS_COMPLETED, calendars.getBackendTypeTasks() ));
+        status.push("COMPLETED");
+    }
+    if ( pFilter.cancelled == "true" )
+    {
+        stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendTypeTasks() ));
+        status.push("CANCELLED");
+    }
+    if (pFilter.delegated == "true" )
+    {
+        var from = [pFilter.datefrom, SQLTYPES.TIMESTAMP];
+        var to = [pFilter.dateto, SQLTYPES.TIMESTAMP];
+        setAllCalendarGrant();
+        user = calendars.getCalendarUser(user);
+        user = db.table(["select ELEMENTUID, OWNER from ASYS_CALENDARBACKEND where ENTRYTYPE = 2 and OWNER != '" + user + "' and ORGANIZER = '"
+            + user + "' and STATUS in ('" + status.join("', '") + "') and (( STARTTIME >= ? and STARTTIME <= ?) or "
+            + "( ENDTIME >= ? and ENDTIME <= ? ) or ( STARTTIME >= ? and ENDTIME <= ? ))", [from, to, from, to, from, to]] );
+
+        for (let i = 0; i < user.length; i++ )
+        {
+            try
+            {
+                entries.push([calendars.getEntry(user[i][0], null, getTitleCalenderUser(user[i][1]), calendars.VTODO)]);
+            }
+            catch(err){
+                logging.log(err);
+            }
+        }
+        setCalendarGrant();
+    }
+    else
+    {
+        if ( typeof( pFilter.user ) != "object" )  user = [user.trim()];
+        for (let i = 0; i < user.length; i++ )
+        for ( var z = 0; z < stati.length; z++ )
+            _addEntryCondition(conditions, ++conditioncount,
+            {
+                TYPE: calendars.VTODO,
+                START: pFilter.datefrom,
+                END: pFilter.dateto,
+                USER: user[i],
+                STATUS: stati[z]
+            });
+
+        conditions["COUNT"] = String(conditioncount);
+        entries = calendars.getEntries(conditions);
+    }
+
+    for (i = 0; i < entries.length; i++)
+    {
+        var entry = entries[i][0];
+        user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
+        if (user == null)  user = entry[calendars.USER2]["cn"];
+         else user = user[tools.TITLE]
+        if ( !(user != vars.getString("$sys.user") && entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) // no privat
+            && !( pFilter.delegated == "true" && ( isAffectedUser( entry, pFilter.user) || exists.indexOf(entry[calendars.ID]) > -1  ) ) // no duplicate
+            && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf( pFilter.category ) > -1 ) ) // Filter category
+            {
+            var entr = [];
+            var links =  entry[calendars.LINKS];
+            var due = entry[calendars.DUE] != "" ? getDate(entry[calendars.DUE]) : "";
+            entr[0] = text.encodeMS([entry[calendars.ID], user]);
+            if (due == today )      entr[1] = "-16744020" ;
+            else if(due == "")      entr[1] = "-13395712";
+            else if (due > today )  entr[1] = "-16777216";
+            else                    entr[1]	= "-1769402";
+            if (entry[calendars.PRIORITY] == "1") entr[2] = "-100";
+            entr[3] = entry[calendars.ATTENDEES].length;
+            entr[4] = entry[calendars.DUE];
+
+            if (pShortForm)
+            {
+                entr[5] = entry[calendars.SUMMARY];
+                entr[6] = entry[calendars.DESCRIPTION];
+            }
+            else
+            {
+                entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo");
+                entr[6] = getCalendarPriority( entry[calendars.PRIORITY], pLanguage);
+                entr[7] = entry[calendars.SUMMARY];
+                entr[8] = getRealName( [ entry[calendars.ORGANIZER2] ] );
+                entr[9] = getRealName( entry[calendars.ATTENDEES] );
+                if (links == undefined) entr[10] = "";	else entr[10] = links;
+                entr[11] = entry[calendars.DESCRIPTION];
+                entr[12] = entry[calendars.CREATED];
+            }
+
+            tab.push(entr);
+            if ( pFilter.delegated == "true" )  exists.push(entry[calendars.ID]);
+        }
+    }
+
+    if (pShortForm)
+        sortArray(tab, -1, 4, 1, 5);
+    else
+        sortArray(tab, -1, 4, 1, 12 );
+
+    return tab;
+}
+
+/*
+ * Fügt eine Condition hinzu
+ *
+ * @param {[]} pConditions req die Conditions
+ * @param {Integer} pIndex req Index der Condition
+ * @param {Object} pValues req
+ *
+ * @return {void}
+ */
+function _addEntryCondition(pConditions, pIndex, pValues)
+{
+    var params = ["TYPE", "START", "END", "USER", "STATUS", "UID"];
+
+    for (var i = 0; i < params.length; i++)
+        if (pValues[params[i]] != undefined)    pConditions[params[i] + "_" + pIndex] = pValues[params[i]];
+}
+
+CalendarUtil.addEntryCondition = function(pConditions, pIndex, pValues)
+{
+    _addEntryCondition(pConditions, pIndex, pValues);
+}
+/*
+ * Liefert Events zu bestimmten Usern/Daten in einem Array.
+ *
+ * @param {Object} pFilter req
+ * @param {String} pLanguage opt
+ * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen
+ *
+ * @return {[]}
+ *				[0] ID
+ *				[1] Vordergrundfarbe
+ *				[2] Hintergrundfarbe
+ *				[3] Start
+ *				[4] Ende
+ *				[5] Betreff
+ *				[6] Inhalt
+ *				[7] User
+ *				[8] Anzahl Verknüpfungen
+ *				[9] Klassifikation (privat/öffentlich)
+ */
+function getEvents( pFilter, pLanguage, pShortForm )
+{
+    if ( pFilter == "" )  pFilter = reset_filterEvent();
+    var tab = [];
+    var conditions = [];
+    var today = getDate(vars.getString("$sys.date"));
+    var conditioncount = 0;
+    var stati = [];
+    var user = undefined;
+    if ( pFilter.tentative == "true" )    stati.push(calendars.STATUS_TENTATIVE);
+    if ( pFilter.cancelled == "true" )    stati.push(calendars.STATUS_CANCELLED);
+    if ( pFilter.confirmed == "true" )
+        stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ));
+
+    if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true")
+        stati.push(calendars.STATUS_FREE);
+
+    if ( pFilter.user != "" )	user = (pFilter.user).trim();
+
+    for ( var z = 0; z < stati.length; z++ )
+        _addEntryCondition(conditions, String(++conditioncount),
+        {
+            TYPE: calendars.VEVENT,
+            START: pFilter.datefrom,
+            END: pFilter.dateto,
+            USER: user,
+            STATUS: stati[z]
+        });
+
+    conditions["COUNT"] = String(conditioncount);
+
+    var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto);
+    for ( var i = 0;i < entries.length; i++)
+    {
+        for (var j = 0; j < entries[i].length; j++)
+        {
+            var entry = entries[i][j];
+            if( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > -1 )
+            {
+                var entr = new Array;
+                var start = getDate(entry[calendars.DTSTART]);
+                var end = getDate(entry[calendars.DTEND]);
+
+                user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length))
+                if(user == null) user = entry[calendars.USER2]["cn"];
+                else user = user[tools.TITLE]
+                entr[0] = text.encodeMS([ entry[calendars.ID], user, entry[calendars.RECURRENCEID]]);
+                if (end < today ) entr[1]	="-6710887" ;
+                else if (start > today) entr[1]	= "-16777216";
+                else entr[1]	= "-16744020" ;
+                entr[2] = "-1"
+                entr[3] = entry[calendars.ATTENDEES].length;
+                entr[4] = entry[calendars.DTSTART];
+                entr[5] = entry[calendars.DTEND];
+                entr[6] = entry[calendars.SUMMARY];
+
+                if (!pShortForm)
+                {
+                    entr[7] = getRealName([entry[calendars.ORGANIZER2]]);
+                    entr[8] = getRealName(entry[calendars.ATTENDEES]);
+                    entr[9] = getCalendarStatus( entry[calendars.STATUS], pLanguage );
+                    if (entry[calendars.LINKS] == undefined) entr[10] = "";
+                    else entr[10] = entry[calendars.LINKS];
+                    entr[11] = entry[calendars.DESCRIPTION];
+                }
+                tab.push( entr );
+            }
+        }
+    }
+    sortArray(tab, -1, 4, 1, 6 );
+    return tab;
+}
+
+/*
+ * Liefert den echten Namen anhand des Logins zurück
+ *
+ * @param {Array}[]} pUserMap req pUserMap
+ *
+ * @return String
+ */
+function getRealName(pUserMap)
+{
+    var resultName = [];
+    var RealNames = getRealNameObject(pUserMap);
+
+    for ( var realname in RealNames )   resultName.push(RealNames[realname]);
+    return resultName.join(", \n");
+}
+
+/*
+ * Liefert den echten Namen anhand des Logins zurück
+ *
+ * @param {Array}[]} pUserMap req pUserMap
+ *
+ * @return Object
+ */
+function getRealNameObject(pUserMap)
+{
+    var resultObject = {};
+    var realname = "";
+
+    for ( let i = 0; i < pUserMap.length; i++ )
+    {
+        let user = tools.getUserByAttribute(tools.CALENDARID, [pUserMap[i]["paramvalue"].substr("mailto:".length)])
+        if ( user != null )
+        {
+            if(vars.exists("$global.firstLastName") && vars.get("$global.firstLastName"))
+                realname = user[tools.PARAMS][tools.LASTNAME] + " " + user[tools.PARAMS][tools.FIRSTNAME];
+            else realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME];
+        }
+        else //Der User existiert nicht im System
+        {
+            realname = pUserMap[i]["cn"] + " " + pUserMap[i]["paramvalue"];
+        }
+        resultObject[pUserMap[i]["cn"]] = realname;
+    }
+    return resultObject;
+}
+
+
+/*
+ * Gibt an ob der User im Calendarobject vorhanden ist
+ *
+ * @param {Object} pEntry req Calendarobject
+ * @param {String} pUser req Title
+ *
+ * @return Object
+ */
+function isAffectedUser( pEntry, pUser)
+{
+    var usermap = pEntry[calendars.ATTENDEES];
+
+    for ( var i = 0; i < usermap.length; i++ )
+        if( usermap[i]["cn"] == pUser )
+            return true;
+    return false;
+}
+
+/*
+ * Liefert das Datum ohne Urzeit zurück
+ *
+ * @param {String} datetimeIn req DatumZeit
+ *
+ * @return {date}
+ */
+function getDate( datetimeIn )
+{
+    if ( datetimeIn != "")
+        return datetime.clearTime(datetimeIn);
+    else return "";
+}
+
+/*
+ * Setzt den Aufgaben-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return {image}
+ */
+function filterToDo( pFilter )
+{
+    var error = true;
+    var von = pFilter.datefrom;
+    var bis = pFilter.dateto;
+    if ( pFilter == "" )	pFilter =  reset_filterToDo();
+    do
+    {
+        vars.set("$local.relation_id", pFilter.user);
+        vars.set("$local.edt_von", pFilter.datefrom);
+        vars.set("$local.edt_bis", pFilter.dateto);
+        vars.set("$local.category", pFilter.category);
+        vars.set("$local.delegated", pFilter.delegated);
+        vars.set("$local.needs_action", pFilter.needs_action);
+        vars.set("$local.in_process", pFilter.in_process);
+        vars.set("$local.completed", pFilter.completed);
+        vars.set("$local.cancelled", pFilter.cancelled);
+        var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_FILTER");
+        if( res != null )
+        {
+            pFilter.user =      res["DLG_TASK_FILTER.relation_id"];
+            pFilter.datefrom =  res["DLG_TASK_FILTER.edt_von"];
+            pFilter.dateto =    res["DLG_TASK_FILTER.edt_bis"];
+            pFilter.category =  res["DLG_TASK_FILTER.category"];
+            pFilter.delegated = res["DLG_TASK_FILTER.delegated"];
+            pFilter.needs_action = res["DLG_TASK_FILTER.needs_action"];
+            pFilter.in_process = res["DLG_TASK_FILTER.in_process"];
+            pFilter.completed = res["DLG_TASK_FILTER.completed"];
+            pFilter.cancelled = res["DLG_TASK_FILTER.cancelled"];
+            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
+            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
+        }
+        else
+        {
+            pFilter.datefrom = von;
+            pFilter.dateto = bis;
+            error = false;
+        }
+    }
+    while ( error )
+    return pFilter;
+}
+
+/*
+ * Setzt den Aufgaben-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return {image}
+ */
+function filterToDo_Neon( pFilter )
+{
+    var error = true;
+    var von = pFilter.datefrom;
+    var bis = pFilter.dateto;
+    if ( pFilter == "" )	pFilter =  reset_filterToDo();
+    do
+    {
+        var prompts = {
+            FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"),
+            RESPONSIBLE: pFilter.user,
+            DATE_FROM: pFilter.datefrom,
+            DATE_TO: pFilter.dateto,
+            CATEGORY_TODO: pFilter.category,
+            DELEGATED: pFilter.delegated,
+            NEEDS_ACTION: pFilter.needs_action,
+            IN_PROCESS: pFilter.in_process,
+            COMPLETED: pFilter.completed,
+            CANCELLED: pFilter.cancelled
+        }
+
+        var buttons = {
+            "ok" : translate.text("OK"),
+            "": translate.text("Abbrechen")
+            };
+        var defaultButton = "ok";
+
+        var res = question.openDialog("DLG_FILTER_TODO_Neon", prompts, buttons, defaultButton);
+
+        if( res.button != null )
+        {
+            pFilter.user =      res.RESPONSIBLE;
+            pFilter.datefrom =  res.DATE_FROM;
+            pFilter.dateto =    res.DATE_TO;
+            pFilter.category =  res.CATEGORY_TODO;
+            pFilter.delegated = res.DELEGATED;
+            pFilter.needs_action = res.NEEDS_ACTION;
+            pFilter.in_process = res.IN_PROCESS;
+            pFilter.completed = res.COMPLETED;
+            pFilter.cancelled = res.CANCELLED;
+            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
+            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
+        }
+        else
+        {
+            pFilter.datefrom = von;
+            pFilter.dateto = bis;
+            error = false;
+        }
+    }
+    while ( error )
+    return pFilter;
+}
+
+
+/*
+ * Anzeige des Aufgaben-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return string Anzeige
+ */
+function show_filterToDo(pFilter)
+{
+    var retstring = "";
+    var userp = tools.getUser( pFilter.user )[tools.PARAMS];
+    if (pFilter.user != "") retstring = (translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]);
+    if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy"));
+    if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy"));
+    if (pFilter.category != "") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category;
+    if (pFilter.delegated == "true") retstring += ", " + translate.text("delegiert");
+    if (pFilter.needs_action == "true") retstring += ", " + translate.text("Nicht begonnen");
+    if (pFilter.in_process == "true") retstring += ", " + translate.text("In Bearbeitung");
+    if (pFilter.completed == "true") retstring += ", " + translate.text("Erledigt");
+    if (pFilter.cancelled == "true") retstring += ", " + translate.text("Zurückgestellt");
+
+    return retstring
+}
+
+/*
+ * Setzt den Aufgaben-Filter zurück
+ *
+ * @return {filter}
+ */
+function reset_filterToDo()
+{
+    var today = getDate (vars.getString("$sys.date"));
+
+    return pFilter =  {
+        user: vars.getString("$sys.user"),
+        datefrom: String(eMath.subInt(today, 720 * datetime.ONE_DAY)),
+        dateto: String(eMath.addInt(eMath.addInt(today, 3 * datetime.ONE_DAY)
+            ,datetime.ONE_DAY - datetime.ONE_MINUTE)),
+        category: "",
+        delegated: "",
+        needs_action: "true",
+        in_process: "true",
+        completed: "",
+        cancelled: ""
+    };
+}
+
+/*
+ * Setzt den Event-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return {image}
+ */
+function filterEvent( pFilter )
+{
+    var error = true;
+    var von = pFilter.datefrom;
+    var bis = pFilter.dateto;
+    if ( pFilter == "" )	pFilter =  reset_filterEvent();
+    do
+    {
+        vars.set("$local.relation_id", pFilter.user);
+        vars.set("$local.edt_von", pFilter.datefrom);
+        vars.set("$local.edt_bis", pFilter.dateto);
+        vars.set("$local.category", pFilter.category);
+        vars.set("$local.tentative", pFilter.tentative);
+        vars.set("$local.confirmed", pFilter.confirmed);
+        vars.set("$local.cancelled", pFilter.cancelled);
+        vars.set("$local.free", pFilter.free);
+        var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_EVENT_FILTER");
+        if( res != null )
+        {
+            pFilter.user =      res["DLG_EVENT_FILTER.relation_id"];
+            pFilter.datefrom =  res["DLG_EVENT_FILTER.edt_von"];
+            pFilter.dateto =    res["DLG_EVENT_FILTER.edt_bis"];
+            pFilter.category =  res["DLG_EVENT_FILTER.category"];
+            pFilter.tentative = res["DLG_EVENT_FILTER.tentative"];
+            pFilter.confirmed = res["DLG_EVENT_FILTER.confirmed"];
+            pFilter.cancelled = res["DLG_EVENT_FILTER.cancelled"];
+            pFilter.free      = res["DLG_EVENT_FILTER.free"];
+            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
+            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
+        }
+        else
+        {
+            pFilter.datefrom = von;
+            pFilter.dateto = bis;
+            error = false;
+        }
+    }
+    while ( error )
+    return pFilter;
+}
+
+/*
+ * Setzt den Event-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return {image}
+ */
+function filterEvent_Neon( pFilter )
+{
+    var error = true;
+    var von = pFilter.datefrom;
+    var bis = pFilter.dateto;
+    if ( pFilter == "" )	pFilter =  reset_filterEvent();
+    do
+    {
+        var buttons = {
+            "ok" : translate.text("OK"),
+            "": translate.text("Abbrechen")
+        };
+        var defaultButton = "ok";
+
+        var prompts = {
+            FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"),
+            RESPONSIBLE_APPOINTMENT: pFilter.user,
+            DATE_FROM: pFilter.datefrom,
+            DATE_TO: pFilter.dateto,
+            CATEGORY_APPOINTMENT: pFilter.category,
+            TENTATIVE: pFilter.tentative,
+            CONFIRMED: pFilter.confirmed,
+            CANCELLED: pFilter.cancelled
+        }
+        var res = question.openDialog("DLG_FILTER_APPOINTMENT_Neon", prompts, buttons, defaultButton);
+        if( res.button != null )
+        {
+            pFilter.user =      res.RESPONSIBLE_APPOINTMENT;
+            pFilter.datefrom =  res.DATE_FROM;
+            pFilter.dateto =    res.DATE_TO;
+            pFilter.category =  res.CATEGORY_APPOINTMENT;
+            pFilter.tentative = res.TENTATIVE;
+            pFilter.confirmed = res.CONFIRMED;
+            pFilter.cancelled = res.CANCELLED;
+            if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false;
+            else question.showMessage(translate.text("Bitte Datumseingabe prüfen!"))
+        }
+        else
+        {
+            pFilter.datefrom = von;
+            pFilter.dateto = bis;
+            error = false;
+        }
+    }
+    while ( error )
+    return pFilter;
+}
+
+/*
+ * Anzeige des Event-Filter
+ *
+ * @param {Object} pFilter req
+ *
+ * @return string Anzeige
+ */
+function show_filterEvent(pFilter)
+{
+    var retstring = "";
+
+    var userp = tools.getUser( pFilter.user )[tools.PARAMS];
+    if (pFilter.user != "") retstring = translate.text("Termine von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME];
+    if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy"));
+    if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy"));
+    if (pFilter.category == "true") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category;
+    if (pFilter.tentative == "true") retstring += ", " + translate.text("Vorläufig");
+    if (pFilter.confirmed == "true") retstring += ", " + translate.text("Bestätigt");
+    if (pFilter.cancelled == "true") retstring += ", " + translate.text("Abgesagt");
+
+    return retstring
+}
+
+/*
+ * Setzt den Event-Filter zurück
+ *
+ * @return {filter}
+ */
+function reset_filterEvent()
+{
+    var today = getDate (vars.getString("$sys.date"));
+
+    return pFilter =  {
+        user: vars.getString("$sys.user"),
+        datefrom: String(today), //nur die Termine ab heute anzeigen,
+        //die von vor einer Woche sind uninteressant
+        dateto: String(eMath.addInt(eMath.addInt(today, datetime.ONE_WEEK)
+            ,datetime.ONE_DAY - datetime.ONE_MINUTE)),
+        category: "",
+        tentative: "true",
+        confirmed: "true",
+        cancelled: "",
+        free: "true"
+    };
+}
+
+/*
+ * Setzt den Aufgaben-Filter in Tab Aufgaben
+ *
+ * @return {image}
+ */
+function filterLinkedToDo()
+{
+    var filtervalues = ["", "false"];
+    vars.set("$local.CalenderUser", getCalenderUser( calendars.RIGHT_READ_TASK ));
+
+    //Vorbelegen der Werte, wenn bereits gewählt wurde:
+    if(vars.exists("$image.FilterValuesT"))
+    {
+        filtervalues = vars.get("$image.FilterValuesT");
+        vars.set("$local.relation_id", filtervalues[0]);
+        vars.set("$local.done", filtervalues[1]);
+    }
+
+    var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_DATE_LINKED_FILTER");
+
+    if( res != null && res != undefined && res != "")
+    {
+        filtervalues[0] = res["DLG_TASK_DATE_LINKED_FILTER.relation_id"];
+        filtervalues[1] = res["DLG_TASK_DATE_LINKED_FILTER.done"]
+    }
+    vars.set("$image.FilterValuesT", filtervalues );
+
+    return(filtervalues);
+}
+
+/*
+ * Setzt den Aufgabe-Filter zurück
+ *
+ * @return {image}
+ */
+function resetfilterLinkedToDo()
+{
+    var filtervalues = ["", "false"];
+
+    vars.set("$image.FilterValuesT", filtervalues );
+
+}
+
+/*
+ * setzt die Kalenderrechte
+ *
+ * @return {void}
+ */
+function setCalendarGrant()
+{
+    calendars.resetCalendarUser();
+    var user_read_todo = [];
+    var user_write_todo = [];   // ["Admin"]
+    var user_read_event = [];
+    var user_write_event = [];
+    var tree = {};
+    var data = db.table("select THEMEID, THEME.THEME_ID, LOGIN, STATUS from THEME "
+        + " left join EMPLOYEE on EMPLOYEE.THEME_ID = THEMEID left join RELATION on RELATION_ID = RELATIONID and STATUS = 1"
+        +" where KIND = 2");
+    for ( let i = 0; i < data.length; i++)
+    {
+        if ( tree[data[i][0]] == undefined )    tree[data[i][0]] = {
+            pid: data[i][1],
+            isuser: false
+        };
+        if ( data[i][2] != "" && data[i][3] != "" )     tree[data[i][2]] = {
+            pid: data[i][0],
+            isuser: true
+        };
+    }
+
+    var user = vars.getString("$sys.user");
+    // Lese- und Schreibrechte auf Kalender aus Datentabelle holen
+    data = db.table("select HASRIGHTFOR, TODO_RIGHTS, EVENT_RIGHTS from AOSYS_CALENDAR_RIGHTS where LOGIN = '" + user + "'");
+    for ( var i = 0; i < data.length; i++ )
+        if(tree[data[i][0]] != undefined)
+            tree[data[i][0]].grants = data[i].slice(1);
+
+    for ( login in tree )
+    {
+        if( tree[login].isuser )
+        {
+            var grantstodo = __getGrants( login, 0 );
+            var grantsevent = __getGrants( login, 1 );
+            if ( grantstodo.length + grantsevent.length > 0 )
+            {
+                if ( grantstodo == "1" || grantstodo == "3")  user_read_todo.push(login);
+                if ( grantstodo == "2" || grantstodo == "3")  user_write_todo.push(login);
+                if ( grantsevent == "1" || grantsevent == "3")  user_read_event.push(login);
+                if ( grantsevent == "2" || grantsevent == "3")  user_write_event.push(login);
+            }
+        }
+    }
+    calendars.setCalendarUser(user_read_todo, calendars.RIGHT_READ_TASK, true, calendars.SORTSTRATEGY_NATURAL );
+    calendars.setCalendarUser(user_write_todo, calendars.RIGHT_WRITE_TASK, true, calendars.SORTSTRATEGY_NATURAL );
+    calendars.setCalendarUser(user_read_event, calendars.RIGHT_READ_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL );
+    calendars.setCalendarUser(user_write_event, calendars.RIGHT_WRITE_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL );
+
+    //********** Ressourcen in Kalender einfügen ************
+    var ressource = tools.getUsersWithRole("PROJECT_Ressource");
+    calendars.setCalendarUser(  ressource, calendars.RIGHT_READ_APPOINTMENT | calendars.RIGHT_WRITE_APPOINTMENT  );
+
+    //add all users from support-role since support-action-tasks (sp_supportAktionen) generates tasks for all support-role members
+    //and if you're a member you are allowed to edit these
+    if (tools.hasRole(user, "PROJECT_Support"))
+    {
+        var support = tools.getUsersWithRole("PROJECT_Support");
+        calendars.setCalendarUser(  support, calendars.RIGHT_WRITE_TASK | calendars.RIGHT_READ_TASK  );
+    }
+
+    function __getGrants( pKey, pIndex )
+    {
+        var grants = [];
+        if ( tree[pKey].grants != undefined && tree[pKey].grants[pIndex]) grants = tree[pKey].grants[pIndex];
+        else if ( tree[pKey].pid != "" )   grants = __getGrants( tree[pKey].pid, pIndex );
+        return grants;
+    }
+}
+
+/*
+ * setzt Recht für alle Kalender
+ *
+ * @return {void}
+ */
+function setAllCalendarGrant()
+{
+    calendars.resetCalendarUser();
+    var users = tools.getStoredUsers();
+    var calendar_user = [];
+    for ( var i = 0; i < users.length; i++ )    calendar_user.push( users[i][1] );
+    calendars.setCalendarUser(calendar_user, calendars.RIGHT_READ_TASK | calendars.RIGHT_WRITE_TASK, false, calendars.SORTSTRATEGY_NATURAL );
+}
+
+/*
+ * gibt die Logins der user, die den übergebenen User als Attribute eingetragen haben, zurück
+ *
+ * @param {[]} pUsers req Logins
+ * @param {String []} pAttrName req AttributeName für Employee
+ * @param {String []} pFields opt
+ *
+ * @return {String []} Logins
+ */
+function getUsersbyAttr( pUsers, pAttrName, pFields )
+{
+    if (typeof(pAttrName) == "string") pAttrName = [pAttrName]
+
+    if ( pFields == undefined )
+    {
+        pFields = ["LOGIN"];
+    }
+
+    var sqlstr = "select " + pFields.join(", ") + " from ATTRLINK join ATTR on ATTRLINK.ATTR_ID = ATTRID and OBJECT_ID = 12 "
+    + "and ATTRNAME in ('" + pAttrName.join("','") + "') "
+    + " join EMPLOYEE on EMPLOYEEID = ATTRLINK.ROW_ID join RELATION on RELATION_ID = RELATIONID join PERS on PERS_ID = PERSID"
+    + " where VALUE_ID in (select EMPLOYEEID from EMPLOYEE where LOGIN in ('" + pUsers.join("','") + "'))"
+    + "";
+
+    if(pFields.length == 1)
+        return db.array(db.COLUMN, sqlstr);
+    else
+        return db.table(sqlstr);
+}
+
+/*
+ * Gibt die Anzahl der verknüpften Aufgaben und Termine zurück.
+ *
+ * @param {String} pID req
+ * @param {String} pFrame req
+ *
+ * @return {String} text
+ */
+function countLinkedTodoEvent(pID, pFrame)
+{
+    var today = getDate (vars.getString("$sys.date"));
+    var datefrom = String(today);
+    var dateto = String(eMath.addInt(today, datetime.ONE_WEEK));
+
+    var str = "select count(distinct ELEMENTUID) from ASYS_CALENDARLINK join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID "
+    + " where FRAME = 'comp." + pFrame + "' and ELEMENTUID is not null and DBID = '" + pID + "'";
+    var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO + " and STATUS in ('"
+        + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '"
+        + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')");
+
+    var eventStatusList = [
+         mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )
+        ,mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() )
+    ];
+
+    if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS)
+        eventStatusList.push(calendars.STATUS_FREE);
+
+    var retevent = db.cell([str + " and ENTRYTYPE = " + calendars.VEVENT + " and STATUS in ('" + eventStatusList.join("', '") + "')"
+            + " and DTSTART >= ? and DTEND <= ?",
+        [ [ String(datefrom), SQLTYPES.DATE ],  [String(dateto), SQLTYPES.DATE ] ]]);
+
+    result.string(translate.withArguments("&Aufg / Term (%0/%1)", [rettask, retevent]));
+}
+
+/*
+ * Gibt die Anzahl der verknüpften Aufgaben zurück.
+ *
+ * @param {String} pID req
+ * @param {String} pFrame req
+ *
+ * @return {String} text
+ */
+function countLinkedTodo(pID, pFrame)
+{
+    var str = "select count(distinct ELEMENTUID) "
+    + "from ASYS_CALENDARLINK "
+    + "join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID "
+    + " where FRAME = 'comp." + pFrame + "' "
+    + "and ELEMENTUID is not null and DBID = '" + pID + "'";
+
+    var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO
+        + " and  STATUS in ('"
+        + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '"
+        + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')"
+        + "");
+
+    result.string(translate.withArguments("&Aufgaben (%0)", [rettask]));
+}
+
+/*
+ * Gibt die Überschneidungen von Termine zurück.
+ *
+ * @param {Date} pStart req
+ * @param {Date} pEnd req
+ * @param {Array} pUsers req
+ *
+ * @return {String Array} Termine
+ */
+function getOverlappingEvents(pStart, pEnd, pUsers  )
+{
+    var resultEvents = new Array();
+    var users = pUsers;
+    if (calendars.getBackendType() == calendars.BACKEND_DB && pStart != "" && pEnd != "" && users.length > 0)
+    {
+        calendars.clearCache();
+        for (var u = 0; u < users.length; u++)
+        {
+            var localuid = vars.get("$image.entry")[calendars.ID]
+            var condition = new Array();
+            condition["COUNT"] = "1";
+            condition["TYPE_1"] = calendars.VFREEBUSY;
+            condition["USER_1"] = users[u][0];
+            condition["START_1"] = pStart;
+            condition["END_1"] = pEnd;
+
+            var fbsall = calendars.getEntries(condition);
+            for (var j = 0; j < fbsall.length; j++)
+            {
+                var fbs = fbsall[j];
+                for (var i = 0; i < fbs.length; i++)
+                {
+                    var next = fbs[i];
+                    var uid = next[calendars.ID];
+                    var sum = next[calendars.SUMMARY];
+                    if (uid != localuid)
+                    {
+                        var freebusy = next[calendars.FREEBUSY];
+                        var freebusyDec = text.decodeMS(freebusy);
+                        var match = false;
+                        for (var k = 0; k < freebusyDec.length; k++)
+                        {
+                            var freebusyInstance = text.decodeMS(freebusyDec[k]);
+                            if (!freebusyInstance[0].equals("FREE"))
+                            {
+                                match = true;
+                            }
+                        }
+                        if (match)  resultEvents.push([users[u][2], sum != null && sum.length > 0 ? sum : "?", uid]);
+                    }
+                }
+            }
+        }
+    }
+    return resultEvents;
+}
+
+/*
+ * Überprüft den Eintrag, wenn eine neue Aufgaben angelegt wird darauf, ob private Aufgaben für andere erstellt werden
+ *
+ * @param {String[]} pUser die Liste der User, denen die Aufgabe zugewiesen werden soll
+ * @param {String} pClassification die Klassifizierung der Aufgabe - "PRIVATE"
+ *
+ * @return {Boolean} ob der Eintrag in der Konstellation möglich ist, wenn nicht wird eine Meldung ausgegeben
+ */
+function checkEntry(pUser, pClassification )
+{
+    if( pClassification == "PRIVATE" &&
+        ( pUser.length > 1 || text.decodeMS(pUser[0][0])[1] != "CN:" + vars.getString("$sys.user")))
+        {
+        question.showMessage(translate.text("Eine private Aufgabe kann nicht jemand anderem zugewiesen werden."));
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+/*
+ * Verschiebt ein Calendareintrag
+ *
+ * @param {String[]} pIDs req die zu verschiebenden Ids mit den Calenderinformationen (Multistring)
+ * @param {String} pTblCompName  opt die Komponente die aktualisiert werden soll
+ *
+ * @return {void}
+ */
+function shiftEntry(pIDs, pTblCompName)
+{
+    var datenew = swing.askUserQuestion(translate.text("Verschieben auf Datum?"), "DLG_DATE");
+    if (datenew != null )
+    {
+        var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK);
+        var usermap = {};
+        var granted = true;
+        for (let i = 0; i < grantedUsers.length; i++)
+        {
+            usermap[grantedUsers[i][1]] = true;
+        }
+
+        datenew = datetime.clearTime(datenew["DLG_DATE.Edit_date"]);
+        if (datenew <= vars.getString("$sys.today"))
+            question.showMessage(translate.text("nur Verschiebung in die Zukunft erlaubt!"));
+        else
+        {
+            for (var i = 0, j = pIDs.length; i < j; i++)
+            {
+                var id = text.decodeMS(pIDs[i]);
+                var entry = calendars.getEntry(id[0], null, id [1], calendars.VTODO);
+                var affectedUsers = entry[calendars.ATTENDEES];
+
+                granted =  hasGrantForEntryByObject(affectedUsers, usermap);
+                if(granted)
+                {
+                    //Zeitdifferenz von Aufgabenstart und -ende
+                    var dateDiff  = eMath.subInt(entry[calendars.DUE], entry[calendars.DTSTART]);
+
+                    //Startzeit der Aufgabe
+                    var startTime = eMath.subInt(entry[calendars.DTSTART]
+                        , datetime.clearTime(entry[calendars.DTSTART]));
+
+                    entry[calendars.DTSTART] = eMath.addInt(datenew, startTime);
+                    entry[calendars.DUE] = eMath.addInt(entry[calendars.DTSTART], dateDiff);
+                    calendars.update( [ entry ] );
+                }
+                else
+                    question.showMessage(translate.text("Keine Berechtigung zum Verschieben der Aufgabe"));
+            }
+        }
+    }
+}
+
+/*
+ * Gibt eine Aufgabe weiter
+ *
+ * @param {String} pIDs die ID der Aufgabe, welche weitergegeben werden soll
+ * @param {String} pTblCompName die Komponente der Aufgaben, die aktualisiert werden soll
+ *
+ * @return {void}
+ */
+function handOverToDo(pIDs, pTblCompName)
+{
+    var calendar_user = "";
+    var users = getCalenderUser( calendars.RIGHT_WRITE_TASK );
+    var publicCount = 0;
+    var privateCount = 0;
+    var notGrantedCount = 0;
+
+    var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK);
+    var userMap = {};
+    var granted = true;
+    for (let i = 0; i < grantedUsers.length; i++)
+    {
+        userMap[grantedUsers[i][1]] = true;
+    }
+
+    if (pIDs.length == 1)  // only one todo and private
+    {
+        var id = text.decodeMS( pIDs[0] );
+        var entry = calendars.getEntry( id[0], null, id[1] );
+        if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE)
+        {
+            question.showMessage(translate.text("Kein Weitergeben von privaten Aufgaben möglich!"));
+            return;
+        }
+    }
+
+    for ( let i = 0; i < users.length; i++)  if (pIDs.length > 0 || users[i][0] != id[1])   calendar_user += "|" + users[i][1];
+    var selection = swing.askQuestion(translate.text("Benutzer auswählen"), swing.QUESTION_COMBOBOX, calendar_user);
+    if (selection != null)
+    {
+        for ( let i = 0; i < users.length; i++)
+        {
+            if ( selection == users[i][1] )
+            {
+                selection = users[i];
+                break;
+            }
+        }
+        for( let i = 0; i < pIDs.length; i++)
+        {
+            let id = text.decodeMS( pIDs[i] );
+            let entry = calendars.getEntry( id[0], null, id[1] );
+            if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE)  privateCount++;
+            else //Nur öffentliche Aufgabe kann weiter gegeben werden.
+            {
+                // User austauschen
+                var usermap = entry[calendars.ATTENDEES];
+                var affectedusers = [];
+
+                granted =  hasGrantForEntryByObject(usermap, userMap);
+
+                for (var ui = 0; ui < usermap.length; ui++)
+                {
+                    var login_cn = usermap[ui]["cn"];
+                    var user = tools.getUserByAttribute(tools.CALENDARID, usermap[ui]["paramvalue"].substr("mailto:".length))
+                    if (user == null)  user = login_cn;
+                    else user = user[tools.TITLE]
+
+                    if ( user == id[1] )   affectedusers.push(selection[0]);
+                    else  if ( user != selection[0] )  affectedusers.push(user);
+                }
+                if(granted)
+                {
+                    entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(affectedusers));
+                    calendars.update([entry]);
+                    publicCount++;
+                }
+                else notGrantedCount++
+            }
+        }
+        question.showMessage(translate.withArguments("%0 Aufgabe(n) erfolgreich weitergegeben an: %1"
+            + (privateCount == 0 ? "" : "\n%2 private Aufgabe(n) können nicht weitergegeben werden.")
+            +(notGrantedCount == 0 ? "" : "\n%3 Aufgabe(n) können aufgrund fehlender Berechtigung nicht weitergegeben werden."),
+            [publicCount, selection[1], privateCount, notGrantedCount]));
+
+    }
+}
+
+// ToDo prüfen !!
+/*
+ * Verschiebt die Kalendereinträge bei Login-Änderung
+ *
+ * @param {String} pNewlogin req
+ * @param {String} pOldlogin req
+ * @param {String} pNewCalendarID req
+ * @param {String} pOldCalendarID req
+ *
+ * @return {void}
+ */
+function moveCalendarData ( pNewlogin, pOldlogin, pNewCalendarID, pOldCalendarID )
+{
+    var newcaluser = text.encodeMS(["mailto:" + pNewCalendarID, "CN:" + pNewlogin]);
+    var oldcaluser = text.encodeMS(["mailto:" + pOldCalendarID, "CN:" + pOldlogin]);
+    db.runStatement("update ASYS_CALENDARBACKEND set OWNER = '" + newcaluser + "' where OWNER = '" + oldcaluser + "'");
+    db.runStatement("update ASYS_CALENDARBACKEND set ORGANIZER = '" + newcaluser + "' where ORGANIZER = '" + oldcaluser + "'");
+
+    if(pNewCalendarID != pOldCalendarID) //Nur wenn sich die E-Mailadresse geändert hat
+    {
+        //Messenger-Historien
+        db.runStatement("update ASYS_XMPP_HISTORY set JID_FROM = '" + pNewCalendarID +"' where JID_FROM = '" + pOldCalendarID +"'", "_____SYSTEMALIAS");
+        db.runStatement("update ASYS_XMPP_HISTORY set JID_TO = '" + pNewCalendarID +"' where JID_TO = '" + pOldCalendarID +"'", "_____SYSTEMALIAS");
+    }
+}
+
+/*
+ * Löst den CalenderUser in lesbarer From auf
+ *
+ * @param {String} pValue req
+ *
+ * @return {String} übersetzten Wert
+ */
+function getCalUser( pValue )
+{
+    var realname = pValue;
+    var user = tools.getUser( text.decodeMS(pValue)[1].split(":")[1] );
+    if ( user != null )
+    {
+        realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME];
+    }
+    return realname;
+}
+
+/*
+ * Gibt den Login eines CalenderUser zurück
+ *
+ * @param {String} pCalendarUser req
+ *
+ * @return {String} Title
+ */
+function getTitleCalenderUser( pCalendarUser )
+{
+    var data = text.decodeMS(pCalendarUser)
+    for ( var i = 0; i < data.length; i++ )
+    {
+        //if login changes we have to check calendarid
+        if ( data[i].substr(0, "mailto:".length).toUpperCase() == "MAILTO:" )
+        {
+            var user = tools.getUserByAttribute(tools.CALENDARID, [data[i].substr("mailto:".length)]);
+            if (user != null )
+                return user[tools.TITLE];
+        }
+
+        if ( data[i].substr(0, 3).toUpperCase() == "CN:" )
+            return data[i].substr(3);
+    }
+    return "";
+}
+
+
+/*
+ * Gibt den richtigen Status zum Prüfen je nach Backend zurück
+ *
+ *
+ * @param {String} pStatus req die konstante für den zu prüfenden status,
+ *                             z.B. calendars.STATUS_INPROCESS
+ *
+ * @param {String} pCalendarType req die konstante für den typen des Termin- oder Aufgabenbackends,
+ *                             z.B. calendars.BACKEND_DB
+ *
+ * @return {String} Konstanten für den Kalender (Backend-Typen), gibt es den status im backend nicht
+ *                  wird null geliefert
+ */
+function mapCalendarStatus(pStatus, pCalendarType)
+{
+    switch (pCalendarType)
+    {
+        //case calendars.BACKEND_EXCHANGE:
+        case calendars.BACKEND_EXCHANGEWS:
+            if (pStatus == calendars.STATUS_CONFIRMED)
+                return calendars.STATUS_BUSY;
+            else
+                return pStatus;
+        default:
+            if (pStatus == calendars.STATUS_OOF)//nur bei exchange
+                return null;
+            else
+                return pStatus;
+    }
+}
+
+/*
+ * Sets the imagevariable with affectedusers
+ *
+ * @param {Object} pEntry req the Entry of Tasks or Appointments
+ *
+ * @return {void}
+ *
+ */
+function setAffectedUsersImage(pEntry)
+{
+    var affectedUsers = [];
+    var usermap = pEntry[calendars.ATTENDEES];
+    var realnames = getRealNameObject(usermap);
+
+    for ( var i = 0; i < usermap.length; i++ )
+    {
+        affectedUsers.push([ text.encodeMS( [usermap[i]["paramvalue"], "CN:" + usermap[i]["cn"]] ), realnames[usermap[i]["cn"]] ]);
+    }
+
+    vars.set("$image.affectedusers", affectedUsers);
+    return affectedUsers;
+}
+
+/*
+ * Opens calendar links
+ *
+ * @param {String} pEntryID req the ID of the link
+ *
+ * @return {void}
+ *
+ */
+function openCalendarLinks(pEntryID)
+{
+    var openFramesObj = {};
+    if (typeof(pEntryID) == "object")
+        openFramesObj = pEntryID;
+    else
+    {
+        var links = db.table("SELECT FRAME, DBIDCOLUMN, DBID FROM ASYS_CALENDARLINK WHERE ENTRYID = '" + pEntryID + "'");
+        for (var i = 0; i < links.length; i++)
+        {
+            var frame = links[i][0].substr( 5 );//remove comp. so the frame can be opened with openFrame
+            if ( openFramesObj[frame] == undefined ) openFramesObj[frame] = {
+                IDField: links[i][1],
+                IDs: []
+            };
+            openFramesObj[frame].IDs.push(links[i][2]);
+        }
+    }
+
+    for ( frame in openFramesObj)
+    {
+        var condition = openFramesObj[frame].IDField + " in ('" + openFramesObj[frame].IDs.join("', '") + "')";
+        var framemode = openFramesObj[frame].IDs.length > 1 ? swing.FRAMEMODE_TABLE_SELECTION : swing.FRAMEMODE_SHOW;
+
+        if ( vars.getString("$global.upwardLink") == "link")
+        {
+            swing.openLinkedFrame(frame, condition, swing.WINDOW_CURRENT, framemode, "", null, false, {
+                autoclose: true
+            } );
+        }
+        else
+        {
+            swing.openFrame(frame, condition, swing.WINDOW_CURRENT, framemode, null, false);
+        }
+    }
+}
+
+/**
+ * Returns the "real" calendar system/backend type (BackendType & SyncBackendType)
+ *
+ * @param {Number} pScope - The needed scope (e.g. "calendars.VEVENT", "calendars.VTODO")
+ * @return {Number} - The backend type (calendars.BACKEND_*)
+ */
+function getCalendarSystemType (pScope)
+{
+    // Check sync backend type
+    if (calendars.getSyncBackendType() != calendars.BACKEND_NONE && calendars.getSyncBackendType() != 3)
+    {
+        var scope = calendars.getSyncBackendTypeScope();
+        if (scope.length == 1 && scope[0] == pScope) // Scope.length = 1 -> VEVENT *OR* VTODO
+            return calendars.getSyncBackendType();
+        else if (scope.length == 2) // Scope.length = 2 -> Both
+            return calendars.getSyncBackendType();
+       // Scope.length = 0 -> Nothing selected -> Skip this block
+    }
+
+    // Fallback to backend type (event)
+    if (calendars.getBackendType() != calendars.BACKEND_NONE && pScope === calendars.VEVENT)
+        return calendars.getBackendType();
+
+    // Second fallback to backend type (todo)
+    if (calendars.getBackendTypeTasks() != calendars.BACKEND_NONE && pScope === calendars.VTODO)
+        return calendars.getBackendTypeTasks();
+
+    // Everything is none
+    return calendars.BACKEND_NONE;
+}
+
+function hasGrantForEntryByMS(pAffectedUsers, pUserMap)
+{
+    for (let i = 0; i < pAffectedUsers.length; i++)
+    {
+        var calUser = getTitleCalenderUser( pAffectedUsers[i][0]);
+        if(pUserMap[calUser] == undefined)
+        {
+            return false;
+            break;
+        }
+        else
+            return true;
+    }
+}
+
+function hasGrantForEntryByObject(pAffectedUsers, pUserMap)
+{
+    for (let i = 0; i < pAffectedUsers.length; i++)
+    {
+        calUser = tools.getUserByAttribute(tools.CALENDARID, pAffectedUsers[i]["paramvalue"].substr("mailto:".length))
+        if (calUser == null)  calUser = pAffectedUsers[i]["cn"];
+        else calUser = calUser[tools.TITLE]
+        if(pUserMap[calUser] == undefined)
+        {
+            return false;
+            break;
+        }
+        else
+            return true;
+    }
+}
diff --git a/process/autostartNeon/process.js b/process/autostartNeon/process.js
index 8b11f3faf4425162254f5c87493816f0cddb28ae..0d612f4106852032aaafe8518e8f1e3c9a834c43 100644
--- a/process/autostartNeon/process.js
+++ b/process/autostartNeon/process.js
@@ -1,5 +1,9 @@
-import("system.calendars")
-
-var users = ["Admin", "Birgit Leicht", "John Doe"]
-calendars.addPermissions(users, calendars.VEVENT, ["READ", "WRITE"], null, false, calendars.SORTSTRATEGY_NATURAL);
+import("system.logging");
+import("system.calendars")
+import("system.notification")
+import("system.text");
+import("system.util");
+
+var users = ["Admin", "Birgit Leicht", "John Doe"]
+calendars.addPermissions(users, calendars.VEVENT, ["READ", "WRITE"], null, false, calendars.SORTSTRATEGY_NATURAL);
 calendars.setCheckAttendeesOnWrite(false);
\ No newline at end of file