diff --git a/public_html/deployment/classes/base.class.php b/public_html/deployment/classes/base.class.php
index 0a647f270142ef7d438d24d78bac841bff94d873..cefb6605b88a9ef59a2eb029e0b16410a45f4bce 100644
--- a/public_html/deployment/classes/base.class.php
+++ b/public_html/deployment/classes/base.class.php
@@ -9,6 +9,10 @@ require_once 'user.class.php';
  */
 class base {
 
+    /**
+     * logged in user
+     * @var object
+     */
     var $oUser=false;
     
     /**
diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php
index a78068597744029416475c666b680038e2e74a53..818cb762188ab2781f428479564783ac2ce12ec6 100644
--- a/public_html/deployment/classes/project.class.php
+++ b/public_html/deployment/classes/project.class.php
@@ -5,7 +5,7 @@ define("OPTION_NONE", -1);
 
 require_once __DIR__.'/../inc_functions.php';
 require_once 'base.class.php';
-require_once 'htmlguielements.class.php';
+
 require_once 'messenger.class.php';
 
 // plugins
@@ -38,43 +38,37 @@ class project extends base {
      * configuration ($aConfig in the config file)
      * @var array
      */
-    private $_aConfig = array();
+    protected $_aConfig = array();
 
     /**
      * configuration of the project (= $aProjects[ID] in the config file)
      * @var array
      */
-    private $_aPrjConfig = array();
+    protected $_aPrjConfig = array();
 
     /**
      * version infos of all phases
      * @var array
      */
-    private $_aData = array();
-
-    /**
-     * existing branches and tags
-     * @var array
-     */
-    private $_aVcsBranches = array();
+    protected $_aData = array();
 
     /**
      * existing versions in the archive dir
      * @var array
      */
-    private $_aVersions = array();
+    protected $_aVersions = array();
 
     /**
      * output file to fetch processing content with ajax request
      * @var string
      */
-    private $_sProcessTempOut = false;
+    protected $_sProcessTempOut = false;
 
     /**
      * places of version infos in each deployment phase
      * @var array 
      */
-    private $_aPlaces = array(
+    protected $_aPlaces = array(
         "onhold" => "Queue",
         "ready2install" => "Puppet",
         "deployed" => "Installiert",
@@ -84,7 +78,7 @@ class project extends base {
      * collector for returncodes of multiple exec calls
      * @var int
      */
-    private $_iRcAll = 0;
+    protected $_iRcAll = 0;
 
         
     /**
@@ -97,7 +91,7 @@ class project extends base {
      * object to access a version control, .e. git
      * @var object
      */
-    private $_oVcs = false;
+    protected $_oVcs = false;
     
     /**
      * object for rollout
@@ -105,7 +99,7 @@ class project extends base {
      */
     public $oRolloutPlugin = false;
     
-    private $_sBranchname = false;
+    protected $_sBranchname = false;
     
     /**
      * send messages
@@ -146,7 +140,7 @@ class project extends base {
      * @param  string $sLevel    warnlevel of the given message
      * @return bool
      */
-    private function log($sMessage, $sLevel = "info") {
+    protected function log($sMessage, $sLevel = "info") {
         global $oCLog;
         return $oCLog->add(basename(__FILE__) . " class " . __CLASS__ . " - " . $sMessage, $sLevel);
     }
@@ -156,7 +150,7 @@ class project extends base {
      * @param string $sMessage
      * @return boolean
      */
-    private function _sendMessage($sMessage){
+    protected function _sendMessage($sMessage){
         $aConfig=array();
         
         if (array_key_exists('messenger', $this->_aPrjConfig)
@@ -207,7 +201,7 @@ class project extends base {
      * read default config file
      * @return boolean
      */
-    private function _readConfig() {
+    protected function _readConfig() {
         global $aConfig;
         $this->_aConfig = $aConfig;
         return true;
@@ -217,7 +211,7 @@ class project extends base {
      * validate config data
      * @return boolean
      */
-    private function _verifyConfig() {
+    protected function _verifyConfig() {
         if (!is_array($this->_aPrjConfig) || !count($this->_aPrjConfig)){
             // die(t("class-project-error-no-config"));
             throw new Exception(t("class-project-error-no-config"));
@@ -273,7 +267,7 @@ class project extends base {
      * @param string $sCommand
      * @return string
      */
-    private function _execAndSend($sCommand, $bFlush = false) {
+    protected function _execAndSend($sCommand, $bFlush = false) {
         $this->log(__FUNCTION__ . " start");
         $sReturn = '';
         $bUseHtml = $_SERVER ? true : false;
@@ -354,7 +348,7 @@ class project extends base {
      * @param string $sAction     project action
      * @param string $sLoglevel   loglevel
      */
-    private function _logaction($sMessage, $sAction = "", $sLoglevel = "info") {
+    protected function _logaction($sMessage, $sAction = "", $sLoglevel = "info") {
         require_once("actionlog.class.php");
         $oLog = new Actionlog($this->_aConfig["id"]);
         $oLog->add($sMessage, (__CLASS__ . "->" . $sAction), $sLoglevel);
@@ -364,7 +358,7 @@ class project extends base {
     // GETTER
     // ----------------------------------------------------------------------
 
-    private function _getConfigFile($sId) {
+    protected function _getConfigFile($sId) {
         if (!$sId) {
             die(t("class-project-error-_getConfigFile-requires-id"));
         }
@@ -375,7 +369,7 @@ class project extends base {
      * get a full ath for temp directory (for a build)
      * @return string
      */
-    private function _getTempDir() {
+    protected function _getTempDir() {
         return $s = $this->_getBuildDir() . '/' . $this->_aPrjConfig["fileprefix"] . "_" . date("Ymd-His");
     }
 
@@ -383,7 +377,7 @@ class project extends base {
      * get full path where the project builds are (a build setes a subdir)
      * @return string
      */
-    private function _getBuildDir() {
+    protected function _getBuildDir() {
         return $this->_aConfig['buildDir'] . '/' . $this->_aConfig["id"];
     }
 
@@ -391,7 +385,7 @@ class project extends base {
      * get full path where the project default files are
      * @return type
      */
-    private function _getDefaultsDir() {
+    protected function _getDefaultsDir() {
         $s = $this->_aConfig['buildDefaultsDir'] . '/' . $this->_aConfig["id"];
         return file_exists($s) ? $s : false;
     }
@@ -402,7 +396,7 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    private function _getFileBase($sPhase, $sPlace) {
+    protected function _getFileBase($sPhase, $sPlace) {
         if (!array_key_exists($sPhase, $this->_aConfig["phases"])) {
             die(sprintf(t("class-project-error-wrong-phase"), $sPhase));
         }
@@ -441,7 +435,7 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    private function _getInfofile($sPhase, $sPlace) {
+    protected function _getInfofile($sPhase, $sPlace) {
         $sBase = $this->_getFileBase($sPhase, $sPlace);
         return $sBase ? $sBase . '/' . $this->_aPrjConfig["fileprefix"] . '.json' : false;
     }
@@ -452,7 +446,7 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    private function _getPackagefile($sPhase, $sPlace) {
+    protected function _getPackagefile($sPhase, $sPlace) {
         $sBase = $this->_getFileBase($sPhase, $sPlace);
         return $sBase ? $sBase . '/' . $this->_aPrjConfig["fileprefix"] : false;
     }
@@ -556,7 +550,7 @@ class project extends base {
      * @param string $sVersion  version number of the build
      * @return string
      */
-    private function _getArchiveDir($sVersion) {
+    protected function _getArchiveDir($sVersion) {
         if (!$sVersion) {
             die(t("class-project-error-_getArchiveDir-requires-id"));
         }
@@ -571,7 +565,7 @@ class project extends base {
      * @param type $sTimestamp
      * @return array
      */
-    private function _getArchiveInfos($sTimestamp) {
+    protected function _getArchiveInfos($sTimestamp) {
         if (!$sTimestamp) {
             die(t("class-project-error-_getArchiveInfos-requires-id"));
         }
@@ -610,6 +604,7 @@ class project extends base {
     }
 
     /**
+     * TODO: REMOVE
      * make an http get request and return the response body
      * @param string $url
      * @return string
@@ -696,7 +691,7 @@ class project extends base {
      * and a rollback ist possible or not
      * return array
      */
-    private function _getVersionUsage() {
+    protected function _getVersionUsage() {
         $aVersionData = array();
         $sLastVersion = false;
         if (!count($this->getVersions())) {
@@ -743,10 +738,10 @@ class project extends base {
 
     /**
      * recursive delete 
-     * @param type $dir
+     * @param string $dir  directory to delete
      * @return type
      */
-    private function _rmdir($dir) {
+    protected function _rmdir($dir) {
         foreach (scandir($dir) as $sEntry) {
             if (is_dir($dir . '/' . $sEntry) && $sEntry != '.' && $sEntry != '..') {
                 $this->_rmdir($dir . '/' . $sEntry);
@@ -1205,7 +1200,7 @@ class project extends base {
     /**
      * get list of remote branches and tags
      * @param bool $bIgnoreCache  flag to ignore exiting cached data
-     * @return string|boolean
+     * @return array|boolean
      */
     public function getRemoteBranches($bIgnoreCache=false) {
         $this->log(__FUNCTION__ . "($bIgnoreCache) start");
@@ -1220,95 +1215,7 @@ class project extends base {
         return false;
     }
 
-    /**
-      }
-     * get html form with selectr for remote branches
-     * @param string $sActiveBranchname  force active branch name
-     * @param bool $bIgnoreCache  flag to ignore exiting cached data
-     * @return string
-     */
-    public function renderSelectRemoteBranches($sActiveBranchname = false, $bIgnoreCache=false) {
-        $this->log(__FUNCTION__."(sActiveBranchname = $sActiveBranchname, bIgnoreCache = ".($bIgnoreCache ? 'true' : 'false').") start");
-        $aReturn = array();
-        $aRadios = array();
-        $bFoundActive = false;
-        $i = 0;
-        if (!$this->_oVcs) {
-            $this->_initVcs();
-        }
-        require_once("formgen.class.php");
-        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($bIgnoreCache) as $aBranch) {
-                $sBranch = $aBranch['name'];
-                $aRadios[$sBranch] = array(
-                    'value' => $sBranch,
-                    'label' => $aBranch['label'],
-                );
-                // if no param was given the first branch will be marked
-                if (!$sActiveBranchname) {
-                    $sActiveBranchname = $sBranch;
-                }
-                if ($sBranch == $sActiveBranchname) {
-                    $bFoundActive = true;
-                    // $aRadios[$sBranch]['checked'] = 'checked';
-                    $aRadios[$sBranch]['selected'] = 'selected';
-                } else {
-                    // for SELECT we need the onclick even on select element
-                    // not on the option (Chrome)
-                    // $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(
-                        'inline' => true,
-                        'type' => 'select',
-                        'onchange' => 'document.getElementById(\'submitBranch\').click()',
-                        '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',
-                'onclick' => 'showModalMessage(\'' . t('branch-switch') . '\'); ',
-                'label' => t("change"),
-                'value' => $this->_oHtml->getIcon('sign-ok').t("change"),
-            );
-        }
 
-        $oFrm = new formgen($aForms);
-        return $oFrm->renderHtml('frmSelectBranch')
-                . '<script>$("#submitBranch").hide();</script>';
-        // return $oFrm->renderHtmlElement('dummy',$aFormData);
-    }
 
     /**
      * get current revision and log message from remote repo
@@ -1337,7 +1244,7 @@ class project extends base {
      * init version control system (git, ...)
      * @return vcs-object
      */
-    private function _initVcs() {
+    protected function _initVcs() {
         $this->log(__FUNCTION__ . " start");
         if (!$this->_oVcs) {
             if (!$this->_aPrjConfig["build"]["type"]) {
@@ -1396,7 +1303,7 @@ class project extends base {
      * get a flat array of all existing ssh keys
      * @return array
      */
-    private function _getSshKeys() {
+    protected function _getSshKeys() {
         $aReturn = array();
         foreach (glob($this->_aConfig["dataDir"] . "/sshkeys/*.pub") as $filename) {
             $aReturn[] = str_replace(".pub", "", basename($filename));
@@ -1410,7 +1317,7 @@ class project extends base {
      * @param string $sPhase  phase
      * @return array
      */
-    private function _getDeploytimes($sPhase) {
+    protected function _getDeploytimes($sPhase) {
         if (!$this->isActivePhase($sPhase)) {
             $sError = sprintf(t("class-project-warning-phase-not-active"), $sPhase);
             $this->_logaction($sError, __FUNCTION__, "error");
@@ -1431,7 +1338,7 @@ class project extends base {
     // SETTER
     // ----------------------------------------------------------------------
 
-    private function _setProcessOutFile($sNewTempfile = false) {
+    protected function _setProcessOutFile($sNewTempfile = false) {
         if ($this->_sProcessTempOut && file_exists($this->_sProcessTempOut)) {
             unlink($this->_sProcessTempOut);
         }
@@ -1446,7 +1353,7 @@ class project extends base {
      * 
      * @return array
      */
-    private function _ldapProjectSearch($sSearchFilter) {
+    protected function _ldapProjectSearch($sSearchFilter) {
         $aReturn = array();
         require_once("ldap.class.php");
         $oLdapIML = new imlldap($this->_aConfig['projects']['ldap']);
@@ -1576,7 +1483,7 @@ class project extends base {
      * @param type $sData
      * @return boolean
      */
-    private function _TempFill($sData, $aActions = array()) {
+    protected function _TempFill($sData, $aActions = array()) {
         if (!$this->_sProcessTempOut) {
             return false;
         }
@@ -1607,7 +1514,7 @@ class project extends base {
      * @param string  $sTempDir  optional; target dir to copy; default=false (=delete file)
      * @return boolean
      */
-    private function _TempDelete($sTempDir=false) {
+    protected function _TempDelete($sTempDir=false) {
         if (!$this->_sProcessTempOut){
             return false;
         }
@@ -2595,1641 +2502,5 @@ class project extends base {
         return false;
     }
 
-    // ----------------------------------------------------------------------
-    // RENDERING
-    // ----------------------------------------------------------------------
-
-    /**
-     * return html code for a div with background color based on a checksum of the given text
-     * @param string $sText      text that is used for checksum; if false ist returns a gray
-     * @param string $sContent   optional: text to show
-     * @return string
-     */
-    private function _getChecksumDiv($sText, $sContent='') {
-        if ($sText){
-            
-            // color ranges in decimal values for RGB from ... to
-            $iFgStart=60;  $iFgEnd=160;
-            $iBgStart=200; $iBgEnd=250;
-
-            // deivider: 3 digits of md5 will be extracted
-            $iFgDivider=16*16*16/($iFgEnd-$iFgStart);
-            $iBgDivider=16*16*16/($iBgEnd-$iBgStart);
-            
-            $sHash=md5($sText);
-            $sColor=''
-                . 'color: rgba(' 
-                . ($iFgStart + round(hexdec(substr($sHash,0,3))/$iFgDivider)) . ','
-                . ($iFgStart + round(hexdec(substr($sHash,3,3))/$iFgDivider)) . ','
-                . ($iFgStart + round(hexdec(substr($sHash,6,3))/$iFgDivider)) . ','
-                . '1'
-                . ');'
-                . 'background: rgba(' 
-                . ($iBgStart + round(hexdec(substr($sHash,0,3))/$iBgDivider)) . ','
-                . ($iBgStart + round(hexdec(substr($sHash,3,3))/$iBgDivider)) . ','
-                . ($iBgStart + round(hexdec(substr($sHash,6,3))/$iBgDivider)) . ','
-                . '1'
-                . ');'
-                ;
-        } else {
-            $sColor = "color: #888; background: #ccc;";
-        }
-        return '<div style="' . $sColor . '; border-top: 3px solid; ">'.($sContent ? $sContent : ' ').'</div>';
-    }
-
-    /**
-     * generate css color based on a checksum of the given text
-     * @param string $sText text that is used for checksum
-     * @return string 
-     */
-    private function _getChecksumColor($sText, $sFormat = "hex", $fAlpha = 1.0) {
-        $sReturn = '';        
-        if ($sText){
-                $sHash=md5($rssItem["feedtitle"]);
-                $iStartFg=100;
-                $iStartBg=220;
-                $sColor=''
-                        . ''
-                        . 'color: rgba(' 
-                        . ($iStartFg + round(hexdec(substr($sHash,0,2))/4)) . ','
-                        . ($iStartFg + round(hexdec(substr($sHash,2,2))/4)) . ','
-                        . ($iStartFg + round(hexdec(substr($sHash,4,2))/4))
-                        . ');'
-                        . 'background: rgba(' 
-                        . ($iStartBg + round(hexdec(substr($sHash,0,2))/8)) . ','
-                        . ($iStartBg + round(hexdec(substr($sHash,2,2))/8)) . ','
-                        . ($iStartBg + round(hexdec(substr($sHash,4,2))/8))
-                        . ');'
-                        ;
-            
-            $s = md5($sText);
-            $sRH = substr($s, 0, 2);
-            $sGH = substr($s, 2, 2);
-            $sBH = substr($s, 4, 2);
-        } else {
-            $sReturn = "background: #aaaaaa;";
-        }
-        switch ($sFormat) {
-            case "rgba":
-                $sReturn = "background: rgba(" . hexdec($sRH) . ", " . hexdec($sGH) . ", " . hexdec($sBH) . ", " . $fAlpha . ")";
-                break;
-
-            default:
-                $sReturn = "background: #$sRH$sGH$sBH";
-                break;
-        }
-        return $sReturn;
-    }
-
-    /**
-     * get html code for the colored bar on top of each phase detail items
-     * @param string $sPhase  phase of a project
-     * @param string $sPlace  place in the given phase
-     * @return string
-     */
-    private function _renderBar($sPhase, $sPlace) {
-        $aDataPhase = $this->getPhaseInfos($sPhase);
-        $aData = $aDataPhase[$sPlace];
-        if (!array_key_exists("revision", $aData)) {
-            return false;
-        }
-        return $this->_getChecksumDiv($aData["revision"]);
-    }
-
-    private function _renderHostsData($aData) {
-        $sReturn = '';
-        if (array_key_exists('_hosts', $aData)) {
-            
-            // $sReturn.= print_r($aData['_hosts'], 1);
-            $sReturn.= '<div class="hosts">'
-                    . '<br><strong>' . t('hosts') . ':</strong><br>'
-            ;
-            foreach ($aData['_hosts'] as $sHostname => $aHostinfos) {
-                $oUpdateDate = date("U", strtotime($aHostinfos['time']));
-                $iAgeUpdate = round((date("U") - $oUpdateDate) / 60);
-                $sAge = $iAgeUpdate < 60 * 60 * 13 ? $iAgeUpdate . " min" : "??";
-
-                $sReturn.= '<div class="host">'
-                        . $this->_getChecksumDiv(
-                            $aHostinfos['_data']['revision'],
-                            $this->_oHtml->getIcon('host').'<br>' . $sHostname
-                        )
-                        . "($sAge)"
-                        . '</div>'
-                ;
-            }
-            $sReturn.= '</div><div style="clear: both;"></div>';
-        }
-        return $sReturn;
-    }
-
-    /**
-     * get html code for list of hosts in a phase
-     * @param string $sPhase  phase of a project
-     * @return string
-     */
-    private function _renderHosts($sPhase) {
-        $aDataPhase = $this->getPhaseInfos($sPhase);
-        if (is_array($aDataPhase) && array_key_exists('deployed', $aDataPhase)) {
-            return $this->_renderHostsData($aDataPhase['deployed']);
-        }
-        return '';
-    }
-
-    /**
-     * get html code for list of files in a phase
-     * @param string $sPhase  phase of a project
-     * @return string
-     */
-    private function _renderFiles($sPhase) {
-        $sReturn = '';
-        $aFiles = $this->getBuildfilesByPlace($sPhase, 'ready2install');
-        if (!$aFiles || !$aFiles['filecount']) {
-            return '';
-        }
-        $sReturn.='<strong>' . t("filelist") . '</strong> (' . $aFiles['filecount'] . '):<br>';
-        foreach ($aFiles['files'] as $sFilename => $aData) {
-            $sReturn.='<div class="file file-' . $aData['type'] . ' fileext-' . $aData['extension'] . '" title="' . $sFilename . ' (' . $aData['type'] . ')">'
-                    . $aData['icon'] . $sFilename
-                    // . ' ('.$aData['type'].')'
-                    . '</div>'
-            ;
-        }
-        $sReturn.='(' . $aFiles['totalsize-hr'] . ')';
-        return $sReturn;
-    }
-
-    /**
-     * return html code for current project errors by rendering a box per error in $this->_errors
-     * @return string
-     */
-    public function renderErrorBoxes(){
-        $sReturn='';
-        if(count($this->_errors)){
-            foreach($this->_errors as $sError){
-                $sReturn.=$this->_oHtml->getBox("error", $sError);
-            }
-        }
-        return $sReturn;
-    }
-    /**
-     * render html for a colored link to any project action
-     * @param string $sFunction name of the action; one of accept|build|cleanup|deploy|new|overview|phase|rollback|setup
-     * @param string $sPhase    current phase where to place the link
-     * @return string
-     */
-    public function renderLink($sFunction, $sPhase = false, $sVersion = false) {
-        $sFirst = $this->getNextPhase();
-        $sNext = $this->getNextPhase($sPhase);
-        $aLinkdata = array(
-            'default' => array('class' => ''),
-            'accept' => array('class' => $sNext,
-                'hint' => sprintf(t("accept-hint"), $sPhase, $sNext),
-                'label' => t('accept'),
-            ),
-            'build' => array('class' => $sFirst,
-                'hint' => sprintf(t("build-hint"), $sFirst),
-                'label' => t('build'),
-                'role' => 'buildProject'
-            ),
-            'cleanup' => array('class' => ''),
-            'deploy' => array('class' => $sPhase,
-                'hint' => sprintf(t("deploy-hint"), $sPhase),
-                'label' => t('deploy'),
-            ),
-            'new' => array(
-                'hint' => t("new-project-hint"),
-                'label' => t('new-project'),
-            ),
-            'overview' => array('class' => '',
-                'hint' => t('menu-project-home') . ' [' . $this->getLabel() . ']',
-                'label' => $this->getLabel()
-            ),
-            'phase' => array('icon' => $this->_oHtml->getIcon('phase'), 'class' => $sPhase,
-                'hint' => sprintf(t('phase-details-hint'), $sPhase),
-                'label' => t('phase-details')
-            ),
-            'rollback' => array('class' => $sPhase,
-                'hint' => sprintf(t('rollback-hint'), $sPhase, $sVersion),
-                'label' => t('rollback')
-            ),
-            'setup' => array('class' => $sPhase,
-                'hint' => sprintf(t('setup-hint'), $sPhase, $sVersion),
-                'label' => t('setup')
-            ),
-        );
-        /*
-          if (!$this->oUser->hasRole("project-action-$sFunction")){
-          // $sClass .= ' disabled';
-          // return '<span title="no permission [project-action-'.$sFunction.']">[ ]</span>';
-          }
-         * 
-         */
-        // fuer wen ist der Link
-        $sRole = '';
-        $sOnMouseover = '';
-        $sOnMouseout = '';
-        switch($sFunction){
-            case 'accept';
-                $sRole = 'developer';
-                if ($sNext == "live") {
-                    $sRole = 'pl';
-                    // $aLinkdata[$sFunction]['icon']='glyphicon glyphicon-star';
-                }
-                $sOnMouseover = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');';
-                $sOnMouseout = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');';
-                break;
-            case 'build';
-                $sRole = 'developer';
-                $sOnMouseover = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');';
-                $sOnMouseout = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');';
-                break;
-            case 'deploy';
-                $sRole = 'developer';
-                $sOnMouseover = '$(\'.td-phase-' . $sPhase . '.td-place-ready2install.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');'
-                        .'$(\'.td-phase-' . $sPhase . '.td-place-deployed.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');'
-                        ;
-                $sOnMouseout = '$(\'.td-phase-' . $sPhase . '.td-place-ready2install.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');'
-                        .'$(\'.td-phase-' . $sPhase . '.td-place-deployed.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');'
-                        ;
-                break;
-        }
-
-        // $sClass = $sPhase;
-        $sIconClass = (array_key_exists($sFunction, $aLinkdata)) ? $aLinkdata[$sFunction]['icon'] : $aLinkdata['default']['icon'];
-        $sHint = (
-                array_key_exists($sFunction, $aLinkdata) && array_key_exists("hint", $aLinkdata[$sFunction])
-                ) ? $aLinkdata[$sFunction]['hint'] : "";
-        $sLabel = (
-                array_key_exists($sFunction, $aLinkdata) && array_key_exists("label", $aLinkdata[$sFunction])
-                ) ? $aLinkdata[$sFunction]['label'] : $sFunction;
-        $sClass = (
-                array_key_exists($sFunction, $aLinkdata) && array_key_exists("class", $aLinkdata[$sFunction])
-                ) ? $aLinkdata[$sFunction]['class'] : '';
-        if ($sRole) {
-            $sClass .= " role role" . $sRole;
-        }
-
-        $sLink = "/deployment/" . ($this->_aConfig["id"] ? $this->_aConfig["id"] : 'all/setup') . "/";
-        if ($sFunction != "overview") {
-            $sLink.="$sFunction/";
-        }
-        if ($sPhase) {
-            $sLink.="$sPhase/";
-        }
-        if ($sVersion) {
-            $sLink.="$sVersion/";
-        }
-        if (!$this->oUser->hasPermission("project-action-$sFunction")) {
-            // $sClass .= ' disabled';
-            return '<span class="btn disabled btn-default" title="no permission [project-action-' . $sFunction . '] for user [' . $this->oUser->getUsername() . ']"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</span>';
-        }
-
-        return $this->_oHtml->getLinkButton(array(
-                    'href' => $sLink,
-                    'title' => $sHint,
-                    'class' => 'btn btn-default ' . $sClass,
-                    'type' => $sFunction,
-                    'onmouseover' => $sOnMouseover,
-                    'onmouseout' => $sOnMouseout,
-                    'label' => $sLabel,
-        ));
-        // return '<a href="' . $sLink . '" ' . $sOnMouseover . ' title="' . $sHint . '" class="btn  btn-default ' . $sClass . '"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</a>';
-    }
-
-    /**
-     * render html for the project overview; it shows the defined phases for 
-     * the project as a table
-     * @return type
-     */
-    public function renderPhaseInfo() {
-        $sRow1 = false;
-        $sRow2 = false;
-        foreach ($this->getActivePhases() as $sPhase) {
-            $sRow1.='<th class="' . $sPhase . '">' . $sPhase . '</th>';
-            $sRow2.='<td class="' . $sPhase . '">'
-                    . t('url') . ': <a href="' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '">' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '</a><br>'
-                    . '<br>' . t('deploytimes') . ':<br>';
-            if (count($this->_getDeploytimes($sPhase))) {
-                $sRow2.=implode("<br>", $this->_getDeploytimes($sPhase));
-            } else {
-                $sRow2.=t('deploytimes-immediately');
-            }
-            $sRow2.='<br>' . $this->renderLink("phase", $sPhase)
-                    . $this->_renderHosts($sPhase)
-                    . '<br>'
-                    . $this->_renderFiles($sPhase)
-                    . '</td>';
-        }
-        return '<table><thead><tr>' . $sRow1 . '</tr></thead><tbody><tr>' . $sRow2 . '</tr></tbody></table>';
-    }
-
-    /**
-     * render html for a place of a phase
-     * @param string  $sPhase    phase
-     * @param string  $sPlace    name of the place; one of onhold|ready2install|deployed
-     * @param bool    $bActions  draw action links (deploy, accept) on/ off
-     * @param bool    $bLong     use long variant to display infos? 
-     * @return string|boolean
-     */
-    public function renderPhaseDetail($sPhase, $sPlace, $bActions = true, $bLong = true) {
-
-        if (!$sPhase) {
-            return false;
-        }
-        if (!$sPlace) {
-            return false;
-        }
-        if (!$this->isActivePhase($sPhase)) {
-            return false;
-        }
-        if (!array_key_exists($sPlace, $this->_aPlaces)) {
-            return false;
-        }
-
-        $sReturn = false;
-        $aDataPhase = $this->getPhaseInfos($sPhase);
-        $aData = $aDataPhase[$sPlace];
-        // foreach($aDataPhase[$sPlace] as $aData) {
-        if (array_key_exists("ok", $aData) && array_key_exists("version", $aData)) {
-            // TODO: getChecksumDiv anhand der Repo-Versionsnummer - dann kann man beim build auch die Farbe mit dem Repo HEAD vergleichen
-            // time
-            $sDateFormat = "d.m.Y H:i";
-            $oPkgDate = date("U", strtotime($aData["date"]));
-            /*
-              $iAge=date("U")-$oPkgDate;
-              $sAgeClass="";
-              if ($iAge< 60*60*24*3){
-              $sAgeClass="last1d";
-              }
-              if ($iAge< 60*60){
-              $sAgeClass="last1h";
-              }
-             */
-
-            if ($bLong) {
-                // long display of the revision
-                // $sJsonUrl = $this->_getInfofile($sPhase, $sPlace);
-                    $sReturn .=$this->_getChecksumDiv(
-                        $aData["revision"], 
-                        $this->_oHtml->getIconByType('calendar') .' ' . date($sDateFormat, $oPkgDate)
-                        . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aData["branch"] . '<br>'
-                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aData["revision"]) . '<br>'
-                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ':<br>'
-                    )
-                    . '<pre>' . strip_tags($aData["message"], '<br>') . '</pre>'
-                // . '<i class="glyphicon glyphicon-globe"></i> ' . t('url') . ': <a href="' . $sJsonUrl . '">' . $sJsonUrl . '</a><br>'
-                ;
-                if ($sPlace == "deployed" && array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase])) {
-                    $sUrl = $this->_aPrjConfig["phases"][$sPhase]["url"];
-                    $sReturn.=$this->_oHtml->getIconByType('link-extern') . ' '. t('url') . ': <a href="' . $sUrl . '">' . $sUrl . '</a><br>';
-                }
-            } else {
-                $sReturn .= $this->_getChecksumDiv(
-                            $aData["revision"], 
-                            $this->_oHtml->getIconByType('calendar') .' ' . date($sDateFormat, $oPkgDate)
-                    );
-                if ($sPlace == "deployed" && array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase])) {
-                    $sMore = $this->_oHtml->getIconByType('link-extern').' '
-                            . t('url')
-                            . ': <a href="' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '">' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '</a><br>';
-                }
-
-                $sReturn.=' ' . $this->renderInfoLink(
-                                $aData, array(
-                            'title' => $this->getLabel() . " :: $sPhase :: $sPlace",
-                            'more' => $sMore,
-                                )
-                );
-            }
-
-            switch ($sPlace) {
-                case "onhold":
-                    if (array_key_exists("phases", $this->_aConfig) && array_key_exists($sPhase, $this->_aConfig["phases"])) {
-                        // $sReturn .= print_r($this->_aConfig["phases"][$sPhase], true);
-                        if (count($this->_getDeploytimes($sPhase))) {
-                            $sReturn .= '<br>'.$this->_oHtml->getIcon('time').t('deploytimes') . ':<br>'
-                                    . implode("<br>", array_values($this->_getDeploytimes($sPhase)))
-                                    . '<br>';
-                        }
-                        if ($bActions) {
-                            $sReturn .= ' ' . $this->renderLink("deploy", $sPhase);
-                        }
-                    }
-                    break;
-
-                case "ready2install":
-                    break;
-
-                case "deployed":
-                    if ($bActions && $this->canAcceptPhase($sPhase)) {
-                        $sReturn .= ' ' . $this->renderLink("accept", $sPhase);
-                    }
-                    break;
-                default:
-                    break;
-            }
-            // $this->_getChecksumDiv($aData["revision"])
-        } else {
-            if (array_key_exists("error", $aData)) {
-                $sReturn.=''
-                        . $this->renderInfoLink(array('error' => $aData["error"]), array())
-                ;
-            } else if (array_key_exists("warning", $aData)) {
-                $sReturn.= '<div class="warning">'.$this->_oHtml->getIcon('sign-info'). t('warning') . ':<br>' . $aData["warning"] . '</div>';
-            } else {
-                return false;
-                // $sReturn.= t('empty');
-            }
-        } // if
-        // } // for
-        return $sReturn;
-    }
-
-    /**
-     * render html for a row with td for all places (first row)
-     * @param string $sPhase  phase (just needed for coloring)
-     * @return string
-     */
-    public function renderPlacesAsTd($sPhase) {
-        $sRow1 = '';
-        foreach (array_keys($this->_aPlaces) as $sPlace) {
-            $sRow1.='<td class="' . $sPhase . ' ' . $this->_aConfig["id"] . ' tdphase">' . t($sPlace) . '</td>';
-        }
-        return $sRow1;
-    }
-
-    /**
-     * render html for a row with td for all places of a phase
-     * @param string $sPhase   phase
-     * @param bool   $bActions draw action links (deploy, accept) on/ off
-     * @param bool   $bLong    use long variant to display infos? 
-     * @return string|boolean
-     */
-    public function renderAllPhaseDetails($sPhase, $bActions = true, $bLong = true) {
-        if (!$sPhase) {
-            return false;
-        }
-        if (!$this->isActivePhase($sPhase)) {
-            return '
-                        <td class="td-phase-' . $sPhase . ' td-phase-inactive ' . $this->_aConfig["id"] . '" colspan="' . count($this->_aPlaces) . '">
-                            <div class="versioninfo center inactive">' . $this->_oHtml->getIcon('sign-info').t('inactive') . '</div>
-                        </td>';
-        }
-        $sRow2 = false;
-
-        $aRows = array();
-        $sLastPlace = '';
-        
-        foreach (array_keys($this->_aPlaces) as $sPlace) {
-            $aRows[$sPlace] = $this->renderPhaseDetail($sPhase, $sPlace, $bActions, $bLong);
-            
-            // generate ">>" sign for lastly generated td
-            if ($sLastPlace && array_key_exists("version", $this->_aData["phases"][$sPhase][$sLastPlace]) 
-                    && array_key_exists("version", $this->_aData["phases"][$sPhase][$sPlace]) 
-                    && $this->_aData["phases"][$sPhase][$sLastPlace]["version"] == $this->_aData["phases"][$sPhase][$sPlace]["version"] 
-                    && !$bLong
-            ) {
-                $aRows[$sLastPlace] = $this->_renderBar($sPhase, $sPlace) . "&raquo;";
-            }
-            $sLastPlace = $sPlace;
-        }
-        
-        foreach (array_keys($this->_aPlaces) as $sPlace) {
-            $sRow2.='<td class=" td-phase-'.$sPhase.' td-place-'.$sPlace.' td' . $this->_aConfig["id"] . '">' . $aRows[$sPlace] . '</td>';
-        }
-        return $sRow2;
-    }
-
-    /**
-     * return html code for the installed version in the repository
-     * @param boolean  $bRefresh  optional: refresh flag; default: use cached information
-     * @return string
-     */
-    public function renderRepoInfo($bRefresh=false) {
-        $sReturn = "";
-        switch ($this->_aPrjConfig["build"]["type"]) {
-            case "git":
-
-                $aRepodata = $this->getRepoRevision($bRefresh);
-                if (array_key_exists("revision", $aRepodata)) {
-                    $sReturn.=$this->_getChecksumDiv($aRepodata["revision"],
-                        $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . (array_key_exists("branch", $aRepodata) ? $aRepodata["branch"] : '-') . '<br>'
-                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aRepodata["revision"]) . '<br>'
-                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ':<br>'
-                        )
-                        ."<pre>" . strip_tags($aRepodata["message"], '<br>') . "</pre>";
-                } else {
-                    $sReturn .= $this->_oHtml->getBox("error", sprintf(t('class-project-error-no-repoinfo'), $aRepodata["error"]))
-                            . $this->renderLink("setup") . '<br>';
-                }
-
-                break;
-
-            default:
-                $sReturn .= $this->_oHtml->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.=t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>';
-        }
-        return $sReturn;
-    }
-
-    /**
-     * get html code for a link to the commit
-     * (works for guithub and gitlab instances)
-     * 
-     * @param string $sRevision
-     * @return string
-     */
-    public function _renderRevision($sRevision) {
-        $sUrl = str_replace('/tree/master', '', $this->_aPrjConfig["build"]["webaccess"]) . '/commit/' . $sRevision;
-        return '<a href="' . $sUrl . '">' . $sRevision . '</a>';
-        return $sUrl;
-    }
-
-    /**
-     * render html code for info link that shows popup with metadata on mouseover
-     * @param array $aInfos   metainfos of the package (from json file)
-     * @param array $aOptions options
-     *                   title - tile in popover; default: empty
-     *                   label - link label; default: empty (results in Infos|ERROR)
-     *                   more  - additional infos in popover; default: empty
-     *                   hpos  - horizontal position; one of left|right; default: right
-     * @return string
-     */
-    public function renderInfoLink($aInfos, $aOptions = array()) {
-        $sReturn = '';
-        $bIsError = false;
-        $this->_oHtml = new htmlguielements();
-
-        $sInfos='';
-        $sTitle='';
-        if (array_key_exists("title", $aOptions) && $aOptions["title"]) {
-            $sTitle.=$aOptions["title"];
-        }
-        if (array_key_exists("ok", $aInfos)) {
-            $sLinktitle = t('infos');
-            if (array_key_exists("message", $aInfos)) {
-                $sInfos.=$this->_getChecksumDiv($aInfos["revision"],
-                        $this->_oHtml->getIconByType('calendar') . t('build-from') . ' ' . date("d.m.Y H:i:s", strtotime($aInfos["date"])) . '<br>'
-                        . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aInfos["branch"] . '<br>'
-                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aInfos["revision"]) . '<br>'
-                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ': '
-                        )
-                        . '<pre>' . strip_tags($aInfos["message"], '<br>') . '</pre>';
-                if (array_key_exists("more", $aOptions)) {
-                    $sInfos.=$aOptions["more"];
-                }
-            }
-        } else {
-            $bIsError = true;
-            if (!$sTitle) {
-                $sTitle.=' ' . t('error');
-            }
-            $sLinktitle = t('error');
-            $sInfos = $aInfos["error"];
-        }
-        $sInfos.=$this->_renderHostsData($aInfos);
-
-        if (array_key_exists("label", $aOptions) && $aOptions["label"]) {
-            $sLinktitle.=$aOptions["label"];
-        }
-
-        // render html
-        $sId = 'info' . md5($sInfos);
-        $sReturn = '<a href="#" class="btn ' . ($bIsError ? 'btn-danger' : 'btn-default') . '" title="" onclick="showIdAsModalMessage(\'' . $sId . '\'); return false;">'
-                // . '<i class="fa fa-info"></i> '
-                . $sLinktitle
-                . '</a><div id="' . $sId . '" style="display: none;" ';
-        if (array_key_exists("hpos", $aOptions)) {
-            $sReturn.=' class="' . $aOptions["hpos"] . '"';
-        }
-        $sReturn.='>';
-
-        if ($sTitle) {
-            $sReturn.='<span class="title">' . $sTitle . '</span><br><br>';
-        }
-
-        $sReturn.=$sInfos . '</div>';
-
-        if ($bIsError) {
-            // $sReturn = '<div class="error">' . $sReturn . '</div>';
-        }
-
-        return $sReturn;
-    }
-
-    /**
-     * return html code for a list of all built packages and their usage
-     * @return string
-     */
-    public function renderVersionUsage() {
-        $sReturn = false;
-        $sRowHead1 = false;
-        $sRowHead2 = '<td></td>';
-
-        $aAllVersions = $this->_getVersionUsage();
-        if (!count($aAllVersions)) {
-            return $this->_oHtml->getBox("info", t('class-project-info-no-package'));
-        }
-
-        foreach ($this->getActivePhases() as $sPhase) {
-            $sRowHead1.='<th class="' . $sPhase . '" colspan="' . (count($this->_aPlaces) + 1) . '">' . $sPhase . '</th>';
-            $sRowHead2.='<td></td>' . $this->renderPlacesAsTd($sPhase);
-        }
-        
-        krsort($aAllVersions);
-        foreach ($aAllVersions as $sVersion => $aData) {
-            $sReturn.='<tr>';
-
-            $sInfos = $this->renderInfoLink($aData["info"], array('hpos' => 'left'));
-            $sReturn.='<td>'
-                        . $this->_getChecksumDiv(
-                            $aData['info']['revision'],
-                            $this->_oHtml->getIconByType('calendar') . t('build-from') . ': ' . $sVersion .'<br>'
-                                . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aData['info']["branch"] . '<br>'
-                                . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aData['info']["revision"]) . '<br>'
-                          )
-                    . '</td><td>'
-                    . '&nbsp;&nbsp;' . $sInfos . '&nbsp;&nbsp;'
-                    . '</td>'
-                    ;
-
-            foreach ($this->getActivePhases() as $sPhase) {
-                $sTLine = '';
-                $bCanRollback = $aData["rollback"][$sPhase];
-
-                // $sReturn.=$aData["rollback"][$sPhase] ? '<td>'.$this->renderLink("rollback", $sPhase, $sVersion).'</td>' : '<td>Rollback NOT possible</td>';
-                // $sReturn.=$aData["rollback"][$sPhase] ? '<td> Y </td>' : '<td> N </td>';
-                $sReturn.='<td>  </td>';
-
-                foreach (array_keys($this->_aPlaces) as $sPlace) {
-                    $bFound = false;
-                    $sReturn.=$aData["usage"][$sPhase][$sPlace] 
-                            ? '<td class="' . $sPhase . '" style="text-align: center;">'
-                            . $this->_getChecksumDiv($aData['info']['revision'], 'X')
-                            . '</td>' 
-                            : '<td> </td>'
-                        ;
-                }
-            }
-            $sReturn.='</tr>';
-        }
-
-        $sReturn = t('class-project-info-table-packages') . '<br><br>'
-                . '<table>'
-                . '<thead><tr><td>Version</td><td></td>'
-                . $sRowHead1
-                . '</tr><tr><td>'
-                . $sRowHead2
-                . '</tr></thead>'
-                . '<tbody>'
-                . $sReturn
-                . '</tbody>'
-                . '</table>';
-        return $sReturn;
-    }
-
-    /**
-     * render graphical overview of process (in project overview)
-     * @return string
-     */
-    public function renderVisual() {
-        $sReturn = '';
-        $sContinue = '<span style="font-size: 300%; color:#ace;">&raquo;&raquo;</span><br><br>';
-
-        $aBranches=$this->getRemoteBranches();
-        if(!is_array($aBranches)){
-            return t("project-setup-incomplete");
-        }
-
-        $sRepoBar = '';
-        /*
-            Speedup:
-            
-        $aRepodata = $this->getRepoRevision();
-        if (array_key_exists("revision", $aRepodata)) {
-            $sRepoBar = $this->_getChecksumDiv($aRepodata["revision"]);
-        } else {
-            $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>';
-        }
-
-        $sPhaseImg = '';
-        $sLastPhase = '';
-        foreach ($this->getActivePhases() as $sPhase) {
-            if ($sPhaseImg) {
-                $sAction = $sContinue;
-                if ($this->canAcceptPhase($sLastPhase)) {
-                    $sAction .= $this->renderLink("accept", $sLastPhase);
-                }
-                $sPhaseImg.='<div class="action">' . $sAction . '</div>';
-            }
-            $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>';
-            }
-            // $sDetail = $sFullbar . '<br><a href="#h3phases" class="scroll-link">' . $sPhase . '</a>';
-            $sDetail = $sFullbar . '<br>' . $sPhase;
-
-            $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>';
-        }
-            $sReturn = '
-            <div class="visualprocess">
-                <div class="process box">
-                    <div class="title">' . $this->_oHtml->getIcon('repository') . t("versioncontrol") . '</div>
-                    <div class="details">
-                        ' . $sRepoBar . '<br>
-                        <!--
-                        <a href="#h3repo" class="scroll-link">' . t("repositoryinfos") . '</a><br>
-                        -->
-                        ' . t("repositoryinfos") . '<br>
-                        ' . $this->_aPrjConfig["build"]["type"] . '</strong> ' . preg_replace('/.*\@(.*):.*/', '($1)', $this->_aPrjConfig["build"]["url"])
-                        . ': <strong title="' . t('branch-select') . '">' . count($aBranches) . '</strong>'
-                    . '<br>
-                    </div>
-                    <div>
-                        <img src="/deployment/images/process/bg_vcs.png" alt="' . t("versioncontrol") . '">
-                    </div>
-                </div>
-                
-                <div class="process">
-                    <div class="title">&nbsp;</div>
-                    <div class="action">' . $sContinue . t("build-hint-overview") . '<br><br>' . ($this->canAcceptPhase() ? $this->renderLink("build") : '') . '</div>
-                </div>
-
-                
-                <div class="process box">
-                    <div class="title">' . $this->_oHtml->getIcon('package') . t("archive") . '</div>
-                    <div class="details">
-                        ' . $sPackagebar . '<br>
-                        <!--
-                        <a href="#h3versions" class="scroll-link">' . t("packages") . '</a><br>
-                        -->
-                        ' . t("packages") . '<br>
-                        (<strong>' . count($this->_getVersionUsage()) . '</strong>)
-                    </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 . sprintf(t("queue-hint-overview"), $this->getNextPhase()).'</div>
-                </div>
-                
-                <div class="process phases box">
-                    <div class="title">'  . $this->_oHtml->getIcon('phase') . t("phases") . '</div>
-                    ' . ($sPhaseImg ? $sPhaseImg : '<div class="process">' . t("none") . '</div>') . '
-                </div>
-            </div>
-            ';
-        
-        return $sReturn;
-    }
-
-    /**
-     * return html code for the setup form of an exsiting project
-     * @return string
-     */
-    public function renderProjectSetup() {
-        if (!$this->oUser->hasPermission("project-action-setup")) {
-            return $this->oUser->showDenied();
-        }
-        $sMessages = '';
-        require_once ("formgen.class.php");
-
-
-            $aSelectProjectGroup = array(
-                'type' => 'select',
-                'name' => 'projectgroup',
-                'label' => t("projectgroup"),
-                'options' => array(
-                    OPTION_NONE => array(
-                        'label' => t('none'),
-                    ),
-                    '' => array(
-                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
-                    ),
-                ),
-            );
-            foreach($this->_aConfig['projectgroups'] as $sGroupid=>$sGroupLabel){
-                $bActive=$this->getProjectGroup() === $sGroupid;
-                $aSelectProjectGroup['options'][$sGroupid] = array(
-                    'label' => $sGroupLabel,
-                    'selected' => $bActive ? 'selected' : false,
-                );
-            }
-            
-        $aSelectSlack = array(
-                'type' => 'hidden',
-                'name' => 'messenger[slack]',
-                'value' => false,
-        );
-        if (
-                isset($this->_aConfig['messenger']['slack']['presets'])
-                && count($this->_aConfig['messenger']['slack']['presets'])
-        ) {
-            $aSelectSlack = array(
-                'type' => 'select',
-                'name' => 'messenger[slack]',
-                'label' => t("messenger-slack"),
-                'options' => array(
-                    OPTION_NONE => array(
-                        'label' => t('none'),
-                    ),
-                    '' => array(
-                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
-                    ),
-                ),
-            );
-            foreach($this->_aConfig['messenger']['slack']['presets'] as $sSlackUrl=>$aSlackCfg){
-                $bActive=$this->_aPrjConfig['messenger']['slack'] === $sSlackUrl;
-                $aSelectSlack['options'][$sSlackUrl] = array(
-                    'label' => array_key_exists('label', $aSlackCfg) ? $aSlackCfg['label'] : $sSlackUrl,
-                    'selected' => $bActive ? 'selected' : false,
-                );
-            }
-            
-        }
-        // ---------- Build plugins
-        /*
-        
-        $aPluginsBuild = array(
-            'select' => array(
-                'type' => 'checkbox',
-                'name' => 'build[enabled_build_plugins]',
-                'label' => t("build-plugins"),
-                'options' => [],
-            ),
-            // 'project-config' => '',
-        );
-        foreach (array_keys($this->getConfiguredPlugins('build')) as $sPluginName){
-
-            $sPluginFile=$this->_getPluginFilename('build', $sPluginName);
-            $TmpRolloutPlugin = false;
-            $sMyClassname='build_'. $sPluginName;
-            if(file_exists($sPluginFile)){
-            try{
-                include_once $this->_getPluginFilename('build', $sPluginName);
-                $TmpRolloutPlugin = new $sMyClassname([]);
-                echo "FOUND $sMyClassname<br>";
-                $aPluginsBuild['select']['options'][$sPluginName]=array(
-                        'label' => $TmpRolloutPlugin->getName(),
-                        'checked' => $bActive,
-                        // 'onclick' => '$(\'.'.$sMyDivClass.'\').hide(); $(\'.' . $sMyDivClassActive . '\').show();',
-                    );
-                } catch (Exception $ex) {
-
-                }
-            } else {
-                $aRollout['project-select']['options'][$sPluginName]=array(
-                        'label' => 'not found: <span class="error">' . $sMyClassname . '</span>',
-                        'checked' => false,
-                        'disabled' => "disabled",
-                    );
-
-                
-            }
-        }
-        echo '<pre>'; print_r($aPluginsBuild); die(__METHOD__);
-        */
-
-        // ---------- /Build plugins
-        
-        // ---------- Rollout plugins
-        $aRollout = array(
-            'project-select' => array(
-                'type' => 'radio',
-                'name' => 'deploy[enabled_rollout_plugin]',
-                'label' => t("deploy-rollout-plugin"),
-            ),
-            'project-config' => '',
-        );
-        foreach (array_keys($this->getConfiguredPlugins('rollout')) as $sPluginName){
-
-            $sPluginFile=$this->_getPluginFilename('rollout', $sPluginName);
-            $TmpRolloutPlugin = false;
-            $sMyClassname='rollout_'. $sPluginName;
-            $sMyDivId='rollout-'. $sPluginName.'-config';
-            $sMyDivClass='rolloutconfigdiv';
-            $sMyDivClassActive='rolloutconfigdiv-'. $sPluginName;
-            $bActive=$sPluginName === $this->oRolloutPlugin->getId();
-
-            if(file_exists($sPluginFile)){
-                try{
-                    include_once $this->_getPluginFilename('rollout', $sPluginName);
-                    $TmpRolloutPlugin = new $sMyClassname(array(
-                        'lang'=>$this->_aConfig['lang'],
-                        'phase'=>false,
-                        'globalcfg'=>$this->_aConfig['plugins']['rollout'][$sPluginName],
-                        'projectcfg'=>$this->_aPrjConfig,
-                    ));
-                    $aRollout['project-select']['options'][$sPluginName]=array(
-                            'label' => $TmpRolloutPlugin->getName(),
-                            'checked' => $bActive,
-                            'onclick' => '$(\'.'.$sMyDivClass.'\').hide(); $(\'.' . $sMyDivClassActive . '\').show();',
-                        );
-                    
-                    $aRollout['project-config'].=''
-                            . '<div id="'.$sMyDivId.'" class="'.$sMyDivClass.' '.$sMyDivClassActive.'"'
-                            . ($bActive ? '' : 'style="display: none;"' )
-                            . '>'
-                                . $TmpRolloutPlugin->renderFormdata4Project()
-                            . '</div>'
-                            ;
-                    
-                    // generate form firlds for each phase
-                    foreach(array_keys($this->getPhases()) as $sMyPhase){
-                        $aRollout[$sMyPhase].=''
-                            . '<div id="'.$sMyDivId.'-'.$sMyPhase.'" class="'.$sMyDivClass.' '.$sMyDivClassActive.'"'
-                            . ($bActive ? '' : 'style="display: none;"' )
-                            . '>'
-                                . $TmpRolloutPlugin->renderFormdata4Phase($sMyPhase)
-                            . '</div>'
-                            ;
-                    }
-                } catch (Exception $ex) {
-
-                }
-            } else {
-                $aRollout['project-select']['options'][$sPluginName]=array(
-                        'label' => 'not found: <span class="error">' . $sMyClassname . '</span>',
-                        'checked' => false,
-                        'disabled' => "disabled",
-                    );
-
-                
-            }
-        }
-        // ---------- /Rollout plugins
-        
-        $aForemanHostgroups = false;
-        $iForemanHostgroupDefault = false;
-        $sForemanHostgroupDefault = false;
-        if (array_key_exists('foreman', $this->_aConfig)) {
-            // echo '<pre>' . print_r($this->_aPrjConfig, 1) . '</pre>';
-            $iForemanHostgroupDefault = (int) $this->_aPrjConfig['deploy']['foreman']['hostgroup'];
-            require_once('foremanapi.class.php');
-            $oForeman = new ForemanApi($this->_aConfig['foreman']);
-            // $oForeman->setDebug(1);
-            // $oForeman->selfcheck(); die(__FUNCTION__);
-
-            $aForemanHostgroups = $oForeman->read(array(
-                'request' => array(
-                    array('hostgroups'),
-                // array('operatingsystems',4),
-                ),
-                'response' => array(
-                    'id', 'title'
-                ),
-            ));
-            $aSelectForemanGroups = array(
-                'type' => 'select',
-                'name' => 'deploy[foreman][hostgroup]',
-                'label' => $this->_oHtml->getIcon('foreman') . t("foreman-hostgroup"),
-                'options' => array(
-                    OPTION_NONE => array(
-                        'label' => t('none'),
-                    ),
-                    '' => array(
-                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
-                    ),
-                ),
-            );
-            if ($aForemanHostgroups && count($aForemanHostgroups)) {
-                foreach ($aForemanHostgroups as $aItem) {
-                    $bActive=$iForemanHostgroupDefault === (int) $aItem['id'];
-                    $aSelectForemanGroups['options'][$aItem['id']] = array(
-                        'label' => $aItem['title'],
-                        'selected' => $bActive ? 'selected' : false,
-                    );
-                    $sForemanHostgroupDefault = $bActive ? $aItem['title'] : $sForemanHostgroupDefault;
-                }
-            }
-        }
-
-
-        $i = 0;
-
-        $aPrefixItem = count($this->getVersions()) ?
-                array(
-            'type' => 'markup',
-            'value' => '<div class="form-group">
-                        <label class="col-sm-2">' . t('fileprefix') . '</label>
-                        <div class="col-sm-10">
-                            <input id="inputprefix" type="hidden" name="fileprefix" value="' . $this->_aPrjConfig["fileprefix"] . '">
-                            ' . $this->_aPrjConfig["fileprefix"] . '
-                        </div></div>
-                            ',
-                ) : array(
-            'type' => 'text',
-            'name' => 'fileprefix',
-            // 'disabled' => 'disabled',
-            'label' => t('fileprefix-label'),
-            'value' => $this->_aPrjConfig["fileprefix"],
-            'required' => 'required',
-            'validate' => 'isastring',
-            'pattern' => '[a-z0-9\-_]*',
-            'size' => 100,
-            'placeholder' => '',
-        );
-
-        // detect access to repo url
-        $aBranches=$this->getRemoteBranches();
-        // $aRepodata = $this->getRepoRevision();
-
-        // if (is_array($aRepodata) && array_key_exists("message", $aRepodata)) {
-        if (is_array($aBranches) && count($aBranches)) {
-            $sRepoCheck = '<span class="ok">' . sprintf(t('class-project-info-repoaccess'), count($aBranches)) . '</span>';
-        } else {
-            $sRepoError=sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]);
-            $sRepoCheck = '<span class="error">' . $sRepoError . '</span>';
-            $sMessages.=$this->_oHtml->getBox("error", $sRepoError);
-        }
-
-        // generate datalist with exisating ssh keys for auth field
-        $sAuthListitems = '';
-        foreach ($this->_getSshKeys() as $sKey) {
-            $sAuthListitems.='<option value="' . $sKey . '">';
-        }
-        $aForms = array(
-            'setup' => array(
-                'meta' => array(
-                    'method' => 'POST',
-                    'action' => '?',
-                ),
-                'validate' => array(),
-                'form' => array(
-                    'input' . $i++ => array(
-                        'type' => 'hidden',
-                        'name' => 'setupaction',
-                        'value' => 'save',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'hidden',
-                        'name' => 'id',
-                        'value' => $this->_aConfig["id"],
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<div class="tabbable">
-                            <ul class="nav nav-tabs">
-                                <li class="active"><a href="#tab1" data-toggle="tab">' . $this->_oHtml->getIcon('list').t('setup-metadata') . '</a></li>
-                                <li><a href="#tab2" data-toggle="tab">' . $this->_oHtml->getIcon('repository').t('repositoryinfos') . '</a></li>
-
-                                <li><a href="#tab3" data-toggle="tab">' . $this->_oHtml->getIcon('deploy-configfile').t('deploy-configfile') . '</a></li>
-                                <li><a href="#tab4" data-toggle="tab">' . $this->_oHtml->getIcon('deploy-rollout-plugin').t('deploy-rollout-plugin') . '</a></li>
-                                <li><a href="#tab5" data-toggle="tab">' . $this->_oHtml->getIcon('phase').t('phases') . '</a></li>
-                                <li><a href="#tab6" data-toggle="tab">' . $this->_oHtml->getIcon('raw-data').t('raw-data') . '</a></li>
-                            </ul>
-                            <div class="tab-content">
-                            <div class="tab-pane active" id="tab1">
-                            
-                            ',
-                    ),
-
-                    // --------------------------------------------------
-                    // Tab for metadata
-                    // --------------------------------------------------
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'label',
-                        'label' => t('projectname'),
-                        'value' => $this->_aPrjConfig["label"],
-                        'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => 'Projekt',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'description',
-                        'label' => t('projectdescription'),
-                        'value' => $this->_aPrjConfig["description"],
-                        'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'contact',
-                        'label' => t('contact'),
-                        'value' => $this->_aPrjConfig["contact"],
-                        'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-
-                    'input' . $i++ => $aSelectProjectGroup,
-
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<p>' . t('messenger') . '</p>',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'messenger[email]',
-                        'label' => t("messenger-email"),
-                        'value' => $this->_aPrjConfig["messenger"]["email"],
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                        'autocomplete' => 'off',
-                    ),
-                    
-                    'input' . $i++ => $aSelectSlack,
-                    
-                    // --------------------------------------------------
-                    // Tab soources repository & build
-                    // --------------------------------------------------
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => ' </div><div class="tab-pane" id="tab2">
-                            <p>' . t('setup-hint-build') . '</p>',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'build[type]',
-                        'label' => t("build-type"),
-                        'value' => $this->_aPrjConfig["build"]["type"],
-                        'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'build[url]',
-                        'label' => t("repository-url"),
-                        'value' => $this->_aPrjConfig["build"]["url"],
-                        // 'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'build[auth]',
-                        'label' => t("repository-auth"),
-                        'value' => $this->_aPrjConfig["build"]["auth"],
-                        // 'required' => 'required',
-                        'list' => 'listauth', // listauth is the next form id below
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<datalist id="listauth">' . $sAuthListitems . '</datalist>',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<div class="form-group">'
-                        . '<label class="col-sm-2"> </label><div class="col-sm-10">'
-                        . $sRepoCheck
-                        . '</div></div>',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'build[webaccess]',
-                        'label' => t("repository-urlwebgui"),
-                        'value' => $this->_aPrjConfig["build"]["webaccess"],
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),
-                    'input' . $i++ => $aPrefixItem,
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<div style="clear: both"></div>',
-                    ),
-                    // task#1498 - handle project without "public" directory
-                    'input' . $i++ => array(
-                        'type' => 'checkbox',
-                        'name' => 'build[haspublic]',
-                        'label' => t("repository-has-public-dir"),
-                        'required' => false,
-                        'validate' => 'isastring',
-                        'options' => array(
-                            '1' => array(
-                                'label' => t("yes"),
-                                'checked' => (array_key_exists('haspublic', $this->_aPrjConfig["build"]) ? $this->_aPrjConfig["build"]["haspublic"] : 0),
-                            ),
-                        ),
-                    ),
-
-                    // --------------------------------------------------
-                    // Tab for config and API key
-                    // --------------------------------------------------
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => ' </div><div class="tab-pane" id="tab3">
-                            <p>' . t('deploy-configfile-hint') . '</p>',
-                    ),
-                    'textarea' . $i++ => array(
-                        'type' => 'textarea',
-                        'name' => 'deploy[configfile]',
-                        'label' => t("deploy-configfile"),
-                        'value' => $this->_aPrjConfig['deploy']["configfile"],
-                        // 'required' => 'required',
-                        'validate' => 'isastring',  
-                        'cols' => 100,
-                        'rows' => 10,
-                        'placeholder' => 'export myvariable=&quot;hello world&quot;',
-                    ),
-   
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'api[secret]',
-                        'label' => t("api-secret"),
-                        'value' => $this->_aPrjConfig["api"]["secret"],
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'placeholder' => '',
-                    ),                    
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => '<div class="col-sm-12">'
-                        . '<p>' . t('api-secret-hint') . '<br>'
-                            . '<a href="#" class="btn btn-default" onclick="$(\'#input'.($i-2).'\').val(generateSecret(64)); return false">'.t("api-secret-generate").'</a>'
-                        . '</p></div>',
-                    ),
-                    
-                    // --------------------------------------------------
-                    // Tab rollout plugin
-                    // --------------------------------------------------
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => ' </div><div class="tab-pane" id="tab4">
-                            <p>' . t('deploy-rollout-plugin-hint') . '</p>',
-                    ),
-                    // select box for active rollout plugin
-                    $aRollout['project-select'],
-                    
-                    // project based config 
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => ''
-                            . '<hr>'
-                                .'<label class="col-sm-2">'.t('deploy-rollout-plugin-config') .'</label>'
-                                .'<div class="col-sm-10">'. $aRollout['project-config'].'</div>'
-                    ),
-                    // --------------------------------------------------
-                    'input' . $i++ => array(
-                        'type' => 'markup',
-                        'value' => ' </div><div class="tab-pane" id="tab5">
-                            <p>' . sprintf(t("class-project-info-setup-phaseinfos"), $this->getNextPhase()) . '</p>',
-                    ),
-                ),
-            ),
-        );
-        // --------------------------------------------------
-        // Tab for phases
-        // --------------------------------------------------
-        if ($aSelectForemanGroups) {
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => '<strong>'.t("defaults-all-phases").'</strong><br><br>',
-            );
-            $aForms["setup"]["form"]['input' . $i++] = $aSelectForemanGroups;
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => '<br><br>',
-            );
-        }
-        foreach (array_keys($this->getPhases()) as $sPhase) {
-
-            $bActivePhase = $this->isActivePhase($sPhase);
-            $sUrl = array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["url"] : "";
-            $sDeploymethod = array_key_exists("deploymethod", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["deploymethod"] : "";
-            $sDeployhosts = array_key_exists("hosts", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["hosts"] : "";
-
-            /*
-             * task-1847 - reove adding ssh key
-            if($sDeployhosts){
-                echo "$sDeployhosts<br>";
-                if(!strpos($sDeployhosts, ",")){
-                    $sCmd=sprintf($this->_aConfig["installPackages"]["addkeycommand"], $sDeployhosts, $sDeployhosts);
-                    exec($sCmd . " 2>&1", $aOut);
-                    echo "<pre>\$ $sCmd<br>"
-                        . implode('<br>', $aOut)
-                        ."</pre>"
-                        ;
-                }
-            }
-             */
-            $sDeploytimes = array_key_exists("deploytimes", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["deploytimes"] : "";
-            $sDivId4PhaseSettings = 'divSettings' . $sPhase;
-            $sDivId4TargetHosts = 'divSettings' . $sPhase . 'hosts';
-
-            if ($aSelectForemanGroups) {
-                $iForemanHostgroup = (int) $this->_aPrjConfig['phases'][$sPhase]['foreman-hostgroup'];
-                $aSelectForemanHostGroup = array(
-                    'type' => 'select',
-                    'name' => 'phases[' . $sPhase . '][foreman-hostgroup]',
-                    'label' => $this->_oHtml->getIcon('foreman') . t("foreman-hostgroup"),
-                    'options' => array(
-                        OPTION_DEFAULT => array(
-                            'label' => t('default') . ' (' . $sForemanHostgroupDefault . ')',
-                            'selected' => $iForemanHostgroup === OPTION_DEFAULT ? 'selected' : false,
-                        ),
-                        OPTION_NONE => array(
-                            'label' => t('none'),
-                            'selected' => $iForemanHostgroup === OPTION_NONE ? 'selected' : false,
-                        ),
-                        '' => array(
-                            'label' => '- - - - - - - - - - - - - - - - - - - - ',
-                        ),
-                    ),
-                );
-                if (is_array($aForemanHostgroups) && count($aForemanHostgroups)) {
-                    foreach ($aForemanHostgroups as $aItem) {
-                        $aSelectForemanHostGroup['options'][$aItem['id']] = array(
-                            'label' => $aItem['title'],
-                            'selected' => ($iForemanHostgroup === $aItem['id']) ? 'selected' : false,
-                        );
-                    }
-                }
-            }
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                // .'<pre>'.print_r($this->_aPrjConfig["phases"][$sPhase], 1).'</pre>'
-                /*
-                  . '<a class="'.$sPhase.'">'
-                  . t("phase") . ' ' . $sPhase
-                  . '</a>'
-                 */
-                . '<table class="table">'
-                . '<tbody>'
-                . '<tr><th class="' . $sPhase . '">' . $this->_oHtml->getIcon('phase') . t("phase") . ' ' . $sPhase . '</th></tr>'
-                . '<tr><td class="' . ($bActivePhase ? $sPhase : '') . '">'
-                . ''
-            );
-
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'checkbox',
-                'name' => 'phases[' . $sPhase . '][active]',
-                'label' => t("phase-is-active"),
-                // 'value' => $bUsePuppet,
-                'required' => false,
-                'validate' => 'isastring',
-                // 'size' => 100,
-                // 'placeholder' => '...',
-                'options' => array(
-                    '1' => array(
-                        'label' => t("yes"),
-                        'checked' => $bActivePhase,
-                        'onclick' => '$(\'#' . $sDivId4PhaseSettings . '\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
-                    ),
-                ),
-            );
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                . '<div id="' . $sDivId4PhaseSettings . '" ' . ($bActivePhase ? '' : ' style="display: none;"') . '">'
-            );
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'text',
-                'name' => 'phases[' . $sPhase . '][url]',
-                'label' => $this->_oHtml->getIcon('url') . t("url-project-website"),
-                'value' => $sUrl,
-                // 'required' => 'required',
-                'validate' => 'isastring',
-                'size' => 100,
-                'placeholder' => 'https://' . $sPhase . '.[' . t("project") . '].[...]/',
-            );
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'radio',
-                'name' => 'phases[' . $sPhase . '][deploymethod]',
-                'label' => $this->_oHtml->getIcon('method') . t("deploymethod"),
-                // 'value' => $bUsePuppet,
-                // 'required' => 'required',
-                'validate' => 'isastring',
-                // 'size' => 100,
-                // 'placeholder' => '...',
-                'options' => array(
-                    'none' => array(
-                        'label' => t("deploymethod-none"),
-                        'checked' => $sDeploymethod === "none",
-                        'onclick' => '$(\'#' . $sDivId4TargetHosts . '\').css(\'display\', (this.checked ? \'none\' : \'block\') )',
-                    ),
-                    'rolloutplugin' => array(
-                        // 'label' => t("deploymethod-puppet").' - '.  $this->oRolloutPlugin->getName(),
-                        'label' => t("deploymethod-rolloutplugin"),
-                        'checked' => $sDeploymethod === "rolloutplugin",
-                        'onclick' => '$(\'#' . $sDivId4TargetHosts . '\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
-                    ),
-                /*
-                 * see deploy method to handle an action
-                  'sshproxy' => array(
-                  'label' => t("deploymethod-sshproxy"),
-                  'checked' => $sDeploymethod==="sshproxy",
-                  'onclick' => '$(\'#'.$sDivId4TargetHosts.'\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
-                  ),
-                 */
-                ),
-            );
-            
-
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                . '<div id="' . $sDivId4TargetHosts . '" ' . ($sDeploymethod !== "none" ? '' : ' style="display: none;"') . '">'
-            );
-            
-            // rollout plugin: phase specific overrides
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                    // . '<hr>'
-                    .'<label class="col-sm-2">'.t('deploy-rollout-plugin-config') .'</label>'
-                    .'<div class="col-sm-10">'.$aRollout[$sPhase].'</div>'
-            ); 
-            
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'text',
-                'name' => 'phases[' . $sPhase . '][hosts]',
-                'label' => $this->_oHtml->getIcon('host') . t("phase-targethosts"),
-                'value' => $sDeployhosts,
-                // 'required' => 'required',
-                'validate' => 'isastring',
-                'size' => 100,
-                'placeholder' => 'FQDN1,FQDN2',
-            );
-
-            /*
-              if ($sPuppethost) {
-
-              // add ssh host key
-              $sOut0 = shell_exec(sprintf($this->_aConfig["installPackages"]["addkeycommand"], $sPuppethost, $sPuppethost));
-
-              $sCmd2 = 'ssh ' . $this->_aConfig["installPackages"]["user"]
-              . '@' . $sPuppethost
-              . ' ' . $this->_aConfig["installPackages"]["testcommand"];
-              $sOut = 'skip';
-              // $sOut = shell_exec($sCmd2);
-              // Check auf Versionsnummer - mehr als n Zeichen ist mutmasslich eine Fehlermeldung
-              if (strlen($sOut) > 7) {
-              $sMessages.=$this->getBox("error", sprintf(t("class-project-error-setup-sudo-pupet-agent-failed"), $sPhase, $sCmd, $sOut));
-              $sOut = '<span class="error" title="' . $sCmd . '">' . $sOut . '</span>';
-              } else {
-              $sOut = '<span class="ok">' . sprintf(t("class-project-info-setup-ssh-and-puppet-ok"), $sPuppethost) . '</span>';
-              }
-              $aForms["setup"]["form"]['input' . $i++] = array(
-              'type' => 'markup',
-              'value' => '<div class="form-group">'
-              . '<label class="col-sm-2"> </label><div class="col-sm-10">'
-              . $sOut
-              . '</div></div>',
-              );
-              }
-             */
-
-            // when to deploy
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'text',
-                'name' => 'phases[' . $sPhase . '][deploytimes]',
-                'label' => $this->_oHtml->getIcon('time') . t("deploytimes"),
-                'value' => $sDeploytimes,
-                // 'required' => 'required',
-                'validate' => 'isastring',
-                'size' => 100,
-                'placeholder' => isset($this->_aConfig["phases"][$sPhase]["deploytimes"]) ? implode(", ", $this->_aConfig["phases"][$sPhase]["deploytimes"]) : '',
-            );
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                . '</div>'
-            );
-
-            if ($aSelectForemanGroups) {
-                $aForms["setup"]["form"]['input' . $i++] = $aSelectForemanHostGroup;
-            }
-
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => ''
-                . '</div>'
-            ); // close div for active phase
-
-
-            $aForms["setup"]["form"]['input' . $i++] = array(
-                'type' => 'markup',
-                'value' => '</td></tr></tbody></table>',
-            );
-        } // END: loop over phases
-
-        // --------------------------------------------------
-        // Tab for raw data
-        // --------------------------------------------------
-        
-        $sRolloutDebug='<hr>DEBUG:<br>';
-        foreach (array_keys($this->getPhases()) as $sPhase) {
-            if ($this->isActivePhase($sPhase)){
-                $sRolloutDebug.='<strong>'.$sPhase.'</strong>'
-                . '<pre>Config = '.print_r($this->oRolloutPlugin->getConfig($sPhase), 1).'</pre>'
-                . '<pre>Commands = '.print_r($this->oRolloutPlugin->getDeployCommands($sPhase), 1).'</pre>'
-                ;
-            }
-        }
-
-        $aForms["setup"]["form"]['input' . $i++] = array(
-            'type' => 'markup',
-            'value' => '</div>'
-            
-                . '<div class="tab-pane" id="tab6">'
-                . '<br><pre>'.print_r($this->_aPrjConfig, 1).'</pre>'
-                . $sRolloutDebug
-                . '</div>'
-            
-            . '</div>'
-            . '</div>'
-            . '<div style="clear: both; margin-bottom: 1em;"></div>'
-            
-            
-            . '<hr>',
-        );
-        $aForms["setup"]["form"]['input' . $i++] = array(
-            'type' => 'submit',
-            'name' => 'btnsave',
-            'label' => t("save"),
-            'value' => $this->_oHtml->getIcon('sign-ok').t("save"),
-        );
-
-        $oForm = new formgen($aForms);
-        return $sMessages . $oForm->renderHtml("setup");
-    }
-
-    /**
-     * return html code for the setup form for a new project
-     * @return string
-     */
-    public function renderNewProject() {
-        global $aParams;
-        if (!$this->oUser->hasPermission("project-action-create")) {
-            return $this->oUser->showDenied();
-        }
-
-        require_once ("formgen.class.php");
-        $i = 0;
-        $sID = array_key_exists("id", $aParams) ? $aParams["id"] : "";
-
-        $aForms = array(
-            'setup' => array(
-                'meta' => array(
-                    'method' => 'POST',
-                    'action' => '?',
-                ),
-                'validate' => array(),
-                'form' => array(
-                    'input' . $i++ => array(
-                        'type' => 'hidden',
-                        'name' => 'setupaction',
-                        'value' => 'create',
-                    ),
-                    'input' . $i++ => array(
-                        'type' => 'text',
-                        'name' => 'id',
-                        'label' => t("class-project-info-setup-projectId"),
-                        'value' => $sID,
-                        'required' => 'required',
-                        'validate' => 'isastring',
-                        'size' => 100,
-                        'pattern' => '[a-z0-9\-_]*',
-                        'placeholder' => t("class-project-info-setup-projectId-placeholder"),
-                    ),
-                ),
-            ),
-        );
-        $aForms["setup"]["form"]['input' . $i++] = array(
-            'type' => 'submit',
-            'name' => 'btnsave',
-            'label' => t("save"),
-            'value' => $this->_oHtml->getIcon('sign-ok') . t("save"),
-        );
-
-        $oForm = new formgen($aForms);
-        return $oForm->renderHtml("setup");
-    }
 
 }
diff --git a/public_html/deployment/classes/project_gui.class.php b/public_html/deployment/classes/project_gui.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca923ad186bf0e1f7d868b72862d9de7047c7759
--- /dev/null
+++ b/public_html/deployment/classes/project_gui.class.php
@@ -0,0 +1,1713 @@
+<?php
+
+echo 'DEBUG: GUI class was loaded - '.__FILE__.'<br>';
+require_once 'project.class.php';
+require_once 'htmlguielements.class.php';
+
+
+/* ######################################################################
+
+  IML DEPLOYMENT
+
+  class project for all actions for single project
+  Rendering of web ui
+
+  ---------------------------------------------------------------------
+  2013-11-08  Axel <axel.hahn@iml.unibe.ch>
+  ###################################################################### */
+
+/**
+ * class for single project
+ */
+// class project {
+class projectgui extends project {
+
+    // ----------------------------------------------------------------------
+    // private functions
+    // ----------------------------------------------------------------------
+
+    /**
+     * return html code for a div with background color based on a checksum of the given text
+     * @param string $sText      text that is used for checksum; if false ist returns a gray
+     * @param string $sContent   optional: text to show
+     * @return string
+     */
+    private function _getChecksumDiv($sText, $sContent='') {
+        if ($sText){
+            
+            // color ranges in decimal values for RGB from ... to
+            $iFgStart=60;  $iFgEnd=160;
+            $iBgStart=200; $iBgEnd=250;
+
+            // deivider: 3 digits of md5 will be extracted
+            $iFgDivider=16*16*16/($iFgEnd-$iFgStart);
+            $iBgDivider=16*16*16/($iBgEnd-$iBgStart);
+            
+            $sHash=md5($sText);
+            $sColor=''
+                . 'color: rgba(' 
+                . ($iFgStart + round(hexdec(substr($sHash,0,3))/$iFgDivider)) . ','
+                . ($iFgStart + round(hexdec(substr($sHash,3,3))/$iFgDivider)) . ','
+                . ($iFgStart + round(hexdec(substr($sHash,6,3))/$iFgDivider)) . ','
+                . '1'
+                . ');'
+                . 'background: rgba(' 
+                . ($iBgStart + round(hexdec(substr($sHash,0,3))/$iBgDivider)) . ','
+                . ($iBgStart + round(hexdec(substr($sHash,3,3))/$iBgDivider)) . ','
+                . ($iBgStart + round(hexdec(substr($sHash,6,3))/$iBgDivider)) . ','
+                . '1'
+                . ');'
+                ;
+        } else {
+            $sColor = "color: #888; background: #ccc;";
+        }
+        return '<div style="' . $sColor . '; border-top: 3px solid; ">'.($sContent ? $sContent : ' ').'</div>';
+    }
+
+
+    /**
+     * get html code for the colored bar on top of each phase detail items
+     * @param string $sPhase  phase of a project
+     * @param string $sPlace  place in the given phase
+     * @return string
+     */
+    private function _renderBar($sPhase, $sPlace) {
+        $aDataPhase = $this->getPhaseInfos($sPhase);
+        $aData = $aDataPhase[$sPlace];
+        if (!array_key_exists("revision", $aData)) {
+            return false;
+        }
+        return $this->_getChecksumDiv($aData["revision"]);
+    }
+
+    private function _renderHostsData($aData) {
+        $sReturn = '';
+        if (array_key_exists('_hosts', $aData)) {
+            
+            // $sReturn.= print_r($aData['_hosts'], 1);
+            $sReturn.= '<div class="hosts">'
+                    . '<br><strong>' . t('hosts') . ':</strong><br>'
+            ;
+            foreach ($aData['_hosts'] as $sHostname => $aHostinfos) {
+                $oUpdateDate = date("U", strtotime($aHostinfos['time']));
+                $iAgeUpdate = round((date("U") - $oUpdateDate) / 60);
+                $sAge = $iAgeUpdate < 60 * 60 * 13 ? $iAgeUpdate . " min" : "??";
+
+                $sReturn.= '<div class="host">'
+                        . $this->_getChecksumDiv(
+                            $aHostinfos['_data']['revision'],
+                            $this->_oHtml->getIcon('host').'<br>' . $sHostname
+                        )
+                        . "($sAge)"
+                        . '</div>'
+                ;
+            }
+            $sReturn.= '</div><div style="clear: both;"></div>';
+        }
+        return $sReturn;
+    }
+
+    /**
+     * get html code for list of hosts in a phase
+     * @param string $sPhase  phase of a project
+     * @return string
+     */
+    private function _renderHosts($sPhase) {
+        $aDataPhase = $this->getPhaseInfos($sPhase);
+        if (is_array($aDataPhase) && array_key_exists('deployed', $aDataPhase)) {
+            return $this->_renderHostsData($aDataPhase['deployed']);
+        }
+        return '';
+    }
+
+    /**
+     * get html code for list of files in a phase
+     * @param string $sPhase  phase of a project
+     * @return string
+     */
+    private function _renderFiles($sPhase) {
+        $sReturn = '';
+        $aFiles = $this->getBuildfilesByPlace($sPhase, 'ready2install');
+        if (!$aFiles || !$aFiles['filecount']) {
+            return '';
+        }
+        $sReturn.='<strong>' . t("filelist") . '</strong> (' . $aFiles['filecount'] . '):<br>';
+        foreach ($aFiles['files'] as $sFilename => $aData) {
+            $sReturn.='<div class="file file-' . $aData['type'] . ' fileext-' . $aData['extension'] . '" title="' . $sFilename . ' (' . $aData['type'] . ')">'
+                    . $aData['icon'] . $sFilename
+                    // . ' ('.$aData['type'].')'
+                    . '</div>'
+            ;
+        }
+        $sReturn.='(' . $aFiles['totalsize-hr'] . ')';
+        return $sReturn;
+    }
+
+    // ----------------------------------------------------------------------
+    // RENDERING
+    // ----------------------------------------------------------------------
+
+
+    /**
+     * render html for a row with td for all places of a phase
+     * @param string $sPhase   phase
+     * @param bool   $bActions draw action links (deploy, accept) on/ off
+     * @param bool   $bLong    use long variant to display infos? 
+     * @return string|boolean
+     */
+    public function renderAllPhaseDetails($sPhase, $bActions = true, $bLong = true) {
+        if (!$sPhase) {
+            return false;
+        }
+        if (!$this->isActivePhase($sPhase)) {
+            return '
+                        <td class="td-phase-' . $sPhase . ' td-phase-inactive ' . $this->_aConfig["id"] . '" colspan="' . count($this->_aPlaces) . '">
+                            <div class="versioninfo center inactive">' . $this->_oHtml->getIcon('sign-info').t('inactive') . '</div>
+                        </td>';
+        }
+        $sRow2 = false;
+
+        $aRows = array();
+        $sLastPlace = '';
+        
+        foreach (array_keys($this->_aPlaces) as $sPlace) {
+            $aRows[$sPlace] = $this->renderPhaseDetail($sPhase, $sPlace, $bActions, $bLong);
+            
+            // generate ">>" sign for lastly generated td
+            if ($sLastPlace && array_key_exists("version", $this->_aData["phases"][$sPhase][$sLastPlace]) 
+                    && array_key_exists("version", $this->_aData["phases"][$sPhase][$sPlace]) 
+                    && $this->_aData["phases"][$sPhase][$sLastPlace]["version"] == $this->_aData["phases"][$sPhase][$sPlace]["version"] 
+                    && !$bLong
+            ) {
+                $aRows[$sLastPlace] = $this->_renderBar($sPhase, $sPlace) . "&raquo;";
+            }
+            $sLastPlace = $sPlace;
+        }
+        
+        foreach (array_keys($this->_aPlaces) as $sPlace) {
+            $sRow2.='<td class=" td-phase-'.$sPhase.' td-place-'.$sPlace.' td' . $this->_aConfig["id"] . '">' . $aRows[$sPlace] . '</td>';
+        }
+        return $sRow2;
+    }
+
+    /**
+     * return html code for current project errors by rendering a box per error in $this->_errors
+     * @return string
+     */
+    public function renderErrorBoxes(){
+        $sReturn='';
+        if(count($this->_errors)){
+            foreach($this->_errors as $sError){
+                $sReturn.=$this->_oHtml->getBox("error", $sError);
+            }
+        }
+        return $sReturn;
+    }
+
+
+    /**
+     * render html code for info link that shows popup with metadata on mouseover
+     * @param array $aInfos   metainfos of the package (from json file)
+     * @param array $aOptions options
+     *                   title - tile in popover; default: empty
+     *                   label - link label; default: empty (results in Infos|ERROR)
+     *                   more  - additional infos in popover; default: empty
+     *                   hpos  - horizontal position; one of left|right; default: right
+     * @return string
+     */
+    public function renderInfoLink($aInfos, $aOptions = array()) {
+        $sReturn = '';
+        $bIsError = false;
+        $this->_oHtml = new htmlguielements();
+
+        $sInfos='';
+        $sTitle='';
+        if (array_key_exists("title", $aOptions) && $aOptions["title"]) {
+            $sTitle.=$aOptions["title"];
+        }
+        if (array_key_exists("ok", $aInfos)) {
+            $sLinktitle = t('infos');
+            if (array_key_exists("message", $aInfos)) {
+                $sInfos.=$this->_getChecksumDiv($aInfos["revision"],
+                        $this->_oHtml->getIconByType('calendar') . t('build-from') . ' ' . date("d.m.Y H:i:s", strtotime($aInfos["date"])) . '<br>'
+                        . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aInfos["branch"] . '<br>'
+                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aInfos["revision"]) . '<br>'
+                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ': '
+                        )
+                        . '<pre>' . strip_tags($aInfos["message"], '<br>') . '</pre>';
+                if (array_key_exists("more", $aOptions)) {
+                    $sInfos.=$aOptions["more"];
+                }
+            }
+        } else {
+            $bIsError = true;
+            if (!$sTitle) {
+                $sTitle.=' ' . t('error');
+            }
+            $sLinktitle = t('error');
+            $sInfos = $aInfos["error"];
+        }
+        $sInfos.=$this->_renderHostsData($aInfos);
+
+        if (array_key_exists("label", $aOptions) && $aOptions["label"]) {
+            $sLinktitle.=$aOptions["label"];
+        }
+
+        // render html
+        $sId = 'info' . md5($sInfos);
+        $sReturn = '<a href="#" class="btn ' . ($bIsError ? 'btn-danger' : 'btn-default') . '" title="" onclick="showIdAsModalMessage(\'' . $sId . '\'); return false;">'
+                // . '<i class="fa fa-info"></i> '
+                . $sLinktitle
+                . '</a><div id="' . $sId . '" style="display: none;" ';
+        if (array_key_exists("hpos", $aOptions)) {
+            $sReturn.=' class="' . $aOptions["hpos"] . '"';
+        }
+        $sReturn.='>';
+
+        if ($sTitle) {
+            $sReturn.='<span class="title">' . $sTitle . '</span><br><br>';
+        }
+
+        $sReturn.=$sInfos . '</div>';
+
+        if ($bIsError) {
+            // $sReturn = '<div class="error">' . $sReturn . '</div>';
+        }
+
+        return $sReturn;
+    }
+
+    /**
+     * render html for a colored link to any project action
+     * @param string $sFunction name of the action; one of accept|build|cleanup|deploy|new|overview|phase|rollback|setup
+     * @param string $sPhase    current phase where to place the link
+     * @return string
+     */
+    public function renderLink($sFunction, $sPhase = false, $sVersion = false) {
+        $sFirst = $this->getNextPhase();
+        $sNext = $this->getNextPhase($sPhase);
+        $aLinkdata = array(
+            'default' => array('class' => ''),
+            'accept' => array('class' => $sNext,
+                'hint' => sprintf(t("accept-hint"), $sPhase, $sNext),
+                'label' => t('accept'),
+            ),
+            'build' => array('class' => $sFirst,
+                'hint' => sprintf(t("build-hint"), $sFirst),
+                'label' => t('build'),
+                'role' => 'buildProject'
+            ),
+            'cleanup' => array('class' => ''),
+            'deploy' => array('class' => $sPhase,
+                'hint' => sprintf(t("deploy-hint"), $sPhase),
+                'label' => t('deploy'),
+            ),
+            'new' => array(
+                'hint' => t("new-project-hint"),
+                'label' => t('new-project'),
+            ),
+            'overview' => array('class' => '',
+                'hint' => t('menu-project-home') . ' [' . $this->getLabel() . ']',
+                'label' => $this->getLabel()
+            ),
+            'phase' => array('icon' => $this->_oHtml->getIcon('phase'), 'class' => $sPhase,
+                'hint' => sprintf(t('phase-details-hint'), $sPhase),
+                'label' => t('phase-details')
+            ),
+            'rollback' => array('class' => $sPhase,
+                'hint' => sprintf(t('rollback-hint'), $sPhase, $sVersion),
+                'label' => t('rollback')
+            ),
+            'setup' => array('class' => $sPhase,
+                'hint' => sprintf(t('setup-hint'), $sPhase, $sVersion),
+                'label' => t('setup')
+            ),
+        );
+        /*
+          if (!$this->oUser->hasRole("project-action-$sFunction")){
+          // $sClass .= ' disabled';
+          // return '<span title="no permission [project-action-'.$sFunction.']">[ ]</span>';
+          }
+         * 
+         */
+        // fuer wen ist der Link
+        $sRole = '';
+        $sOnMouseover = '';
+        $sOnMouseout = '';
+        switch($sFunction){
+            case 'accept';
+                $sRole = 'developer';
+                if ($sNext == "live") {
+                    $sRole = 'pl';
+                    // $aLinkdata[$sFunction]['icon']='glyphicon glyphicon-star';
+                }
+                $sOnMouseover = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');';
+                $sOnMouseout = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');';
+                break;
+            case 'build';
+                $sRole = 'developer';
+                $sOnMouseover = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');';
+                $sOnMouseout = '$(\'.td-phase-' . $sNext . '.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');';
+                break;
+            case 'deploy';
+                $sRole = 'developer';
+                $sOnMouseover = '$(\'.td-phase-' . $sPhase . '.td-place-ready2install.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');'
+                        .'$(\'.td-phase-' . $sPhase . '.td-place-deployed.td' . $this->_aConfig["id"] . '\').addClass(\'highlight\');'
+                        ;
+                $sOnMouseout = '$(\'.td-phase-' . $sPhase . '.td-place-ready2install.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');'
+                        .'$(\'.td-phase-' . $sPhase . '.td-place-deployed.td' . $this->_aConfig["id"] . '\').removeClass(\'highlight\');'
+                        ;
+                break;
+        }
+
+        // $sClass = $sPhase;
+        $sIconClass = (array_key_exists($sFunction, $aLinkdata)) ? $aLinkdata[$sFunction]['icon'] : $aLinkdata['default']['icon'];
+        $sHint = (
+                array_key_exists($sFunction, $aLinkdata) && array_key_exists("hint", $aLinkdata[$sFunction])
+                ) ? $aLinkdata[$sFunction]['hint'] : "";
+        $sLabel = (
+                array_key_exists($sFunction, $aLinkdata) && array_key_exists("label", $aLinkdata[$sFunction])
+                ) ? $aLinkdata[$sFunction]['label'] : $sFunction;
+        $sClass = (
+                array_key_exists($sFunction, $aLinkdata) && array_key_exists("class", $aLinkdata[$sFunction])
+                ) ? $aLinkdata[$sFunction]['class'] : '';
+        if ($sRole) {
+            $sClass .= " role role" . $sRole;
+        }
+
+        $sLink = "/deployment/" . ($this->_aConfig["id"] ? $this->_aConfig["id"] : 'all/setup') . "/";
+        if ($sFunction != "overview") {
+            $sLink.="$sFunction/";
+        }
+        if ($sPhase) {
+            $sLink.="$sPhase/";
+        }
+        if ($sVersion) {
+            $sLink.="$sVersion/";
+        }
+        if (!$this->oUser->hasPermission("project-action-$sFunction")) {
+            // $sClass .= ' disabled';
+            return '<span class="btn disabled btn-default" title="no permission [project-action-' . $sFunction . '] for user [' . $this->oUser->getUsername() . ']"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</span>';
+        }
+
+        return $this->_oHtml->getLinkButton(array(
+                    'href' => $sLink,
+                    'title' => $sHint,
+                    'class' => 'btn btn-default ' . $sClass,
+                    'type' => $sFunction,
+                    'onmouseover' => $sOnMouseover,
+                    'onmouseout' => $sOnMouseout,
+                    'label' => $sLabel,
+        ));
+        // return '<a href="' . $sLink . '" ' . $sOnMouseover . ' title="' . $sHint . '" class="btn  btn-default ' . $sClass . '"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</a>';
+    }
+
+    /**
+     * return html code for the setup form for a new project
+     * @return string
+     */
+    public function renderNewProject() {
+        global $aParams;
+        if (!$this->oUser->hasPermission("project-action-create")) {
+            return $this->oUser->showDenied();
+        }
+
+        require_once ("formgen.class.php");
+        $i = 0;
+        $sID = array_key_exists("id", $aParams) ? $aParams["id"] : "";
+
+        $aForms = array(
+            'setup' => array(
+                'meta' => array(
+                    'method' => 'POST',
+                    'action' => '?',
+                ),
+                'validate' => array(),
+                'form' => array(
+                    'input' . $i++ => array(
+                        'type' => 'hidden',
+                        'name' => 'setupaction',
+                        'value' => 'create',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'id',
+                        'label' => t("class-project-info-setup-projectId"),
+                        'value' => $sID,
+                        'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'pattern' => '[a-z0-9\-_]*',
+                        'placeholder' => t("class-project-info-setup-projectId-placeholder"),
+                    ),
+                ),
+            ),
+        );
+        $aForms["setup"]["form"]['input' . $i++] = array(
+            'type' => 'submit',
+            'name' => 'btnsave',
+            'label' => t("save"),
+            'value' => $this->_oHtml->getIcon('sign-ok') . t("save"),
+        );
+
+        $oForm = new formgen($aForms);
+        return $oForm->renderHtml("setup");
+    }
+    /**
+     * render html for a place of a phase
+     * @param string  $sPhase    phase
+     * @param string  $sPlace    name of the place; one of onhold|ready2install|deployed
+     * @param bool    $bActions  draw action links (deploy, accept) on/ off
+     * @param bool    $bLong     use long variant to display infos? 
+     * @return string|boolean
+     */
+    public function renderPhaseDetail($sPhase, $sPlace, $bActions = true, $bLong = true) {
+
+        if (!$sPhase) {
+            return false;
+        }
+        if (!$sPlace) {
+            return false;
+        }
+        if (!$this->isActivePhase($sPhase)) {
+            return false;
+        }
+        if (!array_key_exists($sPlace, $this->_aPlaces)) {
+            return false;
+        }
+
+        $sReturn = false;
+        $aDataPhase = $this->getPhaseInfos($sPhase);
+        $aData = $aDataPhase[$sPlace];
+        // foreach($aDataPhase[$sPlace] as $aData) {
+        if (array_key_exists("ok", $aData) && array_key_exists("version", $aData)) {
+            // TODO: getChecksumDiv anhand der Repo-Versionsnummer - dann kann man beim build auch die Farbe mit dem Repo HEAD vergleichen
+            // time
+            $sDateFormat = "d.m.Y H:i";
+            $oPkgDate = date("U", strtotime($aData["date"]));
+            /*
+              $iAge=date("U")-$oPkgDate;
+              $sAgeClass="";
+              if ($iAge< 60*60*24*3){
+              $sAgeClass="last1d";
+              }
+              if ($iAge< 60*60){
+              $sAgeClass="last1h";
+              }
+             */
+
+            if ($bLong) {
+                // long display of the revision
+                // $sJsonUrl = $this->_getInfofile($sPhase, $sPlace);
+                    $sReturn .=$this->_getChecksumDiv(
+                        $aData["revision"], 
+                        $this->_oHtml->getIconByType('calendar') .' ' . date($sDateFormat, $oPkgDate)
+                        . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aData["branch"] . '<br>'
+                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aData["revision"]) . '<br>'
+                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ':<br>'
+                    )
+                    . '<pre>' . strip_tags($aData["message"], '<br>') . '</pre>'
+                // . '<i class="glyphicon glyphicon-globe"></i> ' . t('url') . ': <a href="' . $sJsonUrl . '">' . $sJsonUrl . '</a><br>'
+                ;
+                if ($sPlace == "deployed" && array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase])) {
+                    $sUrl = $this->_aPrjConfig["phases"][$sPhase]["url"];
+                    $sReturn.=$this->_oHtml->getIconByType('link-extern') . ' '. t('url') . ': <a href="' . $sUrl . '">' . $sUrl . '</a><br>';
+                }
+            } else {
+                $sReturn .= $this->_getChecksumDiv(
+                            $aData["revision"], 
+                            $this->_oHtml->getIconByType('calendar') .' ' . date($sDateFormat, $oPkgDate)
+                    );
+                if ($sPlace == "deployed" && array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase])) {
+                    $sMore = $this->_oHtml->getIconByType('link-extern').' '
+                            . t('url')
+                            . ': <a href="' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '">' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '</a><br>';
+                }
+
+                $sReturn.=' ' . $this->renderInfoLink(
+                                $aData, array(
+                            'title' => $this->getLabel() . " :: $sPhase :: $sPlace",
+                            'more' => $sMore,
+                                )
+                );
+            }
+
+            switch ($sPlace) {
+                case "onhold":
+                    if (array_key_exists("phases", $this->_aConfig) && array_key_exists($sPhase, $this->_aConfig["phases"])) {
+                        // $sReturn .= print_r($this->_aConfig["phases"][$sPhase], true);
+                        if (count($this->_getDeploytimes($sPhase))) {
+                            $sReturn .= '<br>'.$this->_oHtml->getIcon('time').t('deploytimes') . ':<br>'
+                                    . implode("<br>", array_values($this->_getDeploytimes($sPhase)))
+                                    . '<br>';
+                        }
+                        if ($bActions) {
+                            $sReturn .= ' ' . $this->renderLink("deploy", $sPhase);
+                        }
+                    }
+                    break;
+
+                case "ready2install":
+                    break;
+
+                case "deployed":
+                    if ($bActions && $this->canAcceptPhase($sPhase)) {
+                        $sReturn .= ' ' . $this->renderLink("accept", $sPhase);
+                    }
+                    break;
+                default:
+                    break;
+            }
+            // $this->_getChecksumDiv($aData["revision"])
+        } else {
+            if (array_key_exists("error", $aData)) {
+                $sReturn.=''
+                        . $this->renderInfoLink(array('error' => $aData["error"]), array())
+                ;
+            } else if (array_key_exists("warning", $aData)) {
+                $sReturn.= '<div class="warning">'.$this->_oHtml->getIcon('sign-info'). t('warning') . ':<br>' . $aData["warning"] . '</div>';
+            } else {
+                return false;
+                // $sReturn.= t('empty');
+            }
+        } // if
+        // } // for
+        return $sReturn;
+    }
+
+    /**
+     * render html for the project overview; it shows the defined phases for 
+     * the project as a table
+     * @return type
+     */
+    public function renderPhaseInfo() {
+        $sRow1 = false;
+        $sRow2 = false;
+        foreach ($this->getActivePhases() as $sPhase) {
+            $sRow1.='<th class="' . $sPhase . '">' . $sPhase . '</th>';
+            $sRow2.='<td class="' . $sPhase . '">'
+                    . t('url') . ': <a href="' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '">' . $this->_aPrjConfig["phases"][$sPhase]["url"] . '</a><br>'
+                    . '<br>' . t('deploytimes') . ':<br>';
+            if (count($this->_getDeploytimes($sPhase))) {
+                $sRow2.=implode("<br>", $this->_getDeploytimes($sPhase));
+            } else {
+                $sRow2.=t('deploytimes-immediately');
+            }
+            $sRow2.='<br>' . $this->renderLink("phase", $sPhase)
+                    . $this->_renderHosts($sPhase)
+                    . '<br>'
+                    . $this->_renderFiles($sPhase)
+                    . '</td>';
+        }
+        return '<table><thead><tr>' . $sRow1 . '</tr></thead><tbody><tr>' . $sRow2 . '</tr></tbody></table>';
+    }
+
+    /**
+     * render html for a row with td for all places (first row)
+     * @param string $sPhase  phase (just needed for coloring)
+     * @return string
+     */
+    public function renderPlacesAsTd($sPhase) {
+        $sRow1 = '';
+        foreach (array_keys($this->_aPlaces) as $sPlace) {
+            $sRow1.='<td class="' . $sPhase . ' ' . $this->_aConfig["id"] . ' tdphase">' . t($sPlace) . '</td>';
+        }
+        return $sRow1;
+    }
+
+    /**
+     * return html code for the setup form of an exsiting project
+     * @return string
+     */
+    public function renderProjectSetup() {
+        if (!$this->oUser->hasPermission("project-action-setup")) {
+            return $this->oUser->showDenied();
+        }
+        $sMessages = '';
+        require_once ("formgen.class.php");
+
+
+            $aSelectProjectGroup = array(
+                'type' => 'select',
+                'name' => 'projectgroup',
+                'label' => t("projectgroup"),
+                'options' => array(
+                    OPTION_NONE => array(
+                        'label' => t('none'),
+                    ),
+                    '' => array(
+                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
+                    ),
+                ),
+            );
+            foreach($this->_aConfig['projectgroups'] as $sGroupid=>$sGroupLabel){
+                $bActive=$this->getProjectGroup() === $sGroupid;
+                $aSelectProjectGroup['options'][$sGroupid] = array(
+                    'label' => $sGroupLabel,
+                    'selected' => $bActive ? 'selected' : false,
+                );
+            }
+            
+        $aSelectSlack = array(
+                'type' => 'hidden',
+                'name' => 'messenger[slack]',
+                'value' => false,
+        );
+        if (
+                isset($this->_aConfig['messenger']['slack']['presets'])
+                && count($this->_aConfig['messenger']['slack']['presets'])
+        ) {
+            $aSelectSlack = array(
+                'type' => 'select',
+                'name' => 'messenger[slack]',
+                'label' => t("messenger-slack"),
+                'options' => array(
+                    OPTION_NONE => array(
+                        'label' => t('none'),
+                    ),
+                    '' => array(
+                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
+                    ),
+                ),
+            );
+            foreach($this->_aConfig['messenger']['slack']['presets'] as $sSlackUrl=>$aSlackCfg){
+                $bActive=$this->_aPrjConfig['messenger']['slack'] === $sSlackUrl;
+                $aSelectSlack['options'][$sSlackUrl] = array(
+                    'label' => array_key_exists('label', $aSlackCfg) ? $aSlackCfg['label'] : $sSlackUrl,
+                    'selected' => $bActive ? 'selected' : false,
+                );
+            }
+            
+        }
+        // ---------- Build plugins
+        /*
+        
+        $aPluginsBuild = array(
+            'select' => array(
+                'type' => 'checkbox',
+                'name' => 'build[enabled_build_plugins]',
+                'label' => t("build-plugins"),
+                'options' => [],
+            ),
+            // 'project-config' => '',
+        );
+        foreach (array_keys($this->getConfiguredPlugins('build')) as $sPluginName){
+
+            $sPluginFile=$this->_getPluginFilename('build', $sPluginName);
+            $TmpRolloutPlugin = false;
+            $sMyClassname='build_'. $sPluginName;
+            if(file_exists($sPluginFile)){
+            try{
+                include_once $this->_getPluginFilename('build', $sPluginName);
+                $TmpRolloutPlugin = new $sMyClassname([]);
+                echo "FOUND $sMyClassname<br>";
+                $aPluginsBuild['select']['options'][$sPluginName]=array(
+                        'label' => $TmpRolloutPlugin->getName(),
+                        'checked' => $bActive,
+                        // 'onclick' => '$(\'.'.$sMyDivClass.'\').hide(); $(\'.' . $sMyDivClassActive . '\').show();',
+                    );
+                } catch (Exception $ex) {
+
+                }
+            } else {
+                $aRollout['project-select']['options'][$sPluginName]=array(
+                        'label' => 'not found: <span class="error">' . $sMyClassname . '</span>',
+                        'checked' => false,
+                        'disabled' => "disabled",
+                    );
+
+                
+            }
+        }
+        echo '<pre>'; print_r($aPluginsBuild); die(__METHOD__);
+        */
+
+        // ---------- /Build plugins
+        
+        // ---------- Rollout plugins
+        $aRollout = array(
+            'project-select' => array(
+                'type' => 'radio',
+                'name' => 'deploy[enabled_rollout_plugin]',
+                'label' => t("deploy-rollout-plugin"),
+            ),
+            'project-config' => '',
+        );
+        foreach (array_keys($this->getConfiguredPlugins('rollout')) as $sPluginName){
+
+            $sPluginFile=$this->_getPluginFilename('rollout', $sPluginName);
+            $TmpRolloutPlugin = false;
+            $sMyClassname='rollout_'. $sPluginName;
+            $sMyDivId='rollout-'. $sPluginName.'-config';
+            $sMyDivClass='rolloutconfigdiv';
+            $sMyDivClassActive='rolloutconfigdiv-'. $sPluginName;
+            $bActive=$sPluginName === $this->oRolloutPlugin->getId();
+
+            if(file_exists($sPluginFile)){
+                try{
+                    include_once $this->_getPluginFilename('rollout', $sPluginName);
+                    $TmpRolloutPlugin = new $sMyClassname(array(
+                        'lang'=>$this->_aConfig['lang'],
+                        'phase'=>false,
+                        'globalcfg'=>$this->_aConfig['plugins']['rollout'][$sPluginName],
+                        'projectcfg'=>$this->_aPrjConfig,
+                    ));
+                    $aRollout['project-select']['options'][$sPluginName]=array(
+                            'label' => $TmpRolloutPlugin->getName(),
+                            'checked' => $bActive,
+                            'onclick' => '$(\'.'.$sMyDivClass.'\').hide(); $(\'.' . $sMyDivClassActive . '\').show();',
+                        );
+                    
+                    $aRollout['project-config'].=''
+                            . '<div id="'.$sMyDivId.'" class="'.$sMyDivClass.' '.$sMyDivClassActive.'"'
+                            . ($bActive ? '' : 'style="display: none;"' )
+                            . '>'
+                                . $TmpRolloutPlugin->renderFormdata4Project()
+                            . '</div>'
+                            ;
+                    
+                    // generate form firlds for each phase
+                    foreach(array_keys($this->getPhases()) as $sMyPhase){
+                        $aRollout[$sMyPhase].=''
+                            . '<div id="'.$sMyDivId.'-'.$sMyPhase.'" class="'.$sMyDivClass.' '.$sMyDivClassActive.'"'
+                            . ($bActive ? '' : 'style="display: none;"' )
+                            . '>'
+                                . $TmpRolloutPlugin->renderFormdata4Phase($sMyPhase)
+                            . '</div>'
+                            ;
+                    }
+                } catch (Exception $ex) {
+
+                }
+            } else {
+                $aRollout['project-select']['options'][$sPluginName]=array(
+                        'label' => 'not found: <span class="error">' . $sMyClassname . '</span>',
+                        'checked' => false,
+                        'disabled' => "disabled",
+                    );
+
+                
+            }
+        }
+        // ---------- /Rollout plugins
+        
+        $aForemanHostgroups = false;
+        $iForemanHostgroupDefault = false;
+        $sForemanHostgroupDefault = false;
+        if (array_key_exists('foreman', $this->_aConfig)) {
+            // echo '<pre>' . print_r($this->_aPrjConfig, 1) . '</pre>';
+            $iForemanHostgroupDefault = (int) $this->_aPrjConfig['deploy']['foreman']['hostgroup'];
+            require_once('foremanapi.class.php');
+            $oForeman = new ForemanApi($this->_aConfig['foreman']);
+            // $oForeman->setDebug(1);
+            // $oForeman->selfcheck(); die(__FUNCTION__);
+
+            $aForemanHostgroups = $oForeman->read(array(
+                'request' => array(
+                    array('hostgroups'),
+                // array('operatingsystems',4),
+                ),
+                'response' => array(
+                    'id', 'title'
+                ),
+            ));
+            $aSelectForemanGroups = array(
+                'type' => 'select',
+                'name' => 'deploy[foreman][hostgroup]',
+                'label' => $this->_oHtml->getIcon('foreman') . t("foreman-hostgroup"),
+                'options' => array(
+                    OPTION_NONE => array(
+                        'label' => t('none'),
+                    ),
+                    '' => array(
+                        'label' => '- - - - - - - - - - - - - - - - - - - - ',
+                    ),
+                ),
+            );
+            if ($aForemanHostgroups && count($aForemanHostgroups)) {
+                foreach ($aForemanHostgroups as $aItem) {
+                    $bActive=$iForemanHostgroupDefault === (int) $aItem['id'];
+                    $aSelectForemanGroups['options'][$aItem['id']] = array(
+                        'label' => $aItem['title'],
+                        'selected' => $bActive ? 'selected' : false,
+                    );
+                    $sForemanHostgroupDefault = $bActive ? $aItem['title'] : $sForemanHostgroupDefault;
+                }
+            }
+        }
+
+
+        $i = 0;
+
+        $aPrefixItem = count($this->getVersions()) ?
+                array(
+            'type' => 'markup',
+            'value' => '<div class="form-group">
+                        <label class="col-sm-2">' . t('fileprefix') . '</label>
+                        <div class="col-sm-10">
+                            <input id="inputprefix" type="hidden" name="fileprefix" value="' . $this->_aPrjConfig["fileprefix"] . '">
+                            ' . $this->_aPrjConfig["fileprefix"] . '
+                        </div></div>
+                            ',
+                ) : array(
+            'type' => 'text',
+            'name' => 'fileprefix',
+            // 'disabled' => 'disabled',
+            'label' => t('fileprefix-label'),
+            'value' => $this->_aPrjConfig["fileprefix"],
+            'required' => 'required',
+            'validate' => 'isastring',
+            'pattern' => '[a-z0-9\-_]*',
+            'size' => 100,
+            'placeholder' => '',
+        );
+
+        // detect access to repo url
+        $aBranches=$this->getRemoteBranches();
+        // $aRepodata = $this->getRepoRevision();
+
+        // if (is_array($aRepodata) && array_key_exists("message", $aRepodata)) {
+        if (is_array($aBranches) && count($aBranches)) {
+            $sRepoCheck = '<span class="ok">' . sprintf(t('class-project-info-repoaccess'), count($aBranches)) . '</span>';
+        } else {
+            $sRepoError=sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]);
+            $sRepoCheck = '<span class="error">' . $sRepoError . '</span>';
+            $sMessages.=$this->_oHtml->getBox("error", $sRepoError);
+        }
+
+        // generate datalist with exisating ssh keys for auth field
+        $sAuthListitems = '';
+        foreach ($this->_getSshKeys() as $sKey) {
+            $sAuthListitems.='<option value="' . $sKey . '">';
+        }
+        $aForms = array(
+            'setup' => array(
+                'meta' => array(
+                    'method' => 'POST',
+                    'action' => '?',
+                ),
+                'validate' => array(),
+                'form' => array(
+                    'input' . $i++ => array(
+                        'type' => 'hidden',
+                        'name' => 'setupaction',
+                        'value' => 'save',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'hidden',
+                        'name' => 'id',
+                        'value' => $this->_aConfig["id"],
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<div class="tabbable">
+                            <ul class="nav nav-tabs">
+                                <li class="active"><a href="#tab1" data-toggle="tab">' . $this->_oHtml->getIcon('list').t('setup-metadata') . '</a></li>
+                                <li><a href="#tab2" data-toggle="tab">' . $this->_oHtml->getIcon('repository').t('repositoryinfos') . '</a></li>
+
+                                <li><a href="#tab3" data-toggle="tab">' . $this->_oHtml->getIcon('deploy-configfile').t('deploy-configfile') . '</a></li>
+                                <li><a href="#tab4" data-toggle="tab">' . $this->_oHtml->getIcon('deploy-rollout-plugin').t('deploy-rollout-plugin') . '</a></li>
+                                <li><a href="#tab5" data-toggle="tab">' . $this->_oHtml->getIcon('phase').t('phases') . '</a></li>
+                                <li><a href="#tab6" data-toggle="tab">' . $this->_oHtml->getIcon('raw-data').t('raw-data') . '</a></li>
+                            </ul>
+                            <div class="tab-content">
+                            <div class="tab-pane active" id="tab1">
+                            
+                            ',
+                    ),
+
+                    // --------------------------------------------------
+                    // Tab for metadata
+                    // --------------------------------------------------
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'label',
+                        'label' => t('projectname'),
+                        'value' => $this->_aPrjConfig["label"],
+                        'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => 'Projekt',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'description',
+                        'label' => t('projectdescription'),
+                        'value' => $this->_aPrjConfig["description"],
+                        'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'contact',
+                        'label' => t('contact'),
+                        'value' => $this->_aPrjConfig["contact"],
+                        'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+
+                    'input' . $i++ => $aSelectProjectGroup,
+
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<p>' . t('messenger') . '</p>',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'messenger[email]',
+                        'label' => t("messenger-email"),
+                        'value' => $this->_aPrjConfig["messenger"]["email"],
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                        'autocomplete' => 'off',
+                    ),
+                    
+                    'input' . $i++ => $aSelectSlack,
+                    
+                    // --------------------------------------------------
+                    // Tab soources repository & build
+                    // --------------------------------------------------
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => ' </div><div class="tab-pane" id="tab2">
+                            <p>' . t('setup-hint-build') . '</p>',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'build[type]',
+                        'label' => t("build-type"),
+                        'value' => $this->_aPrjConfig["build"]["type"],
+                        'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'build[url]',
+                        'label' => t("repository-url"),
+                        'value' => $this->_aPrjConfig["build"]["url"],
+                        // 'required' => 'required',
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'build[auth]',
+                        'label' => t("repository-auth"),
+                        'value' => $this->_aPrjConfig["build"]["auth"],
+                        // 'required' => 'required',
+                        'list' => 'listauth', // listauth is the next form id below
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<datalist id="listauth">' . $sAuthListitems . '</datalist>',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<div class="form-group">'
+                        . '<label class="col-sm-2"> </label><div class="col-sm-10">'
+                        . $sRepoCheck
+                        . '</div></div>',
+                    ),
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'build[webaccess]',
+                        'label' => t("repository-urlwebgui"),
+                        'value' => $this->_aPrjConfig["build"]["webaccess"],
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),
+                    'input' . $i++ => $aPrefixItem,
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<div style="clear: both"></div>',
+                    ),
+                    // task#1498 - handle project without "public" directory
+                    'input' . $i++ => array(
+                        'type' => 'checkbox',
+                        'name' => 'build[haspublic]',
+                        'label' => t("repository-has-public-dir"),
+                        'required' => false,
+                        'validate' => 'isastring',
+                        'options' => array(
+                            '1' => array(
+                                'label' => t("yes"),
+                                'checked' => (array_key_exists('haspublic', $this->_aPrjConfig["build"]) ? $this->_aPrjConfig["build"]["haspublic"] : 0),
+                            ),
+                        ),
+                    ),
+
+                    // --------------------------------------------------
+                    // Tab for config and API key
+                    // --------------------------------------------------
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => ' </div><div class="tab-pane" id="tab3">
+                            <p>' . t('deploy-configfile-hint') . '</p>',
+                    ),
+                    'textarea' . $i++ => array(
+                        'type' => 'textarea',
+                        'name' => 'deploy[configfile]',
+                        'label' => t("deploy-configfile"),
+                        'value' => $this->_aPrjConfig['deploy']["configfile"],
+                        // 'required' => 'required',
+                        'validate' => 'isastring',  
+                        'cols' => 100,
+                        'rows' => 10,
+                        'placeholder' => 'export myvariable=&quot;hello world&quot;',
+                    ),
+   
+                    'input' . $i++ => array(
+                        'type' => 'text',
+                        'name' => 'api[secret]',
+                        'label' => t("api-secret"),
+                        'value' => $this->_aPrjConfig["api"]["secret"],
+                        'validate' => 'isastring',
+                        'size' => 100,
+                        'placeholder' => '',
+                    ),                    
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => '<div class="col-sm-12">'
+                        . '<p>' . t('api-secret-hint') . '<br>'
+                            . '<a href="#" class="btn btn-default" onclick="$(\'#input'.($i-2).'\').val(generateSecret(64)); return false">'.t("api-secret-generate").'</a>'
+                        . '</p></div>',
+                    ),
+                    
+                    // --------------------------------------------------
+                    // Tab rollout plugin
+                    // --------------------------------------------------
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => ' </div><div class="tab-pane" id="tab4">
+                            <p>' . t('deploy-rollout-plugin-hint') . '</p>',
+                    ),
+                    // select box for active rollout plugin
+                    $aRollout['project-select'],
+                    
+                    // project based config 
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => ''
+                            . '<hr>'
+                                .'<label class="col-sm-2">'.t('deploy-rollout-plugin-config') .'</label>'
+                                .'<div class="col-sm-10">'. $aRollout['project-config'].'</div>'
+                    ),
+                    // --------------------------------------------------
+                    'input' . $i++ => array(
+                        'type' => 'markup',
+                        'value' => ' </div><div class="tab-pane" id="tab5">
+                            <p>' . sprintf(t("class-project-info-setup-phaseinfos"), $this->getNextPhase()) . '</p>',
+                    ),
+                ),
+            ),
+        );
+        // --------------------------------------------------
+        // Tab for phases
+        // --------------------------------------------------
+        if ($aSelectForemanGroups) {
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => '<strong>'.t("defaults-all-phases").'</strong><br><br>',
+            );
+            $aForms["setup"]["form"]['input' . $i++] = $aSelectForemanGroups;
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => '<br><br>',
+            );
+        }
+        foreach (array_keys($this->getPhases()) as $sPhase) {
+
+            $bActivePhase = $this->isActivePhase($sPhase);
+            $sUrl = array_key_exists("url", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["url"] : "";
+            $sDeploymethod = array_key_exists("deploymethod", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["deploymethod"] : "";
+            $sDeployhosts = array_key_exists("hosts", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["hosts"] : "";
+
+            /*
+             * task-1847 - reove adding ssh key
+            if($sDeployhosts){
+                echo "$sDeployhosts<br>";
+                if(!strpos($sDeployhosts, ",")){
+                    $sCmd=sprintf($this->_aConfig["installPackages"]["addkeycommand"], $sDeployhosts, $sDeployhosts);
+                    exec($sCmd . " 2>&1", $aOut);
+                    echo "<pre>\$ $sCmd<br>"
+                        . implode('<br>', $aOut)
+                        ."</pre>"
+                        ;
+                }
+            }
+             */
+            $sDeploytimes = array_key_exists("deploytimes", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["deploytimes"] : "";
+            $sDivId4PhaseSettings = 'divSettings' . $sPhase;
+            $sDivId4TargetHosts = 'divSettings' . $sPhase . 'hosts';
+
+            if ($aSelectForemanGroups) {
+                $iForemanHostgroup = (int) $this->_aPrjConfig['phases'][$sPhase]['foreman-hostgroup'];
+                $aSelectForemanHostGroup = array(
+                    'type' => 'select',
+                    'name' => 'phases[' . $sPhase . '][foreman-hostgroup]',
+                    'label' => $this->_oHtml->getIcon('foreman') . t("foreman-hostgroup"),
+                    'options' => array(
+                        OPTION_DEFAULT => array(
+                            'label' => t('default') . ' (' . $sForemanHostgroupDefault . ')',
+                            'selected' => $iForemanHostgroup === OPTION_DEFAULT ? 'selected' : false,
+                        ),
+                        OPTION_NONE => array(
+                            'label' => t('none'),
+                            'selected' => $iForemanHostgroup === OPTION_NONE ? 'selected' : false,
+                        ),
+                        '' => array(
+                            'label' => '- - - - - - - - - - - - - - - - - - - - ',
+                        ),
+                    ),
+                );
+                if (is_array($aForemanHostgroups) && count($aForemanHostgroups)) {
+                    foreach ($aForemanHostgroups as $aItem) {
+                        $aSelectForemanHostGroup['options'][$aItem['id']] = array(
+                            'label' => $aItem['title'],
+                            'selected' => ($iForemanHostgroup === $aItem['id']) ? 'selected' : false,
+                        );
+                    }
+                }
+            }
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                // .'<pre>'.print_r($this->_aPrjConfig["phases"][$sPhase], 1).'</pre>'
+                /*
+                  . '<a class="'.$sPhase.'">'
+                  . t("phase") . ' ' . $sPhase
+                  . '</a>'
+                 */
+                . '<table class="table">'
+                . '<tbody>'
+                . '<tr><th class="' . $sPhase . '">' . $this->_oHtml->getIcon('phase') . t("phase") . ' ' . $sPhase . '</th></tr>'
+                . '<tr><td class="' . ($bActivePhase ? $sPhase : '') . '">'
+                . ''
+            );
+
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'checkbox',
+                'name' => 'phases[' . $sPhase . '][active]',
+                'label' => t("phase-is-active"),
+                // 'value' => $bUsePuppet,
+                'required' => false,
+                'validate' => 'isastring',
+                // 'size' => 100,
+                // 'placeholder' => '...',
+                'options' => array(
+                    '1' => array(
+                        'label' => t("yes"),
+                        'checked' => $bActivePhase,
+                        'onclick' => '$(\'#' . $sDivId4PhaseSettings . '\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
+                    ),
+                ),
+            );
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                . '<div id="' . $sDivId4PhaseSettings . '" ' . ($bActivePhase ? '' : ' style="display: none;"') . '">'
+            );
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'text',
+                'name' => 'phases[' . $sPhase . '][url]',
+                'label' => $this->_oHtml->getIcon('url') . t("url-project-website"),
+                'value' => $sUrl,
+                // 'required' => 'required',
+                'validate' => 'isastring',
+                'size' => 100,
+                'placeholder' => 'https://' . $sPhase . '.[' . t("project") . '].[...]/',
+            );
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'radio',
+                'name' => 'phases[' . $sPhase . '][deploymethod]',
+                'label' => $this->_oHtml->getIcon('method') . t("deploymethod"),
+                // 'value' => $bUsePuppet,
+                // 'required' => 'required',
+                'validate' => 'isastring',
+                // 'size' => 100,
+                // 'placeholder' => '...',
+                'options' => array(
+                    'none' => array(
+                        'label' => t("deploymethod-none"),
+                        'checked' => $sDeploymethod === "none",
+                        'onclick' => '$(\'#' . $sDivId4TargetHosts . '\').css(\'display\', (this.checked ? \'none\' : \'block\') )',
+                    ),
+                    'rolloutplugin' => array(
+                        // 'label' => t("deploymethod-puppet").' - '.  $this->oRolloutPlugin->getName(),
+                        'label' => t("deploymethod-rolloutplugin"),
+                        'checked' => $sDeploymethod === "rolloutplugin",
+                        'onclick' => '$(\'#' . $sDivId4TargetHosts . '\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
+                    ),
+                /*
+                 * see deploy method to handle an action
+                  'sshproxy' => array(
+                  'label' => t("deploymethod-sshproxy"),
+                  'checked' => $sDeploymethod==="sshproxy",
+                  'onclick' => '$(\'#'.$sDivId4TargetHosts.'\').css(\'display\', (this.checked ? \'block\' : \'none\') )',
+                  ),
+                 */
+                ),
+            );
+            
+
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                . '<div id="' . $sDivId4TargetHosts . '" ' . ($sDeploymethod !== "none" ? '' : ' style="display: none;"') . '">'
+            );
+            
+            // rollout plugin: phase specific overrides
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                    // . '<hr>'
+                    .'<label class="col-sm-2">'.t('deploy-rollout-plugin-config') .'</label>'
+                    .'<div class="col-sm-10">'.$aRollout[$sPhase].'</div>'
+            ); 
+            
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'text',
+                'name' => 'phases[' . $sPhase . '][hosts]',
+                'label' => $this->_oHtml->getIcon('host') . t("phase-targethosts"),
+                'value' => $sDeployhosts,
+                // 'required' => 'required',
+                'validate' => 'isastring',
+                'size' => 100,
+                'placeholder' => 'FQDN1,FQDN2',
+            );
+
+            /*
+              if ($sPuppethost) {
+
+              // add ssh host key
+              $sOut0 = shell_exec(sprintf($this->_aConfig["installPackages"]["addkeycommand"], $sPuppethost, $sPuppethost));
+
+              $sCmd2 = 'ssh ' . $this->_aConfig["installPackages"]["user"]
+              . '@' . $sPuppethost
+              . ' ' . $this->_aConfig["installPackages"]["testcommand"];
+              $sOut = 'skip';
+              // $sOut = shell_exec($sCmd2);
+              // Check auf Versionsnummer - mehr als n Zeichen ist mutmasslich eine Fehlermeldung
+              if (strlen($sOut) > 7) {
+              $sMessages.=$this->getBox("error", sprintf(t("class-project-error-setup-sudo-pupet-agent-failed"), $sPhase, $sCmd, $sOut));
+              $sOut = '<span class="error" title="' . $sCmd . '">' . $sOut . '</span>';
+              } else {
+              $sOut = '<span class="ok">' . sprintf(t("class-project-info-setup-ssh-and-puppet-ok"), $sPuppethost) . '</span>';
+              }
+              $aForms["setup"]["form"]['input' . $i++] = array(
+              'type' => 'markup',
+              'value' => '<div class="form-group">'
+              . '<label class="col-sm-2"> </label><div class="col-sm-10">'
+              . $sOut
+              . '</div></div>',
+              );
+              }
+             */
+
+            // when to deploy
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'text',
+                'name' => 'phases[' . $sPhase . '][deploytimes]',
+                'label' => $this->_oHtml->getIcon('time') . t("deploytimes"),
+                'value' => $sDeploytimes,
+                // 'required' => 'required',
+                'validate' => 'isastring',
+                'size' => 100,
+                'placeholder' => isset($this->_aConfig["phases"][$sPhase]["deploytimes"]) ? implode(", ", $this->_aConfig["phases"][$sPhase]["deploytimes"]) : '',
+            );
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                . '</div>'
+            );
+
+            if ($aSelectForemanGroups) {
+                $aForms["setup"]["form"]['input' . $i++] = $aSelectForemanHostGroup;
+            }
+
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => ''
+                . '</div>'
+            ); // close div for active phase
+
+
+            $aForms["setup"]["form"]['input' . $i++] = array(
+                'type' => 'markup',
+                'value' => '</td></tr></tbody></table>',
+            );
+        } // END: loop over phases
+
+        // --------------------------------------------------
+        // Tab for raw data
+        // --------------------------------------------------
+        
+        $sRolloutDebug='<hr>DEBUG:<br>';
+        foreach (array_keys($this->getPhases()) as $sPhase) {
+            if ($this->isActivePhase($sPhase)){
+                $sRolloutDebug.='<strong>'.$sPhase.'</strong>'
+                . '<pre>Config = '.print_r($this->oRolloutPlugin->getConfig($sPhase), 1).'</pre>'
+                . '<pre>Commands = '.print_r($this->oRolloutPlugin->getDeployCommands($sPhase), 1).'</pre>'
+                ;
+            }
+        }
+
+        $aForms["setup"]["form"]['input' . $i++] = array(
+            'type' => 'markup',
+            'value' => '</div>'
+            
+                . '<div class="tab-pane" id="tab6">'
+                . '<br><pre>'.print_r($this->_aPrjConfig, 1).'</pre>'
+                . $sRolloutDebug
+                . '</div>'
+            
+            . '</div>'
+            . '</div>'
+            . '<div style="clear: both; margin-bottom: 1em;"></div>'
+            
+            
+            . '<hr>',
+        );
+        $aForms["setup"]["form"]['input' . $i++] = array(
+            'type' => 'submit',
+            'name' => 'btnsave',
+            'label' => t("save"),
+            'value' => $this->_oHtml->getIcon('sign-ok').t("save"),
+        );
+
+        $oForm = new formgen($aForms);
+        return $sMessages . $oForm->renderHtml("setup");
+    }
+
+    /**
+     * return html code for the installed version in the repository
+     * @param boolean  $bRefresh  optional: refresh flag; default: use cached information
+     * @return string
+     */
+    public function renderRepoInfo($bRefresh=false) {
+        $sReturn = "";
+        switch ($this->_aPrjConfig["build"]["type"]) {
+            case "git":
+
+                $aRepodata = $this->getRepoRevision($bRefresh);
+                if (array_key_exists("revision", $aRepodata)) {
+                    $sReturn.=$this->_getChecksumDiv($aRepodata["revision"],
+                        $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . (array_key_exists("branch", $aRepodata) ? $aRepodata["branch"] : '-') . '<br>'
+                        . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aRepodata["revision"]) . '<br>'
+                        . $this->_oHtml->getIconByType('comment') . t('commitmessage') . ':<br>'
+                        )
+                        ."<pre>" . strip_tags($aRepodata["message"], '<br>') . "</pre>";
+                } else {
+                    $sReturn .= $this->_oHtml->getBox("error", sprintf(t('class-project-error-no-repoinfo'), $aRepodata["error"]))
+                            . $this->renderLink("setup") . '<br>';
+                }
+
+                break;
+
+            default:
+                $sReturn .= $this->_oHtml->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.=t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>';
+        }
+        return $sReturn;
+    }
+
+    /**
+     * get html code for a link to the commit
+     * (works for guithub and gitlab instances)
+     * 
+     * @param string $sRevision
+     * @return string
+     */
+    public function _renderRevision($sRevision) {
+        $sUrl = str_replace('/tree/master', '', $this->_aPrjConfig["build"]["webaccess"]) . '/commit/' . $sRevision;
+        return '<a href="' . $sUrl . '">' . $sRevision . '</a>';
+        return $sUrl;
+    }
+    /**
+     * get html form with selectr for remote branches
+     * @param string $sActiveBranchname  force active branch name
+     * @param bool $bIgnoreCache  flag to ignore exiting cached data
+     * @return string
+     */
+    public function renderSelectRemoteBranches($sActiveBranchname = false, $bIgnoreCache=false) {
+        $this->log(__FUNCTION__."(sActiveBranchname = $sActiveBranchname, bIgnoreCache = ".($bIgnoreCache ? 'true' : 'false').") start");
+        $aReturn = array();
+        $aRadios = array();
+        $bFoundActive = false;
+        $i = 0;
+        if (!$this->_oVcs) {
+            $this->_initVcs();
+        }
+        require_once("formgen.class.php");
+        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($bIgnoreCache) as $aBranch) {
+                $sBranch = $aBranch['name'];
+                $aRadios[$sBranch] = array(
+                    'value' => $sBranch,
+                    'label' => $aBranch['label'],
+                );
+                // if no param was given the first branch will be marked
+                if (!$sActiveBranchname) {
+                    $sActiveBranchname = $sBranch;
+                }
+                if ($sBranch == $sActiveBranchname) {
+                    $bFoundActive = true;
+                    // $aRadios[$sBranch]['checked'] = 'checked';
+                    $aRadios[$sBranch]['selected'] = 'selected';
+                } else {
+                    // for SELECT we need the onclick even on select element
+                    // not on the option (Chrome)
+                    // $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(
+                        'inline' => true,
+                        'type' => 'select',
+                        'onchange' => 'document.getElementById(\'submitBranch\').click()',
+                        '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',
+                'onclick' => 'showModalMessage(\'' . t('branch-switch') . '\'); ',
+                'label' => t("change"),
+                'value' => $this->_oHtml->getIcon('sign-ok').t("change"),
+            );
+        }
+
+        $oFrm = new formgen($aForms);
+        return $oFrm->renderHtml('frmSelectBranch')
+                . '<script>$("#submitBranch").hide();</script>';
+        // return $oFrm->renderHtmlElement('dummy',$aFormData);
+    }
+
+    /**
+     * return html code for a list of all built packages and their usage
+     * @return string
+     */
+    public function renderVersionUsage() {
+        $sReturn = false;
+        $sRowHead1 = false;
+        $sRowHead2 = '<td></td>';
+
+        $aAllVersions = $this->_getVersionUsage();
+        if (!count($aAllVersions)) {
+            return $this->_oHtml->getBox("info", t('class-project-info-no-package'));
+        }
+
+        foreach ($this->getActivePhases() as $sPhase) {
+            $sRowHead1.='<th class="' . $sPhase . '" colspan="' . (count($this->_aPlaces) + 1) . '">' . $sPhase . '</th>';
+            $sRowHead2.='<td></td>' . $this->renderPlacesAsTd($sPhase);
+        }
+        
+        krsort($aAllVersions);
+        foreach ($aAllVersions as $sVersion => $aData) {
+            $sReturn.='<tr>';
+
+            $sInfos = $this->renderInfoLink($aData["info"], array('hpos' => 'left'));
+            $sReturn.='<td>'
+                        . $this->_getChecksumDiv(
+                            $aData['info']['revision'],
+                            $this->_oHtml->getIconByType('calendar') . t('build-from') . ': ' . $sVersion .'<br>'
+                                . $this->_oHtml->getIconByType('branch') . t('branch') . ': ' . $aData['info']["branch"] . '<br>'
+                                . $this->_oHtml->getIconByType('revision') . t('revision') . ': ' . $this->_renderRevision($aData['info']["revision"]) . '<br>'
+                          )
+                    . '</td><td>'
+                    . '&nbsp;&nbsp;' . $sInfos . '&nbsp;&nbsp;'
+                    . '</td>'
+                    ;
+
+            foreach ($this->getActivePhases() as $sPhase) {
+                $sTLine = '';
+                $bCanRollback = $aData["rollback"][$sPhase];
+
+                // $sReturn.=$aData["rollback"][$sPhase] ? '<td>'.$this->renderLink("rollback", $sPhase, $sVersion).'</td>' : '<td>Rollback NOT possible</td>';
+                // $sReturn.=$aData["rollback"][$sPhase] ? '<td> Y </td>' : '<td> N </td>';
+                $sReturn.='<td>  </td>';
+
+                foreach (array_keys($this->_aPlaces) as $sPlace) {
+                    $bFound = false;
+                    $sReturn.=$aData["usage"][$sPhase][$sPlace] 
+                            ? '<td class="' . $sPhase . '" style="text-align: center;">'
+                            . $this->_getChecksumDiv($aData['info']['revision'], 'X')
+                            . '</td>' 
+                            : '<td> </td>'
+                        ;
+                }
+            }
+            $sReturn.='</tr>';
+        }
+
+        $sReturn = t('class-project-info-table-packages') . '<br><br>'
+                . '<table>'
+                . '<thead><tr><td>Version</td><td></td>'
+                . $sRowHead1
+                . '</tr><tr><td>'
+                . $sRowHead2
+                . '</tr></thead>'
+                . '<tbody>'
+                . $sReturn
+                . '</tbody>'
+                . '</table>';
+        return $sReturn;
+    }
+
+    /**
+     * render graphical overview of process (in project overview)
+     * @return string
+     */
+    public function renderVisual() {
+        $sReturn = '';
+        $sContinue = '<span style="font-size: 300%; color:#ace;">&raquo;&raquo;</span><br><br>';
+
+        $aBranches=$this->getRemoteBranches();
+        if(!is_array($aBranches)){
+            return t("project-setup-incomplete");
+        }
+
+        $sRepoBar = '';
+        /*
+            Speedup:
+            
+        $aRepodata = $this->getRepoRevision();
+        if (array_key_exists("revision", $aRepodata)) {
+            $sRepoBar = $this->_getChecksumDiv($aRepodata["revision"]);
+        } else {
+            $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>';
+        }
+
+        $sPhaseImg = '';
+        $sLastPhase = '';
+        foreach ($this->getActivePhases() as $sPhase) {
+            if ($sPhaseImg) {
+                $sAction = $sContinue;
+                if ($this->canAcceptPhase($sLastPhase)) {
+                    $sAction .= $this->renderLink("accept", $sLastPhase);
+                }
+                $sPhaseImg.='<div class="action">' . $sAction . '</div>';
+            }
+            $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>';
+            }
+            // $sDetail = $sFullbar . '<br><a href="#h3phases" class="scroll-link">' . $sPhase . '</a>';
+            $sDetail = $sFullbar . '<br>' . $sPhase;
+
+            $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>';
+        }
+            $sReturn = '
+            <div class="visualprocess">
+                <div class="process box">
+                    <div class="title">' . $this->_oHtml->getIcon('repository') . t("versioncontrol") . '</div>
+                    <div class="details">
+                        ' . $sRepoBar . '<br>
+                        <!--
+                        <a href="#h3repo" class="scroll-link">' . t("repositoryinfos") . '</a><br>
+                        -->
+                        ' . t("repositoryinfos") . '<br>
+                        ' . $this->_aPrjConfig["build"]["type"] . '</strong> ' . preg_replace('/.*\@(.*):.*/', '($1)', $this->_aPrjConfig["build"]["url"])
+                        . ': <strong title="' . t('branch-select') . '">' . count($aBranches) . '</strong>'
+                    . '<br>
+                    </div>
+                    <div>
+                        <img src="/deployment/images/process/bg_vcs.png" alt="' . t("versioncontrol") . '">
+                    </div>
+                </div>
+                
+                <div class="process">
+                    <div class="title">&nbsp;</div>
+                    <div class="action">' . $sContinue . t("build-hint-overview") . '<br><br>' . ($this->canAcceptPhase() ? $this->renderLink("build") : '') . '</div>
+                </div>
+
+                
+                <div class="process box">
+                    <div class="title">' . $this->_oHtml->getIcon('package') . t("archive") . '</div>
+                    <div class="details">
+                        ' . $sPackagebar . '<br>
+                        <!--
+                        <a href="#h3versions" class="scroll-link">' . t("packages") . '</a><br>
+                        -->
+                        ' . t("packages") . '<br>
+                        (<strong>' . count($this->_getVersionUsage()) . '</strong>)
+                    </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 . sprintf(t("queue-hint-overview"), $this->getNextPhase()).'</div>
+                </div>
+                
+                <div class="process phases box">
+                    <div class="title">'  . $this->_oHtml->getIcon('phase') . t("phases") . '</div>
+                    ' . ($sPhaseImg ? $sPhaseImg : '<div class="process">' . t("none") . '</div>') . '
+                </div>
+            </div>
+            ';
+        
+        return $sReturn;
+    }
+
+}
diff --git a/public_html/deployment/classes/projectlist.class.php b/public_html/deployment/classes/projectlist.class.php
index 92128f5340820b6aa5332304ec78ab69f279ca68..71a31dc92730724f7b415b543839619a0cb1528f 100644
--- a/public_html/deployment/classes/projectlist.class.php
+++ b/public_html/deployment/classes/projectlist.class.php
@@ -11,7 +11,7 @@
   ###################################################################### */
 
 require_once 'base.class.php';
-require_once 'project.class.php';
+require_once 'project_gui.class.php';
 
 /**
  * class for project overview
@@ -93,7 +93,7 @@ class projectlist extends base{
         ksort($aProjectLabels);
         
         foreach (array_values($aProjectLabels) as $sPrj) {
-            $oPrj = new project($sPrj);
+            $oPrj = new projectgui($sPrj);
             $sPrjFilter.='<option value="' . $sPrj . '">' . $oPrj->getLabel() . '</option>';
 
             $sOutPhases = '';
diff --git a/public_html/deployment/pages/act_accept.php b/public_html/deployment/pages/act_accept.php
index 7241d8ee8274a1ed6ec36533cc7d89c0ab7bfb60..974e87fa0ce80e5d9b88c573dfff3d73378b4fcd 100644
--- a/public_html/deployment/pages/act_accept.php
+++ b/public_html/deployment/pages/act_accept.php
@@ -10,10 +10,10 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 
 // --- Checks
-$oPrj = new project($aParams["prj"]);
+$oPrj = new projectgui($aParams["prj"]);
 
 if (array_key_exists("par3", $aParams)) {
     $sPhase = $aParams["par3"];
diff --git a/public_html/deployment/pages/act_build.php b/public_html/deployment/pages/act_build.php
index 55412973d6938d4a86b2b99e69cecd544b427742..51898dbdbe84ac4b8230e78c2ae594374e882093 100644
--- a/public_html/deployment/pages/act_build.php
+++ b/public_html/deployment/pages/act_build.php
@@ -12,12 +12,12 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 require_once("./classes/formgen.class.php");
 set_time_limit(0);
 
 // --- Checks
-$oPrj = new project($aParams["prj"]);
+$oPrj = new projectgui($aParams["prj"]);
 
 $sOut = '';
 
diff --git a/public_html/deployment/pages/act_delete.php b/public_html/deployment/pages/act_delete.php
index 6c8a94dac4a641a3e6971c6a08fed2da73d03079..a156e9fbd7e248455fffdc594cdc1229e264c9a7 100644
--- a/public_html/deployment/pages/act_delete.php
+++ b/public_html/deployment/pages/act_delete.php
@@ -13,10 +13,10 @@
   2014-03-24  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 require_once("./classes/formgen.class.php");
 
-$oPrj = new project($sPrj);
+$oPrj = new projectgui($sPrj);
 
 $sOut = '<h3>' . t('page-delete-project-info') . '</h3>';
 
diff --git a/public_html/deployment/pages/act_deploy.php b/public_html/deployment/pages/act_deploy.php
index 2d694e35a0b553724d369d21593f0b391da10a8b..77f9b747ed5b87fec96236be7c8b644d2999e031 100644
--- a/public_html/deployment/pages/act_deploy.php
+++ b/public_html/deployment/pages/act_deploy.php
@@ -10,12 +10,12 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 require_once("./classes/formgen.class.php");
 require_once("./inc_functions.php");
 
 // --- Checks
-$oPrj = new project($aParams["prj"]);
+$oPrj = new projectgui($aParams["prj"]);
 
 $sOut = '';
 if (array_key_exists("par3", $aParams)) {
diff --git a/public_html/deployment/pages/act_overview.php b/public_html/deployment/pages/act_overview.php
index 0cfe8e5c297800d51b10808768cef49c021fc6bd..3aca294e30730dffb760158f72cdde7c61b3e761 100644
--- a/public_html/deployment/pages/act_overview.php
+++ b/public_html/deployment/pages/act_overview.php
@@ -29,8 +29,8 @@ if (!array_key_exists("prj", $aParams)) {
     // ----------------------------------------------------------------------
     // overview of a single project
     // ----------------------------------------------------------------------
-    require_once("./classes/project.class.php");
-    $oPrj = new project($aParams["prj"]);
+    require_once("./classes/project_gui.class.php");
+    $oPrj = new projectgui($aParams["prj"]);
     
     $iCountOfBranches=0;
     $iCountOfBuildErrors=count($oPrj->getBuildErrors());
diff --git a/public_html/deployment/pages/act_phase.php b/public_html/deployment/pages/act_phase.php
index 647c274a3f0df699127d222ff9350d0651e9bd56..62a5538e0934f7463a1163f23827a634a56dbc2d 100644
--- a/public_html/deployment/pages/act_phase.php
+++ b/public_html/deployment/pages/act_phase.php
@@ -11,13 +11,13 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 require_once("./inc_functions.php");
 require_once("./classes/config-replacement.class.php");
 
 
 // --- Checks
-$oPrj = new project($aParams["prj"]);
+$oPrj = new projectgui($aParams["prj"]);
 
 $sOut = '';
 if (isset($aParams["par3"])) {
diff --git a/public_html/deployment/pages/act_setup.php b/public_html/deployment/pages/act_setup.php
index ddee084763fda8da636672e5cbe514a5522a0971..82121eda26bc82ccf5c2da7f600e10cfce24ebc9 100644
--- a/public_html/deployment/pages/act_setup.php
+++ b/public_html/deployment/pages/act_setup.php
@@ -12,7 +12,7 @@
   2013-11-08  Axel <axel.hahn@iml.unibe.ch>
   ###################################################################### */
 
-require_once("./classes/project.class.php");
+require_once("./classes/project_gui.class.php");
 require_once("./inc_functions.php");
 $sOut = '';
 
@@ -37,8 +37,8 @@ $aMask=array(
 
 /**
  * hide entries in config array
- * @param type $aMask
- * @param type $aConfig
+ * @param array $aMask
+ * @param array $aConfig
  * @return type
  */
 function maskEntries($aMask, $aConfig){
@@ -196,7 +196,7 @@ if ($aParams["prj"] == "all") {
         if ($aParams["par3"]=="new") {
             $sOut.='<h2>'.t("page-setup-info-new-project").'</h2>'
                     . '<p>'.t("page-setup-info-new-project-introtext").'</p><hr>';
-            $oPrj = new project();
+            $oPrj = new projectgui();
 
             if (array_key_exists("setupaction", $aParams) && $aParams["setupaction"] == "create") {
                 $sError = $oPrj->create($aParams["id"]);
@@ -329,7 +329,7 @@ if ($aParams["prj"] == "all") {
     // ------------------------------------------------------------
     // setup page of a an existing project
     // ------------------------------------------------------------
-    $oPrj = new project($aParams["prj"]);
+    $oPrj = new projectgui($aParams["prj"]);
     /*
     $sOut.='<div style="float: right">'
                 // . 'aParams:<pre>'.print_r($aParams, true).'</pre>'