Index: moodle/admin/uploaduser.php
--- moodle/admin/uploaduser.php Base (1.104)
+++ moodle/admin/uploaduser.php Locally Modified (Based On 1.104)
@@ -268,10 +268,9 @@
         }
 
         // normalize username
-        $user->username = $textlib->strtolower($user->username);
-        if (empty($CFG->extendedusernamechars)) {
-            $user->username = preg_replace('/[^(-\.[:alnum:])]/i', '', $user->username);
-        }
+        $user->username = clean_param($user->username, PARAM_USERNAME);
+        
         if (empty($user->username)) {
             $upt->track('status', get_string('missingfield', 'error', 'username'), 'error');
             $upt->track('username', $errorstr, 'error');

@@ -776,8 +779,30 @@
     $ci = 0;
     echo '<tr class="r'.$ri++.'">';
     foreach ($fields as $field) {
-        echo '<td class="cell c'.$ci++.'">'.s($field).'</td>';;
+        if ($ci == 0) {
+            $newusername = clean_param($field, PARAM_USERNAME);
+            $invalidnewusername = empty($newusername) ? ' uuerror ' : '';
+            if (strcmp($field, $newusername)){
+                echo '<td class="cell c'.$ci++. ' uuerror">'. s($newusername);
+                echo '<br /><span class="currentlink">Originally: ' . s($field);
+                echo '</span></td>';
+            } else {
+                echo '<td class="cell c'.$ci++. '">'.s($field).'</td>';
     }
+        } else {
+            echo '<td class="cell c'.$ci++ . '">' . s($field) . '</td>';
+        }
+
+        
+    }
     echo '</tr>';
 }
 $cir->close();

@@ -829,9 +854,12 @@
         $ci = 0;
         $ri = 1;
         echo '<tr class="r'.$ri++.'">';
-        foreach ($this->_row as $field) {
+        foreach ($this->_row as $key=>$field) {
             foreach ($field as $type=>$content) {
                 if ($field[$type] !== '') {
+                    if ($key == 'username' && $type == 'normal') {
+                        $field[$type] = clean_param($field[$type], PARAM_USERNAME);
+                    }
                     $field[$type] = '<span class="uu'.$type.'">'.$field[$type].'</span>';
                 } else {
                     unset($field[$type]);

Index: moodle/auth/email/auth.php
--- moodle/auth/email/auth.php Base (1.23)
+++ moodle/auth/email/auth.php Locally Modified (Based On 1.23)
@@ -94,7 +94,7 @@
         }
 
         if ($notify) {
-            global $CFG;
+            global $CFG, $PAGE, $OUTPUT;
             $emailconfirm = get_string('emailconfirm');
             $PAGE->navbar->add($emailconfirm);
             $PAGE->set_title($emailconfirm);

Index: moodle/lang/en_utf8/moodle.php
--- moodle/lang/en_utf8/moodle.php Base (1.268)
+++ moodle/lang/en_utf8/moodle.php Locally Modified (Based On 1.268)
@@ -112,7 +112,9 @@
 $string['allparticipants'] = 'All participants';
 $string['allteachers'] = 'All teachers';
 $string['alphabet'] = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';
-$string['alphanumerical'] = 'Can only contain alphabetical letters or numbers';
+$string['alphanumerical'] = 'Can only contain alphanumeric characters, hyphen (-) or  period (.)';
+$string['invalidusername'] = 'The username can only contain alphanumeric lowercase characters, underscore (_), hyphen (-), period (.) or at symbol (@)';
 $string['alreadyconfirmed'] = 'Registration has already been confirmed';
 $string['always'] = 'Always';
 $string['and'] = '$a->one and $a->two';

Index: moodle/lib/moodlelib.php
--- moodle/lib/moodlelib.php Base (1.1266)
+++ moodle/lib/moodlelib.php Locally Modified (Based On 1.1266)
@@ -219,6 +219,10 @@
  */
 define('PARAM_URL',      'url');
 
+/**
+ * PARAM_USERNAME - Clean username to only contains specified characters.
+ */
+define('PARAM_USERNAME',    'username');
 
 
 ///// DEPRECATED PARAM TYPES OR ALIASES - DO NOT USE FOR NEW CODE  /////
@@ -463,6 +467,7 @@
  * @uses PARAM_BASE64
  * @uses PARAM_TAG
  * @uses PARAM_SEQUENCE
+ * @uses PARAM_USERNAME
  * @param mixed $param the variable we are cleaning
  * @param int $type expected format of param after cleaning.
  * @return mixed

@@ -720,6 +725,17 @@
                 return '';  // Specified theme is not installed
             }
 
+        case PARAM_USERNAME:
+            $param = str_replace(" " , "", $param);
+            if (empty($CFG->extendedusernamechars)) {                                                              
+                // regular expression, eliminate all chars EXCEPT:
+                // alphanum, dash (-), underscore (_), at sign (@) and period (.) characters.
+                $param = preg_replace('/[^-\.@_a-z0-9]/', '', $param);
+            } else {
+                $param = preg_replace('/[A-Z]/', '', $param);
+            }
+            return $param;
+
         default:                 // throw error, switched parameters in optional_param or another serious problem
             print_error("unknownparamtype", '', '', $type);
     }
Index: moodle/lib/simpletest/testmoodlelib.php
--- moodle/lib/simpletest/testmoodlelib.php Base (1.29)
+++ moodle/lib/simpletest/testmoodlelib.php Locally Modified (Based On 1.29)
@@ -266,6 +266,7 @@
      * @uses PARAM_LOCALURL
      * @uses PARAM_CLEANHTML
      * @uses PARAM_SEQUENCE
+     * @uses PARAM_USERNAME
      * @param mixed $param the variable we are cleaning
      * @param int $type expected format of param after cleaning.
      * @return mixed
@@ -295,8 +296,36 @@
         $this->assertEqual(clean_param('/just/a/path', PARAM_LOCALURL), '/just/a/path');
         $this->assertEqual(clean_param('funny:thing', PARAM_LOCALURL), '');
         $this->assertEqual(clean_param('course/view.php?id=3', PARAM_LOCALURL), 'course/view.php?id=3');
+
+        $currentstatus =  $CFG->extendedusernamechars;
+        
+        // Run tests with extended character == FALSE;
+        if($CFG->extendedusernamechars == FALSE){
+            $this->assertEqual(clean_param('johndoe123', PARAM_USERNAME), 'johndoe123' );
+            $this->assertEqual(clean_param('john.doe', PARAM_USERNAME), 'john.doe');
+            $this->assertEqual(clean_param('john-doe', PARAM_USERNAME), 'john-doe');
+            $this->assertEqual(clean_param('john- doe', PARAM_USERNAME), 'john-doe');
+            $this->assertEqual(clean_param('john_doe', PARAM_USERNAME), 'john_doe');
+            $this->assertEqual(clean_param('john@doe', PARAM_USERNAME), 'john@doe');
+            $this->assertEqual(clean_param('john~doe', PARAM_USERNAME), 'johndoe');
+            $this->assertEqual(clean_param('john´doe', PARAM_USERNAME), 'johndoe');
+            $this->assertEqual(clean_param('john#$%&() ', PARAM_USERNAME), 'john');
+            $this->assertEqual(clean_param('JOHNdóé ', PARAM_USERNAME), 'd');
+            $this->assertEqual(clean_param('john.,:;-_/|\ñÑ[]A_X-,D {} ~!@#$%^&*()_+ ?><[] ščřžžý ?ýá?ý??doe ', PARAM_USERNAME), 'john.-__-@_doe');
+        } else {
+            // Test success condition, if extendedusernamechars == ENABLE;
+            $this->assertEqual(clean_param('john_doe', PARAM_USERNAME), 'john_doe');
+            $this->assertEqual(clean_param('john@doe', PARAM_USERNAME), 'john@doe');
+            $this->assertEqual(clean_param('john# $%&()+_^', PARAM_USERNAME), 'john#$%&()+_^');
+            $this->assertEqual(clean_param('john~doe', PARAM_USERNAME), 'john~doe');
+            $this->assertEqual(clean_param('joHN´doe', PARAM_USERNAME), 'jo´doe');
+            $this->assertEqual(clean_param('johnDOE', PARAM_USERNAME), 'john');
+            $this->assertEqual(clean_param('johndóé ', PARAM_USERNAME), 'johndóé');
     }
 
+        $CFG->extendedusernamechars = $currentstatus;
+    }
+
     function test_validate_param() {
         try {
             $param = validate_param('11a', PARAM_INT);

Index: moodle/login/signup_form.php
--- moodle/login/signup_form.php Base (1.44)
+++ moodle/login/signup_form.php Locally Modified (Based On 1.44)

 
@@ -98,13 +98,18 @@
         if ($DB->record_exists('user', array('username'=>$data['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) {
             $errors['username'] = get_string('usernameexists');
         } else {
+            //check allowed characters            
+            if ($data['username'] !== moodle_strtolower($data['username'])) {
+                $errors['username'] = get_string('usernamelowercase');
+            } else {
             if (empty($CFG->extendedusernamechars)) {
-                $string = preg_replace("~[^(-\.[:alnum:])]~i", '', $data['username']);
+                $string = clean_param($data['username'], PARAM_USERNAME);
                 if (strcmp($data['username'], $string)) {
-                    $errors['username'] = get_string('alphanumerical');
+                    $errors['username'] = get_string('invalidusername');
                 }
             }
         }
+        }
 
         //check if user exists in external db
         //TODO: maybe we should check all enabled plugins instead

Index: moodle/user/editadvanced.php
--- moodle/user/editadvanced.php Base (1.63)
+++ moodle/user/editadvanced.php Locally Modified (Based On 1.63)
@@ -136,7 +136,7 @@
         $authplugin = get_auth_plugin($usernew->auth);
     }
 
-    $usernew->username     = trim($usernew->username);
+    $usernew->username = clean_param($usernew->username, PARAM_USERNAME);
     $usernew->timemodified = time();
 
     if ($usernew->id == -1) {

Index: moodle/user/editadvanced_form.php
--- moodle/user/editadvanced_form.php Base (1.35)
+++ moodle/user/editadvanced_form.php Locally Modified (Based On 1.35)
@@ -145,9 +145,9 @@
                 $err['username'] = get_string('usernamelowercase');
             } else {
                 if (empty($CFG->extendedusernamechars)) {
-                    $string = preg_replace("/[^(-\.[:alnum:])]/i", '', $usernew->username);
+                    $string = clean_param($usernew->username, PARAM_USERNAME);
                     if ($usernew->username !== $string) {
-                        $err['username'] = get_string('alphanumerical');
+                        $err['username'] = get_string('invalidusername');
                     }
                 }
             }

Index: moodle/login/index.php
--- moodle/login/index.php Base (1.167)
+++ moodle/login/index.php Locally Modified (Based On 1.167)
@@ -114,7 +114,7 @@
     $frm->username = trim(moodle_strtolower($frm->username));

     if (is_enabled_auth('none') && empty($CFG->extendedusernamechars)) {
-        $string = preg_replace("~[^(-\.[:alnum:])]~i", "", $frm->username);
+        $string = clean_param($frm->username, PARAM_USERNAME);
         if (strcmp($frm->username, $string)) {
             $errormsg = get_string('username').': '.get_string("alphanumerical");
             $errorcode = 2;
