diff --git a/bin/account-manager-web.pl b/bin/account-manager-web.pl
index 3bc880ced8d934d640143fabf0998e4e8154f8fe..1c8d8e8b443d07059cee868324503c38999f2a7f 100755
--- a/bin/account-manager-web.pl
+++ b/bin/account-manager-web.pl
@@ -13,6 +13,7 @@ use CGI::Cookie;
 use CGI::Util;
 use Template;
 use Template::Constants qw( :debug );
+
 use POSIX;
 
 use IdPAccountManager::TestAccount;
@@ -194,6 +195,7 @@ sub respond {
 				ENCODING => 'iso-8859-1', ## le défaut apparemment
 				FILTERS => {'encode_utf8', => [\&IdPAccountManager::Tools::encode_utf8, 0],
 					    'escape_quotes' => [\&IdPAccountManager::Tools::escape_quotes, 0]},
+                                INCLUDE_PATH => $Conf::global{'root_manager_dir'}.':'.$Conf::global{'root_manager_dir'}.'/templates/accountProfiles',
                 #DEBUG => 'all',
                 #DEBUG => 'caller',
                 #DEBUG => 'parser'
diff --git a/lib/IdPAccountManager/Tools.pm b/lib/IdPAccountManager/Tools.pm
index d00bfd7df087cd64aefeb372c2b22cd35d0af3b4..0229d4aa3546eedb4d4accf8954471bd01befb16 100644
--- a/lib/IdPAccountManager/Tools.pm
+++ b/lib/IdPAccountManager/Tools.pm
@@ -1,11 +1,32 @@
 package IdPAccountManager::Tools;
 
 use Template;
+
+# load Template::Stash to make method tables visible
+use Template::Stash;
+
 use Digest::SHA;
 use Encode;
 
 my %log_levels = ('debug' => 0, 'info' => 1, 'trace' => 1, 'notice' => 2, 'error' => 3);
 
+INIT {
+    ## a TT2 virtual method to get a variable type
+    $Template::Stash::LIST_OPS->{isa} = sub {
+        my $list = shift;
+        my $type = shift;
+        
+        return 1 if ($type eq 'ARRAY');
+        return 0;
+    };
+    $Template::Stash::SCALAR_OPS->{isa} = sub {
+        my $list = shift;
+        my $type = shift;
+
+        return 1 if ($type eq 'SCALAR');
+        return 0;
+    };
+}
 
 # get SHA256 hash for a string
 sub sha256_hash {
@@ -23,7 +44,7 @@ sub generate_password{
         # 1-tirage des caractères obligatoires : les mettre dans un tableau
         my @uppers=('A'..'N','P'..'Z');
         my @lowers=('a'..'k','m'..'z');
-        my @punctuation=('%',';',':','!','?','&','$','*','(',')','{','}','[',']','<','>','.','=','-','#');
+        my @punctuation=(':','!','?','&','$','=','-','#');
         my @numerics=('0'..'9');
         my @rndtab;
         push(@rndtab,$uppers[rand @uppers]);
@@ -222,6 +243,8 @@ sub boolean2integer {
 	return undef;	
 }
 
+
+
 1; # Magic true value required at end of module
 __END__
 
diff --git a/templates/accountProfiles/student1.tt2 b/templates/accountProfiles/student1.tt2
index e60a6efe3289371bb542795ec7b3ac7586623ebe..a2a726d9f49cedb6f196d2bc6fb79c432eb714fb 100644
--- a/templates/accountProfiles/student1.tt2
+++ b/templates/accountProfiles/student1.tt2
@@ -1,13 +1,16 @@
-'user[% account.get('id') %]:{SHA256}[% account.get('user_password_hash') %]=' => array(
-	'uid' => 'user[% account.get('id') %]',
-	'eduPersonAffiliation' => array('member', 'student'),
-	'eduPersonScopedAffiliation' => array('member@[% conf.idp_scope %]', 'student@[% conf.idp_scope %]'),
+[% account_sp_entityid = account.get('sp_entityid') %]
+[% account_id = account.get('id') %]
+
+[% SET account_profile = {
+  	'uid' => "${account_id}",
+	'eduPersonAffiliation' => ['member', 'student'],
+	'eduPersonScopedAffiliation' => ["member@${conf.idp_scope}", "student@${conf.idp_scope}"],
         'displayName' => 'John Kleinman',
         'cn' => 'John Kleinman',
-        'mail' => 'john.kleinman@[% conf.idp_scope %]',
-        'eduPersonPrincipalName' =>'[% account.get('id') %]@[% conf.idp_scope %]',
-        'eduPersonTargetedID' =>'[% conf.idp_entityid %]![% account.get('sp_entityid') %]!X622UR2A7PG1uVhATobBOrMz+Ys=',
-        'schacHomeOrganization' => '[% conf.idp_scope %]',
+        'mail' => "john.kleinman@${conf.idp_scope}",
+        'eduPersonPrincipalName' =>"${account_id}@${conf.idp_scope}",
+        'eduPersonTargetedID' =>"${conf.idp_entityid}!${account_sp_entityid}!X622UR2A7PG1uVhATobBOrMz+Ys=",
+        'schacHomeOrganization' => "${conf.idp_scope}",
         'schacHomeOrganizationType' => 'urn:schac:homeOrganizationType:int:university',
-	'associatedSP' => '[% account.get('sp_entityid') %]',
-),
+} %]
+
diff --git a/templates/accountProfiles/teacher1.tt2 b/templates/accountProfiles/teacher1.tt2
index a40a063ef54cf15aadc36caaeba994fe0a7c7966..56a3977263dea41634df2202b4c9e79d62e23000 100644
--- a/templates/accountProfiles/teacher1.tt2
+++ b/templates/accountProfiles/teacher1.tt2
@@ -1,13 +1,17 @@
-'user[% account.get('id') %]:{SHA256}[% account.get('user_password_hash') %]=' => array(
-	'uid' => 'user[% account.get('id') %]',
-	'eduPersonAffiliation' => array('member', 'faculty'),
-	'eduPersonScopedAffiliation' => array('member@[% conf.idp_scope %]', 'faculty@[% conf.idp_scope %]'),
+[% account_sp_entityid = account.get('sp_entityid') %]
+[% account_id = account.get('id') %]
+
+[% SET account_profile = {
+  	'uid' => "${account_id}",
+	'eduPersonAffiliation' => ['member', 'faculty'],
+	'eduPersonScopedAffiliation' => ["member@${conf.idp_scope}", "student@${conf.idp_scope}"],
         'displayName' => 'Peter Smith',
         'cn' => 'Peter Smith',
-        'mail' => 'peter.smith@[% conf.idp_scope %]',
-        'eduPersonPrincipalName' =>'[% account.get('id') %]@[% conf.idp_scope %]',
-        'eduPersonTargetedID' =>'[% conf.idp_entityid %]![% account.get('sp_entityid') %]!X622UR2A7PG1uVhATobBOrMz+Ys=',
-        'schacHomeOrganization' => '[% conf.idp_scope %]',
+        'mail' => "peter.smith@${conf.idp_scope}",
+        'eduPersonPrincipalName' =>"${account_id}@${conf.idp_scope}",
+        'eduPersonTargetedID' =>"${conf.idp_entityid}!${account_sp_entityid}!X622UR2A7PG1uVhATobBOrMz+Ys=",
+        'schacHomeOrganization' => "${conf.idp_scope}",
         'schacHomeOrganizationType' => 'urn:schac:homeOrganizationType:int:university',
-	'associatedSP' => '[% account.get('sp_entityid') %]',
-),
+} %]
+
+
diff --git a/templates/accountProfiles/valid-accounts.php.tt2 b/templates/accountProfiles/valid-accounts.php.tt2
index 84e13dad9bfe7f2fd4d749beb6ccad83f4ac33f7..bc06290a9db487ad3ff4f80e84b0210ef681c7fd 100644
--- a/templates/accountProfiles/valid-accounts.php.tt2
+++ b/templates/accountProfiles/valid-accounts.php.tt2
@@ -4,6 +4,18 @@ $validTestAccounts = array (
     'authcrypt:Hash',
 
 [% FOREACH account IN accounts %]
-  [% INCLUDE "${account.get('account_profile')}.tt2" %]
+  [% PROCESS "${account.get('account_profile')}.tt2" %]
+  'user[% account.get('id') %]:{SHA256}[% account.get('user_password_hash') %]=' => array(
+  [% FOREACH attribute IN account_profile.pairs -%]
+   [% IF attribute.value.isa('SCALAR') -%]
+	'[% attribute.key %]' => '[% attribute.value %]',
+   [% ELSE -%]
+	'[% attribute.key %]' => array('[% attribute.value.join("','") %]'),
+   [% END %]
+  [% END %]
+        'associatedSP' => "${account_sp_entityid}",
+
+  ),
+
 [% END %]
 );
diff --git a/templates/web/validate_token.tt2.html b/templates/web/validate_token.tt2.html
index 4d9bf0d9f6a294769c6d3720926108238695e12d..53126761ebeda10228e5eac887ace27f515bbe13 100644
--- a/templates/web/validate_token.tt2.html
+++ b/templates/web/validate_token.tt2.html
@@ -1,5 +1,28 @@
 <h3>Get test accounts</h3>
 
+<script type="text/javascript">
+
+jQuery(document).ready(function($){
+    $( ".account_details" ).dialog({
+        title: "Account details",
+        autoOpen: false,
+        buttons: {
+            Ok: function() {
+                $( this ).dialog( "close" );
+            }
+        }
+    });
+    [% FOREACH account IN test_accounts %]
+    $( "#show_account_details_[% account.get('id') %]" ).click(function() {
+        $("#account_details_[% account.get('id') %]").dialog( "open" );
+    });
+    [% END %]
+});
+
+</script>
+
+
+
 <div>
 Your identity has been checked successfully.
 
@@ -7,11 +30,28 @@ Test accounts with different profiles have been created for you, see details bel
 expire in [% conf.accounts_validity_period %] days. Note also that these test accounts can only be used to login on your SP [% sp_entityid %].
 
 <ol>
-    [% FOREACH test_account IN test_accounts %]
-    <li>account profile: [% test_account.get('account_profile') %]
+    [% FOREACH account IN test_accounts %]
+    <li>account profile: [% account.get('account_profile') %]
         <dl>    
-        <dd>user name: user[% test_account.get('id') %]</dd>
-        <dd>user password: [% test_account.get('user_password') %]</dd>
+        <dd>user name: user[% account.get('id') %]</dd>
+        <dd>user password: [% account.get('user_password') %]</dd>
+        <dd><button class="show_account_details" id="show_account_details_[% account.get('id') %]">show account details</button></dd>
+        <div class="account_details" id="account_details_[% account.get('id') %]">
+            [% PROCESS "${account.get('account_profile')}.tt2" %]
+            Below is the list of user attributes associated to this test account. After a successfull authentication process these attributes are transmited
+            via the SAML protocol from the Test Identity Provider to your Service Provider.
+            <ul>
+            [% FOREACH attribute IN account_profile.pairs -%]
+              [% IF attribute.value.isa('SCALAR') -%]
+                <li>[% attribute.key %]: [% attribute.value %]</li>
+              [% ELSE -%]
+                <li>[% attribute.key %]: [% attribute.value.join(",") %]</li>
+              [% END %]
+            [% END %]
+            </ul>
+            
+            If you a customized test account with additionnal user attributes, you should contact <a href="mailto:[% conf.support_email %]">[% conf.support_email %]</a>.
+        </div>
         </dl>
     </li>
     [% END %]