diff --git a/mod/data/lang/en/data.php b/mod/data/lang/en/data.php
index 0740288cb4e..be37490ed09 100644
--- a/mod/data/lang/en/data.php
+++ b/mod/data/lang/en/data.php
@@ -32,6 +32,7 @@ $string['advancedsearch'] = 'Advanced search';
 $string['alttext'] = 'Alternative text';
 $string['approve'] = 'Approve';
 $string['approved'] = 'Approved';
+$string['areacontent'] = 'Fields';
 $string['ascending'] = 'Ascending';
 $string['asearchtemplate'] = 'Advanced search template';
 $string['atmaxentry'] = 'You have entered the maximum number of entries allowed!';
diff --git a/mod/data/lib.php b/mod/data/lib.php
index d846ea28550..1ebf07e4bfe 100644
--- a/mod/data/lib.php
+++ b/mod/data/lib.php
@@ -2865,6 +2865,10 @@ function data_get_exportdata($dataid, $fields, $selectedfields, $currentgroup=0)
     return $exportdata;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// File API                                                                   //
+////////////////////////////////////////////////////////////////////////////////
+
 /**
  * Lists all browsable file areas
  *
@@ -2876,8 +2880,7 @@ function data_get_exportdata($dataid, $fields, $selectedfields, $currentgroup=0)
  * @return array
  */
 function data_get_file_areas($course, $cm, $context) {
-    $areas = array();
-    return $areas;
+    return array('content' => get_string('areacontent', 'mod_data'));
 }
 
 /**
@@ -2901,55 +2904,65 @@ function mod_data_get_file_info($browser, $areas, $course, $cm, $context, $filea
         return null;
     }
 
-    if ($filearea === 'content') {
-        if (!$content = $DB->get_record('data_content', array('id'=>$itemid))) {
-            return null;
-        }
-
-        if (!$field = $DB->get_record('data_fields', array('id'=>$content->fieldid))) {
-            return null;
-        }
-
-        if (!$record = $DB->get_record('data_records', array('id'=>$content->recordid))) {
-            return null;
-        }
-
-        if (!$data = $DB->get_record('data', array('id'=>$field->dataid))) {
-            return null;
-        }
-
-        //check if approved
-        if ($data->approval and !$record->approved and !data_isowner($record) and !has_capability('mod/data:approve', $context)) {
-            return null;
-        }
-
-        // group access
-        if ($record->groupid) {
-            $groupmode = groups_get_activity_groupmode($cm, $course);
-            if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
-                if (!groups_is_member($record->groupid)) {
-                    return null;
-                }
-            }
-        }
-
-        $fieldobj = data_get_field($field, $data, $cm);
-
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-        if (!$fieldobj->file_ok($filepath.$filename)) {
-            return null;
-        }
-
-        $fs = get_file_storage();
-        if (!($storedfile = $fs->get_file($context->id, 'mod_data', $filearea, $itemid, $filepath, $filename))) {
-            return null;
-        }
-        $urlbase = $CFG->wwwroot.'/pluginfile.php';
-        return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false);
+    if (!isset($areas[$filearea])) {
+        return null;
     }
 
-    return null;
+    if (!has_capability('moodle/course:managefiles', $context)) {
+        return null;
+    }
+
+    if (is_null($itemid)) {
+        require_once($CFG->dirroot.'/mod/data/locallib.php');
+        return new data_file_info_container($browser, $course, $cm, $context, $areas, $filearea);
+    }
+
+    if (!$content = $DB->get_record('data_content', array('id'=>$itemid))) {
+        return null;
+    }
+
+    if (!$field = $DB->get_record('data_fields', array('id'=>$content->fieldid))) {
+        return null;
+    }
+
+    if (!$record = $DB->get_record('data_records', array('id'=>$content->recordid))) {
+        return null;
+    }
+
+    if (!$data = $DB->get_record('data', array('id'=>$field->dataid))) {
+        return null;
+    }
+
+    //check if approved
+    if ($data->approval and !$record->approved and !data_isowner($record) and !has_capability('mod/data:approve', $context)) {
+        return null;
+    }
+
+    // group access
+    if ($record->groupid) {
+        $groupmode = groups_get_activity_groupmode($cm, $course);
+        if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
+            if (!groups_is_member($record->groupid)) {
+                return null;
+            }
+        }
+    }
+
+    $fieldobj = data_get_field($field, $data, $cm);
+
+    $filepath = is_null($filepath) ? '/' : $filepath;
+    $filename = is_null($filename) ? '.' : $filename;
+    if (!$fieldobj->file_ok($filepath.$filename)) {
+        return null;
+    }
+
+    $fs = get_file_storage();
+    if (!($storedfile = $fs->get_file($context->id, 'mod_data', $filearea, $itemid, $filepath, $filename))) {
+        return null;
+    }
+    $urlbase = $CFG->wwwroot.'/pluginfile.php';
+
+    return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false);
 }
 
 /**
diff --git a/mod/data/locallib.php b/mod/data/locallib.php
index d8f8ab90765..4ab3df8e4ab 100644
--- a/mod/data/locallib.php
+++ b/mod/data/locallib.php
@@ -398,3 +398,119 @@ class data_portfolio_caller extends portfolio_module_caller_base {
         return array('mineonly');
     }
 }
+
+
+/**
+ * Class representing the virtual node with all itemids in the file browser
+ *
+ * @category  files
+ * @copyright 2012 David Mudrak <david@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class data_file_info_container extends file_info {
+    /** @var file_browser */
+    protected $browser;
+    /** @var stdClass */
+    protected $course;
+    /** @var stdClass */
+    protected $cm;
+    /** @var string */
+    protected $component;
+    /** @var stdClass */
+    protected $context;
+    /** @var array */
+    protected $areas;
+    /** @var string */
+    protected $filearea;
+
+    /**
+     * Constructor (in case you did not realize it ;-)
+     *
+     * @param file_browser $browser
+     * @param stdClass $course
+     * @param stdClass $cm
+     * @param stdClass $context
+     * @param array $areas
+     * @param string $filearea
+     */
+    public function __construct($browser, $course, $cm, $context, $areas, $filearea) {
+        parent::__construct($browser, $context);
+        $this->browser = $browser;
+        $this->course = $course;
+        $this->cm = $cm;
+        $this->component = 'mod_data';
+        $this->context = $context;
+        $this->areas = $areas;
+        $this->filearea = $filearea;
+    }
+
+    /**
+     * @return array with keys contextid, filearea, itemid, filepath and filename
+     */
+    public function get_params() {
+        return array(
+            'contextid' => $this->context->id,
+            'component' => $this->component,
+            'filearea' => $this->filearea,
+            'itemid' => null,
+            'filepath' => null,
+            'filename' => null,
+        );
+    }
+
+    /**
+     * Can new files or directories be added via the file browser
+     *
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Should this node be considered as a folder in the file browser
+     *
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns localised visible name of this node
+     *
+     * @return string
+     */
+    public function get_visible_name() {
+        return $this->areas[$this->filearea];
+    }
+
+    /**
+     * Returns list of children nodes
+     *
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        global $DB;
+
+        $children = array();
+        $itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'component' => $this->component,
+            'filearea' => $this->filearea), 'itemid DESC', "DISTINCT itemid");
+        foreach ($itemids as $itemid => $unused) {
+            if ($child = $this->browser->get_file_info($this->context, 'mod_data', $this->filearea, $itemid)) {
+                $children[] = $child;
+            }
+        }
+
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     *
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        return $this->browser->get_file_info($this->context);
+    }
+}