diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8640c5e9b2fb92c66b23cdc9cf2d4e0850e2979b..a39f6b84a59b39453a774d63c8279fa71321658e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -97,7 +97,7 @@ When submitting a pull request, use same rule as [Commits](#commits) for the mes
 If your pull request only contains one commit, GitHub will be smart enough to fill it for you.
 Otherwise, please be a bit verbose about what you're providing.
 
-You Pull Request must pass the Continuous Integration checks.
+Your Pull Request must pass the Continuous Integration checks.
 Also, if you want to include a new external library (into htdocs/includes directory), please ask before to the project
 leader to see if such a library can be accepted.
 
diff --git a/dev/mail/source_email_from_thirdparty.txt b/dev/mail/source_email_from_thirdparty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e17afa194149df06ee2be3c2182931e60fa65c04
--- /dev/null
+++ b/dev/mail/source_email_from_thirdparty.txt
@@ -0,0 +1,48 @@
+Content-Type: multipart/mixed; boundary="===============4543832834454763172=="
+Date: Thu, 12 Nov 2015 17:58:00 -0000
+From: Administrator <admin@yourcompany.example.com>
+MIME-Version: 1.0
+Message-ID: 5nLkUQEIn50FnlwxWDkh59NfLof1ode0uC5cZEgm9Y4=@mailhog.example
+Message-Id: <1447351080.369951963424683.576889035053436-dolibarr-7-thirdparty@PCHOME-LD>
+Received: from pchome-ld by mailhog.example (Go-MailHog)
+          id 5nLkUQEIn50FnlwxWDkh59NfLof1ode0uC5cZEgm9Y4=@mailhog.example; Thu, 12 Nov 2015 18:58:00 +0100
+Reply-To: Administrator <admin@yourcompany.example.com>
+Return-Path: <admin@yourcompany.example.com>
+Subject: A test email from thirdparty card
+To: Thirdparty company <thirdpartycompany@yourcompany.example.com>
+
+--===============4543832834454763172==
+Content-Type: multipart/alternative;
+ boundary="===============8764907306434163361=="
+MIME-Version: 1.0
+
+--===============8764907306434163361==
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+
+dGVzdDIKCi0tCkFkbWluaXN0cmF0b3IKClNlbnQgYnkgWW91ckNvbXBhbnkgWzFdIHVzaW5nIE9k
+b28gWzJdCgosICBhY2Nlc3MgZGlyZWN0bHkgdG8gUGFydG5lciBBZ3JvbGFpdCBbM10KCgpbMV0g
+aHR0cDovL3d3dy5leGFtcGxlLmNvbQpbMl0gaHR0cHM6Ly93d3cub2Rvby5jb20vClszXSBodHRw
+Oi8vbG9jYWxob3N0OjgxNjkvd2ViL3NpZ251cD9yZWRpcmVjdD0lMkZ3ZWIlMjNhY3Rpb24lM0Rt
+YWlsLmFjdGlvbl9tYWlsX3JlZGlyZWN0JTI2bW9kZWwlM0RyZXMucGFydG5lciUyNmlkJTNENyZ0
+b2tlbj1nM0s0QWU1T0Q5a3UxaEVubVZUQiZkYj1vZG9vX3Y4Cg==
+
+--===============8764907306434163361==
+Content-Type: text/html; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+
+PHA+dGVzdDI8L3A+Cgo8c3Bhbj4tLTxicj4KQWRtaW5pc3RyYXRvcjwvc3Bhbj4KCjxiciAvPjxz
+bWFsbD5TZW50IGJ5IDxhIHN0eWxlPSdjb2xvcjppbmhlcml0JyBocmVmPSdodHRwOi8vd3d3LmV4
+YW1wbGUuY29tJz5Zb3VyQ29tcGFueTwvYT4gdXNpbmcgPGEgc3R5bGU9J2NvbG9yOmluaGVyaXQn
+IGhyZWY9J2h0dHBzOi8vd3d3Lm9kb28uY29tLyc+T2RvbzwvYT48L3NtYWxsPgoKCiwgPHNwYW4g
+Y2xhc3M9J29lX21haWxfZm9vdGVyX2FjY2Vzcyc+PHNtYWxsPmFjY2VzcyBkaXJlY3RseSB0byA8
+YSBzdHlsZT0nY29sb3I6aW5oZXJpdCcgaHJlZj0naHR0cDovL2xvY2FsaG9zdDo4MTY5L3dlYi9z
+aWdudXA/cmVkaXJlY3Q9JTJGd2ViJTIzYWN0aW9uJTNEbWFpbC5hY3Rpb25fbWFpbF9yZWRpcmVj
+dCUyNm1vZGVsJTNEcmVzLnBhcnRuZXIlMjZpZCUzRDcmdG9rZW49ZzNLNEFlNU9EOWt1MWhFbm1W
+VEImZGI9b2Rvb192OCc+UGFydG5lciBBZ3JvbGFpdDwvYT48L3NtYWxsPjwvc3Bhbj4K
+
+--===============8764907306434163361==--
+
+--===============4543832834454763172==--
\ No newline at end of file
diff --git a/dev/skeletons/skeleton_card.php b/dev/skeletons/skeleton_card.php
index a85969c53ad9301543ec6e8ae6ad67465ab0e97a..7f0ff1fc7d4ad3bbf92cc332f927075c94d21f55 100644
--- a/dev/skeletons/skeleton_card.php
+++ b/dev/skeletons/skeleton_card.php
@@ -112,7 +112,7 @@ if (empty($reshook))
 		if (empty($object->ref))
 		{
 			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")),'errors');
+			setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors');
 		}
 
 		if (! $error)
@@ -152,7 +152,7 @@ if (empty($reshook))
 		if (empty($object->ref))
 		{
 			$error++;
-			setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")),null,'errors');
+			setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors');
 		}
 
 		if (! $error)
@@ -189,8 +189,8 @@ if (empty($reshook))
 		}
 		else
 		{
-			if (! empty($object->errors)) setEventMessages(null,$object->errors,'errors');
-			else setEventMessages($object->error,null,'errors');
+			if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors');
+			else setEventMessages($object->error, null, 'errors');
 		}
 	}
 }
diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
index 271605830bc7a3a4fe47c8488699ed29d244542c..b084f21164c7096ead735f0bd33c5ed6aceaf802 100644
--- a/htdocs/admin/mails.php
+++ b/htdocs/admin/mails.php
@@ -152,7 +152,8 @@ if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GE
 	$subject    = $_POST['subject'];
 	$body       = $_POST['message'];
 	$deliveryreceipt= $_POST["deliveryreceipt"];
-
+	$trackid    = GETPOST('trackid');
+	
 	//Check if we have to decode HTML
 	if (!empty($conf->global->FCKEDITOR_ENABLE_MAILING) && dol_textishtml(dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401))) {
 		$body=dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401);
@@ -202,7 +203,9 @@ if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GE
             $sendtoccc,
             $deliveryreceipt,
             $msgishtml,
-            $errors_to
+            $errors_to,
+        	'',
+        	$trackid	
         );
 
 		$result=$mailfile->sendfile();
@@ -693,6 +696,7 @@ else
 		$formmail = new FormMail($db);
 		$formmail->fromname = (isset($_POST['fromname'])?$_POST['fromname']:$conf->global->MAIN_MAIL_EMAIL_FROM);
 		$formmail->frommail = (isset($_POST['frommail'])?$_POST['frommail']:$conf->global->MAIN_MAIL_EMAIL_FROM);
+		$formmail->trackid='test';
 		$formmail->withfromreadonly=0;
 		$formmail->withsubstit=0;
 		$formmail->withfrom=1;
diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php
index 14c95aa0d2e94cf62481d7bd03e22ce4b876d555..25868b7b2c2cc86b8c0dd8b9ff1bef637f31aca2 100644
--- a/htdocs/admin/modules.php
+++ b/htdocs/admin/modules.php
@@ -37,6 +37,7 @@ $langs->load("admin");
 $mode=GETPOST('mode', 'alpha')?GETPOST('mode', 'alpha'):(isset($_SESSION['mode'])?$_SESSION['mode']:0);
 $action=GETPOST('action','alpha');
 $value=GETPOST('value', 'alpha');
+$page_y=GETPOST('page_y','int');
 
 if (! $user->admin)
 	accessforbidden();
@@ -67,7 +68,7 @@ if ($action == 'set' && $user->admin)
 {
     $result=activateModule($value);
     if ($result) setEventMessages($result, null, 'errors');
-    header("Location: modules.php?mode=".$mode);
+    header("Location: modules.php?mode=".$mode.($page_y?'&page_y='.$page_y:''));
 	exit;
 }
 
@@ -75,7 +76,7 @@ if ($action == 'reset' && $user->admin)
 {
     $result=unActivateModule($value);
     if ($result) setEventMessages($result, null, 'errors');
-    header("Location: modules.php?mode=".$mode);
+    header("Location: modules.php?mode=".$mode.($page_y?'&page_y='.$page_y:''));
 	exit;
 }
 
@@ -425,7 +426,7 @@ if ($mode != 'marketplace')
         	}
         	else
         	{
-        		print '<a href="modules.php?id='.$objMod->numero.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
+        		print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
         		print img_picto($langs->trans("Activated"),'switch_on');
         		print '</a>';
         	}
@@ -488,7 +489,7 @@ if ($mode != 'marketplace')
         	else
         	{
 	        	// Module non actif
-	        	print '<a href="modules.php?id='.$objMod->numero.'&amp;action=set&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
+	        	print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;action=set&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
 	        	print img_picto($langs->trans("Disabled"),'switch_off');
 	        	print "</a>\n";
         	}
diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php
index 66878753b46ee7f00bcebad64449bcbd10308483..2adf79a61748c68bf8e60a6946d9b9d6c2007742 100644
--- a/htdocs/admin/oauth.php
+++ b/htdocs/admin/oauth.php
@@ -43,8 +43,9 @@ if (!$user->admin)
 
 $action = GETPOST('action', 'alpha');
 
-// Supported OAUTH
-$supportedoauth2array=array('OAUTH_GOOGLE_NAME');
+// Supported OAUTH (a provider is supported when a file xxx_oauth2callback.php is available into htdocs/core/modules/oauth)
+$supportedoauth2array=array('OAUTH_GOOGLE_NAME'=>'google');
+
 // API access parameters OAUTH
 $list = array (
             array(
@@ -315,7 +316,7 @@ $var = true;
 foreach ($list as $key)
 {
     $supported=0;
-    if (in_array($key[0], $supportedoauth2array)) $supported=1;
+    if (in_array($key[0], array_keys($supportedoauth2array))) $supported=1;
     if (! $supported) continue;     // show only supported
         
     print '<tr class="liste_titre">';
@@ -325,7 +326,7 @@ foreach ($list as $key)
 
     if ($supported)
     {
-        $redirect_uri=$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php';
+        $redirect_uri=$urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$key[0]].'_oauthcallback.php';
         $var = !$var;
         print '<tr '.$bc[$var].' class="value">';
         print '<td>'.$langs->trans("UseTheFollowingUrlAsRedirectURI").'</td>';
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index dd2bd1dd9c3ee41a21df0aea8f5ce2caa925f900..9b466e3d9b796cbc20059e984e4f83505d6206dd 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -87,7 +87,9 @@ $pid=GETPOST("projectid","int",3);
 $status=GETPOST("status");
 $type=GETPOST("type");
 $maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW);
-$actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':'');
+$actioncode=GETPOST("actioncode","array",3) ? GETPOST("actioncode","array",3):(GETPOST("actioncode")=='0'?'0':'');
+if(is_array($actioncode))$actioncode =implode(',', $actioncode);
+
 
 if ($actioncode == '') $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE);
 if ($status == ''   && ! isset($_GET['status']) && ! isset($_POST['status'])) $status=(empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS)?'':$conf->global->AGENDA_DEFAULT_FILTER_STATUS);
@@ -437,7 +439,7 @@ if ($filtert > 0 || $usergroup > 0) $sql.=", ".MAIN_DB_PREFIX."actioncomm_resour
 if ($usergroup > 0) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element";
 $sql.= ' WHERE a.fk_action = ca.id';
 $sql.= ' AND a.entity IN ('.getEntity('agenda', 1).')';
-if ($actioncode) $sql.=" AND ca.code='".$db->escape($actioncode)."'";
+if ($actioncode) $sql.=" AND ca.code IN ('".implode("','", explode(',',$actioncode))."')";
 if ($pid) $sql.=" AND a.fk_project=".$db->escape($pid);
 if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND (a.fk_soc IS NULL OR sc.fk_user = " .$user->id . ")";
 if ($socid > 0) $sql.= ' AND a.fk_soc = '.$socid;
diff --git a/htdocs/comm/askpricesupplier/card.php b/htdocs/comm/askpricesupplier/card.php
index 389905c3d9487bdfde87dd7d45c0ca58cc4d9e2a..900ef57d56a3722efb01c87bb8ccefc1e4b25d90 100644
--- a/htdocs/comm/askpricesupplier/card.php
+++ b/htdocs/comm/askpricesupplier/card.php
@@ -1786,6 +1786,16 @@ if ($action == 'create')
 		$formmail->fromid = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='spr'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'spr'.$object->id);
+		}
+		
 		$formmail->withfrom = 1;
 		$liste = array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value)
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 1107e3b9b4d3abfb6fcd4db21e2c9d22384260c2..1ef9953a6d9ce69d7b8a3fbd29e2056997db254a 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -1276,7 +1276,7 @@ if ($action == 'create')
 
 	// Ref customer
 	print '<tr><td>' . $langs->trans('RefCustomer') . '</td><td colspan="2">';
-	print '<input type="text" name="ref_client" value=""></td>';
+	print '<input type="text" name="ref_client" value="'.GETPOST('ref_client').'"></td>';
 	print '</tr>';
 
 	// Third party
@@ -1290,6 +1290,19 @@ if ($action == 'create')
 	} else {
 		print '<td colspan="2">';
 		print $form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 1);
+		// reload page to retrieve customer informations
+		if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
+		{
+			print '<script type="text/javascript">
+			$(document).ready(function() {
+				$("#socid").change(function() {
+					var socid = $(this).val();
+					// reload page
+					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&ref_client="+$("input[name=ref_client]").val();
+				});
+			});
+			</script>';
+		}
 		print '</td>';
 	}
 	print '</tr>' . "\n";
@@ -2304,6 +2317,15 @@ if ($action == 'create')
 		$formmail->fromid = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='pro'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'pro'.$object->id);
+		}		
 		$formmail->withfrom = 1;
 		$liste = array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value)
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index 6554073267483d21a928a77cd2710bce6aece392..cfa0d773acc04a1e871bdbbc0302d1d6dc2bd3b1 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -1346,10 +1346,10 @@ if ($action == 'create' && $user->rights->commande->creer)
 
 	// Reference client
 	print '<tr><td>' . $langs->trans('RefCustomer') . '</td><td colspan="2">';
-	if (!empty($conf->global->MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER))
+	if (!empty($conf->global->MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER) && ! empty($origin) && ! empty($originid))
 		print '<input type="text" name="ref_client" value="'.$ref_client.'"></td>';
 	else
-		print '<input type="text" name="ref_client" value=""></td>';
+		print '<input type="text" name="ref_client" value="'.GETPOST('ref_client').'"></td>';
 	print '</tr>';
 
 	// Client
@@ -1363,6 +1363,19 @@ if ($action == 'create' && $user->rights->commande->creer)
 	} else {
 		print '<td colspan="2">';
 		print $form->select_company('', 'socid', 's.client = 1 OR s.client = 3', 1);
+		// reload page to retrieve customer informations
+		if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
+		{
+			print '<script type="text/javascript">
+			$(document).ready(function() { 
+				$("#socid").change(function() {
+					var socid = $(this).val();
+					// reload page
+					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&ref_client="+$("input[name=ref_client]").val();
+				});
+			});
+			</script>';
+		}
 		print '</td>';
 	}
 	print '</tr>' . "\n";
@@ -2402,6 +2415,15 @@ if ($action == 'create' && $user->rights->commande->creer)
 			$formmail->fromid = $user->id;
 			$formmail->fromname = $user->getFullName($langs);
 			$formmail->frommail = $user->email;
+			if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+			{
+				$formmail->trackid='ord'.$object->id;
+			}
+			if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+			{
+				include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+				$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id);
+			}			
 			$formmail->withfrom = 1;
 			$liste = array();
 			foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value)
diff --git a/htdocs/compta/deplacement/card.php b/htdocs/compta/deplacement/card.php
index bc18d379a8790183e924f908e73b9149ea6b609e..f2fcd49027750619350b810b72735d9827472fcb 100644
--- a/htdocs/compta/deplacement/card.php
+++ b/htdocs/compta/deplacement/card.php
@@ -71,7 +71,7 @@ if ($action == 'validate' && $user->rights->deplacement->creer)
         }
         else
         {
-	        setEventMessage($object->error, 'errors');
+	        setEventMessages($object->error, $object->errors, 'errors');
         }
     }
 }
@@ -89,7 +89,7 @@ else if ($action == 'classifyrefunded' && $user->rights->deplacement->creer)
         }
         else
         {
-	        setEventMessage($object->error, 'errors');
+	        setEventMessages($object->error, $object->errors, 'errors');
         }
     }
 }
@@ -104,7 +104,7 @@ else if ($action == 'confirm_delete' && $confirm == "yes" && $user->rights->depl
     }
     else
     {
-	    setEventMessage($object->error, 'errors');
+	    setEventMessages($object->error, $object->errors, 'errors');
     }
 }
 
@@ -150,7 +150,7 @@ else if ($action == 'add' && $user->rights->deplacement->creer)
             }
             else
             {
-	            setEventMessage($object->error, 'errors');
+	            setEventMessages($object->error, $object->errors, 'errors');
                 $action='create';
             }
         }
@@ -190,7 +190,7 @@ else if ($action == 'update' && $user->rights->deplacement->creer)
         }
         else
         {
-	        setEventMessage($object->error, 'errors');
+	        setEventMessages($object->error, $object->errors, 'errors');
         }
     }
     else
@@ -411,8 +411,8 @@ else if ($id)
         }
         else
         {
-            /*
-             * Confirmation de la suppression du deplacement
+           /*
+            * Confirm delete trip 
             */
             if ($action == 'delete')
             {
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 29788e144087bbb4dad622b511c023f29f5c6437..19368863df971bd7417fdd138ce6c1e5333ea107 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -1960,6 +1960,19 @@ if ($action == 'create')
 	{
 		print '<td colspan="2">';
 		print $form->select_company('', 'socid', 's.client = 1 OR s.client = 3', 1);
+		// reload page to retrieve customer informations
+		if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
+		{
+			print '<script type="text/javascript">
+			$(document).ready(function() {
+				$("#socid").change(function() {
+					var socid = $(this).val();
+					// reload page
+					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid;
+				});
+			});
+			</script>';
+		}
 		print '</td>';
 	}
 	print '</tr>' . "\n";
@@ -3839,6 +3852,15 @@ else if ($id > 0 || ! empty($ref))
 		$formmail->fromid = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='inv'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'inv'.$object->id);
+		}		
 		$formmail->withfrom = 1;
 		$liste = array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) {
diff --git a/htdocs/compta/facture/contact.php b/htdocs/compta/facture/contact.php
index 8fe20cd66f6d7b8f1e57639d64c02659c57b4e33..b07a8f8c2d46b2a68f644b137f44344a49e195fa 100644
--- a/htdocs/compta/facture/contact.php
+++ b/htdocs/compta/facture/contact.php
@@ -2,7 +2,7 @@
 /* Copyright (C) 2005      Patrick Rouillon     <patrick@rouillon.net>
  * Copyright (C) 2005-2009 Destailleur Laurent  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
- * Copyright (C) 2011-2012 Philippe Grand       <philippe.grand@atoo-net.com>
+ * Copyright (C) 2011-2015 Philippe Grand       <philippe.grand@atoo-net.com>
  *
  * 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,7 +48,7 @@ $object = new Facture($db);
 
 
 /*
- * Ajout d'un nouveau contact
+ * Add a new contact
  */
 
 if ($action == 'addcontact' && $user->rights->facture->creer)
@@ -71,16 +71,16 @@ if ($action == 'addcontact' && $user->rights->facture->creer)
 		if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS')
 		{
 			$langs->load("errors");
-			setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors');
+			setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
 		}
 		else
 		{
-			setEventMessage($object->error, 'errors');
+			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
 }
 
-// Bascule du statut d'un contact
+// Toggle the status of a contact
 else if ($action == 'swapstatut' && $user->rights->facture->creer)
 {
 	if ($object->fetch($id))
@@ -93,7 +93,7 @@ else if ($action == 'swapstatut' && $user->rights->facture->creer)
 	}
 }
 
-// Efface un contact
+// Deletes a contact
 else if ($action == 'deletecontact' && $user->rights->facture->creer)
 {
 	$object->fetch($id);
@@ -124,7 +124,7 @@ $userstatic=new User($db);
 
 /* *************************************************************************** */
 /*                                                                             */
-/* Mode vue et edition                                                         */
+/* View and edit mode                                                         */
 /*                                                                             */
 /* *************************************************************************** */
 
@@ -139,7 +139,7 @@ if ($id > 0 || ! empty($ref))
 		dol_fiche_head($head, 'contact', $langs->trans('InvoiceCustomer'), 0, 'bill');
 
 		/*
-		 *   Facture synthese pour rappel
+		 *   Summary invoice for reminder
 		 */
 		print '<table class="border" width="100%">';
 
diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php
index f01c288e29edfc49712b4324fdef0a51aad3bca2..3f7aec9809fdffc5e92b3264c48a66bcb692161b 100644
--- a/htdocs/compta/facture/fiche-rec.php
+++ b/htdocs/compta/facture/fiche-rec.php
@@ -70,7 +70,7 @@ if ($action == 'add')
 {
 	if (! GETPOST('titre'))
 	{
-		setEventMessage($langs->transnoentities("ErrorFieldRequired",$langs->trans("Title")), 'errors');
+		setEventMessages($langs->transnoentities("ErrorFieldRequired",$langs->trans("Title")), null, 'errors');
 		$action = "create";
 		$error++;
 	}
@@ -88,13 +88,13 @@ if ($action == 'add')
 		}
 		else
 		{
-			setEventMessage($object->error, 'errors');
+			setEventMessages($object->error, $object->errors, 'errors');
 			$action = "create";
 		}
 	}
 }
 
-// Suppression
+// Delete
 if ($action == 'delete' && $user->rights->facture->supprimer)
 {
 	$object->fetch($id);
diff --git a/htdocs/compta/facture/mergepdftool.php b/htdocs/compta/facture/mergepdftool.php
index e0b821683ce5dd7c4a6c5c01d96d40318acd9d0a..968ab8543c2ea3a2cb683851f3d58ecf9e49bcdf 100644
--- a/htdocs/compta/facture/mergepdftool.php
+++ b/htdocs/compta/facture/mergepdftool.php
@@ -107,14 +107,14 @@ if ($action == 'presend' && GETPOST('sendmail'))
 	if (!isset($user->email))
 	{
 		$error++;
-		setEventMessage("NoSenderEmailDefined");
+		setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings');
 	}
 
 	$countToSend = count($_POST['toSend']);
 	if (empty($countToSend))
 	{
 		$error++;
-		setEventMessage("InvoiceNotChecked","warnings");
+		setEventMessages($langs->trans("InvoiceNotChecked"), null, 'warnings');
 	}
 
 	if (! $error)
@@ -260,11 +260,11 @@ if ($action == 'presend' && GETPOST('sendmail'))
 		if ($nbsent)
 		{
 			$action='';	// Do not show form post if there was at least one successfull sent
-			setEventMessage($nbsent. '/'.$countToSend.' '.$langs->trans("RemindSent"));
+			setEventMessages($nbsent. '/'.$countToSend.' '.$langs->trans("RemindSent"), null, 'mesgs');
 		}
 		else
 		{
-			setEventMessage($langs->trans("NoRemindSent"), 'warnings');  // May be object has no generated PDF file
+			setEventMessages($langs->trans("NoRemindSent"), null, 'warnings');  // May be object has no generated PDF file
 		}
 	}
 }
@@ -349,16 +349,16 @@ if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_s
 			@chmod($file, octdec($conf->global->MAIN_UMASK));
 
 			$langs->load("exports");
-			setEventMessage($langs->trans('FileSuccessfullyBuilt',$filename.'_'.dol_print_date($now,'dayhourlog')));
+			setEventMessages($langs->trans('FileSuccessfullyBuilt',$filename.'_'.dol_print_date($now,'dayhourlog')), null, 'mesgs');
 		}
 		else
 		{
-			setEventMessage($langs->trans('NoPDFAvailableForChecked'),'errors');
+			setEventMessages($langs->trans('NoPDFAvailableForChecked'), null, 'errors');
 		}
 	}
 	else
 	{
-		setEventMessage($langs->trans('InvoiceNotChecked'), 'warnings');
+		setEventMessages($langs->trans('InvoiceNotChecked'), null, 'warnings');
 	}
 }
 
@@ -371,8 +371,8 @@ if ($action == 'remove_file')
 	$upload_dir = $diroutputpdf;
 	$file = $upload_dir . '/' . GETPOST('file');
 	$ret=dol_delete_file($file);
-	if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
-	else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
+	if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
+	else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
 	$action='';
 }
 
@@ -574,6 +574,15 @@ if ($resql)
 		$formmail->fromid   = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='inv'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'inv'.$object->id);
+		}		
 		$formmail->withfrom=1;
 		$liste=array();
 		$formmail->withto=$langs->trans("AllRecipientSelectedForRemind");
diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php
index 78a93d7da0d655ed035f9749155f776c7c24a9a8..47abb50fb8bba0bc2c19241cc45882c8987634e7 100644
--- a/htdocs/compta/facture/prelevement.php
+++ b/htdocs/compta/facture/prelevement.php
@@ -75,12 +75,12 @@ if ($action == "new")
         {
         	$db->commit();
 
-            setEventMessage($langs->trans("RecordSaved"));
+            setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
         }
         else
 		{
         	$db->rollback();
-        	setEventMessage($object->error, $object->errors, 'errors');
+        	setEventMessages($object->error, $object->errors, 'errors');
         }
     }
     $action='';
diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php
index 51a899c074828b4fcfbf350f680f3518946874a4..ba65669aca449d5e07360e4ba73936b792f8d5dd 100644
--- a/htdocs/compta/paiement/card.php
+++ b/htdocs/compta/paiement/card.php
@@ -3,8 +3,8 @@
  * Copyright (C) 2004-2011 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
  * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
- * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
- * Copyright (C) 2015		Juanjo Menent		<jmenent@2byte.es>
+ * Copyright (C) 2013	   Marcos García		 <marcosgdf@gmail.com>
+ * Copyright (C) 2015	   Juanjo Menent		 <jmenent@2byte.es>
  *
  * 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
@@ -66,7 +66,7 @@ if ($action == 'setnote' && $user->rights->facture->paiement)
     }
     else
     {
-	    setEventMessage($object->error, 'errors');
+	    setEventMessages($object->error, $object->errors, 'errors');
         $db->rollback();
     }
 }
@@ -86,7 +86,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->
 	else
 	{
 	    $langs->load("errors");
-		setEventMessage($langs->trans($object->error), 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
         $db->rollback();
 	}
 }
@@ -124,7 +124,7 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->facture->
 	else
 	{
 	    $langs->load("errors");
-		setEventMessage($langs->trans($object->error), 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
 		$db->rollback();
 	}
 }
@@ -135,11 +135,11 @@ if ($action == 'setnum_paiement' && ! empty($_POST['num_paiement']))
     $res = $object->update_num($_POST['num_paiement']);
 	if ($res === 0)
 	{
-		setEventMessage($langs->trans('PaymentNumberUpdateSucceeded'));
+		setEventMessages($langs->trans('PaymentNumberUpdateSucceeded'), null, 'mesgs');
 	}
 	else
 	{
-		setEventMessage($langs->trans('PaymentNumberUpdateFailed'), 'errors');
+		setEventMessages($langs->trans('PaymentNumberUpdateFailed'), null, 'errors');
 	}
 }
 
@@ -150,11 +150,11 @@ if ($action == 'setdatep' && ! empty($_POST['datepday']))
 	$res = $object->update_date($datepaye);
 	if ($res === 0)
 	{
-		setEventMessage($langs->trans('PaymentDateUpdateSucceeded'));
+		setEventMessages($langs->trans('PaymentDateUpdateSucceeded'), null, 'mesgs');
 	}
 	else
 	{
-		setEventMessage($langs->trans('PaymentDateUpdateFailed'), 'errors');
+		setEventMessages($langs->trans('PaymentDateUpdateFailed'), null, 'errors');
 	}
 }
 
diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php
index 803787589fe73f35ec08a309cfb3d4f17699610b..163f242b76d8d5f9e097e43ec373a2fd93330a18 100644
--- a/htdocs/compta/paiement/cheque/card.php
+++ b/htdocs/compta/paiement/cheque/card.php
@@ -79,12 +79,12 @@ if ($action == 'setdate' && $user->rights->banque->cheque)
         $result=$object->set_date($user,$date);
         if ($result < 0)
         {
-			setEventMessage($object->error, 'errors');
+			setEventMessages($object->error, $object->errors, 'errors');
         }
     }
     else
     {
-        setEventMessage($object->error, 'errors');
+        setEventMessages($object->error, $object->errors, 'errors');
     }
 }
 
@@ -98,12 +98,12 @@ if ($action == 'setrefext' && $user->rights->banque->cheque)
         $result=$object->setValueFrom('ref_ext', $ref_ext);
         if ($result < 0)
         {
-            setEventMessage($object->error, 'errors');
+            setEventMessages($object->error, $object->errors, 'errors');
         }
     }
     else
     {
-        setEventMessage($object->error, 'errors');
+        setEventMessages($object->error, $object->errors, 'errors');
     }
 }
 
@@ -117,12 +117,12 @@ if ($action == 'setref' && $user->rights->banque->cheque)
 		$result=$object->set_number($user,$number);
 		if ($result < 0)
 		{
-			setEventMessage($object->error, 'errors');
+			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
 	else
 	{
-		setEventMessage($object->error, 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
 	}
 }
 
@@ -154,12 +154,12 @@ if ($action == 'create' && $_POST["accountid"] > 0 && $user->rights->banque->che
 		}
 		else
 		{
-			setEventMessage($object->error, 'errors');
+			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
 	else
 	{
-		setEventMessage($langs->trans("ErrorSelectAtLeastOne"));
+		setEventMessages($langs->trans("ErrorSelectAtLeastOne"), null, 'mesgs');
 	    $action='new';
 	}
 }
@@ -175,7 +175,7 @@ if ($action == 'remove' && $id > 0 && $_GET["lineid"] > 0 && $user->rights->banq
 	}
 	else
 	{
-		setEventMessage($object->error, 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
 	}
 }
 
@@ -190,7 +190,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->banque->c
 	}
 	else
 	{
-		setEventMessage($paiement->error, 'errors');
+		setEventMessages($paiement->error, $paiement->errors, 'errors');
 	}
 }
 
@@ -217,7 +217,7 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->banque->c
 	}
 	else
 	{
-		setEventMessage($object->error, 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
 	}
 }
 
@@ -230,7 +230,7 @@ if ($action == 'confirm_reject_check' && $confirm == 'yes' && $user->rights->ban
 	$paiement_id = $object->rejectCheck($rejected_check, $reject_date);
 	if ($paiement_id > 0)
 	{
-		setEventMessage($langs->trans("CheckRejectedAndInvoicesReopened"));
+		setEventMessages($langs->trans("CheckRejectedAndInvoicesReopened"), null, 'mesgs');
 		//header("Location: ".DOL_URL_ROOT.'/compta/paiement/card.php?id='.$paiement_id);
 		//exit;
 		$action='';
@@ -282,8 +282,8 @@ else if ($action == 'remove_file' && $user->rights->banque->cheque)
 
 		$file=$dir.get_exdir($object->number,0,1,0,$object,'cheque') . GETPOST('file');
 		$ret=dol_delete_file($file,0,0,0,$object);
-		if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('file')));
-		else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors');
+		if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs');
+		else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors');
 	}
 }
 
diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
index a4e83a0fd59cbb2c1b7e28a7a875776d6e67d19d..1f96d085bb844160639940a9a8cfff168b42c5de 100644
--- a/htdocs/core/actions_sendmails.inc.php
+++ b/htdocs/core/actions_sendmails.inc.php
@@ -221,11 +221,12 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
 			$filename = $attachedfiles['names'];
 			$mimetype = $attachedfiles['mimes'];
 
-			$trackid = GETPOST('trackid','aZ');
+			$trackid = GETPOST('trackid','aZ09');
 
-			if($conf->dolimail->enabled)
+			// Feature to push mail sent into Sent folder
+			if (! empty($conf->dolimail->enabled))
 			{
-				$mailfromid = explode ("#", $_POST['frommail'],3);
+				$mailfromid = explode("#", $_POST['frommail'],3);	// $_POST['frommail'] = 'aaa#Sent# <aaa@aaa.com>'	// TODO Use a better way to define Sent dir.
 				if (count($mailfromid)==0) $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>';
 				else
 				{
@@ -243,7 +244,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
 					{
 					
 						$folder=str_replace($ref, '', $mailboxconfig->folder_cache_key);
-						if (!$folder) $folder = "Sent";
+						if (!$folder) $folder = "Sent";	// Default Sent folder
 					
 						$mailboxconfig->mbox = imap_open($mailboxconfig->get_connector_url().$folder, $mailboxconfig->mailbox_imap_login, $mailboxconfig->mailbox_imap_password);
 						if (FALSE === $mailboxconfig->mbox) 
@@ -276,17 +277,16 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
 				if ($result)
 				{
 					$error=0;
-					if($conf->dolimail->enabled)
+					if (! empty($conf->dolimail->enabled))
 					{
-						$mid = (GETPOST('mid','int') ? GETPOST('mid','int') : 0);
+						$mid = (GETPOST('mid','int') ? GETPOST('mid','int') : 0);	// Original mail id is set ?
 						if ($mid)
 						{
-							// set imap flag answered if it is a answered mail
-							
+							// set imap flag answered if it is an answered mail
 							$dolimail=new DoliMail($db);
 							$dolimail->id = $mid;
 							$res=$dolimail->set_prop($user, 'answered',1);
-				  	}	
+				  		}	
 						if ($imap==1)
 						{
 							// write mail to IMAP Server
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index b3da46ff366bbaf97b474420d4bd6bcbed34d908..82d1444ff731db309b0d9386671c47e29fc16455 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -708,8 +708,10 @@ class CMailFile
 		$trackid = $this->trackid;
 		if ($trackid)
 		{
-			$out.= 'Message-ID: <' . time() . '.phpmail-'.$trackid.'@' . $host . ">" . $this->eol2;
-			$out.= 'references: <' . time() . '.phpmail-'.$trackid.'@' . $host . ">" . $this->eol2;
+			// References is kept in response and Message-ID is returned into In-Reply-To:
+			$out.= 'Message-ID: <' . time() . '.phpmail-dolibarr-'.$trackid.'@' . $host . ">" . $this->eol2;	// Uppercase seems replaced by phpmail
+			$out.= 'References: <' . time() . '.phpmail-dolibarr-'.$trackid.'@' . $host . ">" . $this->eol2;
+			$out.= 'X-Dolibarr-TRACKID: '.$trackid. $this->eol2;
 		}
 		else
 		{
diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php
index 53be6607f3808fe0f9ee8aa6272e5f27b5d51b3a..9aa2d868369bb3c74441723b1f308e9e76fa3f24 100644
--- a/htdocs/core/class/conf.class.php
+++ b/htdocs/core/class/conf.class.php
@@ -418,7 +418,8 @@ class Conf
 		// conf->mailing->email_from = email pour envoi par Dolibarr des mailings
 		$this->mailing->email_from=$this->email_from;
 		if (! empty($this->global->MAILING_EMAIL_FROM))	$this->mailing->email_from=$this->global->MAILING_EMAIL_FROM;
-
+		if (! isset($conf->global->MAIN_EMAIL_ADD_TRACK_ID)) $conf->global->MAIN_EMAIL_ADD_TRACK_ID=1;
+		
         // Format for date (used by default when not found or not searched in lang)
         $this->format_date_short="%d/%m/%Y";            // Format of day with PHP/C tags (strftime functions)
         $this->format_date_short_java="dd/MM/yyyy";     // Format of day with Java tags
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 2198cd9df13005e097692ac275a5526b7212362a..555b44423e145616deec598e326f3c2eb669639a 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -4687,7 +4687,7 @@ class Form
     			foreach ($array as $key => $value)
     			{
     				$out.= '<option value="'.$key.'"';
-    				if (is_array($selected) && ! empty($selected) && in_array($key, $selected))
+    				if (is_array($selected) && ! empty($selected) && in_array($key, $selected) && !empty($key))
     				{
     					$out.= ' selected';
     				}
@@ -4828,7 +4828,7 @@ class Form
 				$ways = $c->print_all_ways();       // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text
 				foreach($ways as $way)
 				{
-					$toprint[] = '<li class="select2-search-choice-dolibarr"'.($c->color?' style="background: #'.$c->color.'"':'').'>'.img_object('','category').' '.$way.'</li>';
+					$toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"'.($c->color?' style="background: #'.$c->color.';"':'').'>'.img_object('','category').' '.$way.'</li>';
 				}
 			}
 			return '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php
index 60fbdc0c467f68bb90249e34ad648c75a85d0b64..a5404135982a20c16ade8dd43c451cc4c3cfc2fb 100644
--- a/htdocs/core/class/html.formactions.class.php
+++ b/htdocs/core/class/html.formactions.class.php
@@ -246,10 +246,11 @@ class FormActions
      *  @param  string		$htmlname       Nom champ formulaire
      *  @param	string		$excludetype	Type to exclude
      *  @param	string		$onlyautoornot	Group list by auto events or not: We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO)
-     *  @param	int			$hideinfohelp	1=Do not show info help
+     *  @param	int		$hideinfohelp	1=Do not show info help
+     *  @param  int		$multiselect    1=Allow multiselect of action type for filter or search
      * 	@return	void
      */
-    function select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0, $hideinfohelp=0)
+    function select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0, $hideinfohelp=0, $multiselect=0)
     {
         global $langs,$user,$form,$conf;
 
@@ -269,7 +270,16 @@ class FormActions
 
        	if (! empty($conf->global->AGENDA_ALWAYS_HIDE_AUTO)) unset($arraylist['AC_OTH_AUTO']);
 
-        print $form->selectarray($htmlname, $arraylist, $selected);
+		if($multiselect==1) {
+	        if(!is_array($selected) && !empty($selected)) $selected = explode(',', $selected);
+			print $form->multiselectarray($htmlname, $arraylist,$selected,0, 0, '', 0, 200);
+			
+		}
+		else {
+			print $form->selectarray($htmlname, $arraylist, $selected);
+		}
+        
+		
         if ($user->admin && empty($onlyautoornot) && empty($hideinfohelp)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
     }
 
diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php
index 51d9dd621dc86e036339dd96c609192567e669bf..dd2726d230689dd1a9950e1bffbe516b73c45ab9 100644
--- a/htdocs/core/class/smtps.class.php
+++ b/htdocs/core/class/smtps.class.php
@@ -1133,8 +1133,10 @@ class SMTPs
 		$trackid = $this->getTrackId();
 		if ($trackid)
 		{
-			$_header .= 'Message-ID: <' . time() . '.SMTPs-'.$trackid.'@' . $host . ">\r\n";
-			$_header .= 'references: <' . time() . '.SMTPs-'.$trackid.'@' . $host . ">\r\n";
+			// References is kept in response and Message-ID is returned into In-Reply-To:
+			$_header .= 'Message-ID: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
+			$_header .= 'References: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
+			$_header .= 'X-Dolibarr-TRACKID: ' . $trackid . "\r\n";
 		}
 		else
 		{
diff --git a/htdocs/core/js/lib_head.js b/htdocs/core/js/lib_head.js
index 6ddfa529beec0e90c722d41991fc563536a5c633..eab995d062b00372522e7091f16d34af66d1002b 100644
--- a/htdocs/core/js/lib_head.js
+++ b/htdocs/core/js/lib_head.js
@@ -924,28 +924,17 @@ function copyToClipboard(text,text2)
 }
 
 
-/* 
- * Timer for delayed keyup function
+/*
+ * Provide a function to get an URL GET parameter in javascript 
  * 
- * TODO Who use this ?
+ * @param 	string	name				Name of parameter
+ * @param	mixed	valueifnotfound		Value if not found
+ * @return	string						Value
  */
-/*
-(function($){
-	$.widget("ui.onDelayedKeyup", {
-	    _init : function() {
-	        var self = this;
-	        $(this.element).bind('keyup input', function() {
-	            if(typeof(window['inputTimeout']) != "undefined"){
-	                window.clearTimeout(inputTimeout);
-	            }  
-	            var handler = self.options.handler;
-	            window['inputTimeout'] = window.setTimeout(function() { handler.call(self.element) }, self.options.delay);
-	        });
-	    },
-	    options: {
-	        handler: $.noop(),
-	        delay: 500
-	    }
-	});
-})(jQuery);
-*/
+function getParameterByName(name, valueifnotfound) 
+{
+    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+        results = regex.exec(location.search);
+    return results === null ? valueifnotfound : decodeURIComponent(results[1].replace(/\+/g, " "));
+}
diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php
index e95bfaa94ef38a4e5dd4fff5bf193b5f54d1d0a2..55600543e64c78ba773f049cea8507d9c0ad2f84 100644
--- a/htdocs/core/lib/agenda.lib.php
+++ b/htdocs/core/lib/agenda.lib.php
@@ -53,7 +53,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
 	$langs->load("companies");
 
 	// Filters
-	print '<form name="listactionsfilter" class="listactionsfilter" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
+	print '<form name="listactionsfilter" class="listactionsfilter" action="' . $_SERVER["PHP_SELF"] . '" method="get">';
 	print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
 	print '<input type="hidden" name="year" value="' . $year . '">';
 	print '<input type="hidden" name="month" value="' . $month . '">';
@@ -86,7 +86,8 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
 		print '<td class="nowrap" style="padding-bottom: 2px; padding-right: 4px;">';
 		print $langs->trans("Type");
 		print ' &nbsp;</td><td class="nowrap maxwidthonsmartphone" style="padding-bottom: 2px; padding-right: 4px;">';
-		print $formactions->select_type_actions($actioncode, "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : 0));
+		//select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0, $hideinfohelp=0, $multiselect=true)
+		print $formactions->select_type_actions($actioncode, "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : 0), 0, 1);
 		print '</td></tr>';
 
 		print '<tr>';
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 013217a9f5792af84a1a65ec24709e4ad3b929c4..daa96d767755cafd0455ec009b63dd74c85366e6 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -263,6 +263,10 @@ function GETPOST($paramname,$check='',$method=0,$filter=NULL,$options=NULL)
 	            $out=trim($out);
 	            if (preg_match('/[^a-z]+/i',$out)) $out='';
 	            break;
+	        case 'aZ09':
+	            $out=trim($out);
+	            if (preg_match('/[^a-z0-9]+/i',$out)) $out='';
+	            break;
 	        case 'array':
 	            if (! is_array($out) || empty($out)) $out=array();
 	            break;
@@ -5043,6 +5047,22 @@ function printCommonFooter($zone='private')
 
 	if (! empty($conf->global->MAIN_HTML_FOOTER)) print $conf->global->MAIN_HTML_FOOTER."\n";
 
+	print "\n";
+	print '<script type="text/javascript" language="javascript">jQuery(document).ready(function() {'."\n";
+	
+	print '<!-- If page_y set, we set scollbar with it -->'."\n";
+	print "page_y=getParameterByName('page_y', 0);";
+	print "if (page_y > 0) $('html, body').scrollTop(page_y);";
+	
+	print '<!-- Set handler to add page_y param on some a href links -->'."\n";
+	print 'jQuery(".reposition").click(function() {
+	           var page_y = $(document).scrollTop();
+	           this.href=this.href+\'&page_y=\'+page_y;
+	           });';
+	print '});'."\n";
+	
+	print '</script>'."\n";
+	
 	// Google Analytics (need Google module)
 	if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID))
 	{
diff --git a/htdocs/core/modules/oauth/getgoogleoauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php
similarity index 85%
rename from htdocs/core/modules/oauth/getgoogleoauthcallback.php
rename to htdocs/core/modules/oauth/google_oauthcallback.php
index e159198314cd4f33a04836dc3dba5414ae240e35..43232ed92f2b9ee22933a1ff5bc1a3894baf4fe7 100644
--- a/htdocs/core/modules/oauth/getgoogleoauthcallback.php
+++ b/htdocs/core/modules/oauth/google_oauthcallback.php
@@ -24,10 +24,8 @@
 
 require '../../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
-use OAuth\Common\Storage\Session;
 use OAuth\Common\Storage\DoliStorage;
 use OAuth\Common\Consumer\Credentials;
-use OAuth\Common\Token\TokenInterface;
 use OAuth\OAuth2\Service\Google;
 
 // Define $urlwithroot
@@ -72,11 +70,18 @@ $credentials = new Credentials(
     $currentUri->getAbsoluteUri()
 );
 
+$requestedpermissionsarray=array();
+if (GETPOST('state')) $requestedpermissionsarray=explode(',', GETPOST('state'));       // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to retrieve some parameters back
+if ($action != 'delete' && empty($requestedpermissionsarray))
+{
+    print 'Error, parameter state is not defined';
+    exit;
+}
+//var_dump($requestedpermissionsarray);exit;
 
 // Instantiate the Api service using the credentials, http client and storage mechanism for the token
 /** @var $apiService Service */
-// TODO remove hardcoded array
-$apiService = $serviceFactory->createService('Google', $credentials, $storage, array('userinfo_email', 'userinfo_profile', 'cloud_print'));
+$apiService = $serviceFactory->createService('Google', $credentials, $storage, $requestedpermissionsarray);
 
 // access type needed for google refresh token
 $apiService->setAccessType('offline');
@@ -129,11 +134,18 @@ if (! empty($_GET['code']))     // We are coming from Google oauth page
     header('Location: ' . $backtourl);
     exit();
 }
-else 
+else // If entry on page with no parameter, we arrive here
 {
     $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl;
     
-    $url = $apiService->getAuthorizationUri();
+    if (GETPOST('state'))
+    {
+        $url = $apiService->getAuthorizationUri(array('state'=>GETPOST('state')));
+    }
+    else
+    {
+        $url = $apiService->getAuthorizationUri();      // Parameter state will be randomly generated
+    }
     // we go on google authorization page
     header('Location: ' . $url);
     exit();
diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php
index aab1ae13bb6f9115c5b04ac7ad653e789b8f03cf..7c6e965f7786a4c4e64bbc2b037c6cb041fdf0f1 100644
--- a/htdocs/core/modules/printing/printgcp.modules.php
+++ b/htdocs/core/modules/printing/printgcp.modules.php
@@ -113,18 +113,20 @@ class printing_printgcp extends PrintingDriver
          
             if ($this->google_id != '' && $this->google_secret != '') {
                 $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthConfigured', 'type'=>'info');
-                $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_ACCESS', 'info'=>$access, 'type'=>'info');
+                $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_ACCESS', 'info'=>$access, 'type'=>'info', 'renew'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?state=userinfo_email,userinfo_profile,cloud_print&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'delete'=>($storage->hasAccessToken('Google')?$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'):''));
                 if ($token_ok) {
                     $refreshtoken = $token->getRefreshToken();
-                    $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_REFRESH', 'info'=>((! empty($refreshtoken))?'Yes':'No'), 'type'=>'info');
-                    $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_EXPIRED', 'info'=>($expire?'Yes':'No'), 'type'=>'info');
+                    $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_REFRESH',   'info'=>((! empty($refreshtoken))?'Yes':'No'), 'type'=>'info');
+                    $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_EXPIRED',   'info'=>($expire?'Yes':'No'), 'type'=>'info');
                     $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_EXPIRE_AT', 'info'=>(dol_print_date($token->getEndOfLife(), "dayhour")), 'type'=>'info');
                 }
-                if (!$storage->hasAccessToken('Google')) {
+                /*
+                if ($storage->hasAccessToken('Google')) {
                     $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
-                } else {
                     $this->conf[] = array('varname'=>'PRINTGCP_DELETE_TOKEN', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'delete');
-                }
+                } else {
+                    $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
+                }*/
             } else {
                 $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthNotConfigured', 'type'=>'info');
             }
diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
index 3ca2c18bf6c3de2a22687ef471d5411f2849dbf3..6a236ab534e128d2ba5e3391bd9857e336bdd8b4 100644
--- a/htdocs/expedition/card.php
+++ b/htdocs/expedition/card.php
@@ -1620,6 +1620,15 @@ else if ($id || $ref)
 		$formmail->fromid   = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='shi'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'shi'.$object->id);
+		}		
 		$formmail->withfrom=1;
 		$liste=array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php
index a247341cdec31c7f8df9aa30c5b02fdd4da323ed..e9b4d94bee6bb3b279cb42725f8d687dc3417462 100644
--- a/htdocs/fichinter/card.php
+++ b/htdocs/fichinter/card.php
@@ -1816,6 +1816,15 @@ else if ($id > 0 || ! empty($ref))
 		$formmail->fromid   = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='int'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'int'.$object->id);
+		}		
 		$formmail->withfrom=1;
 		$liste=array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index 904cd5b3133ed9d05790f38a0fcd8343223ca370..e80f1e6a9f12213cb8839e3165c7c000cb50639f 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -2321,6 +2321,15 @@ elseif (! empty($object->id))
 		$formmail->fromid   = $user->id;
 		$formmail->fromname = $user->getFullName($langs);
 		$formmail->frommail = $user->email;
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+		{
+			$formmail->trackid='sor'.$object->id;
+		}
+		if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+		{
+			include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+			$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'sor'.$object->id);
+		}		
 		$formmail->withfrom=1;
 		$liste=array();
 		foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index f3f9dc6afa306345db9634b2d6c810c3af847aa5..1084bbe382172b5130cbdd4b7191cb24a1ce3081 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -2322,6 +2322,15 @@ else
             $formmail->fromid   = $user->id;
             $formmail->fromname = $user->getFullName($langs);
             $formmail->frommail = $user->email;
+            if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+            {
+            	$formmail->trackid='sin'.$object->id;
+            }
+            if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+            {
+            	include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+            	$formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'sin'.$object->id);
+            }            
             $formmail->withfrom=1;
 			$liste=array();
 			foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php
index 0bc54416fd16a316d4596760ff3cba0b0a8e7602..52750352afa81f7ffd9e1511a7b3533ead4e1cb9 100644
--- a/htdocs/includes/odtphp/odf.php
+++ b/htdocs/includes/odtphp/odf.php
@@ -284,7 +284,7 @@ IMG;
 	private function _parse($type='content')
 	{
 	    // Search all tags fou into condition to complete $this->vars, so we will proceed all tests even if not defined
-	    $reg='@\[!--\sIF\s([{}a-zA-Z_]+)\s--\]@smU';
+	    $reg='@\[!--\sIF\s([{}a-zA-Z0-9\.\,_]+)\s--\]@smU';
 	    preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
 	    //var_dump($this->vars);exit;
 	    foreach($matches as $match)   // For each match, if there is no entry into this->vars, we add it
diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
index 13451e55c5022ad4c15680b83120f9dd7fcd6f75..20ec018ad28fbe5cc4358ed1eee8a4e908cb054e 100755
--- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
+++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
@@ -32,6 +32,8 @@ INSERT INTO llx_const (name, value, type, note, visible) values ('MAIN_SIZE_SHOR
 
 ALTER TABLE llx_accounting_system MODIFY COLUMN pcg_version varchar(32);
 ALTER TABLE llx_accountingaccount MODIFY COLUMN fk_pcg_version varchar(32);
+ALTER TABLE llx_accountingaccount RENAME TO llx_accounting_account;
+ALTER TABLE llx_accounting_account ADD INDEX idx_accounting_account_account_number (account_number);
 
 UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_PREFIX_SPEC')__ WHERE __DECRYPT('name')__ = 'EXPORT_PREFIX_SPEC';
 
@@ -40,8 +42,6 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'b
 UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'amarok';
 UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'cameleo';
 
-ALTER TABLE llx_accountingaccount RENAME TO llx_accounting_account;
-
 ALTER TABLE llx_societe ADD COLUMN model_pdf varchar(255);
 
 ALTER TABLE llx_societe_commerciaux ADD COLUMN import_key varchar(14) AFTER fk_user;
diff --git a/htdocs/install/mysql/tables/llx_accounting_account.key.sql b/htdocs/install/mysql/tables/llx_accounting_account.key.sql
index 7a38b7dd01377daf7c29ab2abc53a795371e3aa0..db08831570d10e31df391e593db19cb73ef62c9d 100644
--- a/htdocs/install/mysql/tables/llx_accounting_account.key.sql
+++ b/htdocs/install/mysql/tables/llx_accounting_account.key.sql
@@ -19,6 +19,7 @@
 
 
 ALTER TABLE llx_accounting_account ADD INDEX idx_accounting_account_fk_pcg_version (fk_pcg_version);
+ALTER TABLE llx_accounting_account ADD INDEX idx_accounting_account_account_number (account_number);
 
 ALTER TABLE llx_accounting_account ADD CONSTRAINT fk_accounting_account_fk_pcg_version  FOREIGN KEY (fk_pcg_version)    REFERENCES llx_accounting_system (pcg_version);
 
diff --git a/htdocs/langs/en_US/oauth.lang b/htdocs/langs/en_US/oauth.lang
index 4567af2a0b622e5691b6f79a0a57e66a50e79ea2..b902ff270981369081d269cab7b857b6beacf556 100644
--- a/htdocs/langs/en_US/oauth.lang
+++ b/htdocs/langs/en_US/oauth.lang
@@ -1,9 +1,12 @@
 # Dolibarr language file - Source file is en_US - oauth
 ConfigOAuth=Oauth Configuration
-NoAccessToken=No token access saved.
-HasAccessToken=A token was generated and saved into database
+NoAccessToken=No access token saved into local database
+HasAccessToken=A token was generated and saved into local database
 NewTokenStored=Token received ans saved
+ToCheckDeleteTokenOnProvider=To check/delete authorization saved by %s OAuth provider
 TokenDeleted=Token deleted
+RequestAccess=Click here to request/renew access and receive a new token to save
+DeleteAccess=Click here to delete token
 UseTheFollowingUrlAsRedirectURI=Use the following URL as the Redirect URI when creating your credential on your OAuth provider:
 ListOfSupportedOauthProviders=Enter here credential provided by your OAuth2 provider. Only supported OAuth2 providers are visible here. This setup may be used by other modules than need OAuth2 authentication.
 OAUTH_AMAZON_NAME=Api Amazon
diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang
index ab70ca671d73af4feb15baba6dd7513c5255d123..427b4973e80c96002022537e3df4608775da55a7 100644
--- a/htdocs/langs/en_US/printing.lang
+++ b/htdocs/langs/en_US/printing.lang
@@ -18,15 +18,13 @@ TestDriver=Test
 TargetedPrinter=Targeted printer
 UserConf=Setup per user
 PRINTGCP=Google Cloud Print
-PRINTGCP_INFO=Google Api State
+PRINTGCP_INFO=Google OAuth API setup
 PRINTGCP_AUTHLINK=Authentication
 PRINTGCP_TOKEN_ACCESS=Google Cloud Print OAuth Token
 PRINTGCP_TOKEN_REFRESH=Token Refresh Present
 PRINTGCP_TOKEN_EXPIRED=Token Expired
 PRINTGCP_TOKEN_EXPIRE_AT=Token expire at
 PRINTGCP_DELETE_TOKEN=Delete saved token
-RequestAccess=Click here to request access and receive a token to save
-DeleteAccess=Click here to delete token
 PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print.
 PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print.
 PrintTestDescprintgcp=List of Printers for Google Cloud Print.
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 354ecb7b611b92e1d97367497e613cf53d6c1ddc..eb2aa212e7ca1234f36f5e8db3a46fb3f19d79cc 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -1605,17 +1605,17 @@ function left_menu($menu_array_before, $helppagename='', $notused='', $menu_arra
     	        $langs->load("users");
     	        $searchform.=printSearchForm(DOL_URL_ROOT.'/user/list.php', DOL_URL_ROOT.'/user/list.php', $langs->trans("Users"), 'user', 'sall', 'M', 'searchleftuser', img_object('','user'));
     	    }
-    
-    	    // Execute hook printSearchForm
-    	    $parameters=array();
-    	    $reshook=$hookmanager->executeHooks('printSearchForm',$parameters);    // Note that $action and $object may have been modified by some hooks
-    		if (empty($reshook))
-    		{
-    			$searchform.=$hookmanager->resPrint;
-    		}
-    		else $searchform=$hookmanager->resPrint;
 	    }
         
+	    // Execute hook printSearchForm
+	    $parameters=array('searchform'=>$searchform);
+	    $reshook=$hookmanager->executeHooks('printSearchForm',$parameters);    // Note that $action and $object may have been modified by some hooks
+		if (empty($reshook))
+		{
+			$searchform.=$hookmanager->resPrint;
+		}
+		else $searchform=$hookmanager->resPrint;
+
 	    // Define $bookmarks
 	    if (! empty($conf->bookmark->enabled) && $user->rights->bookmark->lire)
 	    {
diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php
index 9f2f745ad0c3c77fcb35928313c14f29aba3a9b3..147afc124fc2c0898fa7f10bdf6dc0d333dba5bd 100644
--- a/htdocs/margin/tabs/thirdpartyMargins.php
+++ b/htdocs/margin/tabs/thirdpartyMargins.php
@@ -124,12 +124,13 @@ if ($socid > 0)
 
     print "</table>";
     
-    dol_fiche_end();
-    
     print '</div>';
     print '<div style="clear:both"></div>';
 
-
+    dol_fiche_end();
+    
+    print '<br>';
+    
     $sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client,";
     $sql.= " f.rowid as facid, f.facnumber, f.total as total_ht,";
     $sql.= " f.datef, f.paye, f.fk_statut as statut, f.type,";
diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php
index ce87a5c7178707f8e3f407e6a588dea559c91fd9..ea051113faa3a3083b5dae0c415a4ffcb9e752d5 100644
--- a/htdocs/printing/admin/printing.php
+++ b/htdocs/printing/admin/printing.php
@@ -45,6 +45,7 @@ if (! empty($driver)) $langs->load($driver);
 
 if (!$mode) $mode='config';
 
+
 /*
  * Action
  */
@@ -155,25 +156,18 @@ if ($mode == 'setup' && $user->admin)
                     print '<td>&nbsp;'.($key['example']!=''?$langs->trans("Example").' : '.$key['example']:'').'</td>';
                     print '</tr>'."\n";
                     break;
-                case "authlink":
-                    print '<tr '.$bc[$var].'>';
-                    print '<td>'.$langs->trans($key['varname']).'</td>';
-                    print '<td><a class="button" href="'.$key['link'].'">'.$langs->trans('RequestAccess').'</a></td>';
-                    print '<td>&nbsp;</td>';
-                    print '</tr>'."\n";
-                    break;
-                case "delete":
-                    print '<tr '.$bc[$var].'>';
-                    print '<td>'.$langs->trans($key['varname']).'</td>';
-                    print '<td><a class="button" href="'.$key['link'].'">'.$langs->trans('DeleteAccess').'</a></td>';
-                    print '<td>&nbsp;</td>';
-                    print '</tr>'."\n";
-                    break;
-                case "info":
+                case "info":    // Google Api setup or Google OAuth Token
                     print '<tr '.$bc[$var].'>';
                     print '<td'.($key['required']?' class=required':'').'>'.$langs->trans($key['varname']).'</td>';
                     print '<td>'.$langs->trans($key['info']).'</td>';
-                    print '<td>&nbsp;</td>';
+                    print '<td>';
+                    if ($key['varname'] == 'PRINTGCP_TOKEN_ACCESS')
+                    {
+                        if (! empty($key['delete'])) print '<a class="button" href="'.$key['delete'].'">'.$langs->trans('DeleteAccess').'</a><br><br>';
+                        print '<a class="button" href="'.$key['renew'].'">'.$langs->trans('RequestAccess').'</a><br><br>';
+                        print $langs->trans("ToCheckDeleteTokenOnProvider", 'Google').': <a href="https://security.google.com/settings/security/permissions" target="_google">https://security.google.com/settings/security/permissions</a>';
+                    }
+                    print '</td>';
                     print '</tr>'."\n";
                     break;
                 case "submit":
@@ -225,7 +219,7 @@ if ($mode == 'config' && $user->admin)
         //print '<pre>'.print_r($printer, true).'</pre>';
         $var=!$var;
         print '<tr '.$bc[$var].'>';
-        print '<td>'.img_picto('', $printer->picto).$langs->trans($printer->desc).'</td>';
+        print '<td>'.img_picto('', $printer->picto).' '.$langs->trans($printer->desc).'</td>';
         print '<td class="center">';
         if (! empty($conf->use_javascript_ajax))
         {
diff --git a/htdocs/printing/lib/printing.lib.php b/htdocs/printing/lib/printing.lib.php
index 59e2e1e004898e885c8db047b7c794f694c20ec2..697e986cd56130272236d3ac4f4af8bd5eff4189 100644
--- a/htdocs/printing/lib/printing.lib.php
+++ b/htdocs/printing/lib/printing.lib.php
@@ -43,7 +43,7 @@ function printingadmin_prepare_head($mode)
 
     if ($mode == 'setup')
     {
-	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup";
+	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup&driver=".GETPOST('driver','alpha');
 	    $head[$h][1] = $langs->trans("SetupDriver");
 	    $head[$h][2] = 'setup';
 	    $h++;
@@ -51,7 +51,7 @@ function printingadmin_prepare_head($mode)
 
     if ($mode == 'test')
     {
-	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test";
+	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test&driver=".GETPOST('driver','alpha');
 	    $head[$h][1] = $langs->trans("TargetedPrinter");
 	    $head[$h][2] = 'test';
 	    $h++;
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index 497f676ae8c3409685c3816cde1aa31b3b4b404c..3f16a20d98b19a160ed082ffc685e51e60cda574 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -179,12 +179,6 @@ if (empty($reshook))
 			);
 		}
 
-		if (!$error && $object->update($object->id, $user) < 1) {
-			$error++;
-			setEventMessage($object->error, 'errors');
-			$action = 'edit_price';
-		}
-
 		if (!$error) {
 			$db->begin();
 
@@ -215,6 +209,11 @@ if (empty($reshook))
 			}
 		}
 
+		if (!$error && $object->update($object->id, $user) < 0) {
+			$error++;
+			setEventMessage($object->error, 'errors');
+		}
+
 		if (empty($error)) {
 			$action = '';
 			setEventMessage($langs->trans("RecordSaved"));
@@ -713,7 +712,7 @@ print "</table>\n";
 
 print '</div>';
 print '<div style="clear:both"></div>';
-   
+
 
 dol_fiche_end();
 
@@ -793,7 +792,7 @@ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->se
 	print '<br></form><br>';
 }
  
-if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->service->creer))
+if ($action == 'edit_price' && $object->getRights()->creer)
 {
 	print load_fiche_titre($langs->trans("NewPrice"), '');
 
@@ -809,7 +808,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		print '<table class="border" width="100%">';
 
 		// VAT
-		print '<tr><td>' . $langs->trans("VATRate") . '</td><td>';
+		print '<tr><td>' . $langs->trans("VATRate") . '</td><td colspan="2">';
 		print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr);
 		print '</td></tr>';
 
@@ -817,7 +816,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		print '<tr><td width="20%">';
 		print $langs->trans('PriceBase');
 		print '</td>';
-		print '<td>';
+		print '<td colspan="2">';
 		print $form->selectPriceBaseType($object->price_base_type, "price_base_type");
 		print '</td>';
 		print '</tr>';
@@ -825,7 +824,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
  		// Only show price mode and expression selector if module is enabled
 		if (! empty($conf->dynamicprices->enabled)) {
 			// Price mode selector
-			print '<tr><td>'.$langs->trans("PriceMode").'</td><td>';
+			print '<tr><td>'.$langs->trans("PriceMode").'</td><td colspan="2">';
 			$price_expression = new PriceExpression($db);
 			$price_expression_list = array(0 => $langs->trans("PriceNumeric")); //Put the numeric mode as first option
 			foreach ($price_expression->list_price_expression() as $entry) {
@@ -835,17 +834,18 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 			print $form->selectarray('eid', $price_expression_list, $price_expression_preselection);
 			print '&nbsp; <div id="expression_editor" class="button">'.$langs->trans("PriceExpressionEditor").'</div>';
 			print '</td></tr>';
+
 			// This code hides the numeric price input if is not selected, loads the editor page if editor button is pressed
-			print '<script type="text/javascript">
-				jQuery(document).ready(run);
-				function run() {
-					jQuery("#expression_editor").click(on_click);
+			?>
+
+			<script type="text/javascript">
+				jQuery(document).ready(function() {
+					jQuery("#expression_editor").click(function() {
+						window.location = "<?php echo DOL_URL_ROOT ?>/product/dynamic_price/editor.php?id=<?php echo $id ?>&tab=price&eid=" + $("#eid").attr("value");
+					});
 					jQuery("#eid").change(on_change);
 					on_change();
-				}
-				function on_click() {
-					window.location = "'.DOL_URL_ROOT.'/product/dynamic_price/editor.php?id='.$id.'&tab=price&eid=" + $("#eid").attr("value");
-				}
+				});
 				function on_change() {
 					if ($("#eid").attr("value") == 0) {
 						jQuery("#price_numeric").show();
@@ -853,7 +853,8 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 						jQuery("#price_numeric").hide();
 					}
 				}
-			</script>';
+			</script>
+			<?php
 		}
 
 		// Price
@@ -862,7 +863,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		print '<tr id="price_numeric"><td width="20%">';
 		$text = $langs->trans('SellingPrice');
 		print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
-		print '</td><td>';
+		print '</td><td colspan="2">';
 		if ($object->price_base_type == 'TTC') {
 			print '<input name="price" size="10" value="' . price($product->price_ttc) . '">';
 		} else {
@@ -874,16 +875,22 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		print '<tr><td>';
 		$text = $langs->trans('MinPrice');
 		print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
+		print '</td><td';
+		if (empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) {
+			print ' colspan="2"';
+		}
+		print '>';
 		if ($object->price_base_type == 'TTC') {
-			print '<td><input name="price_min" size="10" value="' . price($object->price_min_ttc) . '">';
+			print '<input name="price_min" size="10" value="' . price($object->price_min_ttc) . '">';
 		} else {
-			print '<td><input name="price_min" size="10" value="' . price($object->price_min) . '">';
+			print '<input name="price_min" size="10" value="' . price($object->price_min) . '">';
 		}
+		print '</td>';
 		if ( !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE))
 		{
 			print '<td align="left">'.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'</td>';
 		}
-		print '</td></tr>';
+		print '</tr>';
 
 		print '</table>';
 
@@ -906,8 +913,8 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		<script>
 
 			var showHidePriceRules = function () {
-				var otherPrices = $('div.fiche form table:not(:first), div.fiche form table:first tr:not(:first)');
-				var minPrice1 = $('div.fiche form:first tr:eq(1)');
+				var otherPrices = $('div.fiche form table tbody tr:not(:first)');
+				var minPrice1 = $('div.fiche form input[name="price_min[1]"]');
 
 				if (jQuery('input#usePriceRules').prop('checked')) {
 					otherPrices.hide();
@@ -927,65 +934,72 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->
 		<?php
 
 		print '<form action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="POST">';
+		print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
+		print '<input type="hidden" name="action" value="update_price">';
+		print '<input type="hidden" name="id" value="' . $object->id . '">';
 
-		for($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++)
-		{
+		if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($conf->global->PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL)) {
+			print $langs->trans('UseMultipriceRules'). ' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.($object->price_autogen ? 'checked' : '').'><br><br>';
+		}
 
-			if ($i > 1) print '<br>';
-			elseif (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($conf->global->PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL)) {
-				print $langs->trans('UseMultipriceRules'). ' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.($object->price_autogen ? 'checked' : '').'><br><br>';
-			}
-			print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
-			print '<input type="hidden" name="action" value="update_price">';
-			print '<input type="hidden" name="id" value="' . $object->id . '">';
-			if (empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL))
-			{
-				print '<input type="hidden" name="tva_tx[' . $i . ']" value="' . $object->tva_tx . '">';
-			}
-			
-			print '<table class="border" width="100%">';
+		print '<table class="noborder">';
+		print '<thead><tr class="liste_titre">
+		<td style="text-align: center">'.$langs->trans("PriceLevel").'</td>';
+		if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {
+			print '<td style="text-align: center">'.$langs->trans("VATRate").'</td>';
+		}
+		print '<td style="text-align: center">'.$langs->trans("SellingPrice").'</td>
+		<td style="text-align: center">'.$langs->trans("MinPrice").'</td>';
+		if (!empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) {
+			print '<td></td>';
+		}
+		print '</tr></thead><tbody>';
+
+		for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) {
+			$var = !$var;
+
+			print '<tr '.$bc[$var].'>';
+			print '<td>';
+			print $form->textwithpicto($langs->trans('SellingPrice') . ' ' . $i, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
+			print '</td>';
 
 			// VAT
-			if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL))	// This option is kept for backward compatibility but has no sense
-			{
-				print '<tr><td>' . $langs->trans("VATRate") . '</td><td>';
+			if (empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {
+				print '<input type="hidden" name="tva_tx[' . $i . ']" value="' . $object->tva_tx . '">';
+			} else {
+				// This option is kept for backward compatibility but has no sense
+				print '<td style="text-align: center">';
 				print $form->load_tva("tva_tx[" . $i.']', $object->multiprices_tva_tx[$i], $mysoc, '', $object->id);
-				print '</td></tr>';
+				print '</td>';
 			}
-			
+
 			// Selling price
-			print '<tr><td width="20%">';
-			$text = $langs->trans('SellingPrice') . ' ' . $i;
-			print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
-			print '</td><td>';
+			print '<td style="text-align: center">';
 			if ($object->multiprices_base_type [$i] == 'TTC') {
 				print '<input name="price[' . $i . ']" size="10" value="' . price($object->multiprices_ttc [$i]) . '">';
 			} else {
 				print '<input name="price[' . $i . ']" size="10" value="' . price($object->multiprices [$i]) . '">';
 			}
 			print '&nbsp;'.$form->selectPriceBaseType($object->multiprices_base_type [$i], "multiprices_base_type[" . $i."]");
-			print '</td></tr>';
+			print '</td>';
 
 			// Min price
-			print '<tr><td>';
-			$text = $langs->trans('MinPrice') . ' ' . $i;
-			print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
+			print '<td style="text-align: center">';
 			if ($object->multiprices_base_type [$i] == 'TTC') {
-				print '<td><input name="price_min[' . $i . ']" size="10" value="' . price($object->multiprices_min_ttc [$i]) . '">';
+				print '<input name="price_min[' . $i . ']" size="10" value="' . price($object->multiprices_min_ttc [$i]) . '">';
 			} else {
-				print '<td><input name="price_min[' . $i . ']" size="10" value="' . price($object->multiprices_min [$i]) . '">';
+				print '<input name="price_min[' . $i . ']" size="10" value="' . price($object->multiprices_min [$i]) . '">';
 			}
 			if ( !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE))
 			{
 				print '<td align="left">'.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'</td>';
 			}
-			print '</td></tr>';
-
-			print '</table>';
+			print '</td>';
 
+			print '</tr>';
 		}
 
-		print '<br><div style="text-align: center">';
+		print '</tbody></table><br><div style="text-align: center">';
 		print '<input type="submit" class="button" value="' . $langs->trans("Save") . '">';
 		print '&nbsp;&nbsp;&nbsp;';
 		print '<input type="submit" class="button" name="cancel" value="' . $langs->trans("Cancel") . '"></div>';
diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php
index 8b640040b80eaa6577324104f2796da21b436e92..b7465abe85b8a294c2ead38f1f6cd74db3c3e6cf 100644
--- a/htdocs/societe/soc.php
+++ b/htdocs/societe/soc.php
@@ -2138,6 +2138,14 @@ else
         print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>'.$object->typent.'</td>';
         print '<tr><td>'.$langs->trans("Staff").'</td><td>'.$object->effectif.'</td></tr>';
 
+        print '</table>';
+        
+        print '</div>';
+        print '<div class="fichehalfright"><div class="ficheaddleft">';
+       
+        print '<div class="underbanner clearboth"></div>';
+        print '<table class="border tableforfield" width="100%">';
+        
         // Legal
         print '<tr><td>'.$langs->trans('JuridicalStatus').'</td><td>'.$object->forme_juridique.'</td></tr>';
 
@@ -2147,14 +2155,6 @@ else
         else print '&nbsp;';
         print '</td></tr>';
 
-        print '</table>';
-        
-        print '</div>';
-        print '<div class="fichehalfright"><div class="ficheaddleft">';
-       
-        print '<div class="underbanner clearboth"></div>';
-        print '<table class="border tableforfield" width="100%">';
-        
         // Default language
         if (! empty($conf->global->MAIN_MULTILANGS))
         {
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index b57fa159b17d8c092496fc9cc58b008fb3f8acbc..59461c1db8779593d226050f12aa8945fa453789 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -232,7 +232,7 @@ body {
 <?php } else { ?>
 	background: rgb(<?php print $colorbackbody; ?>);
 <?php } ?>
-	color: #101010;
+	color: rgb(<?php echo $colortext; ?>);
 	font-size: <?php print $fontsize ?>px;
 	font-family: <?php print $fontlist ?>;
     margin-top: 0;
@@ -3595,6 +3595,9 @@ a span.select2-chosen
   overflow: hidden;
 }
 
+.noborderoncategories {
+	border: none !important;
+}
 
 /* ============================================================================== */
 /*  Multiselect with checkbox                                                     */
diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php
index ae32a624175026a7c8c634e6ba6d0b70ada84610..fa54a128cac53f3f1ed6bc43c61e3a9abe42273f 100644
--- a/htdocs/user/perms.php
+++ b/htdocs/user/perms.php
@@ -331,9 +331,9 @@ if ($result)
         		print '<td class="nowrap">'.img_object('',$picto).' '.$objMod->getName();
         		print '<a name="'.$objMod->getName().'">&nbsp;</a></td>';
         		print '<td align="center" class="nowrap">';
-        		print '<a title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'#'.$objMod->getName().'">'.$langs->trans("All")."</a>";
+        		print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("All")."</a>";
         		print '/';
-        		print '<a title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="perms.php?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module='.$obj->module.'#'.$objMod->getName().'">'.$langs->trans("None")."</a>";
+        		print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="perms.php?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("None")."</a>";
         		print '</td>';
         		print '<td colspan="2">&nbsp;</td>';
         		print '</tr>'."\n";
@@ -360,7 +360,7 @@ if ($result)
         {
         	if ($caneditperms)
         	{
-        		print '<td align="center"><a href="perms.php?id='.$object->id.'&amp;action=delrights&amp;rights='.$obj->id.'#'.$objMod->getName().'">'.img_edit_remove($langs->trans("Remove")).'</a></td>';
+        		print '<td align="center"><a class="reposition" href="perms.php?id='.$object->id.'&amp;action=delrights&amp;rights='.$obj->id.'">'.img_edit_remove($langs->trans("Remove")).'</a></td>';
         	}
         	print '<td align="center" class="nowrap">';
         	print img_picto($langs->trans("Active"),'tick');
@@ -386,7 +386,7 @@ if ($result)
 	        	// Do not own permission
 	        	if ($caneditperms)
 	        	{
-	        		print '<td align="center"><a href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;rights='.$obj->id.'#'.$objMod->getName().'">'.img_edit_add($langs->trans("Add")).'</a></td>';
+	        		print '<td align="center"><a class="reposition" href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;rights='.$obj->id.'">'.img_edit_add($langs->trans("Add")).'</a></td>';
 	        	}
 	        	print '<td>&nbsp</td>';
 	        }
@@ -396,7 +396,7 @@ if ($result)
         	// Do not own permission
         	if ($caneditperms)
         	{
-        		print '<td align="center"><a href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;rights='.$obj->id.'#'.$objMod->getName().'">'.img_edit_add($langs->trans("Add")).'</a></td>';
+        		print '<td align="center"><a class="reposition" href="perms.php?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;rights='.$obj->id.'">'.img_edit_add($langs->trans("Add")).'</a></td>';
         	}
         	print '<td>&nbsp</td>';
         }