diff --git resources/user_resource.inc resources/user_resource.inc
index 554eeab..0407868 100644
--- resources/user_resource.inc
+++ resources/user_resource.inc
@@ -106,7 +106,7 @@ function _user_resource_definition() {
             'optional' => TRUE,
             'type' => 'struct',
             'description' => 'Parameters',
-            'default value' => NULL,
+            'default value' => array(),
             'source' => array('param' => 'parameters'),
           ),
         ),
@@ -172,7 +172,7 @@ function _user_resource_retrieve($uid) {
 /**
  * Create a new user.
  *
- * This function uses drupal_execute() and as such exepects all input to match
+ * This function uses drupal_form_submit() and as such exepects all input to match
  * the submitting form in question.
  *
  * @param $account
@@ -195,14 +195,14 @@ function _user_resource_retrieve($uid) {
  */
 function _user_resource_create($account) {
   // Load the required includes for saving profile information
-  // with drupal_execute().
+  // with drupal_form_submit().
   module_load_include('inc', 'user', 'user.pages');
 
   // Any logged in user is by default authenticated,
   // and leaving this role set in the user's roles array
   // causes big problems because of a FAPI hack that controls
   // this checkbox on the user create and edit form (and thus
-  // causes problems with drupal_execute()). Therefore we just
+  // causes problems with drupal_form_submit()). Therefore we just
   // force it to 0 here.
   if (isset($account->roles[2])) {
     $account->roles[2] = 0;
@@ -234,7 +234,7 @@ function _user_resource_create($account) {
 /**
  * Update an existing user.
  *
- * This function uses drupal_execute() and as such exepects all input to match
+ * This function uses drupal_form_submit() and as such exepects all input to match
  * the submitting form in question.
  *
  * @param $uid
@@ -246,20 +246,17 @@ function _user_resource_create($account) {
  *   The modified user object.
  */
 function _user_resource_update($uid, $account) {
+  $account = (object)$account;
   $account->uid = $uid;
-  // Load the required includes for saving profile information
-  // with drupal_execute().
-  module_load_include('inc', 'user', 'user.pages');
 
-  // Any logged in user is by default authenticated,
-  // and leaving this role set in the user's roles array
-  // causes big problems because of a FAPI hack that controls
-  // this checkbox on the user create and edit form (and thus
-  // causes problems with drupal_execute()). Therefore we just
-  // force it to 0 here.
-  if (isset($account->roles[2])) {
-    $account->roles[2] = 0;
+  $account_loaded = user_load($uid);
+
+  if (!isset($account->roles)) {
+    $account->roles = $account_loaded->roles;
   }
+  // Load the required includes for saving profile information
+  // with drupal_form_submit().
+  module_load_include('inc', 'user', 'user.pages');
 
   // If a profile category was passed in, use it. Otherwise default
   // to 'account' (for saving core user data.)
@@ -270,22 +267,33 @@ function _user_resource_update($uid, $account) {
   }
 
   // Drop any passed in values into the $account var. Anything
-  // unused by the form just gets ignored.
-  foreach ($account as $key => $value) {
-    $form_state['values'][$key] = $value;
+  // unused by the form just gets ignored. We handle roles and
+  // password separately.
+  foreach ((array)$account as $key => $value) {
+    if ($key != 'pass' || $key != 'roles') {
+      $form_state['values'][$key] = $value;
+    }
   }
 
-  if (!isset($account->pass1) && !isset($account->pass2)) {
-      $account->pass1 = $account->pass;
-      $account->pass2 = $account->pass;
+  // Prepare values of roles.
+  foreach ($account->roles as $key => $value) {
+    if (!empty($value)) {
+      $form_state['values']['roles'][$key] = $key;
+    }
+  }
+  unset($form_state['values']['roles'][2]);
+
+  // Prepare values for password.
+  if (isset($account->pass)) {
+    $form_state['values']['pass']['pass1'] = $account->pass;
+    $form_state['values']['pass']['pass2'] = $account->pass;
   }
-  $form_state['values']['op'] = 'Save';
-  $form_state['values']['pass']['pass1'] = $account->pass1;
-  $form_state['values']['pass']['pass2'] = $account->pass1;
+
+  $form_state['values']['op'] = t('Save');
   $form_state['values']['#user_category'] = $category;
-  $form_state['values']['#account'] = (object)$account;
+  $form_state['values']['#account'] = $account_loaded;
 
-  $ret = drupal_form_submit('user_profile_form', $form_state, $account, $category);
+  $ret = drupal_form_submit('user_profile_form', $form_state, $account_loaded, $category);
 
   // Error if needed.
   if ($errors = form_get_errors()) {
@@ -336,21 +344,24 @@ function _user_resource_login($username, $password) {
     return services_error(t('Already logged in as !user.', array('!user' => $user->name)), 406);
   }
 
-  $user = user_load(user_authenticate($username, $password));
-  if ($user->uid) {
-    // Regenerate the session ID to prevent against session fixation attacks.
-    drupal_session_regenerate();
-    module_invoke_all('user', 'login', NULL, $user);
+  $uid = user_authenticate($username, $password);
+
+  if ($uid) {
+    $user = user_load($uid);
+    if ($user->uid) {
+      // Regenerate the session ID to prevent against session fixation attacks.
+      drupal_session_regenerate();
+      module_invoke_all('user', 'login', NULL, $user);
 
-    $return = new stdClass();
-    $return->sessid = session_id();
-    $return->session_name = session_name();
-    $return->user = $user;
+      $return = new stdClass();
+      $return->sessid = session_id();
+      $return->session_name = session_name();
+      $return->user = $user;
 
-    return $return;
+      return $return;
+    }
   }
-  session_destroy();
-  watchdog('user', 'Invalid login attempt.', array('%name' => theme('placeholder', $user->name)));
+  watchdog('user', 'Invalid login attempt for %username.', array('%username' => $username));
   return services_error(t('Wrong username or password.'), 401);
 }
 
@@ -399,7 +410,7 @@ function _user_resource_logout() {
  *
  * @see _node_resource_index() for more notes
  */
-function _user_resource_index($page = 0, $fields = '*', $parameters = NULL) {
+function _user_resource_index($page, $fields, $parameters) {
   $user_select = db_select('users', 'u');
   if ($fields == '*') {
     $user_select->fields('u');
@@ -408,15 +419,12 @@ function _user_resource_index($page = 0, $fields = '*', $parameters = NULL) {
     $fields = explode(',', $fields);
     $user_select->fields('u', $fields);
   }
+  foreach ($parameters as $key => $value) {
+    $user_select->condition('u.' . $key, $value, '=');
+  }
   $user_select->orderBy('created', 'DESC');
   $user_select->range($page * 20, 20);
 
-  if (is_object($parameters)) {
-    foreach ($parameters as $parameter => $parameter_value) {
-      $user_select->condition($parameter, $parameter_value, '=');
-    }
-  }
-
   $result = $user_select->execute();
   $users = array();
   foreach ($result as $user) {
@@ -441,7 +449,7 @@ function _user_resource_access($op = 'view', $args = array()) {
       }
       return user_view_access($account);
     case 'update':
-      $account = user_load($args[1]->uid);
+      $account = user_load($args[0]);
       if (!$account->uid) {
         return services_error('That user ID does not exist', 406);
       }
diff --git services.info services.info
index 4b79c43..8cd098e 100644
--- services.info
+++ services.info
@@ -14,6 +14,7 @@ files[] = services.servers.api.php
 files[] = serviers.services.api.php
 files[] = tests/functional/NoAuthEndpointTestRunner.test
 files[] = tests/functional/ServicesResourceNodeTests.test
+files[] = tests/functional/ServicesResourceUserTests.test
 files[] = tests/functional/ServicesResourceSystemTests.test
 files[] = tests/functional/ServicesEndpointTests.test
 files[] = tests/unit/TestServicesModule.test
diff --git tests/functional/ServicesResourceUserTests.test tests/functional/ServicesResourceUserTests.test
new file mode 100644
index 0000000..c17d2cb
--- /dev/null
+++ tests/functional/ServicesResourceUserTests.test
@@ -0,0 +1,226 @@
+<?php
+// $Id: ServicesResourceUserTests.test,v 1.1.2.1 2011/01/19 00:34:49 ocyrus Exp $
+
+/**
+ * @file
+ * Call the endpoint tests when no authentication is being used.
+ *
+ */
+
+/**
+ * Run test cases for the endpoint with no authentication turned on.
+ *
+ */
+class ServicesResourceUsertests extends ServicesWebtestCase {
+  // Class variables
+  protected $privileged_user = NULL ;
+  // Endpoint details.
+  protected $endpoint = NULL;
+
+  /**
+   * Implementation of setUp().
+   */
+  public function setUp() {
+    parent::setUp(
+      'ctools',
+      'services',
+      'rest_server'
+    );
+    // Set up endpoint.
+    $this->endpoint =  $this->saveNewEndpoint();
+    // Set up privileged user and login.
+    $this->privileged_user = $this->drupalCreateUser(array('administer users', 'access user profiles'));
+    $this->drupalLogin($this->privileged_user);
+  }
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+   return array(
+     'name'        => t('Resource User'),
+     'description' => t('Test the resource User methods and actions.'),
+     'group'       => t('Services'),
+   );
+  }
+
+  /**
+   * Test create method.
+   *
+   * Create user, load user, try ti create user without email.
+   */
+  function testCreateUser() {
+    // Create user.
+    $user = array();
+    $user['name']   = $this->randomName();
+    $user['mail']   = $user['name'] . '@example.com';
+    $user['pass']   = user_password();
+    $user['status'] = 1;
+
+    $response = $this->servicesPost($this->endpoint->path . '/user', array('account' => $user));
+    $account = $response['body'];
+    $this->assertTrue(!empty($account->uid), t('User has been create successfully.'), 'UserResource: Create');
+
+    // Load user.
+    $user_load = user_load($account['uid']);
+    $this->assertTrue(!empty($user_load), t('Newly created user has been loaded successfully.'), 'UserResource: Create');
+
+    // Try to create user without email.
+    $user = array();
+    $user['name']   = $this->randomName();
+    $user['pass']   = user_password();
+    $user['status'] = 1;
+    $response = $this->servicesPost($this->endpoint->path . '/user', array('account' => $user));
+    $this->assertTrue(strpos($response['status'], 'E-mail address field is required') !== FALSE, t('It is not possible to create user without email.'), 'UserResource: Create');
+  }
+
+  /**
+   * Test retrieve method.
+   */
+  function testRetrieveUser() {
+    $response = $this->servicesGET($this->endpoint->path . '/user/' . $this->privileged_user->uid);
+    $account = $response['body'];
+
+    $users_are_the_same =  ($account->name == $this->privileged_user->name)
+                        && ($account->mail = $this->privileged_user->mail)
+                        && ($account->roles = $this->privileged_user->roles);
+    $this->assertTrue($users_are_the_same, t('Retrieved user is the same as created.'), 'UserResource: Retrieve');
+  }
+
+  /**
+   * Test update method.
+   *
+   * Create user, update email.
+   */
+  function testUpdateUser() {
+    // Create user.
+    $account = $this->drupalCreateUser();
+
+    // Update mail of the user.
+    $updated_account = array(
+      'mail' => $this->randomName() . '@example.com',
+    );
+    $response = $this->servicesPut($this->endpoint->path . '/user/' . $account->uid, array('data' => $updated_account));
+
+    $user_load = user_load($account->uid);
+    $this->assertEqual($updated_account['mail'], $user_load->mail, t('User details have been updated successfully'), 'UserResource: Update');
+  }
+
+  /**
+   * Test delete method.
+   */
+  function testDeleteUser() {
+    // Create user.
+    $account = $this->drupalCreateUser();
+
+    // Delete user.
+    $response = $this->servicesDelete($this->endpoint->path . '/user/' . $account->uid);
+
+    $user_load = user_load($account->uid);
+    $this->assertTrue(empty($user_load), t('User has been deleted successfully.'), 'UserResource: Delete');
+  }
+
+  /**
+   * Test index method.
+   *
+   * Create several users list them. List one user by name.
+   */
+  function testUserIndex() {
+    // Create several users.
+    $accounts = array();
+    for ($i = 0; $i < 5; $i++) {
+      $account = $this->drupalCreateUser();
+      $accounts[$account->uid] = $account;
+    }
+
+    $accounts_copy = $accounts;
+
+    $response = $this->servicesGet($this->endpoint->path . '/user');
+    $response_accounts = $response['body'];
+
+    foreach ($response_accounts as $response_account) {
+      // We do not check anonymous and admin users.
+      if ($response_account->uid < 2) {
+        continue;
+      }
+      // If name and email are the same we believe that accounts are the same.
+      if (isset($accounts[$response_account->uid])) {
+        $saved_account = $accounts[$response_account->uid];
+        if ($response_account->name == $saved_account->name && $response_account->mail == $saved_account->mail) {
+          unset($accounts_copy[$response_account->uid]);
+        }
+      }
+    }
+
+    $this->assertTrue(empty($accounts_copy), t('Users were listed properly.'), 'UserResource: Index');
+
+    $accounts_copy = $accounts;
+    $account = array_pop($accounts_copy);
+
+    // Get user with specific name.
+    $response = $this->servicesGet($this->endpoint->path . '/user', array('parameters' => array('name' => $account->name)));
+    $response_accounts = $response['body'];
+    $response_account = current($response['body']);
+
+    $proper_answer = count($response_accounts) == 1
+                  && $response_account->name == $account->name;
+    $this->assertTrue($proper_answer, t('User was listed by name properly.'), 'UserResource: Index');
+  }
+
+  /**
+   * Test login method.
+   *
+   * Create user. Login. Try to login with another user (to get error).
+   * Login with wrong credentials (to get error).
+   */
+  function testUserLogin() {
+    $account = $this->drupalCreateUser();
+
+    // Logout first.
+    $this->drupalLogout();
+
+    $response = $this->servicesPost($this->endpoint->path . '/user/login', array('username' => $account->name, 'password' => $account->pass_raw));
+
+    $response_data = $response['body'];
+
+    $proper_answer = isset($response_data->sessid)
+                  && isset($response_data->user)
+                  && $response_data->user->name == $account->name;
+    $this->assertTrue($proper_answer, t('User successfully logged in.'), 'UserResource: Login');
+
+    // Save session details.
+    $this->session_id = $response_data->sessid;
+    $this->session_name = $response_data->session_name;
+    $this->loggedInUser = $response_data->user;
+
+    // Try to login with another user to get error.
+    $account2 = $this->drupalCreateUser();
+    $response = $this->servicesPost($this->endpoint->path . '/user/login', array('username' => $account2->name, 'password' => $account2->pass_raw));
+    $this->assertTrue(strpos($response['status'], 'Already logged in as ' . $account->name) !== FALSE, t('Session is properly opened for logged in user.'), 'UserResource: Login');
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Try to login with wrong credentials.
+    $response = $this->servicesPost($this->endpoint->path . '/user/login', array('username' => $account->name, 'password' => $this->randomString()));
+    $this->assertTrue(strpos($response['status'], 'Wrong username or password') !== FALSE, t('User cannot login with wrong username / password.'), 'UserResource: Login');
+  }
+
+  /**
+   * Test logout method.
+   */
+  function testUserLogout() {
+    // Logout via REST call.
+    $response = $this->servicesPost($this->endpoint->path . '/user/logout');
+    // Try logout second time.
+    $this->drupalGet('user/logout');
+    $this->assertText(t('You are not authorized to access this page'), t('User logout successfully.'), 'UserResource: Logout');
+    // Login again.
+    $this->drupalLogin($this->privileged_user);
+    // Logout via REST call.
+    $response = $this->servicesPost($this->endpoint->path . '/user/logout');
+    // Try to logout second time via REST call.
+    $response = $this->servicesPost($this->endpoint->path . '/user/logout');
+    $this->assertTrue(strpos($response['status'], 'User is not logged in'), t('User cannot logout when is anonymous'), 'UserResource: Logout');
+  }
+}
