diff --git a/protected_node.info b/protected_node.info
index 79b9f81..1105a57 100644
--- a/protected_node.info
+++ b/protected_node.info
@@ -4,11 +4,12 @@
 version = 7.x-dev
 package = Access
 configure = admin/config/content/protected_node
 recommends[] = tokens
 recommends[] = upload
 
 files[] = tests/protected_node.test
 files[] = tests/protected_node.per_node.test
 files[] = tests/protected_node.per_type.test
 files[] = tests/protected_node.global.test
-files[] = tests/protected_node.mail.test
\ No newline at end of file
+files[] = tests/protected_node.mail.test
+files[] = tests/protected_node.private_file.test
diff --git a/protected_node.module b/protected_node.module
index 728f191..5f4c7c5 100644
--- a/protected_node.module
+++ b/protected_node.module
@@ -74,21 +74,21 @@
  * @link http://api.drupal.org/api/function/hook_permission/7
  */
 function protected_node_permission() {
   $perms = array(
     'access protected content' => array(
       'title' => t('access protected content'),
       'description' => t('Access password screen for protected content. Without this permission user will be denied access completely.'),
     ),
     'bypass password protection' => array(
       'title' => t('bypass password protection'),
-      'description' => t('Bypass password protection'),
+      'description' => t('Bypass password protection for the node view page only'),
     ),
     'edit any password' => array(
       'title' => t('edit any password'),
       'description' => t('Edit any password'),
     ),
     'view protected content' => array(
       'title' => t('view protected content'),
       'description' => t('View potected content'),
     ),
   );
@@ -151,22 +151,20 @@
   }
 
   return TRUE;
 }
 
 /**
  * Implements hook_init().
  * @link http://api.drupal.org/api/function/hook_init/7
  */
 function protected_node_init() {
-  global $user;
-
   // Let Drush bypass password protection.
   if (function_exists('drush_main')) {
     return;
   }
 
   // Are we about to display a node?
   // Can user see all nodes anyway?
   if (user_access('bypass password protection')) {
     return;
   }
@@ -193,23 +191,25 @@
     else {
       // Any access right?
       $nid = protected_node_is_locked(arg(1));
     }
     if ($nid === TRUE || $nid === -1) {
       drupal_access_denied();
       exit();
     }
   }
   elseif (arg(0) == 'system' && arg(1) == 'files') {
-    if (!empty($param2)) {
-      // $param2 is a filename in this case.
-      $nid = protected_node_and_attachment($param2);
+    $requested_url = drupal_parse_url(request_uri());
+    $path = explode('/', $requested_url['path']);
+    if (!empty($path)) {
+      $filename = end($path);
+      $nid = protected_node_and_attachment($filename);
     }
   }
 
   if ($nid) {
     $query = drupal_get_destination();
     if (!empty($_SERVER['HTTP_REFERER'])) {
       $query['back'] = urlencode($_SERVER['HTTP_REFERER']);
     }
     $query['protected_page'] = $nid;
 
@@ -321,24 +321,21 @@
 
 /**
  * If gathering an attachment, verify that it is accessible and if
  * not ask for the password.
  *
  * @param[in] $filename  The name of the attachment file.
  */
 function protected_node_and_attachment($filename) {
   global $user;
 
-  // The upload module glues the attachments and nodes together without that
-  // module, we cannot test anything here (it is not requiredanyway if the user
-  // is going to the /node/# page itself).
-  if (user_access('bypass password protection') || !module_exists('upload')) {
+  if (user_access('bypass password protection')) {
     return FALSE;
   }
 
   // Check whether the node linked to this file attachment is protected.
   $query = db_select('node', 'n');
   $query->join('file_usage', 'fu', 'n.nid = fu.id');
   $query->join('file_managed', 'fm', 'fm.fid = fu.fid');
   $query->join('protected_nodes', 'pn', 'n.nid = pn.nid');
   $query->fields('n', array('nid', 'uid'));
   $query->fields('pn', array('protected_node_passwd_changed'));
@@ -370,35 +367,20 @@
     else {
       // Got the password?
       if (isset($_SESSION['_protected_node']['passwords'][$file_info->nid])) {
         $when = $_SESSION['_protected_node']['passwords'][$file_info->nid];
         if ($when > $file_info->protected_node_passwd_changed  /* this page reset time */
          && $when > variable_get('protected_node_session_timelimit', 0)) { /* global reset time */
           return FALSE;
         }
         // The session is out of date, we can as well get rid of it now.
         unset($_SESSION['_protected_node']['passwords'][$file_info->nid]);
-      }
-    }
-
-    // Avoid the drupal_goto() if another module anyway forbids access
-    // to the file.
-    foreach (module_implements('file_download') as $module) {
-      // Skip ourself, we already know the answer!
-      if ($module != 'protected_node') {
-        $function = $module . '_file_download';
-        $result = call_user_func_array($function, array($filename));
-        if (isset($result) && $result == -1) {
-          // This $module forbids the file download, forget it a password won't
-          // help.
-          return FALSE;
-        }
       }
     }
 
     // No password, access denied.
     return $file_info->nid;
   }
 }
 
 
 /**
@@ -674,28 +656,20 @@
   $node->body = '';
   $node->content = array();
 }
 
 
 /**
  * Implements hook_file_download().
  */
 function protected_node_file_download($uri) {
   global $user;
-
-  // The upload module glues the attachments and nodes together
-  // without that module, we cannot test anything here
-  // (it is not required anyway if the user is going to the /node/#
-  // page itself.)
-  if (user_access('bypass password protection')) {
-    return array();
-  }
   $path = file_uri_target($uri);
 
   // Private file access for image style derivatives.
   if (strpos($path, 'styles/') === 0) {
     $original_uri = _protected_node_get_original_uri($path, $uri);
 
     // Check that the file exists and is an image.
     if ($info = image_get_info($uri)) {
       // Check the permissions of the original to grant access to this image.
       $headers = module_invoke_all('file_download', $original_uri);
@@ -720,33 +694,33 @@
       $query->condition('fu.fid', $file->fid);
       $query->condition('fu.type', 'node');
       $query->condition('pn.protected_node_is_protected', '1');
       $number_of_results = $query->countQuery()->execute()->fetchField();
       if (0 == $number_of_results) {
         return array(); /* Row doesn't exist, it's not protected */
       }
       $result = $query->execute();
 
       foreach ($result as $file_info) {
-        if($file_info === FALSE || ($user->uid && $user->uid == $file_info->uid)) {
+        // if the file belongs to the current user let them see it.
+        if ($file_info === FALSE || ($user->uid && $user->uid == $file_info->uid)) {
           return array();
         }
 
         // Got the global password?
         if (isset($_SESSION['_protected_node']['passwords']['global'])) {
           $when = $_SESSION['_protected_node']['passwords']['global'];
           if ($when > $file_info->protected_node_passwd_changed  /* this page reset time */
             && $when > variable_get('protected_node_session_timelimit', 0)) { /* global reset time */
               return array();
           }
         }
-
         elseif (isset($_SESSION['_protected_node']['passwords'][$file_info->nid])) {
           $when = $_SESSION['_protected_node']['passwords'][$file_info->nid];
           if ($when > $file_info->protected_node_passwd_changed  /* this page reset time */
            && $when > variable_get('protected_node_session_timelimit', 0)) { /* global reset time */
             return array();
           }
         }
       }
     }
   }
diff --git a/tests/protected_node.per_node.test b/tests/protected_node.per_node.test
index c55ac23..cacaaa6 100644
--- a/tests/protected_node.per_node.test
+++ b/tests/protected_node.per_node.test
@@ -113,21 +113,21 @@
     // Generate random password.
     $password = $this->randomName(10);
     // Create a new page node.
     $node = $this->createProtectedNode($password);
     // Once the node created logout the User.
     $this->drupalLogout();
 
     // User that can see published content sees the node.
     $this->drupalLogin($this->normalNonAccessAllowedUser);
     $this->drupalGet('node/' . $node->nid);
-    $this->assertResponse(403, "User with no access permission is not allowed to access a protected node");
+    $this->assertResponse(403, "User with no access permission is not allowed to access a protected node", $this->group);
   }
 
   /**
    * Helper method to create a protected node.
    *
    * Please make sure the user has the permission to create the node before
    * calling the method.
    * @argument password.
    * @return node object.
    */
diff --git a/tests/protected_node.private_file.test b/tests/protected_node.private_file.test
new file mode 100644
index 0000000..5c512cd
--- /dev/null
+++ b/tests/protected_node.private_file.test
@@ -0,0 +1,204 @@
+<?php
+
+/**
+ * @file Test protected node behavior with private files.
+ */
+
+/**
+ * Configure protected_node to use per node password and use private file field.
+ */
+class ProtectedNodePrivateFile extends ProtectedNodeBaseTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Protected node private file',
+      'description' => "This tests the behavior of protected node with private file field",
+      'group' => 'Protected Node',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Log in an Admin.
+    $this->drupalLogin($this->adminUser);
+    // Submit the configuration form.
+    $protected_node_settings = array(
+      'protected_node_use_global_password' => PROTECTED_NODE_PER_NODE_PASSWORD,
+    );
+    $this->drupalPost('admin/config/content/protected_node', $protected_node_settings, t('Save configuration'));
+
+    // Private file system already set by simpletest.
+
+    // Set private file field for basic page.
+    $this->createFileField('private_file', 'page', array(
+      'uri_scheme' => 'private',
+    ));
+
+    // Get a file to upload.
+    $this->text_file = current($this->drupalGetTestFiles('text'));
+  }
+
+  /**
+   * Test that a file on a node protected with per node protection can be
+   * downloaded with the right password.
+   */
+  public function testAllowedView() {
+    // Log in as Admin.
+    $this->drupalLogin($this->adminUser);
+    // Generate random password.
+    $password = $this->randomName(10);
+    // Create a new page node.
+    $node = $this->createProtectedNode($password);
+    // Once the node created logout the User.
+    $this->drupalLogout();
+
+    // An authenticated user sees the node.
+    $this->drupalLogin($this->normalAccessAllowedUser);
+    $form = array('password' => $password);
+    $this->drupalPost('node/' . $node->nid, $form, t('OK'));
+
+    // Ensure the file can be downloaded.
+		$this->drupalGet(file_create_url($node->private_file['und'][0]['uri']));
+		$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.', $this->group);
+  }
+
+  /**
+   * Test that a file on a node protected with per node protection can't be
+   * downloaded with the wrong password.
+   */
+  public function testAllowedViewWrongPassword() {
+    // Log in as Admin.
+    $this->drupalLogin($this->adminUser);
+    // Generate random password.
+    $password = $this->randomName(10);
+    // Create a new page node.
+    $node = $this->createProtectedNode($password);
+    // Once the node created logout the User.
+    $this->drupalLogout();
+
+    // An authenticated user sees the node.
+    $this->drupalLogin($this->normalAccessAllowedUser);
+    $another_password = $this->randomName(12);
+    $form = array('password' => $another_password);
+    $this->drupalPost('node/' . $node->nid, $form, t('OK'));
+
+    // Ensure the file cannot be downloaded.
+		$file_uri = $node->private_file['und'][0]['uri'];
+		$file_url = file_create_url($file_uri);
+		$file_text = file_get_contents(drupal_realpath($file_uri));
+		$this->drupalGet($file_url);
+		$this->assertNoText($file_text, 'Confirmed that access is denied for the file without access to the node.', $this->group);
+  }
+
+  /**
+   * Test that a file on a node protected with per node protection can't be
+   * downloaded by an authenticated but not allowed user.
+   */
+  public function testAuthenticatedNonAllowedView() {
+    // Log in as Admin.
+    $this->drupalLogin($this->adminUser);
+    // Generate random password.
+    $password = $this->randomName(10);
+    // Create a new page node.
+    $node = $this->createProtectedNode($password);
+    // Once the node created logout the User.
+    $this->drupalLogout();
+
+		// Ensure the file cannot be downloaded.
+		$this->drupalLogin($this->normalNonAccessAllowedUser);
+		$this->drupalGet(file_create_url($node->private_file['und'][0]['uri']));
+		$this->assertResponse(403, 'Confirmed that access is denied for the file without access to the node.', $this->group);
+  }
+
+  /**
+   * Creates a new file field.
+   *
+   * @param $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param $type_name
+   *   The node type that this field will be added to.
+   * @param $field_settings
+   *   A list of field settings that will be added to the defaults.
+   * @param $instance_settings
+   *   A list of instance settings that will be added to the instance defaults.
+   * @param $widget_settings
+   *   A list of widget settings that will be added to the widget defaults.
+   */
+  function createFileField($name, $type_name, $field_settings = array(), $instance_settings = array(), $widget_settings = array()) {
+    $field = array(
+      'field_name' => $name,
+      'type' => 'file',
+      'settings' => array(),
+      'cardinality' => ! empty($field_settings['cardinality']) ? $field_settings['cardinality'] : 1
+    );
+    $field['settings'] = array_merge($field['settings'], $field_settings);
+    field_create_field($field);
+
+    $this->attachFileField($name, 'node', $type_name, $instance_settings, $widget_settings);
+  }
+
+  /**
+   * Attaches a file field to an entity.
+   *
+   * @param $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param $entity_type
+   *   The entity type this field will be added to.
+   * @param $bundle
+   *   The bundle this field will be added to.
+   * @param $field_settings
+   *   A list of field settings that will be added to the defaults.
+   * @param $instance_settings
+   *   A list of instance settings that will be added to the instance defaults.
+   * @param $widget_settings
+   *   A list of widget settings that will be added to the widget defaults.
+   */
+  function attachFileField($name, $entity_type, $bundle, $instance_settings = array(), $widget_settings = array()) {
+    $instance = array(
+      'field_name' => $name,
+      'label' => $name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle,
+      'required' => ! empty($instance_settings['required']),
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'file_generic',
+        'settings' => array()
+      )
+    );
+    $instance['settings'] = array_merge($instance['settings'], $instance_settings);
+    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
+    field_create_instance($instance);
+  }
+
+  /**
+   * Helper method to create a protected node.
+   *
+   * Please make sure the user has the permission to create the node before
+   * calling the method.
+   * @argument password.
+   * @return node object.
+   */
+  public function createProtectedNode($password) {
+    // Add a new page node that is protected.
+    $node_title = $this->randomName(8);
+    $node_data = array(
+      'title' => $node_title,
+      'files[private_file_und_0]' => drupal_realpath($this->text_file->uri),
+      'protected_node_is_protected' => TRUE,
+      'protected_node_passwd[pass1]' => $password,
+      'protected_node_passwd[pass2]' => $password,
+    );
+    $this->drupalPost('node/add/page', $node_data, t('Save'));
+
+    return $this->drupalGetNodeByTitle($node_title);
+  }
+
+}