diff --git a/config/inc_projects_config.php b/config/inc_projects_config.php
index 53c00fcc609fdb56ff667403baa17812da3beaa0..9debed14af8a92e74d96f0e7e7c2e52380e6648b 100644
--- a/config/inc_projects_config.php
+++ b/config/inc_projects_config.php
@@ -11,7 +11,7 @@ $aConfig = array(
     'builtsToKeep' => 3, // for cleanup: keep n failed builds
     'hooks' => array(
         'build-postclone' => 'hooks/onbuild-postclone',
-        'build-precompress' => 'hooks/onbuild',
+        'build-precompress' => 'hooks/onbuild', // TODO: remove this
     ),
     'lang' => 'de', // for available languages see ./config/lang/*.json
     // rsync of archives
@@ -86,9 +86,19 @@ switch (php_uname("n")) {
         break;
 }
 
+// ----------------------------------------------------------------------
+// TODO: include custom settings that were saved in the GUI
+// ----------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------
+// generate some vars
+// ----------------------------------------------------------------------
+
 $aConfig = array_merge($aConfig, array(
     'appRootDir' => dirname(dirname(__FILE__)),
     'configDir' => dirname(__FILE__),
+    'dataDir' => $aConfig['workDir'] . '/data',    // to write data: ssh keys, projects, database
     'buildDir' => $aConfig['workDir'] . '/build',
     'buildDefaultsDir' => $aConfig['workDir'] . '/defaults',
     'packageDir' => $aConfig['workDir'] . '/packages',
diff --git a/config/lang/de.json b/config/lang/de.json
index fc2547ecdbbd2e5d0ab85e21904e6a2217545c0f..a31ebe36c9efd64aa32525b6579eb07bea9a6c93 100644
--- a/config/lang/de.json
+++ b/config/lang/de.json
@@ -70,7 +70,7 @@
     "class-project-error-build-dir-was-not-created": "Das Verzeichnis %s wurde nicht angelegt.",
     "class-project-error-build-type-not-supported": "Repository Typ %s wird nicht unterstützt.",
     "class-project-error-build-docroot-not-found": "Es gibt kein Unterverzeichnis "public_html" oder "public" im Arbeitsverzeichnis.",
-    "class-project-error-command-failed": "Eines der Kommandos ist fehlgeschlagen (s.o.).<br>Frage ggf. den Administrator. Das Arbeitsverzeichnis wird f&uumlr eine Analyse nicht gel&ouml;scht.",
+    "class-project-error-command-failed": "Eines der Kommandos ist fehlgeschlagen (s. Fehlermeldung in der Ausgabe).<br>Frage ggf. den Administrator. Das Arbeitsverzeichnis wird f&uumlr eine Analyse nicht gel&ouml;scht.",
     "class-project-error-getPhaseInfos-package-not-found": "Die Paket-Datei (.tgz) wurde nicht gefunden: %s",
     "class-project-error-getPhaseInfos-requires-phase": "Die Methode getPhaseInfos erfordert die Angabe eine Phase.",
     "class-project-error-datafile-does-not-exist": "Die Paket-Datei &quot;%s&quot; existiert nicht.",
@@ -139,6 +139,8 @@
     "class-project-warning-cannot-delete-build-dir": "WARNUNG: Das Build-Verzeichnis %s konnte nicht gel&ouml;scht werden.",
     "class-project-warning-phase-not-active": "Die Phase %s ist nicht aktiv.",
 
+    "class-user-error-deny-no-role": "FEHLER: Sie haben nicht gen&uuml;gend Berechtigungen.",
+    
     "page-accept-error-cannot-accept-phase": "Die Phase [%s] kann nicht akzeptiert werden.",
     "page-accept-info": "Die Software wurde erfolgreich in der Phase <span class=\"%s\">%s</span> getestet und soll auf die n&auml;chstePhase <span class=\"%s\">%s</span> ausgerollt werden?",
     "page-accept-warning-version-exists-in-next-queue": "In der Queue von Phase [%s] ist die Version von [%s] bereits vorhanden!",
@@ -195,14 +197,18 @@
     "accept-hint": "Accept Phase [%s] und in die Queue von Phase [%s] stellen.",
     "all": "alle",
     "archive": "Archiv",
+    "branch": "Branch",
+    "branch-select": "Vorhandene Branches",
     "build": "Build",
     "build-hint": "neues Paket erstellen und in Phase [%s] stellen.",
     "build-from": "Build vom",
     "build-type": "Build Typ",
     "commitmessage": "Commit-Message",
+    "change": "Wechseln",
     "contact": "Kontakt",
     "creating-directory": "Lege das Verzeichnis %s an.",
     "creating-file": "Lege Datei %s an.",
+    "defaultbranch": "[default: Master oder Trunk]",
     "deploy": "Deploy",
     "deploy-hint": "Deploy der Queue von Phase [%s]",
     "deploytimes": "Deployment Zeitpunkte",
@@ -228,7 +234,7 @@
     "new-project-hint": "ein neues Projekt anlegen",
     "no": "nein",
     "none": "kein(e)",
-   "packages": "Pakete",
+    "packages": "Pakete",
     "phase": "Phase",
     "phase-details": "Details",
     "phase-details-hint": "Details zur Phase [%s]",
diff --git a/config/lang/en.json b/config/lang/en.json
index f20a90f75ec7bbc296524b568208e445ebd8fefc..2178d4d254dcd6f90071305cf12c3cca0250ccb5 100644
--- a/config/lang/en.json
+++ b/config/lang/en.json
@@ -69,7 +69,7 @@
     "class-project-error-build-dir-was-not-created": "The directory %s was not created.",
     "class-project-error-build-type-not-supported": "Repository type %s is not supported.",
     "class-project-error-build-docroot-not-found": "There is no subdirectory &quot;public_html&quot; or &quot;public&quot; in the working directory.",
-    "class-project-error-command-failed": "The execution of a command failed (see above).<br>Ask your admin. The working directory was NOT deleted that you can analyze the problem.",
+    "class-project-error-command-failed": "The execution of a command failed (see error message in the output below).<br>Ask your admin. The working directory was NOT deleted that you can analyze the problem.",
     "class-project-error-getPhaseInfos-package-not-found": "The package file (.tgz) was not found: %s",
     "class-project-error-getPhaseInfos-requires-phase": "The method getPhaseInfos requires the name of a pfase.",
     "class-project-error-datafile-does-not-exist": "The package file &quot;%s&quot; does not exist.",
@@ -140,6 +140,8 @@
     "class-project-warning-cannot-delete-build-dir": "WARNING: The Build directory %s could not be deleted.",
     "class-project-warning-phase-not-active": "The phase %s is not aktive.",
 
+    "class-user-error-deny-no-role": "ERRROR: Your User has not enough permissions.",
+
     "page-accept-error-cannot-accept-phase": "The phase [%s] cannot be accepted.",
     "page-accept-info": "The software was tested successfully in phase <span class=\"%s\">%s</span> and shall be rolled out in the next phase <span class=\"%s\">%s</span>?",
     "page-accept-warning-version-exists-in-next-queue": "In the queue of phase [%s] the version [%s] already exists!",
@@ -197,14 +199,18 @@
     "accept-hint": "Accept phase [%s] and put package to the queue of phase [%s].",
     "all": "all",
     "archive": "Archive",
+    "branch": "Branch",
+    "branch-select": "Existing branches",
     "build": "Build",
     "build-hint": "Create new package and rollout to first active phase [%s].",
     "build-from": "Build date",
     "build-type": "Build type",
+    "change": "Change",
     "commitmessage": "Commit message",
     "contact": "contact",
     "creating-directory": "Creating directory %s",
     "creating-file": "Creating file %s",
+    "defaultbranch": "[default: master or trunk]",
     "deploy": "Deploy",
     "deploy-hint": "Deploy queue of phase [%s]",
     "deploytimes": "Deploy time window",
diff --git a/config/projects/.htkeep b/config/projects/.htkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/config/sshkeys/.htkeep b/config/sshkeys/.htkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/database/.htkeep b/database/.htkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/hooks/onbuild b/hooks/onbuild
index 9475aa37f562274bfbc43997ba6c504963476ec9..868e19370d85bb75ea7bf9eff73e1afe710e3c30 100644
--- a/hooks/onbuild
+++ b/hooks/onbuild
@@ -1,16 +1,15 @@
 #!/bin/bash
 # ======================================================================
 #
-# ONBUILD fuer CI Deployment GUI
+# ONDEPLOY fuer CI Deployment GUI
 #
 # Aufgaben:
-# - gibt dem Wrapper fuer SSH Connections zu Git X-Rechte
-# - minimiert Rechte auf SSH Keyfiles
+# - Projekt-Configs anpassen
 #
-# 2013-11-12  axel.hahn@iml.unibe.ch
+# 2014-05-07  axel.hahn@iml.unibe.ch
 # ======================================================================
 
-echo ONBUILD fuer CI Deployment GUI
+echo ONDEPLOY fuer CI Deployment GUI
 echo
 cd `dirname $0`
 cd ..
diff --git a/public_html/deployment/classes/actionlog.class.php b/public_html/deployment/classes/actionlog.class.php
index 9c325bca8d77f88719268db7f7a68e0323abd86a..d592286539b17c06ca9b64860e449a2751507c36 100644
--- a/public_html/deployment/classes/actionlog.class.php
+++ b/public_html/deployment/classes/actionlog.class.php
@@ -34,7 +34,7 @@ class Actionlog {
         if (!is_array($aConfig) || !array_key_exists("appRootDir", $aConfig)) {
             die(__CLASS__ . "::".__FUNCTION__." ERROR: configuration with \$aConfig was not loaded.");
         }
-        $this->_dbfile = $aConfig['appRootDir'] . '/database/logs.db';
+        $this->_dbfile = $aConfig['dataDir'] . '/database/logs.db';
         if (!file_exists($this->_dbfile)) {
             $this->_createDb();
             if (!file_exists($this->_dbfile)) {
diff --git a/public_html/deployment/classes/base.class.php b/public_html/deployment/classes/base.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ef4c3559a3e833105a9312dbe5aecf0c54ded5a
--- /dev/null
+++ b/public_html/deployment/classes/base.class.php
@@ -0,0 +1,26 @@
+<?php
+
+require_once 'user.class.php';
+
+/**
+ * base class for available variables and objects in other objects
+ *
+ * @author hahn
+ */
+class base {
+
+    var $oUser=false;
+    
+    /**
+     * init user with optional given user
+     * @param type $sUser
+     */
+    public function __construct(){
+        $this->oUser=new user();
+        
+        if (method_exists($this, "_construct2")){
+            $this->_construct2();
+        }
+    }
+    
+}
diff --git a/public_html/deployment/classes/formgen.class.php b/public_html/deployment/classes/formgen.class.php
index 271d3a64319705e7457bb920c8733bb68ea6a260..8d33c8ec68ae3e7e0c7ebaaa012e329622f85a09 100644
--- a/public_html/deployment/classes/formgen.class.php
+++ b/public_html/deployment/classes/formgen.class.php
@@ -52,7 +52,7 @@ class formgen {
         }
         $sReturn.='<form ';
         if (array_key_exists("meta", $this->aForm[$sFormId])) {
-            foreach (array("method", "action", "target", "accept-charset", "class") as $sAttr) {
+            foreach (array("method", "action", "target", "accept-charset", "class", "id", "name") as $sAttr) {
                 if (array_key_exists($sAttr, $this->aForm[$sFormId]["meta"])) {
                     $sReturn.=$sAttr . '="' . $this->aForm[$sFormId]["meta"][$sAttr] . '" ';
                 }
diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php
index 0dd0ac95654964c9a2c9bfd8bfcde3ffe7b0944b..c6091e30c124dc5e47ead78800bfa5919f283f28 100644
--- a/public_html/deployment/classes/project.class.php
+++ b/public_html/deployment/classes/project.class.php
@@ -71,7 +71,8 @@ class project {
      * @var type 
      */
     private $_oVcs = false;
-    
+    private $_sBranchname = false;
+
     // ----------------------------------------------------------------------
     // constructor
     // ----------------------------------------------------------------------
@@ -133,8 +134,24 @@ class project {
                 die(sprintf(t("class-project-error-missing-prjkey"), $sKey, print_r($this->_aPrjConfig, true)));
             }
         }
-
+        
         // TODO: verify ausbauen
+        /*
+        if (!$this->_aConfig["dataDir"]) {
+            die(t("class-project-error-datadir-empty"));
+        }
+        if (!file_exists($this->_aConfig["dataDir"])) {
+            die(sprintf(t("class-project-error-data-does-not-exist"), $this->_aConfig['dataDir']));
+        }
+
+        foreach (array("database", "projects", "sshkeys") as $sKey) {
+            $sTestDir=$this->_aConfig["dataDir"]."/$sKey";
+            if (!file_exists($sTestDir)) {
+                mkdir($sTestDir);
+                // die(sprintf(t("class-project-error-missing-prjkey"), $sKey, print_r($this->_aPrjConfig, true)));
+            }
+        }
+        */
         return true;
     }
 
@@ -151,52 +168,52 @@ class project {
             ob_implicit_flush(true);
         }
         // ob_end_flush();
-        
+
         $sReturn.="[" . date("H:i:s d.m.Y") . "] ";
         $sReturn.=$bUseHtml ? "<strong>$sCommand</strong>" : "$sCommand";
         $sReturn.=$bUseHtml ? "<br>" : "\n";
 
-        $sOutput=false;
+        $sOutput = false;
         exec($sCommand, $aOutput, $iRc);
-        $sReturn.=(count($aOutput))?implode("\n", $aOutput)."\n":"";
+        $sReturn.=(count($aOutput)) ? implode("\n", $aOutput) . "\n" : "";
         /*
-        $descriptorspec = array(
-            0 => array("pipe", "r"), // stdin is a pipe that the child will read from
-            1 => array("pipe", "w"), // stdout is a pipe that the child will write to
-            2 => array("pipe", "w")    // stderr is a pipe that the child will write to
-        );
-        if ($bFlush) {
-            flush();
-        }
-        $process = proc_open($sCommand, $descriptorspec, $pipes, realpath('./'), array());
-
-
-        $sErrors = false;
-        if (is_resource($process)) {
-            while ($s = fgets($pipes[1])) {
-                $sReturn.=$s;
-                if ($bFlush) {
-                    flush();
-                }
-            }
-            while ($s = fgets($pipes[2])) {
-                $sErrors.=$s;
-                if ($bFlush) {
-                    flush();
-                }
-            }
-        }
-        if ($sErrors) {
-            $sReturn.="STDERR:\n" . $sErrors;
-        }
-        $oStatus = proc_get_status($process);
-        $iRc = $oStatus['exitcode'];
+          $descriptorspec = array(
+          0 => array("pipe", "r"), // stdin is a pipe that the child will read from
+          1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+          2 => array("pipe", "w")    // stderr is a pipe that the child will write to
+          );
+          if ($bFlush) {
+          flush();
+          }
+          $process = proc_open($sCommand, $descriptorspec, $pipes, realpath('./'), array());
+
+
+          $sErrors = false;
+          if (is_resource($process)) {
+          while ($s = fgets($pipes[1])) {
+          $sReturn.=$s;
+          if ($bFlush) {
+          flush();
+          }
+          }
+          while ($s = fgets($pipes[2])) {
+          $sErrors.=$s;
+          if ($bFlush) {
+          flush();
+          }
+          }
+          }
+          if ($sErrors) {
+          $sReturn.="STDERR:\n" . $sErrors;
+          }
+          $oStatus = proc_get_status($process);
+          $iRc = $oStatus['exitcode'];
          */
-        
+
         if ($iRc != 0) {
-            $this->_logaction("command failed: $sCommand - rc=".$iRc, __FUNCTION__, "error");
+            $this->_logaction("command failed: $sCommand - rc=" . $iRc, __FUNCTION__, "error");
         }
-                
+
         $this->_iRcAll += $iRc;
         $sReturn.="[" . date("H:i:s d.m.Y") . "] " . t("exitcode") . " " . $iRc;
         if ($bUseHtml) {
@@ -234,7 +251,7 @@ class project {
         if (!$sId) {
             die(t("class-project-error-_getConfigFile-requires-id"));
         }
-        return $this->_aConfig["configDir"] . '/projects/' . $sId . ".json";
+        return $this->_aConfig["dataDir"] . '/projects/' . $sId . ".json";
     }
 
     /**
@@ -495,7 +512,7 @@ class project {
 
         // keep a few
         $iKeep = $bDeleteAll ? 0 : $this->_aConfig["versionsToKeep"];
-        while (count($aUnused) > $iKeep) {
+        while (count($aUnused) >= $iKeep) {
             $sVersion = array_shift($aUnused);
             $sDir2 = $sDir . '/' . $sVersion;
             if ($this->_rmdir($sDir2)) {
@@ -679,7 +696,7 @@ class project {
      */
     public function getProjects() {
         $aReturn = array();
-        foreach (glob($this->_aConfig["configDir"] . '/projects/' . "/*.json") as $filename) {
+        foreach (glob(dirname($this->_getConfigFile("dummy")). "/*.json") as $filename) {
             $aReturn[] = str_replace(".json", "", basename($filename));
         }
         sort($aReturn);
@@ -757,10 +774,10 @@ class project {
         if (!$sPhase) {
             // for better performance: skip check on overview page
             /*
-            $aRepodata = $this->getRepoRevision();
-            if (!array_key_exists("revision", $aRepodata)) {
-                return false;
-            }
+              $aRepodata = $this->getRepoRevision();
+              if (!array_key_exists("revision", $aRepodata)) {
+              return false;
+              }
              */
             $sNext = $this->getNextPhase($sPhase);
             return $sNext > '';
@@ -775,22 +792,100 @@ class project {
             return false;
         }
         $sNext = $this->getNextPhase($sPhase);
-        if (!$sNext){
+        if (!$sNext) {
             return false;
         }
-        
+
         // ensure that _aData is filled
         $this->getPhaseInfos($sPhase);
 
         // array key "ok" must be in the ready2install and deployed info
         if (
                 array_key_exists($sPhase, $this->_aData["phases"]) && array_key_exists("onhold", $this->_aData["phases"][$sPhase]) && array_key_exists("ready2install", $this->_aData["phases"][$sPhase]) && array_key_exists("deployed", $this->_aData["phases"][$sPhase]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["onhold"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["ready2install"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["deployed"])
-        ){
+        ) {
             return true;
         }
         return false;
     }
 
+    /**
+     * get html form with selectr for remote branches
+     * @param string $sActiveBranchname  force active branch name
+     * @return string
+     */
+    public function getRemoteBranches($sActiveBranchname = false) {
+        $aReturn = array();
+        $aRadios = array();
+        $bFoundActive = false;
+        $i = 0;
+        if (!$this->_oVcs) {
+            $this->_initVcs();
+        }
+
+        if (!$sActiveBranchname) {
+            $sActiveBranchname = $this->_sBranchname;
+        }
+        if ($this->_oVcs) {
+            if (!method_exists($this->_oVcs, "getRemoteBranches")) {
+                // the version control class does not have this method
+                return '';
+            }
+            foreach ($this->_oVcs->getRemoteBranches() as $sBranch) {
+                $aRadios[$sBranch] = array(
+                    'label' => $sBranch,
+                );
+                // if no param was given the first branch will be marked
+                if (!$sActiveBranchname) {
+                    $sActiveBranchname = $sBranch;
+                }
+                if ($sBranch == $sActiveBranchname) {
+                    $bFoundActive = true;
+                    $aRadios[$sBranch]['checked'] = 'checked';
+                } else {
+                    $aRadios[$sBranch]['onclick'] = 'document.getElementById(\'submitBranch\').click()';
+                }
+            };
+        }
+        // no branches were found
+        if (count($aRadios) == 0) {
+            return '';
+        }
+
+        $aForms = array(
+            'frmSelectBranch' => array(
+                'meta' => array(
+                    'method' => 'POST',
+                    'action' => '?',
+                    'id' => 'frmSelectBranch',
+                ),
+                'validate' => array(),
+                'form' => array(
+                    'branchname' => array(
+                        'type' => 'radio',
+                        'name' => 'branchname',
+                        'label' => '<strong>' . t('branch-select') . '</strong>',
+                        'validate' => 'isastring',
+                        'options' => $aRadios,
+                    ),
+                ),
+            ),
+        );
+
+        // submit to switch branches - only if a selection is available
+        if (count($aRadios) > 1 || !$bFoundActive) {
+            $aForms['frmSelectBranch']['form']['submitBranch'] = array(
+                'type' => 'submit',
+                'name' => 'btnsave',
+                'label' => t("change"),
+                'value' => '<i class="icon-ok"></i> ' . t("change"),
+            );
+        }
+
+        $oFrm = new formgen($aForms);
+        return $oFrm->renderHtml('frmSelectBranch');
+        // return $oFrm->renderHtmlElement('dummy',$aFormData);
+    }
+
     /**
      * get current revision and log message from remote repo
      * @return array
@@ -802,12 +897,12 @@ class project {
         ) {
             return $this->_aData["phases"]["source"];
         }
-        
-        if (!$this->_aPrjConfig["build"]["type"]){
+
+        if (!$this->_aPrjConfig["build"]["type"]) {
             $this->_aData["phases"]["source"] = array("error" => t("class-project-error-repo-type-not-set"),);
         } else {
             $this->_initVcs();
-            if ($this->_oVcs){
+            if ($this->_oVcs) {
                 $this->_aData["phases"]["source"] = $this->_oVcs->getRepoRevision();
             } else {
                 $this->_aData["phases"]["source"] = array(
@@ -817,23 +912,31 @@ class project {
         }
         return $this->_aData["phases"]["source"];
     }
-    
+
     /**
      * init version control system (git, ...)
      * @return vcs-object
      */
-    private function _initVcs(){
+    private function _initVcs() {
         if (!$this->_oVcs) {
-            if (!$this->_aPrjConfig["build"]["type"]){
+            if (!$this->_aPrjConfig["build"]["type"]) {
                 $this->_aData["phases"]["source"] = array("error" => t("class-project-error-repo-type-not-set"),);
             } else {
-                if (!@include_once("vcs.".$this->_aPrjConfig["build"]["type"].".class.php")){
+                if (!@include_once("vcs." . $this->_aPrjConfig["build"]["type"] . ".class.php")) {
                     $this->_aData["phases"]["source"] = array(
                         "error" => sprintf(t("class-project-error-repo-type-not-supported"), $this->_aPrjConfig["build"]["type"]),
                     );
                 } else {
-
-                    $this->_oVcs=new vcs($this->_aPrjConfig["build"]);
+                    $aConfig = $this->_aPrjConfig["build"];
+                    // for vcs classes
+                    $aConfig["appRootDir"] = $this->_aConfig["appRootDir"];
+                    $aConfig["dataDir"] = $this->_aConfig["dataDir"];
+                    $this->_oVcs = new vcs($aConfig);
+                    if ($this->_sBranchname) {
+                        if (method_exists($this->_oVcs, "setCurrentBranch")) {
+                            $this->_oVcs->setCurrentBranch($this->_sBranchname);
+                        }
+                    }
                 }
             }
         }
@@ -864,9 +967,7 @@ class project {
         $this->_aConfig["id"] = $sId;
 
         $this->_aPrjConfig = json_decode(file_get_contents($this->_getConfigFile($sId)), true);
-        
-        // for vcs classes
-        $this->_aPrjConfig["build"]["appRootDir"]=$this->_aConfig["appRootDir"];
+
         // $aData=json_decode(file_get_contents($this->_getConfigFile($sId)), true);
         // echo "<pre>" . print_r($aData, true) . "</pre>";
 
@@ -874,6 +975,21 @@ class project {
         return true;
     }
 
+    /**
+     * set a branchname
+     * @param string $sBranchname name of the branch, i.e. "origin/master"
+     * @return bool
+     */
+    public function setBranchname($sBranchname) {
+        $this->_sBranchname = $sBranchname;
+        if ($this->_oVcs) {
+            if (method_exists($this->_oVcs, "setCurrentBranch")) {
+                $this->_oVcs->setCurrentBranch($sBranchname);
+            }
+        }
+        return $this->_sBranchname;
+    }
+
     // ----------------------------------------------------------------------
     // ACTIONS
     // ----------------------------------------------------------------------
@@ -999,8 +1115,8 @@ class project {
             $sError = sprintf(t('class-project-error-build-type-not-supported'), $this->_aPrjConfig["build"]["type"]);
             $this->_logaction($sError, __FUNCTION__, "error");
             return $this->getBox("error", $sError . $sReturn);
-        }        
-        
+        }
+
         // --------------------------------------------------
         // create workdir
         // --------------------------------------------------
@@ -1032,17 +1148,15 @@ class project {
         // --------------------------------------------------
         $sReturn.='<h3>' . t('class-project-build-label-get-sources-from-version-control') . '</h3>';
 
-        $this->_oVcs->getSources($sTempDir);
+        $sReturn.='<pre>' . $this->_oVcs->getSources($sTempDir) . '</pre>';
 
-        $aVersion=$this->_oVcs->getRevision($sTempDir);
-        $sRevision=$aVersion["revision"];
-        $sCommitMsg=$aVersion["message"];
+        $aVersion = $this->_oVcs->getRevision($sTempDir);
+        $sRevision = $aVersion["revision"];
+        $sCommitMsg = $aVersion["message"];
         $sCommitMsg = str_replace("\n", "<br>", $sCommitMsg);
         $sCommitMsg = str_replace('"', "&quot;", $sCommitMsg);
-        // $sCommitMsg = str_replace('<', "&lt;", $sCommitMsg);
-        // $sCommitMsg = str_replace('>', "&gt;", $sCommitMsg);
         $sReturn.=$this->getBox("info", $sCommitMsg);
-        
+
         $sReturn.=$this->_execAndSend("ls -lisa $sTempDir");
 
         if (!$this->_iRcAll == 0) {
@@ -1062,7 +1176,7 @@ class project {
         $sHookfile = $this->_aConfig['hooks']['build-postclone'];
         $sReturn.='<h3>' . t('class-project-build-label-execute-hook-postclone') . ' (' . $sHookfile . ')</h3>';
         if (file_exists($sTempDir . '/' . $sHookfile)) {
-            $sReturn.=$this->_execAndSend('chmod 755 '.$sTempDir.'/hooks/on*');
+            $sReturn.=$this->_execAndSend('chmod 755 ' . $sTempDir . '/hooks/on*');
             // $this->_iRcAll = 0;
             $sReturn.=$this->_execAndSend('bash --login -c \'' . $sTempDir . '/' . $sHookfile . '\'');
             if (!$this->_iRcAll == 0) {
@@ -1098,7 +1212,7 @@ class project {
         $sHookfile = $this->_aConfig['hooks']['build-precompress'];
         $sReturn.='<h3>' . t('class-project-build-label-execute-hook-precompress') . ' (' . $sHookfile . ')</h3>';
         if (file_exists($sTempDir . '/' . $sHookfile)) {
-            $sReturn.=$this->_execAndSend('chmod 755 '.$sTempDir.'/hooks/on*');
+            $sReturn.=$this->_execAndSend('chmod 755 ' . $sTempDir . '/hooks/on*');
             // $this->_iRcAll = 0;
             $sReturn.=$this->_execAndSend('bash --login -c \'' . $sTempDir . '/' . $sHookfile . '\'');
             if (!$this->_iRcAll == 0) {
@@ -1118,10 +1232,10 @@ class project {
         // cleanup .git, .svn, ...
         // --------------------------------------------------
         $sReturn.='<h3>' . t('class-project-build-label-cleanup-project') . '</h3>';
-        if ($this->_oVcs){
+        if ($this->_oVcs) {
             $this->_oVcs->cleanupWorkdir($sTempDir);
         }
-        
+
         // $sReturn.=$this->_execAndSend("cd $sTempDir && rm -rf .git");
         // $sReturn.=$this->_execAndSend("cd $sTempDir && rm -rf .svn");
         // $sReturn.=$this->_execAndSend("find  $sTempDir -type d -name '.svn' -exec rm -rf {} \;");
@@ -1161,24 +1275,38 @@ class project {
         // generate info file
         $sTs = date("Y-m-d H:i:s");
         $sTs2 = date("Ymd_His");
+        $sBranch = ($this->_sBranchname ? $this->_sBranchname : t("defaultbranch"));
         $sInfoFileWebroot = $sWebroot . '/' . basename($this->_getInfofile($sFirstLevel, "deployed"));
         $sInfoFileArchiv = $this->_getArchiveDir($sTs2) . '/' . basename($this->_getInfofile($sFirstLevel, "deployed"));
         $sPackageFileArchiv = $this->_getArchiveDir($sTs2) . '/' . basename($this->_getPackagefile($sFirstLevel, "deployed"));
 
-        $sInfos = '{
-            "date": "' . $sTs . '",
-            "version": "' . $sTs2 . '",
-            "revision": "' . $sRevision . '",
-            "message": "' . $sCommitMsg . '"
-        }';
+        $aInfos = array(
+            'date' => $sTs,
+            'version' => $sTs2,
+            'branch' => $sBranch,
+            'revision' => $sRevision,
+            'message' => $sCommitMsg,
+        );
+        /*
+          $sInfos = '{
+          "date": "' . $sTs . '",
+          "version": "' . $sTs2 . '",
+          "branch": "' . $sBranch . '",
+          "revision": "' . $sRevision . '",
+          "message": "' . $sCommitMsg . '"
+          }';
+         * 
+         */
         /*
           "user": "' . $aParams["inputUser"] . '",
           "remark": "' . $aParams["inputComment"] . '"
          */
 
         $sReturn.=t("class-project-info-build-write-meta-to-webroot") . "<br>";
-        file_put_contents($sInfoFileWebroot, $sInfos);
+        // file_put_contents($sInfoFileWebroot, $sInfos);
+        file_put_contents($sInfoFileWebroot, json_encode($aInfos));
         $sReturn.=$this->_execAndSend("ls -l $sInfoFileWebroot");
+        $sReturn.=$this->_execAndSend("cat $sInfoFileWebroot");
 
         if (!file_exists(dirname($sPackageFileArchiv))) {
             $sReturn.=sprintf(t("creating-directory"), dirname($sPackageFileArchiv)) . "<br>";
@@ -1201,7 +1329,8 @@ class project {
 
         // write info file (.json)
         $sReturn.=sprintf(t("creating-file"), $sInfoFileArchiv) . "<br>";
-        file_put_contents($sInfoFileArchiv, $sInfos);
+        // file_put_contents($sInfoFileArchiv, $sInfos);
+        file_put_contents($sInfoFileArchiv, json_encode($aInfos));
 
         // copy template files
         if (file_exists($sTempDir . '/hooks/templates/')) {
@@ -1436,7 +1565,7 @@ class project {
         // $sReturn.=$this->_execAndSend("ln -s $sLinkTarget $sLinkName");
         if (array_key_exists('mirrorPackages', $this->_aConfig) && count($this->_aConfig['mirrorPackages'])) {
             foreach ($this->_aConfig['mirrorPackages'] as $sLabel => $aTarget) {
-                $sReturn.='<h3>'.sprintf(t("class-project-info-deploy-synching-package"), $sLabel) . "</h3>";
+                $sReturn.='<h3>' . sprintf(t("class-project-info-deploy-synching-package"), $sLabel) . "</h3>";
                 if (array_key_exists('type', $aTarget)) {
                     $sCmd = false;
                     // $sSource=$this->_aConfig["packageDir"]."/$sPhase/*";
@@ -1473,7 +1602,7 @@ class project {
         // TODO: run puppet agent on target server(s) - for preview only
         if (array_key_exists("puppethost", $this->_aPrjConfig["phases"][$sPhase]) && $this->_aPrjConfig["phases"][$sPhase]["puppethost"]
         ) {
-            $sReturn.='<h3>'.t("class-project-info-deploy-start-puppet") . '</h3>';
+            $sReturn.='<h3>' . t("class-project-info-deploy-start-puppet") . '</h3>';
             $sCmd = 'ssh ' . $this->_aConfig["installPackages"]["user"]
                     . '@' . $this->_aPrjConfig["phases"][$sPhase]["puppethost"]
                     . ' ' . $this->_aConfig["installPackages"]["command"];
@@ -1874,7 +2003,9 @@ class project {
                 ' . $this->_renderBar($sPhase, $sPlace) . '
                 <i class="icon-calendar"></i> ' . t('build-from') . ' ' . date("d.m.Y H:i:s", strtotime($aData["date"]));
             if ($bLong) {
-                $sReturn.='<br><i class="icon-tag"></i> ' . t('revision') . ': ' . $aData["revision"] . '<br>
+                $sReturn.='<br>
+                    <i class="icon-bookmark"></i> ' . t('branch') . ': ' . $aData["branch"] . '<br>
+                    <i class="icon-tag"></i> ' . t('revision') . ': ' . $aData["revision"] . '<br>
                     <i class="icon-comment"></i> ' . t('commitmessage') . ':<br><pre>' . strip_tags($aData["message"], '<br>') . '</pre>';
                 if ($sPlace == "deployed" && array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase])) {
                     $sReturn.='<i class="icon-globe"></i> ' . t('url') . ': <a href="' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '">' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '</a><br>';
@@ -1996,9 +2127,9 @@ class project {
 
                 $aRepodata = $this->getRepoRevision();
                 if (array_key_exists("revision", $aRepodata)) {
-                    $sRevision = $aRepodata["revision"];
-                    $sReturn.=$this->_getChecksumDiv($sRevision);
-                    $sReturn.= '<i class="icon-tag"></i> ' . t('revision') . ': ' . $sRevision;
+                    $sReturn.=$this->_getChecksumDiv($aRepodata["revision"]);
+                    $sReturn.= '<i class="icon-bookmark"></i> ' . t('branch') . ': ' . (array_key_exists("branch", $aRepodata) ? $aRepodata["branch"] : '-') . '<br>';
+                    $sReturn.= '<i class="icon-tag"></i> ' . t('revision') . ': ' . $aRepodata["revision"] . '<br>';
                     $sReturn.="<pre>" . strip_tags($aRepodata["message"], '<br>') . "</pre>";
                 } else {
                     $sReturn .= $this->getBox("error", sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]))
@@ -2010,8 +2141,11 @@ class project {
             default:
                 $sReturn .= $this->getBox("error", sprintf(t('class-project-error-wrong-buildtype'), $this->_aPrjConfig["build"]["type"]));
         }
+        if (array_key_exists("url", $this->_aPrjConfig["build"])) {
+            $sReturn.=t('repository-url') . ': ' . $this->_aPrjConfig["build"]["url"] . '<br>';
+        }
         if (array_key_exists("webaccess", $this->_aPrjConfig["build"])) {
-            $sReturn.='<br>' . t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>';
+            $sReturn.=t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>';
         }
         return $sReturn;
     }
@@ -2038,6 +2172,7 @@ class project {
             $sLinktitle = t('infos');
             if (array_key_exists("message", $aInfos)) {
                 $sInfos.='<i class="icon-calendar"></i> ' . t('build-from') . ' ' . date("d.m.Y H:i:s", strtotime($aInfos["date"])) . '<br>'
+                        . '<i class="icon-bookmark"></i> ' . t('branch') . ': ' . $aInfos["branch"] . '<br>'
                         . '<i class="icon-tag"></i> ' . t('revision') . ': ' . $aInfos["revision"] . '<br>'
                         . '<i class="icon-comment"></i> ' . t('commitmessage') . ':<br><span class="pre">' . strip_tags($aInfos["message"], '<br>') . '</span>';
                 if (array_key_exists("more", $aOptions)) {
@@ -2134,93 +2269,92 @@ class project {
         return $sReturn;
     }
 
-    
     /**
      * render graphical overview of process (in project overview)
      * @return string
      */
-    public function renderVisual(){
-        $sReturn='';
-        $sContinue='&raquo;&raquo;';
+    public function renderVisual() {
+        $sReturn = '';
+        $sContinue = '&raquo;&raquo;';
 
 
-        $sRepoBar='';
+        $sRepoBar = '';
         $aRepodata = $this->getRepoRevision();
         if (array_key_exists("revision", $aRepodata)) {
-            $sRepoBar=$this->_getChecksumDiv($aRepodata["revision"]);
+            $sRepoBar = $this->_getChecksumDiv($aRepodata["revision"]);
         } else {
-            $sRepoBar='<span class="error">' . t("error") . '</span>';
+            $sRepoBar = '<span class="error">' . t("error") . '</span>';
         }
-        
-        $sPackagebar='';
-        $aVersions=$this->_getVersionUsage();
-        foreach ($aVersions as $sVersion=>$aData){
-            $sBar=$aData["info"]["revision"]?$this->_getChecksumDiv($aData["info"]["revision"]):'';
-            $sPackagebar.='<span title="'.$sVersion.'" style="float: left; background:#eee; height: 3px; width:'.(100/count($aVersions)).'%">'.$sBar.'&nbsp;</span>';
+
+        $sPackagebar = '';
+        $aVersions = $this->_getVersionUsage();
+        foreach ($aVersions as $sVersion => $aData) {
+            $sBar = $aData["info"]["revision"] ? $this->_getChecksumDiv($aData["info"]["revision"]) : '';
+            $sPackagebar.='<span title="' . $sVersion . '" style="float: left; background:#eee; height: 3px; width:' . (100 / count($aVersions)) . '%">' . $sBar . '&nbsp;</span>';
         }
-        
-        $sPhaseImg='';
-        $sLastPhase='';
+
+        $sPhaseImg = '';
+        $sLastPhase = '';
         foreach ($this->getActivePhases() as $sPhase) {
-            if ($sPhaseImg){
-                $sAction=$sContinue;
-                if ($this->canAcceptPhase($sLastPhase)){
-                    $sAction=$this->renderLink("accept", $sLastPhase);
+            if ($sPhaseImg) {
+                $sAction = $sContinue;
+                if ($this->canAcceptPhase($sLastPhase)) {
+                    $sAction = $this->renderLink("accept", $sLastPhase);
                 }
-                $sPhaseImg.='<div class="action">'.$sAction.'</div>';
+                $sPhaseImg.='<div class="action">' . $sAction . '</div>';
             }
-            $sLastPhase=$sPhase;
+            $sLastPhase = $sPhase;
 
-            $sFullbar='';
-            foreach (array_keys($this->_aPlaces) as $sPlace){
-                $sFullbar.='<span title="'.$this->_aPlaces[$sPlace].'" style="float: left; background:#eee; height: 3px; width:'.(100/count($this->_aPlaces)).'%">'.$this->_renderBar($sPhase, $sPlace).'&nbsp;</span>';
+            $sFullbar = '';
+            foreach (array_keys($this->_aPlaces) as $sPlace) {
+                $sFullbar.='<span title="' . $this->_aPlaces[$sPlace] . '" style="float: left; background:#eee; height: 3px; width:' . (100 / count($this->_aPlaces)) . '%">' . $this->_renderBar($sPhase, $sPlace) . '&nbsp;</span>';
             }
-            $sDetail=$sFullbar.'<br><a href="#h3phases" class="scroll-link">'.$sPhase.'</a>';
-            
+            $sDetail = $sFullbar . '<br><a href="#h3phases" class="scroll-link">' . $sPhase . '</a>';
+
             $sPhaseImg.='
-            <div class="process '.$sPhase.'">
-                <div class="details">'.$sDetail.' </div>
-                <div><img src="/deployment/images/process/bg_phase.png" alt="'.t("phase").' '.$sPhase.'"></div>
+            <div class="process ' . $sPhase . '">
+                <div class="details">' . $sDetail . ' </div>
+                <div><img src="/deployment/images/process/bg_phase.png" alt="' . t("phase") . ' ' . $sPhase . '"></div>
             </div>';
         }
 
-        $sReturn='
+        $sReturn = '
         <div class="visualprocess">
             <div class="process">
-                <div class="title">'.t("versioncontrol").'</div>
+                <div class="title">' . t("versioncontrol") . '</div>
                 <div class="details">
-                    '.$sRepoBar.'<br>
+                    ' . $sRepoBar . '<br>
                     <a href="#h3repo" class="scroll-link">' . t("repositoryinfos") . '</a><br>
-                    <strong>'. $this->_aPrjConfig["build"]["type"].'</strong> '.preg_replace('/.*\@(.*):.*/','($1)',$this->_aPrjConfig["build"]["url"]).'<br>
+                    <strong>' . $this->_aPrjConfig["build"]["type"] . '</strong> ' . preg_replace('/.*\@(.*):.*/', '($1)', $this->_aPrjConfig["build"]["url"]) . '<br>
                 </div>
                 <div>
-                    <img src="/deployment/images/process/bg_vcs.png" alt="'.t("versioncontrol").'">
+                    <img src="/deployment/images/process/bg_vcs.png" alt="' . t("versioncontrol") . '">
                 </div>
             </div>
             
             <div class="process">
                 <div class="title">&nbsp;</div>
-                <div class="action">'.($this->canAcceptPhase()?$this->renderLink("build"):'').'</div>
+                <div class="action">' . ($this->canAcceptPhase() ? $this->renderLink("build") : '') . '</div>
             </div>
             
             <div class="process archive">
-                <div class="title">'.t("archive").'</div>
+                <div class="title">' . t("archive") . '</div>
                 <div class="details">
-                    '.$sPackagebar.'<br>
+                    ' . $sPackagebar . '<br>
                     <a href="#h3versions" class="scroll-link">' . t("packages") . '</a><br>
-                    (<strong>'.count($this->_getVersionUsage()) . '</strong>)
+                    (<strong>' . count($this->_getVersionUsage()) . '</strong>)
                 </div>
-                <div><img src="/deployment/images/process/bg_archive.png" alt="'.t("archive").'"></div>
+                <div><img src="/deployment/images/process/bg_archive.png" alt="' . t("archive") . '"></div>
             </div>
             
             <div class="process">
                 <div class="title">&nbsp;</div>
-                <div class="action">'.$sContinue.'</div>
+                <div class="action">' . $sContinue . '</div>
             </div>
             
             <div class="process phases">
-                <div class="title">'.t("phases").'</div>
-                '.($sPhaseImg?$sPhaseImg:'<div class="process">'.t("none").'</div>').'
+                <div class="title">' . t("phases") . '</div>
+                ' . ($sPhaseImg ? $sPhaseImg : '<div class="process">' . t("none") . '</div>') . '
             </div>
         </div>
         <div style="clear: both;"></div>
@@ -2229,10 +2363,10 @@ class project {
         <strong>' . t('contact') . '</strong>: ' . $this->_aPrjConfig['contact'] . '<br><br>
             ' . $this->renderLink("setup") . '
         ';
-        
+
         return $sReturn;
     }
-    
+
     /**
      * return html code for the setup form of an exsiting project
      * @return string
diff --git a/public_html/deployment/classes/projectlist.class.php b/public_html/deployment/classes/projectlist.class.php
index 8273a02112c33a2194e3df6de975460ad0d1d53d..6ed6ce0471834732d291c59756bbccd2635b9428 100644
--- a/public_html/deployment/classes/projectlist.class.php
+++ b/public_html/deployment/classes/projectlist.class.php
@@ -10,25 +10,25 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
+require_once 'base.class.php';
 require_once 'project.class.php';
 
 /**
  * class for project overview
  */
-class projectlist {
+class projectlist extends base{
     // ----------------------------------------------------------------------
     // CONFIG
-    // ----------------------------------------------------------------------
+    // ----------------------------------------------------------------------    
     // ----------------------------------------------------------------------
     // constructor
     // ----------------------------------------------------------------------
 
     /**
-     * constructor
-     * @param array $aProjects array with all projects (overrides config data)
+     * constructor2 called from constructor of base class
      */
-    public function __construct($aProjects = false) {
-        
+    public function _construct2() {
+        // define 
     }
 
     // ----------------------------------------------------------------------
@@ -49,6 +49,10 @@ class projectlist {
      * @return string
      */
     public function renderOverview() {
+        
+        if (!$this->oUser->hasRole("viewProjectOverview")){
+            return $this->oUser->showDenied();
+        }
         $sOut = '';  // table
         $sOut2 = ''; // tiles
         $oPrj = false;
diff --git a/public_html/deployment/classes/sws.class.php b/public_html/deployment/classes/sws.class.php
index 64ef326103ab7a42ab9bf38773dc8af9f743b3d7..5da960db10976988d6108636fb9dc48f63538909 100644
--- a/public_html/deployment/classes/sws.class.php
+++ b/public_html/deployment/classes/sws.class.php
@@ -506,8 +506,8 @@ class sws {
                     . '<blockquote>'
                     
                         . '<h5>init parameters of class &quot;'.$sMyClass.'&quot;</h5>'
-                        . '<code>$o = new '.$sMyClass.' ( ... )</code><br>'
                         . '<blockquote>'
+                            . '<code>$o = new '.$sMyClass.' ( ... )</code><br>'
                             . $this->_showMethodInputForm($sMyClass, "__construct", $sIdPrefix."init")
                     ;
                     if (count($RefClass['actions']["__construct"]['params'])){
@@ -519,8 +519,8 @@ class sws {
                     $sReturn .= '</blockquote>'
 
                         . '<h5>parameters of method &quot;'.$sAction.'&quot;</h5>'
-                        . '<code>$o ->' . $sAction . ' ( ... )</code><br>'
                         . '<blockquote>'
+                            . '<code>$o ->' . $sAction . ' ( ... )</code><br>'
                             . $this->_showMethodInputForm($sMyClass, $sAction, $sIdPrefix."args");
                     if (count($RefClass['actions'][$sAction]['params'])){
                         $sReturn .='OR<br><fieldset><legend>json</legend>'
@@ -734,6 +734,10 @@ class sws {
                                         if (
                                             sVal.indexOf(\'"\')<0
                                             && sVal.indexOf("\'")<0
+                                            && sVal.indexOf("\[")<0
+                                            && sVal.indexOf("\]")<0
+                                            && sVal.indexOf("\{")<0
+                                            && sVal.indexOf("\}")<0
                                         ){
                                             sVal=\'"\'+sVal+\'"\';
                                         }
diff --git a/public_html/deployment/classes/user.class.php b/public_html/deployment/classes/user.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..9cbddf405d08ea0a38741e53834a1975a7e8b37e
--- /dev/null
+++ b/public_html/deployment/classes/user.class.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * user class contains username and its roles
+ * This class is used in the base class
+ *
+ * @author hahn
+ */
+class user {
+    
+    private $_sUsername=false;
+    private $_aUserGroups=array();
+    private $_aUserRoles=array();
+    private $_sLastCheckedRole=false;
+    
+    /**
+     * init user with optional given user
+     * @param type $sUser
+     */
+    public function __construct($sUser=false){
+        $this->setUser($sUser);
+    }
+    
+    /**
+     * detect a user
+     * @return type
+     */
+    private function _autoDetectUser(){
+        $sUser=false;
+        if (is_array($_SERVER) && array_key_exists("PHP_AUTH_USER", $_SERVER)){
+            $sUser=$_SERVER["PHP_AUTH_USER"];
+        }
+        return $sUser;
+    }
+
+    /**
+     * TODO: reimplement
+     * get the user groups of the current user from an internal source.
+     * The function returns a flat aray with names of the groups
+     * @return array
+     */
+    private function _getUserGroups(){
+        $aGroups=array();
+        if ($this->_sUsername){
+            $aGroups[]="authenticated";
+            $aGroups[]=$this->_sUsername;
+        }
+        $this->_aUserGroups=$aGroups;
+        return $this->_aUserGroups;
+    }
+
+    /**
+     * TODO: reimplement
+     * get the user roles of the current user from an internal source.
+     * The function returns a flat aray with names of the roles
+     * @return array
+     */
+    private function _getUserRoles(){
+        $aRoles=array();
+
+        // anonymous roles:
+        // $aRoles[]="view";
+        $aRoles[]="viewProjectOverview";
+        
+        if ($this->hasGroup("authenticated")){
+            if ($this->hasGroup("developer")){
+                $aRoles[]="build";
+                /*
+                $aRoles[]="deploy";
+                $aRoles[]="accept";
+                $aRoles[]="setup-project";
+                 * 
+                 */
+            }
+            if ($this->hasGroup("admin")){
+                // $aRoles[]="setup-all";
+            }
+        }
+        
+        $this->_aUserRoles=$aRoles;
+        return $this->_aUserRoles;
+    }
+    
+    /**
+     * TODO: implement authentication somewhere
+     * set a new authenticated user
+     * @param string $sUser  username
+     */
+    public function setUser($sUser=false){
+        if (!$sUser){
+            $sUser=$this->_autoDetectUser();
+        }
+        $this->_sUsername=$sUser;
+        $this->_getUserGroups();
+        $this->_getUserRoles();
+    }
+
+    /**
+     * get the current username
+     * @return string
+     */
+    public function getUsername(){
+        return $this->_sUsername;
+    }
+    /**
+     * get a flat array with roles of the current user
+     * @return string
+     */
+    public function getUserGroups(){
+        return $this->_aUserGroups;
+    }
+    /**
+     * get a flat array with roles of the current user
+     * @return string
+     */
+    public function getUserRoles(){
+        return $this->_aUserRoles;
+    }
+
+    /**
+     * check if the current user has a given role name
+     * @param string  $sGroupname  name of the role to check
+     * @return type
+     */
+    public function hasGroup($sGroupname){
+        return (array_search($sGroupname, $this->_aUserGroups)!==false);
+    }
+    /**
+     * check if the current user has a given role name
+     * @param string  $sRolename  name of the role to check
+     * @return type
+     */
+    public function hasRole($sRolename){
+        $this->_sLastCheckedRole=$sRolename;
+        return (array_search($sRolename, $this->_aUserRoles)!==false);
+    }
+
+    /**
+     * return html code to display a denied message
+     * @return type
+     */
+    public function showDenied(){
+        return '<div class="error">'.t("class-user-error-deny-no-role").' ('.$this->_sLastCheckedRole.')</div>';
+    }
+    
+}
diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php
index 5e167636b98d5e23e91413f3a6a1421a648286ec..b38eaf5485d26a04a791a6cfc8d4d54a6c711511 100644
--- a/public_html/deployment/classes/vcs.git.class.php
+++ b/public_html/deployment/classes/vcs.git.class.php
@@ -14,34 +14,46 @@ class vcs implements iVcs {
 
     /**
      * configuration
-     * @var type 
+     * @var array 
      */
-    private $_aCfg=array();
-    
+    private $_aCfg = array();
+
     /**
      * temp dir to fetch repo version and ommit message; its value will be
      * generated in set_config()
-     * @var type 
+     * @var string
      */
-    private $_sTempDir= false;  // 
-    
+    private $_sTempDir = false;  // 
+
     /**
      * filename of ssh key file with complete path
-     * @var type 
+     * @var string
      */
     private $_sKeyfile = false;
-    
+
     /**
      * filename of ssh wrapper script with complete path
-     * @var type 
+     * @var string
      */
     private $_sWrapper = false;
 
+    /**
+     * flat array with remote branch names
+     * @var array
+     */
+    private $_aRemoteBranches = array();
+
+    /**
+     * name of the remote branch to access
+     * @var type 
+     */
+    private $_sCurrentBranch = "origin/master";
+
     /**
      * constructor
-     * @param type $aRepoConfig
+     * @param array $aRepoConfig
      */
-    public function __construct($aRepoConfig=array()) {
+    public function __construct($aRepoConfig = array()) {
         $this->setConfig($aRepoConfig);
     }
 
@@ -50,42 +62,49 @@ class vcs implements iVcs {
      * @param array $aRepoConfig
      * @return boolean
      */
-    public function setConfig($aRepoConfig=array()){
-        
+    public function setConfig($aRepoConfig = array()) {
+
         // checks
-        foreach(array("type", "url") as $key){
-            if (!array_key_exists($key, $aRepoConfig)){
-                die("ERROR: key $key does not exist in config <pre>". print_r($aRepoConfig, true)."</pre>");
+        foreach (array("type", "url") as $key) {
+            if (!array_key_exists($key, $aRepoConfig)) {
+                die("ERROR: key $key does not exist in config <pre>" . print_r($aRepoConfig, true) . "</pre>");
             }
-            if (!$aRepoConfig[$key]){
-                die("ERROR: key $key in config exists but is empty<pre>". print_r($aRepoConfig, true)."</pre>");
+            if (!$aRepoConfig[$key]) {
+                die("ERROR: key $key in config exists but is empty<pre>" . print_r($aRepoConfig, true) . "</pre>");
             }
         }
-        if ($aRepoConfig["type"]!=="git") {
-                die("ERROR: type is not git<pre>". print_r($aRepoConfig, true)."</pre>");
+        if ($aRepoConfig["type"] !== "git") {
+            die("ERROR: type is not git<pre>" . print_r($aRepoConfig, true) . "</pre>");
         }
-        
+
         // set config array
-        $this->_aCfg=$aRepoConfig;
+        $this->_aCfg = $aRepoConfig;
         
         // define temp dir
-        $this->_sTempDir=$this->_aCfg["url"];
-        $this->_sTempDir=preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir);
-        $this->_sTempDir=(getenv("temp")?getenv("temp"):"/tmp").'/checkout_vcsgit_'. $this->_sTempDir . "/";
-        $this->_sKeyfile = $this->_aCfg["appRootDir"] . "/" . $this->_aCfg["auth"];
+        $this->_sTempDir = $this->_aCfg["url"];
+        $this->_sTempDir = preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir);
+        $this->_sTempDir = (getenv("temp") ? getenv("temp") : "/tmp") . '/checkout_vcsgit_' . $this->_sTempDir . "/";
+        $this->_sKeyfile = $this->_aCfg["dataDir"] . "/sshkeys/" . $this->_aCfg["auth"];
         $this->_sWrapper = $this->_aCfg["appRootDir"] . "/shellscripts/gitsshwrapper.sh";
-        
-        return $this->_aCfg=$aRepoConfig;
+
+        return $this->_aCfg = $aRepoConfig;
+    }
+
+    /**
+     * set the current branch
+     * @param string $sBranchname  name of the branch
+     */
+    public function setCurrentBranch($sBranchname) {
+        return $this->_sCurrentBranch=$sBranchname;
     }
-    
     /**
      * helper: dump values
      * @return boolean
      */
-    public function dump(){
-        echo "<h3>Dump class ".__CLASS__."</h3>";
+    public function dump() {
+        echo "<h3>Dump class " . __CLASS__ . "</h3>";
         echo "config array: <pre>" . print_r($this->_aCfg, true) . "</pre>";
-        echo "temp dir to read revision: ".$this->_sTempDir."<br>";
+        echo "temp dir to read revision: " . $this->_sTempDir . "<br>";
         return true;
     }
 
@@ -98,8 +117,8 @@ class vcs implements iVcs {
         if (!is_dir($sWorkDir)) {
             return false;
         }
-        shell_exec('rm -rf "'.$sWorkDir.'/.git"');
-        @unlink($sWorkDir."/.gitignore");
+        shell_exec('rm -rf "' . $sWorkDir . '/.git"');
+        @unlink($sWorkDir . "/.gitignore");
         return true;
     }
 
@@ -111,6 +130,43 @@ class vcs implements iVcs {
         return $this->_aCfg["type"];
     }
 
+    /**
+     * read remote repository and get a flat array with names of all branches
+     * @return array
+     */
+    private function _fetchRemoteBranches() {
+        $aReturn = array();
+        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+        if (!file_exists($this->_sTempDir . ".git")) {
+            $sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
+            $sGitCmd.='git init >/dev/null && ';
+            $sGitCmd.='git remote add origin "' . $this->getUrl() . '"  && ';
+        } else {
+            $sGitCmd.='cd "' . $this->_sTempDir . '" && ';
+        }
+        $sGitCmd.='git branch -r ; ';
+        exec($sGitCmd, $aOutput, $iRc);
+        if ($iRc == 0) {
+            foreach ($aOutput as $sBranch) {
+                // $aReturn[] = str_replace("origin/", "", trim($sBranch));
+                $aReturn[] = trim($sBranch);
+            }
+        }
+        $this->_aRemoteBranches = $aReturn;
+        return $aReturn;
+    }
+
+    /**
+     * get a flat array with names of all remote branches
+     * @return array
+     */
+    public function getRemoteBranches() {
+        if (!$this->_aRemoteBranches) {
+            $this->_aRemoteBranches = $this->_fetchRemoteBranches();
+        }
+        return $this->_aRemoteBranches;
+    }
+
     /**
      * get current revision and log message from remote repository
      * @see $this::getRevision
@@ -119,7 +175,7 @@ class vcs implements iVcs {
     public function getRepoRevision() {
         return $this->getRevision(false);
     }
-    
+
     /**
      * get current revision and log message from an existing directory or a
      * remote repository
@@ -137,25 +193,25 @@ class vcs implements iVcs {
      *      );
      * @return array
      */
-    public function getRevision($sWorkDir=false) {
-        $aReturn=array();
-        $sGitCmd = 'export GIT_SSH="'.$this->_sWrapper.'" ; export PKEY="'.$this->_sKeyfile.'" ; ';
-        
-        if ($sWorkDir){
-            $sGitCmd.='cd "'.$sWorkDir.'" && ';
+    public function getRevision($sWorkDir = false) {
+        $aReturn = array();
+        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+
+        if ($sWorkDir) {
+            $sGitCmd.='cd "' . $sWorkDir . '" && ';
         } else {
             if (!file_exists($this->_sTempDir . ".git")) {
-                $sGitCmd.='mkdir "'.$this->_sTempDir.'" && cd "'.$this->_sTempDir.'" && ';
+                $sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
                 $sGitCmd.='git init >/dev/null && ';
                 $sGitCmd.='git remote add origin "' . $this->getUrl() . '"  && ';
             } else {
-                $sGitCmd.='cd "'.$this->_sTempDir.'" && ';
+                $sGitCmd.='cd "' . $this->_sTempDir . '" && ';
             }
-            $sGitCmd.='git fetch --update-head-ok 2>&1 && ';
+            $sGitCmd.='git fetch --update-head-ok --depth 1 2>&1 && ';
         }
-        
-        $sGitCmd.='git log -1 origin/master ; ';
-        $sLoginfo.= shell_exec($sGitCmd);
+
+        $sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" ; ';
+        $sLoginfo = shell_exec($sGitCmd);
 
         $sRevision = false;
         if (preg_match('#commit\ (.*)#', $sLoginfo, $aRev)) {
@@ -164,6 +220,7 @@ class vcs implements iVcs {
 
         if ($sRevision) {
             $aReturn = array(
+                "branch" => $this->_sCurrentBranch,
                 "revision" => $sRevision,
                 "message" => $sLoginfo
             );
@@ -172,10 +229,9 @@ class vcs implements iVcs {
                 $sLoginfo = $sGitCmd;
             }
             $aReturn = array(
-                "error" => $sLoginfo
+                "error" => '<pre>'.$sLoginfo.'<hr>'.$sGitCmd.'</pre>'
             );
         }
-
         return $aReturn;
     }
 
@@ -184,14 +240,17 @@ class vcs implements iVcs {
      * @return bool
      */
     public function getSources($sWorkDir) {
-        if (!$sWorkDir || !is_dir($sWorkDir)){
+        if (!$sWorkDir || !is_dir($sWorkDir)) {
             return false;
         }
+        $sBranchname=$this->_sCurrentBranch;
+        $sBranchname=str_replace("origin/", "", $sBranchname);
         
-        $sGitCmd = 'export GIT_SSH="'.$this->_sWrapper.'" ; export PKEY="'.$this->_sKeyfile.'" ; ';
-        $sGitCmd .= 'git clone "'.$this->getUrl().'" "'.$sWorkDir.'"; ';
-        
-        return shell_exec($sGitCmd);
+        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+        $sGitCmd .= 'echo git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" ; ';
+        $sGitCmd .= 'git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" 2>&1; ';
+        $sReturn=shell_exec($sGitCmd);
+        return $sReturn;
     }
 
     /**
diff --git a/public_html/deployment/gen__htusers.bat b/public_html/deployment/gen__htusers.bat
index 282452caace50348126ee3b7934c222560416a62..ba85c8a44cd0e8ca36d5ad4cd76054a79c69d734 100644
--- a/public_html/deployment/gen__htusers.bat
+++ b/public_html/deployment/gen__htusers.bat
@@ -1,9 +1,10 @@
-@echo off
-
-set outfile=%~dp0.htusers
-
-if not exist %outfile% echo.>%outfile%
-C:\xampp\apache\bin\htpasswd.exe -b %outfile% iml deployment
-echo %outfile%
-type %outfile%
+@echo off
+
+set outfile=%~dp0.htusers
+
+if not exist %outfile% echo.>%outfile%
+C:\xampp\apache\bin\htpasswd.exe -b %outfile% iml deployment
+C:\xampp\apache\bin\htpasswd.exe -b %outfile% admin deployment
+echo %outfile%
+type %outfile%
 timeout 20
\ No newline at end of file
diff --git a/public_html/deployment/inc_functions.php b/public_html/deployment/inc_functions.php
index 7d2ecfeca98cbe35a29fc33901b8a628279f4086..b2536f36d47615b226ac89878d589554849b17f7 100644
--- a/public_html/deployment/inc_functions.php
+++ b/public_html/deployment/inc_functions.php
@@ -55,8 +55,19 @@ if (isset($_SERVER) && is_array($_SERVER) && array_key_exists("REQUEST_URI", $_S
     if (count($_POST))
         foreach ($_POST as $key => $value)
             $aParams[$key] = $value;
+    
+    /* force integer params
+    foreach (array("id") as $sKey) {
+            if (array_key_exists($sKey, $aParams)) {
+                    $aParams[$sKey]=(int)$aParams[$sKey];
+            }
+    }
+    */
+    
+    foreach(array_keys($aParams) as $sKey) {
+        $aParams[$sKey]=str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $aParams[$sKey]);
+    }
 }
-
 $sImageBase = "/deployment/images/nuvola64x64/";
 $aImages = array(
     'overview' => 'apps/fsview.png',
@@ -109,9 +120,9 @@ function getTopArea() {
     global $aParams, $sImageBase, $aImages, $aConfig;
     $sReturn = '';
     require_once("./classes/project.class.php");
-    require_once("./classes/projectlist.class.php");
-
-    $oPrjList = new projectlist();
+    require_once("./classes/user.class.php");
+    $oUser=new user();
+    
     $sMyPhase = "[phase]";
     $sMyRev = " [no rev] ";
     $sJsonfile = $_SERVER["DOCUMENT_ROOT"] . "ci-webgui.json";
@@ -120,23 +131,12 @@ function getTopArea() {
         if (array_key_exists("date", $aJson))
             $sMyRev = $aJson["date"];
     }
-    $sPhase = '(unknown)';
 
-    // TODO - Phasen nach Hostname - das kann nicht public gehen
-    $aPhases = array(
-        'dev.ci.iml.unibe.ch' => array('phase' => 'dev',),
-        'aum-cba02.unibe.ch' => array('phase' => 'preview',),
-        'ci.iml.unibe.ch' => array('phase' => 'live',),
-    );
-    if (array_key_exists($_SERVER["SERVER_NAME"], $aPhases)) {
-        $sPhase = $aPhases[$_SERVER["SERVER_NAME"]]["phase"];
-    }
     $sBaseUrl = '/deployment/';
     $sWikiBaseUrl = 'https://secure.iml.unibe.ch/wiki/doku.php';
     $sReturn = '
         <span id="top"></span>
         <div class="navbar">
-          <span class="version ' . $sPhase . '">' . $sPhase . ' :: ' . $sMyRev . '</span>
           <div class="navbar-inner">
             <span class="brand">IML Deployment GUI</span>
             <ul class="nav">
@@ -144,13 +144,13 @@ function getTopArea() {
                 <li class="dropdown';
                 if (!array_key_exists("prj", $aParams))$sReturn.=' active';
                 $sReturn.='">' . str_replace('</a>', ' <b class="caret"></b></a>', aHome("")) . '
-                        <ul class="dropdown-menu">
-                            <li><a href="' . $sBaseUrl . 'all/setup/">' . t("menu-settings") . '</a></li>
-                            <li><a href="' . $sBaseUrl . 'all/setup/actionlog/">' . t("menu-logs") . '</a></li>
-                            <li><a href="' . $sBaseUrl . 'all/setup/new/">' . t("menu-new-project") . '</a></li>
-                        </ul>
-                    </li>
-
+                    <ul class="dropdown-menu">
+                        <li><a href="' . $sBaseUrl . 'all/setup/">' . t("menu-settings") . '</a></li>
+                        <li><a href="' . $sBaseUrl . 'all/setup/actionlog/">' . t("menu-logs") . '</a></li>
+                        <li><a href="' . $sBaseUrl . 'all/setup/new/">' . t("menu-new-project") . '</a></li>
+                    </ul>
+                </li>
+                    
                 <!-- list of projects -->
                 <li class="dropdown">
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown">' . t("menu-projects") . '<b class="caret"></b></a>
@@ -167,7 +167,7 @@ function getTopArea() {
     if (array_key_exists("prj", $aParams) && $aParams["prj"] <> "all") {
         $oPrj = new project($aParams["prj"]);
         $sReturn.='
-                    <li style="border-left: 1px solid #ccc;" class="active">' . aPrjHome(" ") . '</li>
+                    <li class="active">' . aPrjHome(" ") . '</li>
                     ';
         if (array_key_exists("action", $aParams) and FALSE) {
             $sReturn.='<li><a href="#">Aktion: ' . $aParams["action"] . '</a></li>';
@@ -206,6 +206,16 @@ function getTopArea() {
                 -->
             </ul>
             <ul class="nav pull-right">
+                    <!-- userdata -->
+                    <li class="dropdown">
+                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">user: ' . $oUser->getUsername() . '<b class="caret"></b></a>
+                        <ul class="dropdown-menu" style="width: 300px;">
+                            <li>groups: <pre>'.print_r($oUser->getUserGroups(), true).'</pre></li>
+                            <li>roles: <pre>'.print_r($oUser->getUserRoles(), true).'</pre></li>
+                        </ul>
+                    </li>
+
+
                     <li class="dropdown">
                         <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class=" icon-question-sign"></i> ' . t("menu-help") . '<b class="caret"></b></a>
                         <ul class="dropdown-menu">
@@ -218,6 +228,7 @@ function getTopArea() {
                     </li>
             </ul>
           </div>          
+          <span class="version ">' . $sMyRev . ' @ '.php_uname("n").'</span>
         </div><div id="header2">';
 
     if (!array_key_exists("prj", $aParams)) {
diff --git a/public_html/deployment/js/functions.js b/public_html/deployment/js/functions.js
index 8a146a9c67ec74669dfaa76b24b765e5f224a2e0..dc54f043fc0144355d2357c66ad494ddfa1b87de 100644
--- a/public_html/deployment/js/functions.js
+++ b/public_html/deployment/js/functions.js
@@ -116,6 +116,6 @@ function filterLogTable(){
 
 $(document).ready(function() {
     initSoftscroll();
-    $(".optionName").popover({trigger: "hover"});
-    $("#content").hide().fadeIn(300);
+    // $(".optionName").popover({trigger: "hover"});
+    // $("#content").hide().fadeIn(300);
 });
\ No newline at end of file
diff --git a/public_html/deployment/main.css b/public_html/deployment/main.css
index 705a23b9ccd558b5edf826104ae8946f42fca6dc..be5dd3e4e229e029783bb766918d3a58837ea671 100644
--- a/public_html/deployment/main.css
+++ b/public_html/deployment/main.css
@@ -33,11 +33,11 @@ body, label, input, button, select, textarea, p, .btn {
 
 .description{font-weight:bold; color:#ccc; font-size: 150%; font-style: italic;}
 .navbar .brand {color:#a33;}
-.navbar .version {float: right; position: fixed; top: 0px; right: 0;padding: 0 0.5em; 
-                  transform: rotate(0deg);
+.navbar .version {float: right; right: 0em; position: absolute; padding: 0 0.5em; 
                   border-bottom: 1px solid #fff; 
                   border-left: 1px solid #fff; 
                   box-shadow: 0 0 5px #888;
+                  background: #ccc;
                   border-bottom-left-radius: 10px;
 }
 
diff --git a/public_html/deployment/pages/act_build.php b/public_html/deployment/pages/act_build.php
index 3a71c418a2b5bb98d63a3a17bc1f8e449008fa8e..ec8748fd082fd881abbc76cb6c5150463d043825 100644
--- a/public_html/deployment/pages/act_build.php
+++ b/public_html/deployment/pages/act_build.php
@@ -19,13 +19,23 @@ $oPrj = new project($aParams["prj"]);
 
 $sOut = '';
 
+// switch to a branch if it was selected
+$sBranchname='';
+if (array_key_exists("branchname", $aParams)) {
+    $sBranchname=$aParams["branchname"];
+    $oPrj->setBranchname($aParams["branchname"]);
+}
+
 if (!array_key_exists("confirm", $aParams)) {
     // ------------------------------------------------------------
     // let the user click a button to make a new build
     // ------------------------------------------------------------
     $sNext = $oPrj->getNextPhase();
     $aPhaseData2 = $oPrj->getPhaseInfos($sNext);
-    $sOut.='<p>' . sprintf(t("page-build-info"), $sNext, $sNext) . '</p>';
+    
+    $sOut.='<p>' . sprintf(t("page-build-info"), $sNext, $sNext) . '</p>
+       ' ;
+
     $sRevison = false;
     $aRepodata = $oPrj->getRepoRevision();
     if (array_key_exists("revision", $aRepodata)) {
@@ -45,13 +55,16 @@ if (!array_key_exists("confirm", $aParams)) {
         <table>
              <thead>
                  <tr>
-                     <th class="versioncontrol">' . t("versioncontrol") . '</th>
+                     <th class="versioncontrol" colspan="2">' . t("versioncontrol") . '</th>
                      <th> </th>
                      <th class="' . $sNext . '" colspan="2">' . $sNext . '</th>
                  </tr>
              </thead>
              <tbody>
                  <tr>
+                     <td class="">
+                         ' . $oPrj->getRemoteBranches() . '
+                     </td>
                      <td class="">
                          ' . $oPrj->renderRepoInfo() . '
                      </td>
@@ -77,6 +90,7 @@ if (!array_key_exists("confirm", $aParams)) {
         $sOut.='
                  <form action="?" method="post" enctype="multipart/form-data">
                     <input type="hidden" name="confirm" value="1">
+                    <input type="hidden" name="branchname" value="'.$sBranchname.'">
                     <!-- ' . enterDeployinfos() . '
                      <hr>
                     -->
@@ -95,6 +109,7 @@ if (!array_key_exists("confirm", $aParams)) {
     // action run: start action as background process
     // it will be initialized with jQuery $.post( "' . $sUrlStartAction . '" ... )
     // see a few lines below
+    
     if (array_key_exists("run", $aParams)) {
         echo $oPrj->build($sOutDir . "/" . $aParams["ajax"]);
         die();
@@ -112,7 +127,7 @@ if (!array_key_exists("confirm", $aParams)) {
         $sTmpFile = $sOutDir . "/" . $aParams["ajax"];
         $sOut = file_exists($sTmpFile) ? file_get_contents($sTmpFile) : "";
 
-        echo $sLine . "/" . $sProcesses;
+        echo $sLine . $sProcesses;
         if ($sOut) {
             echo '<div style="margin-left: 3em; border-left: 5px dotted #eee; padding-left: 1em;">'
             . $sOut . '</div><div style="clear: both;"></div>' . $sLine;
@@ -129,6 +144,7 @@ if (!array_key_exists("confirm", $aParams)) {
             . "&prj=" . $aParams["prj"]
             . "&action=" . $aParams["action"]
             . "&confirm=" . $aParams["confirm"]
+            . "&branchname=" . $aParams["branchname"]
             . "&ajax=" . $sTmpFile
     ;
     $sUrlStartAction = $sUrl . "&run=1";
diff --git a/public_html/deployment/pages/act_setup.php b/public_html/deployment/pages/act_setup.php
index cce7bd3803203d838eb2ac25c258518b31e21df1..3e7a734f6c7772d2da3ea3b06d876830343d70bb 100644
--- a/public_html/deployment/pages/act_setup.php
+++ b/public_html/deployment/pages/act_setup.php
@@ -29,8 +29,101 @@ if ($aParams["prj"] == "all") {
                 . '<a href="./checklang/">'.t("page-setup-info-check-lang").'</a><br>'
                 . '<a href="./actionlog/">'.t("class-actionlog-title").'</a><br>'
                 . '</p>';
-    }
+        
+        
+        $i = 0;
+        require_once ("./classes/formgen.class.php");
+        
+        // define editable options
+        $aMapping=array(
+            'general'=>array(
+                '["workDir"]'=>array('type'=>'text'),
+                '["versionsToKeep"]'=>array('type'=>'text', 'validate'=>'isinteger'),
+                '["builtsToKeep"]'=>array('type'=>'text', 'validate'=>'isinteger'),
+                '["lang"]'=>array('type'=>'text'),
+            ),
+            'install'=>array(
+                '["installPackages"]["user"]'=>array('type'=>'text'),
+                '["installPackages"]["addkeycommand"]'=>array('type'=>'text'),
+                '["installPackages"]["testcommand"]'=>array('type'=>'text'),
+                '["installPackages"]["command"]'=>array('type'=>'text'),
+            ),
+        );
+        foreach ($aConfig['phases'] as $sPhase => $aPhaseData){
+            $aMapping['phase-'.$sPhase]=array(
+                '["phases"]["'.$sPhase.'"]["css"]["bgdark"]'=>array('type'=>'text'),
+                '["phases"]["'.$sPhase.'"]["css"]["bglight"]'=>array('type'=>'text'),
+                '["phases"]["'.$sPhase.'"]["css"]["bgbutton"]'=>array('type'=>'text'),
+            );
+            /*
+            if (array_key_exists("deploytimes", $aConfig["phases"][$sPhase])){
+                $aMapping['phase-'.$sPhase]['["phases"]["'.$sPhase.'"]["deploytimes"]']=array('type'=>'text');
+            }
+             * 
+             */
+        }
+        
+        $aForms = array(
+            'setup' => array(
+                'meta' => array(
+                    'method' => 'POST',
+                    'action' => '?',
+                ),
+                'validate' => array(),
+                'form' => array(
+                    'input' . $i++ => array(
+                        'type' => 'hidden',
+                        'name' => 'setupaction',
+                        'value' => 'save',
+                    ),
+                ),
+            )
+        );
+        foreach ($aMapping as $sPartname=>$aPartData){
+            
+            // add a headline
+            $aForms['setup']['form']['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => '<h3>'.t('setup-deployment-'.$sPartname).'</h3>',
+            );
+            
+            // add input items
+            foreach ($aPartData as $sName=>$aFormOptions){
+                
+                $sEval='$sCfgVal=$aConfig'.$sName.';';
+                eval($sEval);
+                
+                // checks
+                if (!$sCfgVal){
+                    $sError.='<li>configration variable $sConfig'.$sName.' does not exist.</li>';
+                }
+                // echo $sEval . ' .. ' . $sName . " :: " . $sCfgVar."<br>";
+                $sFormname=str_replace('"', '' , 'aConfig'.$sName);
 
+                
+                $aForms['setup']['form']['input' . $i++] = array(
+                    'value' => '<h3>'.t('setup-deployment-'.$sPartname).'</h3>',
+                    'type' => $aFormOptions['type'],
+                    'name' => $sFormname,
+                    'label' => 'aConfig'.$sName,
+                    'value' => $sCfgVal,
+                    // 'required' => 'required',
+                    'validate' => 'isastring',
+                    'title' => htmlentities($sCfgVal),
+                    'size' => 100,
+                    'placeholder' => htmlentities($sCfgVal),
+                );
+            }
+        }
+        if ($sError){
+            $sOut.=$oPrj->getBox("error", '<ul>'.$sError.'</ul>');
+        } else {
+            $oForm = new formgen($aForms);
+            $sOut.=$oForm->renderHtml("setup");
+        }
+        
+    }
+        
     if (array_key_exists("par3", $aParams)) {
         
         // ------------------------------------------------------------