diff --git a/database/database.mysql b/database/database.mysql
index bd8af26464e681afa0745a18031ec49c8e775ab4..eea199a22b8eee6bd09904fe59da2981069b6b76 100644
--- a/database/database.mysql
+++ b/database/database.mysql
@@ -247,6 +247,7 @@ CREATE TABLE files (
   nid int(10) unsigned NOT NULL default '0',
   vid int(10) unsigned NOT NULL default '0',
   filename varchar(255) NOT NULL default '',
+  description varchar(255) NOT NULL default '',
   filepath varchar(255) NOT NULL default '',
   filemime varchar(255) NOT NULL default '',
   filesize int(10) unsigned NOT NULL default '0',
diff --git a/database/database.pgsql b/database/database.pgsql
index 140e0cbc08eb9582078ab968c6c15408a380bfda..c3cf8738d99721fa63d0f7773428f6ae25c5112b 100644
--- a/database/database.pgsql
+++ b/database/database.pgsql
@@ -242,6 +242,7 @@ CREATE TABLE files (
   fid SERIAL,
   nid integer NOT NULL default '0',
   vid integer NOT NULL default '0',
+  description varchar(255) NOT NULL default '',
   filename varchar(255) NOT NULL default '',
   filepath varchar(255) NOT NULL default '',
   filemime varchar(255) NOT NULL default '',
diff --git a/database/updates.inc b/database/updates.inc
index 1cde1f4bd994070e2138afffbcb72ec47796e624..988cb3a6f22fee8e359f8cbe5286785deb2c1320 100644
--- a/database/updates.inc
+++ b/database/updates.inc
@@ -65,7 +65,8 @@
   "2005-08-15" => "update_145",
   "2005-08-25" => "update_146",
   "2005-09-07" => "update_147",
-  "2005-09-18" => "update_148"
+  "2005-09-18" => "update_148",
+  "2005-09-27" => "update_149"
 );
 
 function update_110() {
@@ -829,6 +830,22 @@ function update_148() {
   return $ret;
 }
 
+function update_149() {
+  $ret = array();
+
+  switch ($GLOBALS['db_type']) {
+    case 'pgsql':
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("ALTER TABLE {files} ADD COLUMN description VARCHAR(255) NOT NULL DEFAULT ''");
+      break;
+    default:
+      break;
+  }
+
+  return $ret;
+}
+
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
diff --git a/modules/filter.module b/modules/filter.module
index e8ee308c7a5a3f147bc4b3f258912d23056d5811..0b72f3a94e0c7e3b2993d09445d189247a012411 100644
--- a/modules/filter.module
+++ b/modules/filter.module
@@ -747,7 +747,8 @@ function filter_form($name = 'format', $value = FILTER_FORMAT_DEFAULT) {
       $output .= theme('filter_tips', $tips);
       $output .= '</div>';
     }
-    return theme('form_element', t('input format'), $output, $extra, NULL, _form_get_error($name));
+
+    return form_group_collapsible(t('Input format'), $output, $extra);
   }
   else {
     // Only one format available: use a hidden form item and only show tips.
diff --git a/modules/filter/filter.module b/modules/filter/filter.module
index e8ee308c7a5a3f147bc4b3f258912d23056d5811..0b72f3a94e0c7e3b2993d09445d189247a012411 100644
--- a/modules/filter/filter.module
+++ b/modules/filter/filter.module
@@ -747,7 +747,8 @@ function filter_form($name = 'format', $value = FILTER_FORMAT_DEFAULT) {
       $output .= theme('filter_tips', $tips);
       $output .= '</div>';
     }
-    return theme('form_element', t('input format'), $output, $extra, NULL, _form_get_error($name));
+
+    return form_group_collapsible(t('Input format'), $output, $extra);
   }
   else {
     // Only one format available: use a hidden form item and only show tips.
diff --git a/modules/upload.module b/modules/upload.module
index d9f34d738c1da6e800ef209401cf0d01c2d56aea..f1f9b463cf6b8012f57c4e34013653e00bede7ae 100644
--- a/modules/upload.module
+++ b/modules/upload.module
@@ -152,6 +152,7 @@ function upload_nodeapi(&$node, $op, $arg) {
             $node->files[$file->source] = $file;
             $node->files[$key]->list = $node->list[$key];
             $node->files[$key]->remove = $node->remove[$key];
+            $node->files[$key]->description = $node->description[$key];
             if ($file->source) {
               $filesize += $file->filesize;
             }
@@ -244,7 +245,7 @@ function upload_nodeapi(&$node, $op, $arg) {
         foreach ($node->files as $file) {
           if ($file->list) {
             $rows[] = array(
-              '<a href="'. check_url(($file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path())))) .'">'. check_plain($file->filename) .'</a>',
+              '<a href="'. check_url(($file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path())))) .'">'. check_plain($file->description ? $file->description : $file->filename) .'</a>',
               format_size($file->filesize)
             );
             // We save the list of files still in preview for later
@@ -342,8 +343,8 @@ function upload_save($node) {
       // Insert new files:
       if ($file = file_save_upload($file, $file->filename)) {
         $fid = db_next_id('{files}_fid');
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)",
-                 $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key]);
+        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
+                 $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key], $file->description);
       }
     }
   }
@@ -360,15 +361,15 @@ function upload_save($node) {
   }
   foreach ((array)$node->list as $key => $value) {
     if (!$node->remove[$key]) {
-      db_query('UPDATE {files} SET list = %d WHERE fid = %d AND vid = %d', $node->list[$key], $key, $node->vid);
+      db_query('UPDATE {files} SET list = %d, description = \'%s\' WHERE fid = %d AND vid = %d', $node->list[$key], $node->description[$key], $key, $node->vid);
     }
   }
   if ($node->old_vid) {
     foreach ((array)$node->remove as $key => $remove) {
       if (!$remove) {
         $file = db_fetch_object(db_query('SELECT * FROM {files} WHERE vid = %d AND fid = %d', $node->old_vid, $key));
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)",
-                 $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $file->list);
+        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
+                 $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $file->list, $file->description);
       }
     }
   }
@@ -393,7 +394,7 @@ function upload_form($node) {
 }
 
 function _upload_form($node) {
-  $header = array(t('Delete'), t('List'), t('Url'), t('Size'));
+  $header = array(t('Delete'), t('List'), t('Description'), t('Size'));
   $rows = array();
   $output = '';
 
@@ -402,7 +403,7 @@ function _upload_form($node) {
       $rows[] = array(
         form_checkbox('', "remove][$key", 1, $file->remove),
         form_checkbox('', "list][$key", 1, $file->list),
-        $file->filename ."<br /><small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>",
+        form_textfield('', "description][$key", $file->description ? $file->description : $file->filename, 60, 256) ."<br /><small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>",
         format_size($file->filesize)
       );
     }
diff --git a/modules/upload/upload.module b/modules/upload/upload.module
index d9f34d738c1da6e800ef209401cf0d01c2d56aea..f1f9b463cf6b8012f57c4e34013653e00bede7ae 100644
--- a/modules/upload/upload.module
+++ b/modules/upload/upload.module
@@ -152,6 +152,7 @@ function upload_nodeapi(&$node, $op, $arg) {
             $node->files[$file->source] = $file;
             $node->files[$key]->list = $node->list[$key];
             $node->files[$key]->remove = $node->remove[$key];
+            $node->files[$key]->description = $node->description[$key];
             if ($file->source) {
               $filesize += $file->filesize;
             }
@@ -244,7 +245,7 @@ function upload_nodeapi(&$node, $op, $arg) {
         foreach ($node->files as $file) {
           if ($file->list) {
             $rows[] = array(
-              '<a href="'. check_url(($file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path())))) .'">'. check_plain($file->filename) .'</a>',
+              '<a href="'. check_url(($file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path())))) .'">'. check_plain($file->description ? $file->description : $file->filename) .'</a>',
               format_size($file->filesize)
             );
             // We save the list of files still in preview for later
@@ -342,8 +343,8 @@ function upload_save($node) {
       // Insert new files:
       if ($file = file_save_upload($file, $file->filename)) {
         $fid = db_next_id('{files}_fid');
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)",
-                 $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key]);
+        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
+                 $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key], $file->description);
       }
     }
   }
@@ -360,15 +361,15 @@ function upload_save($node) {
   }
   foreach ((array)$node->list as $key => $value) {
     if (!$node->remove[$key]) {
-      db_query('UPDATE {files} SET list = %d WHERE fid = %d AND vid = %d', $node->list[$key], $key, $node->vid);
+      db_query('UPDATE {files} SET list = %d, description = \'%s\' WHERE fid = %d AND vid = %d', $node->list[$key], $node->description[$key], $key, $node->vid);
     }
   }
   if ($node->old_vid) {
     foreach ((array)$node->remove as $key => $remove) {
       if (!$remove) {
         $file = db_fetch_object(db_query('SELECT * FROM {files} WHERE vid = %d AND fid = %d', $node->old_vid, $key));
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)",
-                 $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $file->list);
+        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
+                 $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $file->list, $file->description);
       }
     }
   }
@@ -393,7 +394,7 @@ function upload_form($node) {
 }
 
 function _upload_form($node) {
-  $header = array(t('Delete'), t('List'), t('Url'), t('Size'));
+  $header = array(t('Delete'), t('List'), t('Description'), t('Size'));
   $rows = array();
   $output = '';
 
@@ -402,7 +403,7 @@ function _upload_form($node) {
       $rows[] = array(
         form_checkbox('', "remove][$key", 1, $file->remove),
         form_checkbox('', "list][$key", 1, $file->list),
-        $file->filename ."<br /><small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>",
+        form_textfield('', "description][$key", $file->description ? $file->description : $file->filename, 60, 256) ."<br /><small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>",
         format_size($file->filesize)
       );
     }