diff --git a/entity/360Degree_entity/recordcontainers/jdito/contentProcess.js b/entity/360Degree_entity/recordcontainers/jdito/contentProcess.js
index 771f35a4cbb15d2d093a5608ffb933c51fdc7261..f74342ef8fe31213bd81788524244cb58c2a2271 100644
--- a/entity/360Degree_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/360Degree_entity/recordcontainers/jdito/contentProcess.js
@@ -12,7 +12,7 @@ if (vars.exists("$param.ObjectType_param") && vars.get("$param.ObjectType_param"
 {
     
     var active;
-    var selectMap = ContextUtils._getSelectMap()
+    var selectMap = ContextUtils.getSelectMap ()
     if(vars.exists("$local.filter") && vars.get("$local.filter") )
     {
         var filter = JSON.parse(vars.getString("$local.filter"));
@@ -42,7 +42,7 @@ if (vars.exists("$param.ObjectType_param") && vars.get("$param.ObjectType_param"
                 record[5] = translate.text(active);
             else
             {
-               if(selectMap[context][8].indexOf(row[3]) > -1)    
+               if(selectMap[context].activeStates.indexOf(row[3]) > -1)    
                   record[5] = translate.text("true");
                else
                   record[5] = translate.text("false");
diff --git a/process/Context_lib/process.js b/process/Context_lib/process.js
index 70bfde6d1d7400705ed17cb54f44a85fdbe799fd..82a5ac3b5be8785d93f10d708fb497c212a430fe 100644
--- a/process/Context_lib/process.js
+++ b/process/Context_lib/process.js
@@ -4,6 +4,7 @@ import("system.vars");
 import("system.SQLTYPES");
 import("Keyword_lib");
 import("Sql_lib");
+import("Proto_lib");
 import("Contact_lib");
 import("system.logging");
 
@@ -41,7 +42,7 @@ ContextUtils.getContextName = function(pContextId)
 
 /**
  *
- * @param {Boolean} [pFilter=false] filter only for contexts which have a mapping in ContextUtils._getSelectMap
+ * @param {Boolean} [pFilter=false] filter only for contexts which have a mapping in ContextUtils.getSelectMap 
  * @param {String[]} [pExcludeContexts] contextIds that shall not be included (so this is a additional filter to the pFiler param)
  *
  * @return {String[][]} the contexts [[contextId, contextName, contextTitle], [... ], ...]
@@ -59,7 +60,7 @@ ContextUtils.getContexts = function(pFilter, pExcludeContexts)
             if (pExcludeContexts && pExcludeContexts.indexOf(pContext[0]) > -1)
                 return false;
             // filter only contexts which have defined mappings in Context_lib
-            return ContextUtils._getSelectMap()[pContext[0]] != undefined;
+            return ContextUtils.getSelectMap ()[pContext[0]] != undefined;
         });
     }
     else if (pExcludeContexts)
@@ -111,161 +112,146 @@ ContextUtils._contextDataMapping = function(pContext)
     return [pContext[0], contextName, (pContext[1] ? pContext[1] : contextName)];
 }
 
+function ContextSelector(pSqlNameSelect, pTableName, pIdField)
+{
+    //the >>this.property = null;<< is for autocomplete in the designer
+    this.sqlNameSelect = null; ProtoPropertyUtils.makeSemiReadOnly(this, "sqlNameSelect");
+    this.setSqlNameSelect(pSqlNameSelect);
+
+    this.tableName = null; ProtoPropertyUtils.makeSemiReadOnly(this, "tableName");
+    this.setTableName(pTableName);
+    
+    this.idField = null; ProtoPropertyUtils.makeSemiReadOnly(this, "idField");
+    this.setIdField(pIdField);
+    
+    this.sqlJoin = null; ProtoPropertyUtils.makeSemiReadOnly(this, "sqlJoin");
+    this.contactIdField = null; ProtoPropertyUtils.makeSemiReadOnly(this, "contactIdField");
+    this.creationDateField = null; ProtoPropertyUtils.makeSemiReadOnly(this, "creationDateField");
+    this.stateField = null; ProtoPropertyUtils.makeSemiReadOnly(this, "stateField");
+    this.activeStates = null; ProtoPropertyUtils.makeSemiReadOnly(this, "activeStates");
+}
+ContextSelector.create = function(pSqlNameSelect, pTableName, pIdField) 
+{
+    return new ContextSelector(pSqlNameSelect, pTableName, pIdField);
+};
+ContextSelector.prototype.getFullIdField = function()
+{
+    return this.tableName + "." + this.idField;
+};
+
+ContextSelector.prototype.getFullFromClause = function()
+{
+    if (this.sqlJoin)
+        return " " + this.tableName + " " + this.sqlJoin + " ";
+    else
+        return this.tableName;
+        
+};
+ContextSelector.prototype.setSqlNameSelect = function(pValue)
+{
+    this._sqlNameSelect = pValue;
+    return this;
+};
+ContextSelector.prototype.setTableName = function(pValue)
+{
+    this._tableName = pValue;
+    return this;
+};
+ContextSelector.prototype.setIdField = function(pValue)
+{
+    this._idField = pValue;
+    return this;
+};
+ContextSelector.prototype.setSqlJoin = function(pValue)
+{
+    this._sqlJoin = pValue;
+    return this;
+};
+ContextSelector.prototype.setContactIdField = function(pValue)
+{
+    this._contactIdField = pValue;
+    return this;
+};
+ContextSelector.prototype.setCreationDateField = function(pValue)
+{
+    this._creationDateField = pValue;
+    return this;
+};
+ContextSelector.prototype.setStateField = function(pValue)
+{
+    this._stateField = pValue;
+    return this;
+};
+ContextSelector.prototype.setActiveStates = function(pValue)
+{
+    this._activeStates = pValue;
+    return this;
+};
 /**
  * TODO: !!!temporary function until you can get fields from another Entity!!!
  */
-ContextUtils._getSelectMap = function()
+ContextUtils.getSelectMap  = function()
 {
     var maskingUtils = new SqlMaskingUtils();
     return {
-        // contextId,
-        // nameField, 0
-        // Tablename 1
-        // joins (if needed), 2
-        // IDField, 3
-        // RelationField, 4
-        // CreationDate 5
-        // override Tablename (needed if Tablename is a join clause) 6
-        // StateField 7
-        // Active States 8
-        
-        // "Appointment": ["SUMMARY", "ASYS_CALENDARBACKEND", "UID"]
-        "Organisation": [
-            "\"NAME\"",
-            "ORGANISATION",
-            "",
-            "ORGANISATIONID",
-            "",
-            "",
-            "",
-            "",
-            []
-        ],
-        "Person": [
-            (new ContactTitleRenderer(Contact.createWithColumnPreset()).asSql()),
-            "PERSON",
-            " join CONTACT on PERSON.PERSONID = CONTACT.PERSON_ID join ORGANISATION on ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID ",
-            "CONTACTID",
-            "CONTACT",
-            "",
-            "CONTACT",
-            "",
-            []
-        ],
-        "Activity": [
-            "SUBJECT",
-            "ACTIVITY",
-            "",
-            "ACTIVITYID",
-            "",
-            "",
-            "",
-            "",
-            []
-        ],
-        "Salesproject": [
-            maskingUtils.concat([
-                "'" + translate.text("Salesproject") + "'",
-                "' '",
-                maskingUtils.cast("PROJECTCODE", SQLTYPES.VARCHAR, 10),
-                "' | '",
-                "PROJECTTITLE"
-            ], "", false),
-            "SALESPROJECT",
-            "",
-            "SALESPROJECTID",
-            "CONTACT_ID",
-            "STARTDATE",
-            "",
-            "STATE",
-            ["25b0ac77-ef92-4809-802e-bb9d8782f865", "23d38486-4cce-41ce-a8df-164ad44df706"]
-        ],
-        "Contract": [
-            maskingUtils.concat([
-                KeywordUtils.getResolvedTitleSqlPart("ContractType", "CONTRACTTYPE"),
-                maskingUtils.cast("CONTRACTCODE", SQLTYPES.VARCHAR, 10)
-            ], " "),
-            "CONTRACT",
-            "",
-            "CONTRACTID",
-            "CONTACT_ID",
-            "CONTRACTSTART",
-            "",
-            "CONTRACTSTATUS",
-           ["e12d37e9-3429-40b5-973b-c1569843ca46", "3579eb0c-d8ca-4b6b-85ee-f1800a9301eb", "4c63c82d-0276-4c12-9937-13fd361ad786"]
-        ],
-        "Offer": [
-            maskingUtils.concat([
-                "'" + translate.text("Offer") + "'",
-                "' '",
-                maskingUtils.cast("OFFERCODE", SQLTYPES.VARCHAR, 10),
-                "'-'",
-                maskingUtils.cast("VERSNR", SQLTYPES.VARCHAR, 10)
-            ], "", false),
-            "OFFER",
-            "",
-            "OFFERID",
-            "CONTACT_ID",
-            "OFFERDATE",
-            "",
-            "STATUS",
-            ["5134153d-2e18-452f-ab35-7a52f1aee7d1", "e5d6b5a4-7576-440f-8332-bc40147c0335"]
-        ],
-        "Order": [
-            maskingUtils.concat([
-                "'" + translate.text("Order") + "'",
-                "' '",
-                maskingUtils.cast("SALESORDERCODE", SQLTYPES.VARCHAR, 10),
-                "'-'",
-                maskingUtils.cast("VERSNR", SQLTYPES.VARCHAR, 10)
-            ], "", false),
-            "SALESORDER",
-            "",
-            "SALESORDERID",
-            "CONTACT_ID",
-            "ORDERDATE",
-            "",
-            "",
-            []
-        ],
-        "Product": [
-            maskingUtils.concat([
-                "PRODUCTCODE",
-                "' | '",
-                "PRODUCTNAME"
-            ], "", false),
-            "PRODUCT",
-            "",
-            "PRODUCTID",
-            "",
-            "",
-            "",
-            "",
-            []
-        ],
-        "Task": [
-            "SUBJECT",
-            "TASK",
-            "",
-            "TASKID",
-            translate.text("Task"),
-            "",
-            "",
-            "",
-            []
-        ]
+             "Organisation": ContextSelector.create("NAME", "ORGANISATION", "ORGANISATIONID")
+            ,"Person": ContextSelector.create(null, "PERSON", "CONTACTID")
+                                      .setSqlNameSelect(new ContactTitleRenderer(Contact.createWithColumnPreset()).asSql())
+                                      .setSqlJoin("join CONTACT on PERSON.PERSONID = CONTACT.PERSON_ID join ORGANISATION on ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID")
+            ,"Activity": ContextSelector.create("SUBJECT", "ACTIVITY", "ACTIVITYID")
+            ,"Salesproject": ContextSelector.create(null, "SALESPROJECT", "SALESPROJECTID")
+                                            .setSqlNameSelect(maskingUtils.concat([
+                                                                "'" + translate.text("Salesproject") + "'",
+                                                                "' '",
+                                                                maskingUtils.cast("PROJECTCODE", SQLTYPES.VARCHAR, 10),
+                                                                "' | '",
+                                                                "PROJECTTITLE"
+                                                                ], "", false))
+                                            .setContactIdField("CONTACT_ID")
+                                            .setCreationDateField("STARTDATE")
+                                            .setStateField("STATE")
+                                            .setActiveStates(["25b0ac77-ef92-4809-802e-bb9d8782f865", "23d38486-4cce-41ce-a8df-164ad44df706"])
+            ,"Contract": ContextSelector.create(null, "CONTRACT", "CONTRACTID")
+                                        .setSqlNameSelect(maskingUtils.concat([
+                                                                KeywordUtils.getResolvedTitleSqlPart("ContractType", "CONTRACTTYPE"),
+                                                                maskingUtils.cast("CONTRACTCODE", SQLTYPES.VARCHAR, 10)
+                                                                ], " "))
+                                        .setContactIdField("CONTACT_ID")
+                                        .setCreationDateField("CONTRACTSTART")
+                                        .setStateField("CONTRACTSTATUS")
+                                        .setActiveStates(["e12d37e9-3429-40b5-973b-c1569843ca46", "3579eb0c-d8ca-4b6b-85ee-f1800a9301eb", "4c63c82d-0276-4c12-9937-13fd361ad786"])
+            ,"Offer": ContextSelector.create(null, "OFFER", "OFFERID")
+                                     .setSqlNameSelect(maskingUtils.concat([
+                                                "'" + translate.text("Offer") + "'",
+                                                "' '",
+                                                maskingUtils.cast("OFFERCODE", SQLTYPES.VARCHAR, 10),
+                                                "'-'",
+                                                maskingUtils.cast("VERSNR", SQLTYPES.VARCHAR, 10)
+                                                ], "", false))
+                                     .setContactIdField("CONTACT_ID")
+                                     .setStateField("STATUS")
+                                     .setActiveStates(["5134153d-2e18-452f-ab35-7a52f1aee7d1", "e5d6b5a4-7576-440f-8332-bc40147c0335"])
+            ,"Order": ContextSelector.create(null, "SALESORDER", "")
+                                     .setSqlNameSelect(maskingUtils.concat([
+                                                        "'" + translate.text("Order") + "'",
+                                                        "' '",
+                                                        maskingUtils.cast("SALESORDERCODE", SQLTYPES.VARCHAR, 10),
+                                                        "'-'",
+                                                        maskingUtils.cast("VERSNR", SQLTYPES.VARCHAR, 10)
+                                                        ], "", false))
+                                     .setContactIdField("CONTACT_ID")
+                                     .setCreationDateField("ORDERDATE")
+            ,"Product": ContextSelector.create(null, "PRODUCT", "PRODUCTID")
+                                       .setSqlNameSelect(maskingUtils.concat([
+                                            "PRODUCTCODE",
+                                            "' | '",
+                                            "PRODUCTNAME"
+                                            ], "", false))
+            ,"Task": ContextSelector.create("SUBJECT", "TASK", "TASKID")
+                                    .setContactIdField(translate.text("Task"))//wait, what?
     }
 }
 
-ContextUtils.getFieldTitle = function(pContextId, pDefault)
-{
-    if (ContextUtils._getSelectMap()[pContextId] != undefined && ContextUtils._getSelectMap()[pContextId].length >= 4)
-        return ContextUtils._getSelectMap()[pContextId][4];
-
-    return pDefault;
-}
-
-
 /**
  * TODO: !!!temporary function until you can get fields from another Entity!!!
  */
@@ -273,10 +259,10 @@ ContextUtils.getNameSubselectSql = function(pContextIdDbField, pRowIdDbField)
 {
     var select = "(case " + pContextIdDbField + " ";
 
-    var selectMap = ContextUtils._getSelectMap()
+    var selectMap = ContextUtils.getSelectMap ()
     for (let contextId in selectMap)
     {
-        select += "when '" + contextId + "' then (select " + selectMap[contextId][0] + " from " + selectMap[contextId][1] + " " + selectMap[contextId][2] + (pRowIdDbField ? " where " + selectMap[contextId][3] + " = " + pRowIdDbField : " ") + ") ";
+        select += "when '" + contextId + "' then (select " + selectMap[contextId].sqlNameSelect + " from " + selectMap[contextId].getFullFromClause() + (pRowIdDbField ? " where " + selectMap[contextId].idField + " = " + pRowIdDbField : " ") + ") ";
     }
 
     select += "else 'Not defined in ContextUtils.getNameSql()!'";
@@ -290,10 +276,10 @@ ContextUtils.getNameSubselectSql = function(pContextIdDbField, pRowIdDbField)
  */
 ContextUtils.getNameSql = function(pContextId, pRowId)
 {
-    var selectMap = ContextUtils._getSelectMap()
+    var selectMap = ContextUtils.getSelectMap ()
     if (selectMap[pContextId] != undefined)
     {
-        return SqlCondition.begin().andPrepare((selectMap[pContextId][6] ? selectMap[pContextId][6] : selectMap[pContextId][1]) + "." + selectMap[pContextId][3], pRowId).buildSql("select " + selectMap[pContextId][0] + " from " + selectMap[pContextId][1] + " " + selectMap[pContextId][2], "1=2");
+        return SqlCondition.begin().andPrepare(selectMap[pContextId].getFullIdField(), pRowId).buildSql("select " + selectMap[pContextId].sqlNameSelect + " from " + selectMap[pContextId].getFullFromClause(), "1 = 2");
     }
     else
         return "select 1 from person where 1=2";
@@ -304,36 +290,36 @@ ContextUtils.getNameSql = function(pContextId, pRowId)
  */
 ContextUtils.getContextDataSql = function(pContextId, pRowId, pWithDate, pActive, pWithState)
 {
-    var selectMap = ContextUtils._getSelectMap()
+    var selectMap = ContextUtils.getSelectMap ();
     var cond = SqlCondition.begin();
     if (pRowId)
     {
-        cond.andPrepare(selectMap[pContextId][1] + "." + selectMap[pContextId][4], pRowId)
+        cond.andPrepare(selectMap[pContextId].tableName + "." + selectMap[pContextId].contactIdField, pRowId)
     }
     
     if (pActive != undefined)
     {
-        var activeStates = selectMap[pContextId][8]
+        var activeStates = selectMap[pContextId].activeStates;
         if(activeStates != null && activeStates.length > 0)
         {
             var condSub = SqlCondition.begin();
             activeStates.forEach(function (state) 
             {   
                 if(pActive)
-                    condSub.orPrepare(selectMap[pContextId][1] + "." + selectMap[pContextId][7], state)
+                    condSub.orPrepare(selectMap[pContextId].tableName + "." + selectMap[pContextId].stateField, state)
                 else
-                    condSub.andPrepare(selectMap[pContextId][1] + "." + selectMap[pContextId][7], state, "# != ?")
+                    condSub.andPrepare(selectMap[pContextId].tableName + "." + selectMap[pContextId].stateField, state, "# != ?")
             });
             cond.andSqlCondition(condSub);   
         }
     }
     var dateColumn = "";
     if (pWithDate === true)
-        dateColumn = ", " + selectMap[pContextId][5];
+        dateColumn = ", " + (selectMap[pContextId].creationDateField || "''");
     
     var stateColumn = "";
     if (pWithState === true)
-        stateColumn = ", " + selectMap[pContextId][7];
+        stateColumn = ", " + (selectMap[pContextId].stateField || "''");
 
-    return cond.buildSql("select " + selectMap[pContextId][3] + ", " + selectMap[pContextId][0] + dateColumn + stateColumn +  " from " + selectMap[pContextId][1] + " " + selectMap[pContextId][2], "1=1");
+    return cond.buildSql("select " + selectMap[pContextId].getFullIdField() + ", " + selectMap[pContextId].sqlNameSelect + dateColumn + stateColumn +  " from " + selectMap[pContextId].getFullFromClause(), "1=1");
 }
diff --git a/process/Proto_lib/Proto_lib.aod b/process/Proto_lib/Proto_lib.aod
new file mode 100644
index 0000000000000000000000000000000000000000..99585a3435e1e59f774bb6872bae063923df18bf
--- /dev/null
+++ b/process/Proto_lib/Proto_lib.aod
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.0">
+  <name>Proto_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/Proto_lib/process.js</process>
+</process>
diff --git a/process/Proto_lib/process.js b/process/Proto_lib/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..04d65e8fcb43af5d8e3caf539bb1fa4259934966
--- /dev/null
+++ b/process/Proto_lib/process.js
@@ -0,0 +1,11 @@
+function ProtoPropertyUtils(){}
+
+ProtoPropertyUtils.makeSemiReadOnly = function(pObj, pPropName)
+{
+    Object.defineProperty(pObj, pPropName, {
+        enumerable: true,
+        get: function (){
+            return pObj["_" + pPropName];
+        }
+    });
+};
\ No newline at end of file