diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php
index 73fb3d915873b7904847a18b1951f90bbd80f33e..04427f636cd852547d3f2bcbabb1d94e8c89bf5a 100644
--- a/htdocs/admin/notification.php
+++ b/htdocs/admin/notification.php
@@ -55,7 +55,7 @@ if ($action == 'setvalue' && $user->admin)
 	$result=dolibarr_set_const($db, "NOTIFICATION_EMAIL_FROM", $_POST["email_from"], 'chaine', 0, '', $conf->entity);
     if ($result < 0) $error++;
 
-    if (! $error)
+    if (! $error && is_array($_POST))
     {
     	//var_dump($_POST);
 	    foreach($_POST as $key => $val)
@@ -172,7 +172,7 @@ $var=true;
 $i=0;
 foreach($listofnotifiedevents as $notifiedevent)
 {
-    
+
     $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
 
     if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
@@ -183,7 +183,7 @@ foreach($listofnotifiedevents as $notifiedevent)
 
     if ($i) print ', ';
     print $label;
-     
+
     $i++;
 }
 print '</td></tr>';
@@ -213,7 +213,7 @@ $listofnotifiedevents=$notificationtrigger->getListOfManagedEvents();
 $var=true;
 foreach($listofnotifiedevents as $notifiedevent)
 {
-    
+
     $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
 
     if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
diff --git a/htdocs/admin/websites.php b/htdocs/admin/websites.php
index 0336a2533c0890db6f6900999b930be426bfe3d7..66776220d325ad57174a560fbdd5505a382e65c7 100644
--- a/htdocs/admin/websites.php
+++ b/htdocs/admin/websites.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,24 +48,21 @@ $acts[1] = "disable";
 $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
 $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
 
-$listoffset=GETPOST('listoffset');
-$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
 $status = 1;
 
-$sortfield = GETPOST("sortfield",'alpha');
-$sortorder = GETPOST("sortorder",'alpha');
-$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
-$offset = $listlimit * $page ;
+// Load variable for pagination
+$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
+$sortfield = GETPOST('sortfield','alpha');
+$sortorder = GETPOST('sortorder','alpha');
+$page = GETPOST('page','int');
+if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
+$offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
 $hookmanager->initHooks(array('admin'));
 
-// This page is a generic page to edit dictionaries
-// Put here declaration of dictionaries properties
-
 // Name of SQL tables of dictionaries
 $tabname=array();
 $tabname[1] = MAIN_DB_PREFIX."website";
@@ -118,7 +115,7 @@ $elementList = array();
 $sourceList=array();
 
 // Actions add or modify an entry into a dictionary
-if (GETPOST('actionadd') || GETPOST('actionmodify'))
+if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
 {
     $listfield=explode(',',$tabfield[$id]);
     $listfieldinsert=explode(',',$tabfieldinsert[$id]);
@@ -138,7 +135,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     }
 
     // Si verif ok et action add, on ajoute la ligne
-    if ($ok && GETPOST('actionadd'))
+    if ($ok && GETPOST('actionadd','alpha'))
     {
         if ($tabrowid[$id])
         {
@@ -200,7 +197,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     }
 
     // Si verif ok et action modify, on modifie la ligne
-    if ($ok && GETPOST('actionmodify'))
+    if ($ok && GETPOST('actionmodify','alpha'))
     {
         if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
         else { $rowidcol="rowid"; }
@@ -252,7 +249,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
 }
 
-if (GETPOST('actioncancel'))
+if (GETPOST('actioncancel','alpha'))
 {
     //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
 }
@@ -262,7 +259,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes')       // delete
     if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
     else { $rowidcol="rowid"; }
 
-    $sql = "DELETE from ".MAIN_DB_PREFIX."website_pages WHERE fk_website ='".$rowid."'";
+    $sql = "DELETE from ".MAIN_DB_PREFIX."website_page WHERE fk_website ='".$rowid."'";
     $result = $db->query($sql);
 
     $sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'";
@@ -341,7 +338,7 @@ if ($action == 'delete')
 //var_dump($elementList);
 
 /*
- * Show a dictionary
+ * Show website list
  */
 if ($id)
 {
@@ -412,11 +409,11 @@ if ($id)
 
         $obj = new stdClass();
         // If data was already input, we define them in obj to populate input fields.
-        if (GETPOST('actionadd'))
+        if (GETPOST('actionadd','alpha'))
         {
             foreach ($fieldlist as $key=>$val)
             {
-                if (GETPOST($val))
+                if (GETPOST($val,'alpha'))
                 	$obj->$val=GETPOST($val);
             }
         }
@@ -447,8 +444,7 @@ if ($id)
 
 
 
-    // List of available values in database
-    dol_syslog("htdocs/admin/dict", LOG_DEBUG);
+    // List of websites in database
     $resql=$db->query($sql);
     if ($resql)
     {
@@ -465,14 +461,6 @@ if ($id)
 
             print '<table class="noborder" width="100%">';
 
-            // There is several pages
-            if ($num > $listlimit)
-            {
-                print '<tr class="none"><td align="right" colspan="'.(3+count($fieldlist)).'">';
-                print_fleche_navigation($page, $_SERVER["PHP_SELF"], '', ($num > $listlimit), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page+1).'</span></li>');
-                print '</td></tr>';
-            }
-
             // Title of lines
             print '<tr class="liste_titre">';
             foreach ($fieldlist as $field => $value)
diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php
index 8f8295f0e53d39a64680b36ea0fdfb12f9ac3f02..eca126697cc515e77b8c9ba80ccbbd6ae8d9b7b0 100644
--- a/htdocs/bookmarks/bookmarks.lib.php
+++ b/htdocs/bookmarks/bookmarks.lib.php
@@ -53,11 +53,13 @@ function printBookmarksList($aDb, $aLangs)
 	    // No urlencode, all param $url will be urlencoded later
 	    if ($sortfield) $tmpurl.=($tmpurl?'&':'').'sortfield='.$sortfield;
 	    if ($sortorder) $tmpurl.=($tmpurl?'&':'').'sortorder='.$sortorder;
-	    foreach($_POST as $key => $val)
+	    if (is_array($_POST))
 	    {
-            if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val;
+    	    foreach($_POST as $key => $val)
+    	    {
+                if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val;
+    	    }
 	    }
-
 	    $url.=($tmpurl?'?'.$tmpurl:'');
 	}
 
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index 76a53924ad5cd2f6e0ad39ecdef7da63b00df396..9e293e09799599f4989295d2e2c243430cb1aaf2 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -129,10 +129,13 @@ $hookmanager->initHooks(array('agenda'));
 if (GETPOST("viewlist") || $action == 'show_list')
 {
     $param='';
-    foreach($_POST as $key => $val)
+    if (is_array($_POST))
     {
-        if ($key=='token') continue;
-        $param.='&'.$key.'='.urlencode($val);
+        foreach($_POST as $key => $val)
+        {
+            if ($key=='token') continue;
+            $param.='&'.$key.'='.urlencode($val);
+        }
     }
     //print $param;
     header("Location: ".DOL_URL_ROOT.'/comm/action/listactions.php?'.$param);
@@ -142,10 +145,13 @@ if (GETPOST("viewlist") || $action == 'show_list')
 if (GETPOST("viewperuser") || $action == 'show_peruser')
 {
     $param='';
-    foreach($_POST as $key => $val)
+    if (is_array($_POST))
     {
-        if ($key=='token') continue;
-        $param.='&'.$key.'='.urlencode($val);
+        foreach($_POST as $key => $val)
+        {
+            if ($key=='token') continue;
+            $param.='&'.$key.'='.urlencode($val);
+        }
     }
     //print $param;
     header("Location: ".DOL_URL_ROOT.'/comm/action/peruser.php?'.$param);
diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php
index 9cb14454cd510d651fd43e9e2ce3dcb4e706e11d..9e0d1530e85f940208b0679862d332bb5859ee15 100644
--- a/htdocs/comm/action/listactions.php
+++ b/htdocs/comm/action/listactions.php
@@ -120,10 +120,13 @@ $hookmanager->initHooks(array('agendalist'));
 if (GETPOST("viewcal") || GETPOST("viewweek") || GETPOST("viewday"))
 {
 	$param='';
-	foreach($_POST as $key => $val)
-	{
-		$param.='&'.$key.'='.urlencode($val);
-	}
+    if (is_array($_POST))
+    {
+    	foreach($_POST as $key => $val)
+    	{
+    		$param.='&'.$key.'='.urlencode($val);
+    	}
+    }
 	//print $param;
 	header("Location: ".DOL_URL_ROOT.'/comm/action/index.php?'.$param);
 	exit;
diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php
index fbd27b0d8412f760498a023fc77f372555f73c86..d5854297f43b76fc3cb056277149e17ddade97de 100644
--- a/htdocs/contact/card.php
+++ b/htdocs/contact/card.php
@@ -625,7 +625,7 @@ else
             // EMail
             if (($objsoc->typent_code == 'TE_PRIVATE' || ! empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->email)) == 0) $object->email = $objsoc->email;	// Predefined with third party
             print '<tr><td><label for="email">'.$langs->trans("Email").'</label></td>';
-	        print '<td><input name="email" id="email" type="text" class="maxwidth100onsmartphone" maxlength="80" value="'.(GETPOST("email",'alpha')?GETPOST("email",'alpha'):$object->email).'"></td>';
+	        print '<td><input name="email" id="email" type="text" class="maxwidth100onsmartphone" value="'.(GETPOST("email",'alpha')?GETPOST("email",'alpha'):$object->email).'"></td>';
             if (! empty($conf->mailing->enabled))
             {
             	print '<td><label for="no_email">'.$langs->trans("No_Email").'</label></td>';
@@ -860,7 +860,7 @@ else
 
             // EMail
             print '<tr><td><label for="email">'.$langs->trans("EMail").'</label></td>';
-	        print '<td><input name="email" id="email" type="text" class="flat maxwidthonsmartphone" maxlength="80" value="'.(isset($_POST["email"])?GETPOST("email"):$object->email).'"></td>';
+	        print '<td><input name="email" id="email" type="text" class="flat maxwidthonsmartphone" value="'.(isset($_POST["email"])?GETPOST("email"):$object->email).'"></td>';
             if (! empty($conf->mailing->enabled))
             {
                 $langs->load("mails");
diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php
index 03b33b19eb1d525d3da78db44c196cb4804b3be3..b8ae96cb9201dda4d6449c6254b0dd2ea96663c6 100644
--- a/htdocs/core/actions_setmoduleoptions.inc.php
+++ b/htdocs/core/actions_setmoduleoptions.inc.php
@@ -32,16 +32,19 @@ if ($action == 'setModuleOptions')
     $db->begin();
 
     // Process common param fields
-    foreach($_POST as $key => $val)
+    if (is_array($_POST))
     {
-        if (preg_match('/^param(\d*)$/', $key, $reg))    // Works for POST['param'], POST['param1'], POST['param2'], ...
+        foreach($_POST as $key => $val)
         {
-            $param=GETPOST("param".$reg[1],'alpha');
-            $value=GETPOST("value".$reg[1],'alpha');
-            if ($param)
+            if (preg_match('/^param(\d*)$/', $key, $reg))    // Works for POST['param'], POST['param1'], POST['param2'], ...
             {
-                $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity);
-                if (! $res > 0) $error++;
+                $param=GETPOST("param".$reg[1],'alpha');
+                $value=GETPOST("value".$reg[1],'alpha');
+                if ($param)
+                {
+                    $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity);
+                    if (! $res > 0) $error++;
+                }
             }
         }
     }
diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
index 137a55172317df35a7d807beae346dafeb0ea305..431c5d19eebb656f7c3ac05babbb3dfea426580d 100644
--- a/htdocs/core/class/menubase.class.php
+++ b/htdocs/core/class/menubase.class.php
@@ -402,7 +402,8 @@ class Menubase
     }
 
     /**
-     * 	Load entries found from database in this->newmenu array.
+     * 	Load entries found from database (and stored into $tabMenu) in $this->newmenu array.
+     *  Warning: Entries in $tabMenu must have child after parent
      *
      * 	@param	Menu	$newmenu        Menu array to complete (in most cases, it's empty, may be already initialized with some menu manager like eldy)
      * 	@param	string	$mymainmenu		Value for mainmenu to filter menu to load (often $_SESSION["mainmenu"])
@@ -435,10 +436,10 @@ class Menubase
         // We initialize newmenu with first already found menu entries
         $this->newmenu = $newmenu;
 
-        // Now edit this->newmenu->list to add entries found into tabMenu that are childs of mainmenu claimed, using the fk_menu link (old method)
+        // Now complete $this->newmenu->list to add entries found into $tabMenu that are childs of mainmenu=$menutopid, using the fk_menu link that is int (old method)
         $this->recur($tabMenu, $menutopid, 1);
 
-        // Now update this->newmenu->list when fk_menu value is -1 (left menu added by modules with no top menu)
+        // Now complete $this->newmenu->list when fk_menu value is -1 (left menu added by modules with no top menu)
         foreach($tabMenu as $key => $val)
         {
         	//var_dump($tabMenu);
@@ -479,6 +480,10 @@ class Menubase
         			}
         			//print 'We must insert menu entry between entry '.$lastid.' and '.$nextid.'<br>';
         			if ($found) $this->newmenu->insert($lastid, $val['url'], $val['titre'], $searchlastsub, $val['perms'], $val['target'], $val['mainmenu'], $val['leftmenu'], $val['position']);
+        			else {
+        			    dol_syslog("Error. Modules ".$val['module']." has defined a menu entry with a parent='fk_mainmenu=".$val['fk_leftmenu'].",fk_leftmenu=".$val['fk_leftmenu']."' and position=".$val['position'].'. The parent was not found. May be you forget it into your definition of menu, or may be the parent has a "position" that is after the child (fix field "position" of parent or child in this case).', LOG_WARNING);
+        			    //print "Parent menu not found !!<br>";
+        			}
         		}
         	}
         }
@@ -494,7 +499,7 @@ class Menubase
      *  @param	string	$myleftmenu     Value for left that defined leftmenu
      *  @param  int		$type_user      Looks for menu entry for 0=Internal users, 1=External users
      *  @param  string	$menu_handler   Name of menu_handler used ('auguria', 'eldy'...)
-     *  @param  array	$tabMenu       Array to store new entries found (in most cases, it's empty, but may be alreay filled)
+     *  @param  array	$tabMenu        Array to store new entries found (in most cases, it's empty, but may be alreay filled)
      *  @return int     		        >0 if OK, <0 if KO
      */
     function menuLoad($mymainmenu, $myleftmenu, $type_user, $menu_handler, &$tabMenu)
@@ -610,6 +615,11 @@ class Menubase
                 $a++;
             }
             $this->db->free($resql);
+
+            // Currently $tabMenu is sorted on position.
+            // If a child have a position lower that its parent, we can make a loop to fix this here, but we prefer to show a warning
+            // into the leftMenuCharger later to avoid useless operations.
+
             return 1;
         }
         else
@@ -622,7 +632,7 @@ class Menubase
     /**
      *  Complete this->newmenu with menu entry found in $tab
      *
-     *  @param  array	$tab			Tab array
+     *  @param  array	$tab			Tab array with all menu entries
      *  @param  int		$pere			Id of parent
      *  @param  int		$level			Level
      *  @return	void
diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
index 5836cb740dc017aebb6daf88906939ce1ce21b2c..aa0a31e972e6b964dfed22bed74a1a3ef932e65e 100644
--- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
+++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
@@ -74,7 +74,7 @@ ALTER TABLE llx_holiday ADD COLUMN ref	varchar(30) NULL;
 ALTER TABLE llx_holiday ADD COLUMN ref_ext	varchar(255);
 
 
-create table llx_notify_def_object
+CREATE TABLE llx_notify_def_object
 (
   id				integer AUTO_INCREMENT PRIMARY KEY,
   entity			integer DEFAULT 1 NOT NULL,		-- multi company id
@@ -129,14 +129,15 @@ ALTER TABLE llx_bank_account ADD COLUMN extraparams		varchar(255);
 -- VMYSQL4.1 ALTER TABLE llx_adherent MODIFY COLUMN country integer DEFAULT NULL;
 -- VPGSQL8.2 ALTER TABLE llx_adherent MODIFY COLUMN country integer USING country::integer;
 
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_CREATE','Product or service created','Executed when a product or sevice is created','product',30);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_MODIFY','Product or service modified','Executed when a product or sevice is modified','product',30);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_DELETE','Product or service deleted','Executed when a product or sevice is deleted','product',30);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('PRODUCT_CREATE','Product or service created','Executed when a product or sevice is created','product',30);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('PRODUCT_MODIFY','Product or service modified','Executed when a product or sevice is modified','product',30);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('PRODUCT_DELETE','Product or service deleted','Executed when a product or sevice is deleted','product',30);
 
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_CREATE','Expense report created','Executed when an expense report is created','expense_report',201);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_VALIDATE','Expense report validated','Executed when an expense report is validated','expense_report',202);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_APPROVE','Expense report approved','Executed when an expense report is approved','expense_report',203);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_PAYED','Expense report billed','Executed when an expense report is set as billed','expense_report',204);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('EXPENSE_REPORT_CREATE','Expense report created','Executed when an expense report is created','expense_report',201);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('EXPENSE_REPORT_CREATE','Expense report created','Executed when an expense report is created','expense_report',201);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('EXPENSE_REPORT_VALIDATE','Expense report validated','Executed when an expense report is validated','expense_report',202);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('EXPENSE_REPORT_APPROVE','Expense report approved','Executed when an expense report is approved','expense_report',203);
+INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('EXPENSE_REPORT_PAYED','Expense report billed','Executed when an expense report is set as billed','expense_report',204);
 
 ALTER TABLE llx_c_email_templates ADD COLUMN content_lines text;
 
@@ -196,7 +197,7 @@ CREATE TABLE llx_product_attribute_combination
 );
 
 
-ALTER TABLE llx_bank_account drop foreign key bank_fk_accountancy_journal;
+ALTER TABLE llx_bank_account DROP FOREIGN KEY bank_fk_accountancy_journal;
 
 -- Fix missing entity column after init demo
 ALTER TABLE llx_accounting_journal ADD COLUMN entity integer DEFAULT 1;
@@ -209,18 +210,18 @@ INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (
 INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Has new journal', 9, 1);
 INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (6,'ER', 'Expense report journal', 5, 1);
 -- Fix old entries
-UPDATE llx_accounting_journal SET nature = 1 where code = 'OD' and nature = 0;
-UPDATE llx_accounting_journal SET nature = 2 where code = 'VT' and nature = 1;
-UPDATE llx_accounting_journal SET nature = 3 where code = 'AC' and nature = 2;
-UPDATE llx_accounting_journal SET nature = 4 where (code = 'BK' or code = 'BQ') and nature = 3;
+UPDATE llx_accounting_journal SET nature = 1 WHERE code = 'OD' AND nature = 0;
+UPDATE llx_accounting_journal SET nature = 2 WHERE code = 'VT' AND nature = 1;
+UPDATE llx_accounting_journal SET nature = 3 WHERE code = 'AC' AND nature = 2;
+UPDATE llx_accounting_journal SET nature = 4 WHERE (code = 'BK' OR code = 'BQ') AND nature = 3;
 
-UPDATE llx_bank_account as ba set accountancy_journal = 'BQ' where accountancy_journal = 'BK';
-UPDATE llx_bank_account as ba set accountancy_journal = 'OD' where accountancy_journal IS NULL;
+UPDATE llx_bank_account SET accountancy_journal = 'BQ' WHERE accountancy_journal = 'BK';
+UPDATE llx_bank_account SET accountancy_journal = 'OD' WHERE accountancy_journal IS NULL;
 
 ALTER TABLE llx_bank_account ADD COLUMN fk_accountancy_journal integer;
 ALTER TABLE llx_bank_account ADD INDEX idx_fk_accountancy_journal (fk_accountancy_journal);
 
-UPDATE llx_bank_account as ba set fk_accountancy_journal = (SELECT rowid FROM llx_accounting_journal as aj where ba.accountancy_journal = aj.code) where accountancy_journal not in ('1', '2', '3', '4', '5', '6', '5', '8', '9', '10', '11', '12', '13', '14', '15');
+UPDATE llx_bank_account AS ba SET fk_accountancy_journal = (SELECT rowid FROM llx_accounting_journal AS aj WHERE ba.accountancy_journal = aj.code) WHERE accountancy_journal NOT IN ('1', '2', '3', '4', '5', '6', '5', '8', '9', '10', '11', '12', '13', '14', '15');
 ALTER TABLE llx_bank_account ADD CONSTRAINT fk_bank_account_accountancy_journal FOREIGN KEY (fk_accountancy_journal) REFERENCES llx_accounting_journal (rowid);
 
 --Update general ledger for FEC format & harmonization
@@ -233,7 +234,7 @@ ALTER TABLE llx_accounting_bookkeeping ADD COLUMN subledger_account varchar(32);
 ALTER TABLE llx_accounting_bookkeeping CHANGE COLUMN thirdparty_label subledger_label varchar(255);    	-- If field was already created, rename it	
 ALTER TABLE llx_accounting_bookkeeping ADD COLUMN subledger_label varchar(255) AFTER subledger_account;	-- If field dod not exists yet
 
-update llx_accounting_bookkeeping set subledger_account = numero_compte where subledger_account IS NULL;
+UPDATE llx_accounting_bookkeeping SET subledger_account = numero_compte WHERE subledger_account IS NULL;
 
 ALTER TABLE llx_accounting_bookkeeping MODIFY COLUMN label_compte varchar(255);
 ALTER TABLE llx_accounting_bookkeeping MODIFY COLUMN code_journal varchar(32);
@@ -358,9 +359,9 @@ ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_tx	     d
 ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_price	 double(24,8) DEFAULT NULL;
 ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_price_ttc double(24,8) DEFAULT NULL;
 
-UPDATE llx_contrat set ref = rowid where ref is null or ref = '';
+UPDATE llx_contrat SET ref = rowid WHERE ref IS NULL OR ref = '';
 
-create table llx_payment_various
+CREATE TABLE llx_payment_various
 (
   rowid                 integer AUTO_INCREMENT PRIMARY KEY,
   tms                   timestamp,
@@ -381,7 +382,7 @@ create table llx_payment_various
 )ENGINE=innodb;
 
 
-create table llx_default_values
+CREATE TABLE llx_default_values
 (
   rowid           integer AUTO_INCREMENT PRIMARY KEY,
   entity          integer DEFAULT 1 NOT NULL,		-- multi company id
@@ -441,27 +442,27 @@ ALTER TABLE llx_inventorydet ADD INDEX idx_inventorydet_tms (tms);
 ALTER TABLE llx_inventorydet ADD INDEX idx_inventorydet_datec (datec);
 ALTER TABLE llx_inventorydet ADD INDEX idx_inventorydet_fk_inventory (fk_inventory);
 
-insert into llx_c_tva(fk_pays,taux,code,recuperableonly,note,active)                                                   values (1, '8.5', '85', '0','VAT standard rate (DOM sauf Guyane et Saint-Martin)',0);
-insert into llx_c_tva(fk_pays,taux,code,recuperableonly,note,active)                                                   values (1, '8.5', '85NPR', '1','VAT standard rate (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0);
-insert into llx_c_tva(fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,note,active)                          values (1, '8.5', '85NPROM', '1', 2, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer',0);
-insert into llx_c_tva(fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values (1, '8.5', '85NPROMOMR', '1', 2, 3, 2.5, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer et Octroi de Mer Regional',0);
+INSERT INTO llx_c_tva(fk_pays,taux,code,recuperableonly,note,active)                                                   VALUES (1, '8.5', '85', '0','VAT standard rate (DOM sauf Guyane et Saint-Martin)',0);
+INSERT INTO llx_c_tva(fk_pays,taux,code,recuperableonly,note,active)                                                   VALUES (1, '8.5', '85NPR', '1','VAT standard rate (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0);
+INSERT INTO llx_c_tva(fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,note,active)                          VALUES (1, '8.5', '85NPROM', '1', 2, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer',0);
+INSERT INTO llx_c_tva(fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) VALUES (1, '8.5', '85NPROMOMR', '1', 2, 3, 2.5, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer et Octroi de Mer Regional',0);
 
 ALTER TABLE llx_events MODIFY COLUMN ip varchar(250);
 
 ALTER TABLE llx_facture ADD COLUMN fk_fac_rec_source integer;
 
-DELETE from llx_c_actioncomm where code in ('AC_PROP','AC_COM','AC_FAC','AC_SHIP','AC_SUP_ORD','AC_SUP_INV') AND id NOT IN (SELECT DISTINCT fk_action FROM llx_actioncomm);
+DELETE FROM llx_c_actioncomm WHERE code IN ('AC_PROP','AC_COM','AC_FAC','AC_SHIP','AC_SUP_ORD','AC_SUP_INV') AND id NOT IN (SELECT DISTINCT fk_action FROM llx_actioncomm);
 
 -- Fix: delete orphelin category.
-delete from llx_categorie_product where fk_categorie not in (select rowid from llx_categorie where type = 0);
-delete from llx_categorie_societe where fk_categorie not in (select rowid from llx_categorie where type in (1, 2));
-delete from llx_categorie_member where fk_categorie not in (select rowid from llx_categorie where type = 3);
-delete from llx_categorie_contact where fk_categorie not in (select rowid from llx_categorie where type = 4);
-delete from llx_categorie_project where fk_categorie not in (select rowid from llx_categorie where type = 5);
+DELETE FROM llx_categorie_product WHERE fk_categorie NOT IN (SELECT rowid FROM llx_categorie WHERE type = 0);
+DELETE FROM llx_categorie_societe WHERE fk_categorie NOT IN (SELECT rowid FROM llx_categorie WHERE type IN (1, 2));
+DELETE FROM llx_categorie_member WHERE fk_categorie NOT IN (SELECT rowid FROM llx_categorie WHERE type = 3);
+DELETE FROM llx_categorie_contact WHERE fk_categorie NOT IN (SELECT rowid FROM llx_categorie WHERE type = 4);
+DELETE FROM llx_categorie_project WHERE fk_categorie NOT IN (SELECT rowid FROM llx_categorie WHERE type = 5);
 
 ALTER TABLE llx_inventory ADD COLUMN ref varchar(48);
 
-create table llx_loan_schedule
+CREATE TABLE llx_loan_schedule
 (
   rowid				integer AUTO_INCREMENT PRIMARY KEY,
   fk_loan			integer,
@@ -495,6 +496,31 @@ ALTER TABLE llx_usergroup_rights DROP INDEX fk_usergroup;
 ALTER TABLE llx_usergroup_rights ADD UNIQUE INDEX uk_usergroup_rights (entity, fk_usergroup, fk_id);
 ALTER TABLE llx_usergroup_rights ADD CONSTRAINT fk_usergroup_rights_fk_usergroup FOREIGN KEY (fk_usergroup) REFERENCES llx_usergroup (rowid);
 
+-- For new module website
+
+CREATE TABLE llx_website_page
+(
+	rowid         integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
+	fk_website    integer NOT NULL,
+	pageurl       varchar(16) NOT NULL,
+	title         varchar(255),						
+	description   varchar(255),						
+	keywords      varchar(255),
+	content		  mediumtext,		-- text is not enough in size
+    status        integer,
+    fk_user_create integer,
+    fk_user_modif  integer,
+    date_creation  datetime,
+	tms            timestamp
+) ENGINE=innodb;
+
+ALTER TABLE llx_website_page ADD UNIQUE INDEX uk_website_page_url (fk_website,pageurl);
+
+ALTER TABLE llx_website_page ADD CONSTRAINT fk_website_page_website FOREIGN KEY (fk_website) REFERENCES llx_website (rowid);
+
+
+-- For new module blockedlog
+
 CREATE TABLE llx_blockedlog 
 ( 
 	rowid integer AUTO_INCREMENT PRIMARY KEY, 
diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql
index f67869f67baac18558561dc75ac88e562ec46a5f..f2e5066a0665d05e1aba92d1afb60aa9f793ddfe 100755
--- a/htdocs/install/mysql/migration/repair.sql
+++ b/htdocs/install/mysql/migration/repair.sql
@@ -330,7 +330,7 @@ drop table tmp_c_shipment_mode;
 -- Restore id of user on link for payment of expense report
 drop table tmp_bank_url_expense_user;
 create table tmp_bank_url_expense_user (select e.fk_user_author, bu2.fk_bank from llx_expensereport as e, llx_bank_url as bu2 where bu2.url_id = e.rowid and bu2.type = 'payment_expensereport');
-update llx_bank_url as bu set url_id = (select e.fk_user_author from tmp_bank_url_expense_user as e where e.fk_bank = bu.fk_bank) where bu.url_id = 0 and bu.type ='user';
+update llx_bank_url as bu set url_id = (select e.fk_user_author from tmp_bank_url_expense_user as e where e.fk_bank = bu.fk_bank) where (bu.url_id = 0 OR bu.url_id IS NULL) and bu.type ='user';
 drop table tmp_bank_url_expense_user;
 
 
diff --git a/htdocs/install/mysql/tables/llx_website_pages.key.sql b/htdocs/install/mysql/tables/llx_website_page.key.sql
similarity index 97%
rename from htdocs/install/mysql/tables/llx_website_pages.key.sql
rename to htdocs/install/mysql/tables/llx_website_page.key.sql
index 095dffabc95bc6c1cacdf2629320572c7912bee3..14488e588dc415341a241d3bcf7ccdf02abfa8f7 100644
--- a/htdocs/install/mysql/tables/llx_website_pages.key.sql
+++ b/htdocs/install/mysql/tables/llx_website_page.key.sql
@@ -16,7 +16,7 @@
 --
 -- ===========================================================================
 
-ALTER TABLE llx_website_page ADD UNIQUE INDEX uk_website_page_url (fk_website,pageurl);
+ALTER TABLE llx_website_page ADD UNIQUE INDEX uk_website_page_url (fk_website, pageurl);
 
 ALTER TABLE llx_website_page ADD CONSTRAINT fk_website_page_website FOREIGN KEY (fk_website) REFERENCES llx_website (rowid);
 
diff --git a/htdocs/install/mysql/tables/llx_website_pages.sql b/htdocs/install/mysql/tables/llx_website_page.sql
similarity index 100%
rename from htdocs/install/mysql/tables/llx_website_pages.sql
rename to htdocs/install/mysql/tables/llx_website_page.sql
diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php
index a0fdc22a015ccefc15856da4adfa4365ca5ea9cb..a8d17388d41fda7f48ce7ac0f2b33fda0c6cfad8 100644
--- a/htdocs/install/step1.php
+++ b/htdocs/install/step1.php
@@ -345,11 +345,14 @@ if (! $error && $db->connected)
 if (! $error && $db->connected && $action == "set")
 {
     umask(0);
-    foreach($_POST as $key => $value)
+    if (is_array($_POST))
     {
-        if (! preg_match('/^db_pass/i', $key)) {
-			dolibarr_install_syslog("step1: choice for " . $key . " = " . $value);
-		}
+        foreach($_POST as $key => $value)
+        {
+            if (! preg_match('/^db_pass/i', $key)) {
+    			dolibarr_install_syslog("step1: choice for " . $key . " = " . $value);
+    		}
+        }
     }
 
     // Show title of step
diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang
index 8fab0a7b07f510fee1877325ddc7b32ac671bbc3..5a3470aebce9d3289759797763790e3b78d3cd01 100644
--- a/htdocs/langs/en_US/modulebuilder.lang
+++ b/htdocs/langs/en_US/modulebuilder.lang
@@ -38,3 +38,5 @@ PathToModulePackage=Path to zip of module/application package
 PathToModuleDocumentation=Path to file of module/application documentation
 SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed.
 FileNotYetGenerated=File not yet generated
+SpecificationFile=File with business rules
+ConfirmDeleteProperty=Are you sure you want to delete the property <strong>%s</strong> ? This will change code in PHP class but also remove column from table definition of object.
\ No newline at end of file
diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
index abb7f7e56d34075b677b53a91c386f7c50f81de2..cc2f31143ceae1139aee790843e325994d6c4405 100644
--- a/htdocs/langs/en_US/website.lang
+++ b/htdocs/langs/en_US/website.lang
@@ -4,6 +4,7 @@ WebsiteSetupDesc=Create here as much entry as number of different websites you n
 DeleteWebsite=Delete website
 ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. 
 WEBSITE_PAGENAME=Page name/alias
+WEBSITE_HTML_HEADER=HTML Header
 WEBSITE_CSS_URL=URL of external CSS file
 WEBSITE_CSS_INLINE=CSS content
 PageNameAliasHelp=Name or alias of the page.<br>This alias is also used to forge a SEO URL when website is read from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "<strong>%s</strong>" to edit this alias.  
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index b5f88def445b17576cb84db4c1a9ca423deff3c5..1edc67d582f44033ba54fd179842a8ec0f648238 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -1498,10 +1498,12 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
 	    {
 	        $qs=dol_escape_htmltag($_SERVER["QUERY_STRING"]);
 
-			foreach($_POST as $key=>$value) {
-				if ($key!=='action' && !is_array($value)) $qs.='&'.$key.'='.urlencode($value);
-			}
-
+	        if (is_array($_POST))
+	        {
+    			foreach($_POST as $key=>$value) {
+    				if ($key!=='action' && !is_array($value)) $qs.='&'.$key.'='.urlencode($value);
+    			}
+	        }
 			$qs.=(($qs && $morequerystring)?'&':'').$morequerystring;
 	        $text ='<a href="'.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.$qs.($qs?'&':'').'optioncss=print" target="_blank">';
 	        //$text.= img_picto(":".$langs->trans("PrintContentArea"), 'printer_top.png', 'class="printer"');
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index 2547b893055c4705992692c65e3c6c35ebdf28e5..a1c30b7c94a60d15d5913da16b5395aab1d68a42 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -37,9 +37,10 @@ $cancel=GETPOST('cancel','alpha');
 $module=GETPOST('module','alpha');
 $tab=GETPOST('tab','aZ09');
 $tabobj=GETPOST('tabobj','alpha');
+$propertykey=GETPOST('propertykey','alpha');
 if (empty($module)) $module='initmodule';
 if (empty($tab)) $tab='description';
-if (empty($tabobj)) $tabobj='newobject';
+if (empty($tabobj)) $tabobj='newobjectifnoobj';
 $file=GETPOST('file','alpha');
 
 $modulename=dol_sanitizeFileName(GETPOST('modulename','alpha'));
@@ -58,6 +59,7 @@ $FILEFLAG='modulebuilder.txt';
 
 $now=dol_now();
 
+
 /*
  * Actions
  */
@@ -320,6 +322,29 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname)
     $tabobj = 'deleteobject';
 }
 
+if ($dirins && $action == 'confirm_deleteproperty' && $propertykey)
+{
+    if (! $error)
+    {
+        $modulelowercase=strtolower($module);
+        $objectlowercase=strtolower($objectname);
+
+        // File of class
+        $fileforclass = $dirins.'/'.$modulelowercase.'/class/'.$objectlowercase.'.class.php';
+
+        // TODO
+
+        // File of sql
+        $fileforsql = $dirins.'/'.$modulelowercase.'/sql/'.$objectlowercase.'.sql';
+        $fileforsqlkey = $dirins.'/'.$modulelowercase.'/sql/'.$objectlowercase.'.key.sql';
+
+
+        // TODO
+    }
+}
+
+
+
 if ($dirins && $action == 'generatepackage')
 {
     $modulelowercase=strtolower($module);
@@ -838,9 +863,11 @@ elseif (! empty($module))
             $h++;
 
             $listofobject = dol_dir_list($dir, 'files', 0, '\.txt$');
+            $firstobjectname='';
             foreach($listofobject as $fileobj)
             {
                 $objectname = preg_replace('/\.txt$/', '', $fileobj['name']);
+                if (empty($firstobjectname)) $firstobjectname = $objectname;
 
                 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.'&tabobj='.$objectname;
                 $head3[$h][1] = $objectname;
@@ -853,6 +880,12 @@ elseif (! empty($module))
             $head3[$h][2] = 'deleteobject';
             $h++;
 
+            // If tabobj was not defined, then we check if there is one obj. If yes, we force on it, if no, we will show tab to create new objects.
+            if ($tabobj == 'newobjectifnoobj')
+            {
+                if ($firstobjectname) $tabobj=$firstobjectname;
+                else $tabobj = 'newobject';
+            }
 
             dol_fiche_head($head3, $tabobj, '', -1, '');
 
@@ -888,91 +921,167 @@ elseif (! empty($module))
             }
             else
             {
-                try {
-                    $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
-                    $pathtoapi = strtolower($module).'/class/api_'.strtolower($tabobj).'.class.php';
-                    $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.class.php';
-                    $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.class.php';
-                    print '<span class="fa fa-file"></span> '.$langs->trans("ClassFile").' : <strong>'.$pathtoclass.'</strong><br>';
-                    print '<span class="fa fa-file"></span> '.$langs->trans("ApiClassFile").' : <strong>'.$pathtoapi.'</strong><br>';
-                    print '<span class="fa fa-file"></span> '.$langs->trans("PageForList").' : <strong>'.$pathtolist.'</strong><br>';
-                    print '<span class="fa fa-file"></span> '.$langs->trans("PageForCreateEditView").' : <strong>'.$pathtocard.'</strong><br>';
-
-                    $result = dol_include_once($pathtoclass);
-                    $tmpobjet = new $tabobj($db);
-
-                    $reflector = new ReflectionClass($tabobj);
-                    $properties = $reflector->getProperties();          // Can also use get_object_vars
-                    $propdefault = $reflector->getDefaultProperties();  // Can also use get_object_vars
-                    //$propstat = $reflector->getStaticProperties();
+                if ($action == 'deleteproperty')
+                {
+                    $formconfirm = $form->formconfirm(
+                        $_SERVER["PHP_SELF"].'?propertykey='.urlencode(GETPOST('propertykey','alpha')).'&objectname='.urlencode($objectname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj),
+                        $langs->trans('Delete'), $langs->trans('ConfirmDeleteProperty', GETPOST('propertykey','alpha')), 'confirm_deleteproperty', '', 0, 1
+                        );
 
-                    print load_fiche_titre($langs->trans("Properties"), '', '');
+                    // Print form confirm
+                    print $formconfirm;
+                }
 
-                    print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-                    print '<input type="hidden" name="action" value="initobject">';
-                    print '<input type="hidden" name="tab" value="objects">';
-                    print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                    print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                    print '<table class="noborder">';
-                    print '<tr class="liste_titre">';
-                    print '<td>'.$langs->trans("Property");
-                    print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
-                    print '</td>';
-                    print '<td>'.$langs->trans("Comment").'</td>';
-                    print '<td>'.$langs->trans("Type").'</td>';
-                    print '<td>'.$langs->trans("DefaultValue").'</td>';
-                    print '<td></td>';
-                    print '</tr>';
-                    print '<tr>';
-                    print '<td><input class="text" name="propname" value=""></td>';
-                    print '<td><input class="text" name="propname" value=""></td>';
-                    print '<td><input class="text" name="propname" value=""></td>';
-                    print '<td><input class="text" name="propname" value=""></td>';
-                    print '<td align="center">';
-                    print '<input class="button" type="submit" name="add" value="'.$langs->trans("Add").'">';
-                    print '</td></tr>';
-                    foreach($properties as $propkey => $propval)
-                    {
-                        if ($propval->class == $tabobj)
+                if ($action != 'editfile' || empty($file))
+                {
+                    try {
+                        $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
+                        $pathtoapi = strtolower($module).'/class/api_'.strtolower($tabobj).'.class.php';
+                        $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.php';
+                        $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php';
+                        print '<span class="fa fa-file"></span> '.$langs->trans("ClassFile").' : <strong>'.$pathtoclass.'</strong>';
+                        print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&file='.urlencode($pathtoclass).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
+                        print '<br>';
+                        print '<span class="fa fa-file"></span> '.$langs->trans("ApiClassFile").' : <strong>'.$pathtoapi.'</strong>';
+                        print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
+                        print '<br>';
+                        print '<span class="fa fa-file"></span> '.$langs->trans("PageForList").' : <strong>'.$pathtolist.'</strong>';
+                        print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&file='.urlencode($pathtolist).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
+                        print '<br>';
+                        print '<span class="fa fa-file"></span> '.$langs->trans("PageForCreateEditView").' : <strong>'.$pathtocard.'</strong>';
+                        print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&file='.urlencode($pathtocard).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
+                        print '<br>';
+
+                        $result = dol_include_once($pathtoclass);
+                        $tmpobjet = new $tabobj($db);
+
+                        $reflector = new ReflectionClass($tabobj);
+                        $properties = $reflector->getProperties();          // Can also use get_object_vars
+                        $propdefault = $reflector->getDefaultProperties();  // Can also use get_object_vars
+                        //$propstat = $reflector->getStaticProperties();
+
+                        print load_fiche_titre($langs->trans("Properties"), '', '');
+
+                        print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
+                        print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+                        print '<input type="hidden" name="action" value="initobject">';
+                        print '<input type="hidden" name="tab" value="objects">';
+                        print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
+                        print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
+
+                        print '<table class="noborder">';
+                        print '<tr class="liste_titre">';
+                        print '<td>'.$langs->trans("Property");
+                        print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
+                        print '</td>';
+                        print '<td>'.$langs->trans("Label").'</td>';
+                        print '<td>'.$langs->trans("Type").'</td>';
+                        print '<td>'.$langs->trans("Position").'</td>';
+                        print '<td>'.$langs->trans("DefaultValue").'</td>';
+                        print '<td>'.$langs->trans("Index").'</td>';
+                        print '<td>'.$langs->trans("Comment").'</td>';
+                        print '<td></td>';
+                        print '</tr>';
+                        print '<tr>';
+                        print '<td><input class="text" name="propname" value=""></td>';
+                        print '<td><input class="text" name="proplabel" value=""></td>';
+                        print '<td><input class="text" name="proptype" value=""></td>';
+                        print '<td><input class="text" name="propposition" value=""></td>';
+                        print '<td><input class="text" name="propdefault" value=""></td>';
+                        print '<td><input class="text" name="propindex" value=""></td>';
+                        print '<td><input class="text" name="propcomment" value=""></td>';
+                        print '<td align="center">';
+                        print '<input class="button" type="submit" name="add" value="'.$langs->trans("Add").'">';
+                        print '</td></tr>';
+
+                        $properties = $tmpobjet->fields;
+
+                        foreach($properties as $propkey => $propval)
                         {
-                            $propname=$propval->getName();
-
-                            // Discard generic properties
-                            if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue;
-
-                            // Keep or not lines
-                            if (in_array($propname, array('fk_element', 'lines'))) continue;
-
+                            /* If from Reflection
+                            if ($propval->class == $tabobj)
+                            {
+                                $propname=$propval->getName();
+                                $comment=$propval->getDocComment();
+                                $type=gettype($tmpobjet->$propname);
+                                $default=$propdefault[$propname];
+                                // Discard generic properties
+                                if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue;
+
+                                // Keep or not lines
+                                if (in_array($propname, array('fk_element', 'lines'))) continue;
+                            }*/
+
+                            $propname=$propkey;
+                            $proplabel=$propval['label'];
+                            $proptype=$propval['type'];
+                            $propposition=$propval['position'];
+                            $propdefault=$propval['default'];
+                            $propindex=$propval['index'];
+                            $propcomment=$propval['comment'];
+
+                            print '<tr class="oddeven">';
 
-                            print '<tr class="oddeven"><td>';
+                            print '<td>';
                             print $propname;
                             print '</td>';
                             print '<td>';
-                            print $propval->getDocComment();
+                            print $proplabel;
                             print '</td>';
                             print '<td>';
-                            print gettype($tmpobjet->$propname);
+                            print $proptype;
                             print '</td>';
-
                             print '<td>';
-                            print $propdefault[$propname];
+                            print $propposition;
                             print '</td>';
-
                             print '<td>';
-
+                            print $propdefault;
+                            print '</td>';
+                            print '<td>';
+                            print yn($propindex);
+                            print '</td>';
+                            print '<td>';
+                            print $propcomment;
+                            print '</td>';
+                            print '<td class="center">';
+                            print '<a href="'.$_SERVER["PHP_SELF"].'?action=deleteproperty&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
                             print '</td>';
+
                             print '</tr>';
                         }
-                    }
-                    print '</table>';
+                        print '</table>';
 
-                    print '</form>';
+                        print '</form>';
+                    }
+                    catch(Exception $e)
+                    {
+                        print $e->getMessage();
+                    }
                 }
-                catch(Exception $e)
+                else
                 {
-                    print $e->getMessage();
+                    $fullpathoffile=dol_buildpath($file, 0);
+
+                    $content = file_get_contents($fullpathoffile);
+
+                    // New module
+                    print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
+                    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+                    print '<input type="hidden" name="action" value="savefile">';
+                    print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
+                    print '<input type="hidden" name="tab" value="'.$tab.'">';
+                    print '<input type="hidden" name="module" value="'.$module.'">';
+
+                    $doleditor=new DolEditor('editfilecontent', $content, '', '600', 'Full', 'In', true, false, false, 0, '99%');
+                    print $doleditor->Create(1, '', false);
+                    print '<br>';
+                    print '<center>';
+                    print '<input type="submit" class="button" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
+                    print ' &nbsp; ';
+                    print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
+                    print '</center>';
+
+                    print '</form>';
                 }
             }
         }
diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
index 9ef593367c992d2026c5f2922d1692e56219cbb2..4c85a6e5a86352f9cb7453b75d68e14624970b8a 100644
--- a/htdocs/modulebuilder/template/class/myobject.class.php
+++ b/htdocs/modulebuilder/template/class/myobject.class.php
@@ -52,22 +52,24 @@ class MyObject extends CommonObject
 	 * @var array  Does myobject support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
 	 */
 	protected $ismultientitymanaged = 1;
-
-
 	/**
-     * @var string String with name of icon for myobject
-     */
+	 * @var string String with name of icon for myobject
+	 */
 	public $picto = 'myobject';
 
-	/**
-	 * @var int    Entity Id
-	 */
-	public $entity;
 
+	/* BEGIN PROPERTY FIELDS - Do not remove this comment */
 	/**
      * @var array  Array with all fields and their property
      */
-	public $fields;
+	public $fields=array(
+	    'ref'=>array('type'=>'string','label'=>'Ref','position'=>10,'index'=>true,'comment'=>'Reference of object'),
+	    'entity'=>array('type'=>'integer','label'=>'Entity','index'=>true),
+	    'status'=>array('type'=>'integer','label'=>'Status','index'=>true),
+	    'date'=>array('type'=>'date','label'=>'Date','default'=>'__NOW__'),
+	    'title'=>array('type'=>'string','label'=>'Title'),
+	);
+	/* END PROPERTY FIELDS - Do not remove this comment */
 
 
 
diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
index 33c52d58bea1a950eafcc4642d11af3555b65a33..cd3fb22be80afa5ae43c70b01d3fa3263b2cea3f 100644
--- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
+++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
@@ -99,7 +99,7 @@ class modMyModule extends DolibarrModules
 		                        );
 
 		// Data directories to create when module is enabled.
-		// Example: this->dirs = array("/mymodule/temp");
+		// Example: this->dirs = array("/mymodule/temp","/mymodule/subdir");
 		$this->dirs = array();
 
 		// Config pages. Put here list of php page, stored into mymodule/admin directory, to use to setup module.
@@ -288,6 +288,12 @@ class modMyModule extends DolibarrModules
 
 		$this->_load_tables('/mymodule/sql/');
 
+		// Create extrafields
+		include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+		$extrafields = new ExtraFields($this->db);
+		//$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty');
+		//$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'string', 1, 10, 'project');
+
 		return $this->_init($sql, $options);
 	}
 
diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
index 28624dc9fc2cec391b709c1cd695354e32b760b5..7e67c04ecc292c3cc3e1f3e0ce70e7d4d7d4745b 100644
--- a/htdocs/modulebuilder/template/myobject_list.php
+++ b/htdocs/modulebuilder/template/myobject_list.php
@@ -68,13 +68,7 @@ $toselect   = GETPOST('toselect', 'array');
 
 $id			= GETPOST('id','int');
 $backtopage = GETPOST('backtopage');
-$myparam	= GETPOST('myparam','alpha');
-
-$search_all=trim(GETPOST("sall"));
-$search_field1=GETPOST("search_field1");
-$search_field2=GETPOST("search_field2");
-$search_myfield=GETPOST('search_myfield');
-$optioncss = GETPOST('optioncss','alpha');
+$optioncss  = GETPOST('optioncss','alpha');
 
 // Load variable for pagination
 $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
@@ -85,6 +79,7 @@ if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined,
 $offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
+
 if (! $sortfield) $sortfield="t.rowid"; // Set here default search field
 if (! $sortorder) $sortorder="ASC";
 
@@ -96,6 +91,19 @@ if ($user->societe_id > 0)
 	//accessforbidden();
 }
 
+// Initialize array of search criterias
+$object=new MyModule($db);
+$search_all=trim(GETPOST("search_all"));
+$search=array();
+foreach($object->fields as $key)
+{
+    if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
+}
+/*$search_field1=GETPOST("search_field1");
+$search_field2=GETPOST("search_field2");
+$search_myfield=GETPOST('search_myfield');
+*/
+
 // Initialize technical object to manage context to save list fields
 $contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'myobjectlist';
 
@@ -133,8 +141,6 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
 }
 
 
-$object=new Skeleton_Class($db);
-
 
 
 
diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php
index 9cda69560d59c2f17826f0b742a167aa50596b77..908767afe320a51b564fb19bed271f80be8ac849 100644
--- a/htdocs/projet/activity/perday.php
+++ b/htdocs/projet/activity/perday.php
@@ -200,22 +200,25 @@ if ($action == 'addtime' && $user->rights->projet->lire)
 {
     $timespent_duration=array();
 
-    foreach($_POST as $key => $time)
+    if (is_array($_POST))
     {
-        if (intval($time) > 0)
+        foreach($_POST as $key => $time)
         {
-            // Hours or minutes of duration
-            if (preg_match("/([0-9]+)duration(hour|min)/",$key,$matches))
+            if (intval($time) > 0)
             {
-                $id = $matches[1];
-				if ($id > 0)
-				{
-	                // We store HOURS in seconds
-	                if($matches[2]=='hour') $timespent_duration[$id] += $time*60*60;
-
-	                // We store MINUTES in seconds
-	                if($matches[2]=='min') $timespent_duration[$id] += $time*60;
-				}
+                // Hours or minutes of duration
+                if (preg_match("/([0-9]+)duration(hour|min)/",$key,$matches))
+                {
+                    $id = $matches[1];
+    				if ($id > 0)
+    				{
+    	                // We store HOURS in seconds
+    	                if($matches[2]=='hour') $timespent_duration[$id] += $time*60*60;
+
+    	                // We store MINUTES in seconds
+    	                if($matches[2]=='min') $timespent_duration[$id] += $time*60;
+    				}
+                }
             }
         }
     }
diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php
index 5146e3ad6a59345ac2c09a2f23f6f7af8dc824cf..d7b683f92e7809571e5d734e81cd0ae8738b552c 100644
--- a/htdocs/societe/price.php
+++ b/htdocs/societe/price.php
@@ -187,7 +187,7 @@ if (! empty($conf->notification->enabled))
 	$langs->load("mails");
 $head = societe_prepare_head($object);
 
-dol_fiche_head($head, 'price', $langs->trans("ThirdParty"), 0, 'company');
+dol_fiche_head($head, 'price', $langs->trans("ThirdParty"), -1, 'company');
 
 $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php">'.$langs->trans("BackToList").'</a>';
 
@@ -200,11 +200,11 @@ print '<table class="border centpercent">';
 
 if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
 {
-	print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
+	print '<tr><td class="titlefield">' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
 }
 
 if ($object->client) {
-	print '<tr><td>';
+	print '<tr><td class="titlefield">';
 	print $langs->trans('CustomerCode') . '</td><td colspan="3">';
 	print $object->code_client;
 	if ($object->check_codeclient() != 0)
@@ -213,7 +213,7 @@ if ($object->client) {
 }
 
 if ($object->fournisseur) {
-	print '<tr><td>';
+	print '<tr><td class="titlefield">';
 	print $langs->trans('SupplierCode') . '</td><td colspan="3">';
 	print $object->code_fournisseur;
 	if ($object->check_codefournisseur() != 0)
diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js
index eabd0c58bd3dcf0f793d6fbeae51644c8aa7e60d..cddbef17dd1dc422da06c1c3ab94a10067f708d3 100644
--- a/htdocs/theme/eldy/ckeditor/config.js
+++ b/htdocs/theme/eldy/ckeditor/config.js
@@ -15,6 +15,7 @@ CKEDITOR.editorConfig = function( config )
 	//config.height = '300px';
 	//config.resize_dir = 'vertical';	// horizontal, vertical, both
 	config.removePlugins = 'elementspath,save'; // config.removePlugins = 'elementspath,save,font';
+	//config.extraPlugins = 'docprops,scayt,showprotected';
 	config.removeDialogTabs = 'flash:advanced';	// config.removeDialogTabs = 'flash:advanced;image:Link';
 	config.protectedSource.push( /<\?[\s\S]*?\?>/g );   // Prevent PHP Code to be formatted
 	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea' 
@@ -25,7 +26,10 @@ CKEDITOR.editorConfig = function( config )
 	config.dialog_backgroundCoverColor = 'rgb(255, 254, 253)';
 	//config.contentsCss = '/css/mysitestyles.css';
 	config.image_previewText=' ';	// Must no be empty
-		
+	//config.autoParagraph = false;
+	//config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd';		// See also rules on this.dataProcessor.writer.setRules
+	//config.forcePasteAsPlainText = true;
+	
 	config.toolbar_Full =
 	[
 	    ['Templates','NewPage'],
diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js
index 6f1bbe7fb3006e88f224ae6d4a957bca45e755d7..e0374f6b271d2d38912c33cc07a0d86aaa17cc9e 100644
--- a/htdocs/theme/md/ckeditor/config.js
+++ b/htdocs/theme/md/ckeditor/config.js
@@ -15,6 +15,7 @@ CKEDITOR.editorConfig = function( config )
 	//config.height = '300px';
 	//config.resize_dir = 'vertical';	// horizontal, vertical, both
 	config.removePlugins = 'elementspath,save'; // config.removePlugins = 'elementspath,save,font';
+	//config.extraPlugins = 'docprops,scayt,showprotected';
 	config.removeDialogTabs = 'flash:advanced';	// config.removeDialogTabs = 'flash:advanced;image:Link';
 	config.protectedSource.push( /<\?[\s\S]*?\?>/g );   // Prevent PHP Code to be formatted
 	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea' 
@@ -25,7 +26,10 @@ CKEDITOR.editorConfig = function( config )
 	config.dialog_backgroundCoverColor = 'rgb(255, 254, 253)';
 	//config.contentsCss = '/css/mysitestyles.css';
 	config.image_previewText=' ';	// Must no be empty
-		
+	//config.autoParagraph = false;
+	//config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd';		// See also rules on this.dataProcessor.writer.setRules
+	//config.forcePasteAsPlainText = true;
+	
 	config.toolbar_Full =
 	[
 	    ['Templates','NewPage'],
diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php
index 99fd4d64603da91e738e8a9e23fa33fb608ebdc1..4f9dc58c615dd70fa65f83e8001dc4c66523d41f 100644
--- a/htdocs/websites/class/websitepage.class.php
+++ b/htdocs/websites/class/websitepage.class.php
@@ -129,7 +129,7 @@ class WebsitePage extends CommonObject
 		$sql.= 'content,';
 		$sql.= 'status,';
 		$sql.= 'date_creation,';
-		$sql.= 'date_modification';
+		$sql.= 'tms';
 		$sql .= ') VALUES (';
 		$sql .= ' '.(! isset($this->fk_website)?'NULL':$this->fk_website).',';
 		$sql .= ' '.(! isset($this->pageurl)?'NULL':"'".$this->db->escape($this->pageurl)."'").',';
diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php
index a5c2ae4e0463f349f423523dc689305206d719e1..2c9c364edac0ed27868f358271cbf6d51bcfb3f8 100644
--- a/htdocs/websites/index.php
+++ b/htdocs/websites/index.php
@@ -129,6 +129,7 @@ if ($pageid > 0 && $action != 'add')
 
 global $dolibarr_main_data_root;
 $pathofwebsite=$dolibarr_main_data_root.'/websites/'.$website;
+$filehtmlheader=$pathofwebsite.'/header.html';
 $filecss=$pathofwebsite.'/styles.css.php';
 $filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php';
 $fileindex=$pathofwebsite.'/index.php';
@@ -240,25 +241,30 @@ if ($action == 'delete')
 // Update css
 if ($action == 'updatecss')
 {
-    //$db->begin();
-
     $res = $object->fetch(0, $website);
 
-    /*
-    $res = $object->update($user);
-    if ($res > 0)
-    {
-        $db->commit();
-        $action='';
-    }
-    else
+    // Html header file
+    $htmlheadercontent = '<!-- BEGIN DOLIBARR-WEBSITE-ADDED-HEADER -->'."\n";
+    $htmlheadercontent.= '<!-- File generated to save common html header - YOU CAN MODIFY DIRECTLY THIS FILE. Change affects all pages of website. -->'."\n";
+    $htmlheadercontent.= '<!-- END -->'."\n";
+    $htmlheadercontent.= GETPOST('WEBSITE_HTML_HEADER');
+
+    dol_syslog("Save file css into ".$filehtmlheader);
+
+    dol_mkdir($pathofwebsite);
+    $result = file_put_contents($filehtmlheader, $htmlheadercontent);
+    if (! empty($conf->global->MAIN_UMASK))
+        @chmod($filehtmlheader, octdec($conf->global->MAIN_UMASK));
+
+    if (! $result)
     {
         $error++;
-       $db->rollback();
-    }*/
+        setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors');
+    }
 
+    // Css file
     $csscontent = '<!-- BEGIN DOLIBARR-WEBSITE-ADDED-HEADER -->'."\n";
-    $csscontent.= '<!-- File generated to wrap the css file - DO NOT MODIFY - It is just a copy of database css content -->'."\n";
+    $csscontent.= '<!-- File generated to wrap the css file - YOU CAN MODIFY DIRECTLY THIS FILE. Change affects all pages of website. -->'."\n";
     $csscontent.= '<?php '."\n";
     $csscontent.= "header('Content-type: text/css');\n";
     $csscontent.= "?>"."\n";
@@ -278,6 +284,7 @@ if ($action == 'updatecss')
         setEventMessages('Failed to write file '.$filecss, null, 'errors');
     }
 
+
     if (! $error)
     {
         setEventMessages($langs->trans("Saved"), null, 'mesgs');
@@ -310,7 +317,7 @@ if ($action == 'setashome')
         dol_delete_file($fileindex);
 
         $indexcontent = '<?php'."\n";
-        $indexcontent.= '// File generated to wrap the home page - DO NOT MODIFY - It is just an include'."\n";
+        $indexcontent.= '// File generated to provide a shortcut to the Home Page - DO NOT MODIFY - It is just an include.'."\n";
         $indexcontent.= "include_once './".basename($filetpl)."'\n";
         $indexcontent.= '?>'."\n";
         $result = file_put_contents($fileindex, $indexcontent);
@@ -406,6 +413,7 @@ if ($action == 'updatemeta')
             $tplcontent.= '<?php require "./master.inc.php"; ?>'."\n";
             $tplcontent.= '<html>'."\n";
             $tplcontent.= '<header>'."\n";
+            $tplcontent.= '<title>'.dol_escape_htmltag($objectpage->title).'</title>'."\n";
             $tplcontent.= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'."\n";
             $tplcontent.= '<meta name="robots" content="index, follow" />'."\n";
             $tplcontent.= '<meta name="viewport" content="width=device-width, initial-scale=0.8">'."\n";
@@ -414,8 +422,10 @@ if ($action == 'updatemeta')
             $tplcontent.= '<meta name="title" content="'.dol_escape_htmltag($objectpage->title).'" />'."\n";
             $tplcontent.= '<meta name="description" content="'.dol_escape_htmltag($objectpage->description).'" />'."\n";
             $tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.'" />'."\n";
+            $tplcontent.= '<!-- Include link to CSS file -->'."\n";
             $tplcontent.= '<link rel="stylesheet" href="styles.css.php?websiteid='.$object->id.'" type="text/css" />'."\n";
-            $tplcontent.= '<title>'.dol_escape_htmltag($objectpage->title).'</title>'."\n";
+            $tplcontent.= '<!-- Include common page header file -->'."\n";
+            $tplcontent.= '<?php print file_get_contents(DOL_DATA_ROOT."/websites/'.$object->ref.'/header.html"); ?>'."\n";
             $tplcontent.= '</header>'."\n";
 
             $tplcontent.= '<body>'."\n";
@@ -458,7 +468,8 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage
     if (! is_link(dol_osencode($pathtomediasinwebsite)))
     {
         dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
-        symlink($pathtomedias, $pathtomediasinwebsite);
+        dol_mkdir(dirname($pathtomediasinwebsite));     // To be sure dir for website exists
+        $result = symlink($pathtomedias, $pathtomediasinwebsite);
     }
 
     /*if (GETPOST('savevirtualhost') && $object->virtualhost != GETPOST('previewsite'))
@@ -560,6 +571,7 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage
                 $tplcontent.= "// END PHP ?>\n";
         	    $tplcontent.= '<html>'."\n";
         	    $tplcontent.= '<header>'."\n";
+        	    $tplcontent.= '<title>'.dol_escape_htmltag($objectpage->title).'</title>'."\n";
         	    $tplcontent.= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'."\n";
         	    $tplcontent.= '<meta name="robots" content="index, follow" />'."\n";
         	    $tplcontent.= '<meta name="viewport" content="width=device-width, initial-scale=0.8">'."\n";
@@ -567,8 +579,10 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage
         	    $tplcontent.= '<meta name="title" content="'.dol_escape_htmltag($objectpage->title).'" />'."\n";
         	    $tplcontent.= '<meta name="description" content="'.dol_escape_htmltag($objectpage->description).'" />'."\n";
         	    $tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.'" />'."\n";
-        	    $tplcontent.= '<link rel="stylesheet" href="styles.css.php?websiteid='.$object->id.'" type="text/css" />'."\n";
-        	    $tplcontent.= '<title>'.dol_escape_htmltag($objectpage->title).'</title>'."\n";
+                $tplcontent.= '<!-- Include link to CSS file -->'."\n";
+                $tplcontent.= '<link rel="stylesheet" href="styles.css.php?websiteid='.$object->id.'" type="text/css" />'."\n";
+        	    $tplcontent.= '<!-- Include common page header file -->'."\n";
+                $tplcontent.= '<?php print file_get_contents(DOL_DATA_ROOT."/websites/'.$object->ref.'/header.html"); ?>'."\n";
         	    $tplcontent.= '</header>'."\n";
 
         	    $tplcontent.= '<body>'."\n";
@@ -939,6 +953,11 @@ if ($action == 'editcss')
 
     print '<br>';
 
+    $htmlheader = @file_get_contents($filehtmlheader);
+    // Clean the php css file to remove php code and get only html part
+    $htmlheader = preg_replace('/<!-- BEGIN DOLIBARR.*END -->/s', '', $htmlheader);
+
+
     $csscontent = @file_get_contents($filecss);
     // Clean the php css file to remove php code and get only css part
     $csscontent = preg_replace('/<!-- BEGIN DOLIBARR.*END -->/s', '', $csscontent);
@@ -957,11 +976,19 @@ if ($action == 'editcss')
     print '<tr><td class="tdtop">';
     print $langs->trans('WEBSITE_CSS_INLINE');
     print '</td><td>';
-    print '<textarea class="flat centpercent" rows="32" name="WEBSITE_CSS_INLINE">';
+    print '<textarea class="flat centpercent" rows="20" name="WEBSITE_CSS_INLINE">';
     print $csscontent;
     print '</textarea>';
     print '</td></tr>';
 
+    print '<tr><td class="tdtop">';
+    print $langs->trans('WEBSITE_HTML_HEADER');
+    print '</td><td>';
+    print '<textarea class="flat centpercent" rows="20" name="WEBSITE_HTML_HEADER">';
+    print $htmlheader;
+    print '</textarea>';
+    print '</td></tr>';
+
     /*print '<tr><td>';
     print $langs->trans('WEBSITE_CSS_URL');
     print '</td><td>';
@@ -1089,7 +1116,10 @@ if ($action == 'preview')
         $out.=$csscontent;
         $out.='</style>'."\n";
 
-        $out.=$objectpage->content."\n";
+        // Replace php code
+        $content = preg_replace('/<\?php.*\?>/ims', '<span style="background: #ddd; border: 1px solid #ccc; border-radius: 4px;">...php...</span>', $objectpage->content);
+
+        $out.=$content."\n";
 
         $out.='</div>';
 
diff --git a/test/phpunit/RestAPIDocumentTest.php b/test/phpunit/RestAPIDocumentTest.php
index b60a7e9e8336220ecea347ad584d9804f84f0dbf..7eb485ffbab9414d498107cf0ce288f21abece94 100644
--- a/test/phpunit/RestAPIDocumentTest.php
+++ b/test/phpunit/RestAPIDocumentTest.php
@@ -144,11 +144,11 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
 
         echo __METHOD__.' Request POST url='.$url."\n";
 
-        
+
         // Send to non existant directory
-        
+
         dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit');
-        
+
         //$data = '{ "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "" }';
         $data = array(
             'filename'=>"mynewfile.txt",
@@ -158,7 +158,7 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
             'filecontent'=>"content text",
             'fileencoding'=>""
         );
-        
+
         $result = getURLContent($url, 'POST', $data, 1);
         echo __METHOD__.' Result for sending document: '.var_export($result, true)."\n";
         echo __METHOD__.' curl_error_no: '.$result['curl_error_no']."\n";
@@ -166,11 +166,11 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
         $this->assertNotNull($object, 'Parsing of json result must no be null');
         $this->assertEquals('401', $object['error']['code']);
 
-        
+
         // Send to existant directory
-        
+
         dol_mkdir(DOL_DATA_ROOT.'/medias/tmpphpunit/tmpphpunit2');
-        
+
         $data = array(
             'filename'=>"mynewfile.txt",
             'modulepart'=>"medias",
@@ -187,5 +187,7 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
         $this->assertNotNull($object2, 'Parsing of json result must no be null');
         $this->assertEquals($result2['curl_error_no'], '');
         $this->assertEquals($result2['content'], 'true');
+
+        dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit');
     }
 }