diff --git resources/node_resource.inc resources/node_resource.inc
index 9dfccf2..9cdbc66 100644
--- resources/node_resource.inc
+++ resources/node_resource.inc
@@ -271,6 +271,7 @@ function _node_resource_delete($nid) {
  *       for index requests more straightforward?
  **/
 function _node_resource_index($page = 1, $fields = '*', $parameters = array()) {
+
   $node_select = db_select('node', 'n')
     ->extend('PagerDefault')
     ->addTag('node_access')
@@ -280,17 +281,18 @@ function _node_resource_index($page = 1, $fields = '*', $parameters = array()) {
     
   if ($fields == '*') {
     $node_select->fields('n');
-  } else {
+  }
+  else {
     $fields = explode(',', $fields);
     $node_select->fields('n', $fields);
   }
-  
-  if (!user_access('administer nodes')) {
+
+ if (!user_access('administer nodes')) {
     $node_select->condition('status', 1);
-  }
+ }
 
   $result = $node_select->execute();
-  
+
   foreach($result as $node) {
     if ($uri = services_resource_uri(array('node', $node->nid))) {
       $node->uri = $uri;
diff --git resources/user_resource.inc resources/user_resource.inc
index 51ef667..29d17a1 100644
--- resources/user_resource.inc
+++ resources/user_resource.inc
@@ -65,7 +65,7 @@ function _user_resource_definition() {
           ),
         ),
       ),
-     
+
       'delete' => array(
         'help' => 'Deletes a user',
         'callback' => '_user_resource_delete',
@@ -92,7 +92,7 @@ function _user_resource_definition() {
             'optional' => TRUE,
             'type' => 'int',
             'description' => 'The zero-based index of the page to get, defaults to 0.',
-            'default value' => 1,
+            'default value' => 0,
             'source' => array('param' => 'page'),
           ),
           array(
@@ -108,7 +108,7 @@ function _user_resource_definition() {
             'optional' => TRUE,
             'type' => 'struct',
             'description' => 'Parameters',
-            'default value' => NULL,
+            'default value' => array(),
             'source' => array('param' => 'parameters'),
           ),
         ),
@@ -174,11 +174,11 @@ 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_execute() and as such exepects all input to match
  * the submitting form in question.
  *
  * @param $account
- *   A object containing account information. The $account object should 
+ *   A object containing account information. The $account object should
  *   contain, at minimum, the following properties:
  *     - name (user name)
  *     - mail (email address)
@@ -190,8 +190,8 @@ function _user_resource_retrieve($uid) {
  *
  *  Roles can be passed in a roles property which is an associative
  *  array formatted with '<role id>' => '<role id>', not including
- *  the authenticated user role, which is given by default. 
- *  
+ *  the authenticated user role, which is given by default.
+ *
  * @return
  *   The user object of the newly created user.
  */
@@ -217,7 +217,7 @@ function _user_resource_create($account) {
     'pass2' => $account->pass,
   );
   $form_state['values']['op'] = t('Create new account');
-  
+
   $ret = drupal_form_submit('user_register_form', $form_state);
 
   // Error if needed.
@@ -236,7 +236,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_execute() and as such exepects all input to match
  * the submitting form in question.
  *
  * @param $uid
@@ -248,21 +248,18 @@ function _user_resource_create($account) {
  *   The modified user object.
  */
 function _user_resource_update($uid, $account) {
+  $account = (object)$account;
   $account->uid = $uid;
+
+  $account_loaded = user_load($uid);
+
+  if (!isset($account->roles)) {
+    $account->roles = $account_loaded->roles;
+  }
   // 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;
-  }
-  
   // If a profile category was passed in, use it. Otherwise default
   // to 'account' (for saving core user data.)
   $category = 'account';
@@ -270,24 +267,35 @@ function _user_resource_update($uid, $account) {
     $category = $account->category;
     unset($account->category);
   }
-  
+
   // 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;
+    }
+  }
+
+  // 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]);
 
-  if(!isset($account->pass1) && !isset($account->pass2)) {
-      $account->pass1 = $account->pass;
-      $account->pass2 = $account->pass;
+  // 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()) {
@@ -338,21 +346,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);
 }
 
@@ -392,7 +403,7 @@ function _user_resource_logout() {
  * @param $page
  *   Page number of results to return (in pages of 20).
  * @param $fields
- *   The fields you want returned. 
+ *   The fields you want returned.
  * @param $parameters
  *   An array of fields and values used to build a sql WHERE clause indicating
  *   what items should be deleted.
@@ -401,18 +412,22 @@ function _user_resource_logout() {
  *
  * @see _node_resource_index() for more notes
  **/
-function _user_resource_index($page = 1, $fields = '*', $parameters = array()) {
+function _user_resource_index($page, $fields, $parameters) {
   $user_select = db_select('users', 'u')->extend('PagerDefault');
-  if($fields == '*') { 
-    $user_select->fields('u');  
-  } else {
+  if ($fields == '*') {
+    $user_select->fields('u');
+  }
+  else {
     $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->limit($page * 20);
+  $user_select->range($page, 20);
   $result = $user_select->execute();
-  foreach($result as $user) {  
+  foreach($result as $user) {
     if ($uri = services_resource_uri(array('user', $user->uid))) {
       $user->uri = $uri;
     }
@@ -432,12 +447,12 @@ function _user_resource_access($op = 'view', $args = array()) {
         if(!$account->uid) {
           return services_error('That user ID does not exist', 406);
         }
-        return user_view_access($account);   
+        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);
-        }      
+        }
       return ($user->uid == $account->uid || user_access('administer users'));
     case 'create':
       return user_access('administer users');
diff --git services.runtime.inc services.runtime.inc
index 68b32c3..e7655f9 100644
--- services.runtime.inc
+++ services.runtime.inc
@@ -63,7 +63,7 @@ class ServicesArgumentException extends ServicesException {
    *  Information that can be used by the server to return information about
    *  the error.
    */
-  public function __construct($message, $argument_name, $code, $data) {
+  public function __construct($message, $argument_name, $code, $data = NULL) {
     parent::__construct($message, $code, $data);
 
     $this->argument = $argument_name;
diff --git tests/functional/ServicesResourceNodeTests.test tests/functional/ServicesResourceNodeTests.test
index 1abec2a..167e1b2 100644
--- tests/functional/ServicesResourceNodeTests.test
+++ tests/functional/ServicesResourceNodeTests.test
@@ -1,5 +1,5 @@
 <?php
-// $Id: ServicesResourceNodeTests.test,v 1.2 2011/01/27 03:16:00 ocyrus Exp $
+// $Id:
 
 /**
  * @file
diff --git tests/functional/ServicesResourceUserTests.test tests/functional/ServicesResourceUserTests.test
new file mode 100644
index 0000000..3703b54
--- /dev/null
+++ tests/functional/ServicesResourceUserTests.test
@@ -0,0 +1,228 @@
+<?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.
+ *
+ */
+
+require_once('ServicesWebTestCase.php') ;
+
+/**
+ * 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');
+  }
+}
diff --git tests/functional/ServicesWebTestCase.php tests/functional/ServicesWebTestCase.php
index 036e1f1..78f908e 100644
--- tests/functional/ServicesWebTestCase.php
+++ tests/functional/ServicesWebTestCase.php
@@ -1,5 +1,5 @@
 <?php
-// $Id: ServicesWebTestCase.php,v 1.4 2011/01/30 16:21:04 heyrocker Exp $
+// $Id:
 
 class ServicesWebTestCase extends DrupalWebTestCase {
 
@@ -148,6 +148,7 @@ class ServicesWebTestCase extends DrupalWebTestCase {
       'title'  => $this->randomName(20),
       'path'   => $this->randomName(10),
       'server' => 'rest_server',
+      'services_use_content_permissions' => TRUE,
     );
   }
 
