diff --git a/attachment.php b/attachment.php
index 9a386baae761ec683859f59cb45b1be75319c66e..8e45d8e155c83cae6c31697f49f5b8bfd3910a9e 100644
--- a/attachment.php
+++ b/attachment.php
@@ -16,23 +16,23 @@
 **********************************************************************/
 require('secure.inc.php');
 require_once(INCLUDE_DIR.'class.attachment.php');
-//Basic checks
+// Basic checks
 if (!$thisclient
         || !$_GET['id']
         || !$_GET['h']
         || !($attachment=Attachment::lookup($_GET['id']))
-        || !($file=$attachment->getFile()))
+        || !($file=$attachment->getFile())
+        || strcasecmp(trim($_GET['h']), $file->getDownloadHash())
+        || !($object=$attachment->getObject())
+        || !$object instanceof ThreadEntry
+        || !($ticket=$object->getThread()->getObject())
+        || !$ticket instanceof Ticket
+        )
     Http::response(404, __('Unknown or invalid file'));
 
-//Validate session access hash - we want to make sure the link is FRESH! and the user has access to the parent ticket!!
-$vhash=md5($attachment->getFileId().session_id().strtolower($file->getKey()));
-if (strcasecmp(trim($_GET['h']), $vhash)
-        || !($thread=$attachment->getThread())
-        || !($object=$thread->getObject())
-        || !$object instanceof Ticket
-        || !$object->checkUserAccess($thisclient))
-    Http::response(404, __('Unknown or invalid file'));
-//Download the file..
-$file->download();
+if (!$ticket->checkUserAccess($thisclient))
+    die(__('Access Denied'));
 
+// Download the file..
+$file->download();
 ?>
diff --git a/bootstrap.php b/bootstrap.php
index 354c9bd208acc4ecde10f0d75df299d53c0e4357..d16f10feefc17f3e4c462a7f792f553208cf00fb 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -92,7 +92,6 @@ class Bootstrap {
 
         define('THREAD_TABLE', $prefix.'thread');
         define('THREAD_ENTRY_TABLE', $prefix.'thread_entry');
-        define('THREAD_ENTRY_ATTACHMENT_TABLE', $prefix.'thread_entry_attachment');
         define('THREAD_ENTRY_EMAIL_TABLE', $prefix.'thread_entry_email');
 
         define('TICKET_TABLE',$prefix.'ticket');
diff --git a/include/class.attachment.php b/include/class.attachment.php
index fdcbe4ee2770463906d1ba470797a74dcf7c9955..a1ecfd97af55ea66d0ea9c684bb07ef96ab0ba03 100644
--- a/include/class.attachment.php
+++ b/include/class.attachment.php
@@ -21,35 +21,25 @@ class Attachment {
     var $file_id;
 
     var $ht;
-    var $thread;
+    var $object;
 
-    function Attachment($id, $tid=0) {
+    function Attachment($id) {
 
-        $sql = 'SELECT a.*, e.thread_id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE.' a '
-             . 'LEFT JOIN '.THREAD_ENTRY_TABLE.' e ON (e.id = a.thread_entry_id) '
+        $sql = 'SELECT a.* FROM '.ATTACHMENT_TABLE.' a '
              . 'WHERE a.id='.db_input($id);
-        if($tid)
-            $sql.=' AND a.thread_entry_id='.db_input($tid);
+        if (!($res=db_query($sql)) || !db_num_rows($res))
+            return;
 
-        if(!($res=db_query($sql)) || !db_num_rows($res))
-            return false;
-
-        $this->ht=db_fetch_array($res);
-
-        $this->id=$this->ht['id'];
-        $this->file_id=$this->ht['file_id'];
-
-        $this->file = $this->thread = null;
-
-        return true;
+        $this->ht = db_fetch_array($res);
+        $this->file = $this->object = null;
     }
 
     function getId() {
-        return $this->id;
+        return $this->ht['id'];
     }
 
     function getFileId() {
-        return $this->file_id;
+        return $this->ht['file_id'];
     }
 
     function getFile() {
@@ -59,10 +49,6 @@ class Attachment {
         return $this->file;
     }
 
-    function getCreateDate() {
-        return $this->ht['created'];
-    }
-
     function getHashtable() {
         return $this->ht;
     }
@@ -71,32 +57,32 @@ class Attachment {
         return $this->getHashtable();
     }
 
-    function getThread() {
+    function getObject() {
 
-        if (!isset($this->thread))
-            $this->thread = Thread::lookup($this->ht['thread_id']);
+        if (!isset($this->object))
+            $this->object = ObjectModel::lookup(
+                    $this->ht['object_id'], $this->ht['type']);
 
-        return $this->thread;
+        return $this->object;
     }
 
-    /* Static functions */
-    static function getIdByFileHash($hash, $tid=0) {
-        $sql='SELECT a.id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE.' a '
+    static function getIdByFileHash($hash, $objectId=0) {
+        $sql='SELECT a.id FROM '.ATTACHMENT_TABLE.' a '
             .' INNER JOIN '.FILE_TABLE.' f ON(f.id=a.file_id) '
             .' WHERE f.`key`='.db_input($hash);
-        if($tid)
-            $sql.=' AND a.thread_entry_id='.db_input($tid);
+        if ($objectId)
+            $sql.=' AND a.object_id='.db_input($objectId);
 
         return db_result(db_query($sql));
     }
 
-    static function lookup($var, $tid=0) {
+    static function lookup($var, $objectId=0) {
 
-        $id = is_numeric($var) ? $var : self::getIdByFileHash($var, $tid);
+        $id = is_numeric($var) ? $var : self::getIdByFileHash($var, $oid);
 
         return ($id
                 && is_numeric($id)
-                && ($attach = new Attachment($id, $tid))
+                && ($attach = new Attachment($id, $oid))
                 && $attach->getId()==$id
             ) ? $attach : null;
     }
@@ -174,7 +160,8 @@ class GenericAttachments {
     function _getList($separate=false, $inlines=false, $lang=false) {
         if(!isset($this->attachments)) {
             $this->attachments = array();
-            $sql='SELECT f.id, f.size, f.`key`, f.name, a.inline, a.lang '
+            $sql='SELECT f.id, f.size, f.`key`, f.name '
+                .', a.inline, a.lang, a.id as attach_id '
                 .' FROM '.FILE_TABLE.' f '
                 .' INNER JOIN '.ATTACHMENT_TABLE.' a ON(f.id=a.file_id) '
                 .' WHERE a.`type`='.db_input($this->getType())
@@ -192,7 +179,7 @@ class GenericAttachments {
             if (($a['inline'] != $separate || $a['inline'] == $inlines)
                     && $lang == $a['lang']) {
                 $a['file_id'] = $a['id'];
-                $a['hash'] = md5($a['file_id'].session_id().strtolower($a['key']));
+                $a['hash'] = md5($a['file_id'].session_id().$a['key']);
                 $attachments[] = $a;
             }
         }
diff --git a/include/class.file.php b/include/class.file.php
index 7fe6a769942d88d4bd96545496f44d19d2b97a94..caafae2bf9cab7018b6aee5d4a8503d2f7d84295 100644
--- a/include/class.file.php
+++ b/include/class.file.php
@@ -35,7 +35,7 @@ class AttachmentFile {
             .' FROM '.FILE_TABLE.' f '
             .' LEFT JOIN '.ATTACHMENT_TABLE.' a
                 ON(a.file_id=f.id) '
-            .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' t
+            .' LEFT JOIN '.ATTACHMENT_TABLE.' t
                 ON(t.file_id = f.id) '
             .' WHERE f.id='.db_input($id)
             .' GROUP BY f.id';
@@ -579,9 +579,8 @@ class AttachmentFile {
         // XXX: Allow plugins to define filetypes which do not represent
         //      files attached to tickets or other things in the attachment
         //      table and are not logos
+        //FIXME: Just user straight up left join
         $sql = 'SELECT id FROM '.FILE_TABLE.' WHERE id NOT IN ('
-                .'SELECT file_id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE
-                .' UNION '
                 .'SELECT file_id FROM '.ATTACHMENT_TABLE
             .") AND `ft` = 'T' AND TIMESTAMPDIFF(DAY, `created`, CURRENT_TIMESTAMP) > 1";
 
diff --git a/include/class.thread.php b/include/class.thread.php
index 7b48da65d94b89c2bb6e761f8a5ccfb7af10c6e5..0cd0e5b2620c88001c368c037b9032cab8221b99 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -32,13 +32,13 @@ class Thread {
             return null;
 
         $sql='SELECT thread.* '
-            .' ,count(DISTINCT attach.id) as attachments '
+            .' ,count(DISTINCT a.id) as attachments '
             .' ,count(DISTINCT entry.id) as entries '
             .' FROM '.THREAD_TABLE.' thread '
             .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry
                 ON (entry.thread_id = thread.id) '
-            .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach
-                ON (attach.thread_entry_id=entry.id) '
+            .' LEFT JOIN '.ATTACHMENT_TABLE.' a
+                ON (a.object_id=entry.id AND a.`type` = "H") '
             .' WHERE thread.id='.db_input($id)
             .' GROUP BY thread.id';
 
@@ -98,8 +98,8 @@ class Thread {
                 ON (entry.user_id=user.id) '
             .' LEFT JOIN '.STAFF_TABLE.' staff
                 ON (entry.staff_id=staff.staff_id) '
-            .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach
-                ON (attach.thread_entry_id = entry.id) '
+            .' LEFT JOIN '.ATTACHMENT_TABLE.' attach
+                ON (attach.object_id = entry.id AND attach.`type`="H") '
             .' WHERE  entry.thread_id='.db_input($this->getId());
 
         if($type && is_array($type))
@@ -129,9 +129,9 @@ class Thread {
     function deleteAttachments() {
 
         // Clear reference table
-        $sql = 'DELETE FROM '.THREAD_ENTRY_ATTACHMENT_TABLE. ' a '
+        $sql = 'DELETE FROM '.ATTACHMENT_TABLE. ' a '
              . 'INNER JOIN '.THREAD_ENTRY_TABLE.' e
-                    ON(e.id = a.thread_entry_id) '
+                    ON(e.id = a.object_id AND a.`type`= "H") '
              . ' WHERE e.thread_id='.db_input($this->getId());
 
         $deleted=0;
@@ -225,8 +225,8 @@ Class ThreadEntry {
             .' FROM '.THREAD_ENTRY_TABLE.' entry '
             .' LEFT JOIN '.THREAD_ENTRY_EMAIL_TABLE.' email
                 ON (email.thread_entry_id=entry.id) '
-            .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach
-                ON (attach.thread_entry_id=entry.id) '
+            .' LEFT JOIN '.ATTACHMENT_TABLE.' attach
+                ON (attach.object_id=entry.id AND attach.`type` = "H") '
             .' WHERE  entry.id='.db_input($id);
 
         if ($type)
@@ -242,8 +242,7 @@ Class ThreadEntry {
 
         $this->ht = db_fetch_array($res);
         $this->id = $this->ht['id'];
-
-        $this->attachments = array();
+        $this->attachments = new GenericAttachments($this->id, 'H');
 
         return true;
     }
@@ -461,7 +460,7 @@ Class ThreadEntry {
                  XXX: We're doing it here because it will eventually become a thread post comment (hint: comments coming!)
                  XXX: logNote must watch for possible loops
                */
-                $this->getTicket()->logNote(__('File Upload Error'), $error, 'SYSTEM', false);
+                $this->getThread()->getObject()->logNote(__('File Upload Error'), $error, 'SYSTEM', false);
             }
 
         }
@@ -491,12 +490,12 @@ Class ThreadEntry {
         $id=0;
         if ($attachment['error'] || !($id=$this->saveAttachment($attachment))) {
             $error = $attachment['error'];
-
             if(!$error)
-                $error = sprintf(_S('Unable to import attachment - %s'),$attachment['name']);
-
-            $this->getTicket()->logNote(_S('File Import Error'), $error,
-                _S('SYSTEM'), false);
+                $error = sprintf(_S('Unable to import attachment - %s'),
+                        $attachment['name']);
+            //FIXME: $this->logComment();
+            $this->getThread()->getObject()->logNote(
+                    _S('File Import Error'), $error, _S('SYSTEM'), false);
         }
 
         return $id;
@@ -508,29 +507,9 @@ Class ThreadEntry {
     */
     function saveAttachment(&$file) {
 
-        if (is_numeric($file))
-            $fileId = $file;
-        elseif (is_array($file) && isset($file['id']))
-            $fileId = $file['id'];
-        elseif (!($fileId = AttachmentFile::save($file)))
-            return 0;
-
         $inline = is_array($file) && @$file['inline'];
 
-        // TODO: Add a unique index to THREAD_ENTRY_ATTACHMENT_TABLE (file_id,
-        // thread_entry_id), and remove this block
-        if ($id = db_result(db_query('SELECT id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE
-                .' WHERE file_id='.db_input($fileId)
-                .' AND thread_entry_id=' .db_input($this->getId()))))
-
-            return $id;
-
-        $sql ='INSERT IGNORE INTO '.THREAD_ENTRY_ATTACHMENT_TABLE.' SET created=NOW() '
-             .' ,file_id='.db_input($fileId)
-             .' ,thread_entry_id='.db_input($this->getId())
-             .' ,inline='.db_input($inline ? 1 : 0);
-
-        return (db_query($sql) && ($id=db_insert_id()))?$id:0;
+        return $this->attachments->save($file, $inline);
     }
 
     function saveAttachments($files) {
@@ -543,52 +522,39 @@ Class ThreadEntry {
     }
 
     function getAttachments() {
-
-        if ($this->attachments)
-            return $this->attachments;
-
-        //XXX: inner join the file table instead?
-        $sql='SELECT a.id, f.id as file_id, f.size, lower(f.`key`) as file_hash, f.name, a.inline '
-            .' FROM '.FILE_TABLE.' f '
-            .' INNER JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' a
-                ON(a.file_id=f.id) '
-            .' WHERE a.thread_entry_id='.db_input($this->getId());
-
-        $this->attachments = array();
-        if (($res=db_query($sql)) && db_num_rows($res)) {
-            while ($rec=db_fetch_array($res))
-                $this->attachments[] = $rec;
-        }
-
-        return $this->attachments;
+        return $this->attachments->getAll(true, false);
     }
 
     function getAttachmentUrls($script='image.php') {
         $json = array();
         foreach ($this->getAttachments() as $att) {
-            $json[$att['file_hash']] = array(
-                'download_url' => sprintf('attachment.php?id=%d&h=%s', $att['id'],
-                    strtolower(md5($att['file_id'].session_id().$att['file_hash']))),
+            $json[$att['key']] = array(
+                'download_url' => sprintf('attachment.php?id=%d&h=%s',
+                    $att['attach_id'], $att['download']),
                 'filename' => $att['name'],
             );
         }
+
         return $json;
     }
 
-    function getAttachmentsLinks($file='attachment.php', $target='', $separator=' ') {
+    function getAttachmentsLinks($file='attachment.php', $target='_blank', $separator=' ') {
 
         $str='';
-        foreach($this->getAttachments() as $attachment ) {
-            if ($attachment['inline'])
-                continue;
-            /* The hash can be changed  but must match validation in @file */
-            $hash=md5($attachment['file_id'].session_id().$attachment['file_hash']);
+        foreach ($this->getAttachments() as $att ) {
+            if ($att['inline']) continue;
             $size = '';
-            if($attachment['size'])
-                $size=sprintf('<em>(%s)</em>', Format::file_size($attachment['size']));
+            if ($att['size'])
+                $size=sprintf('<em>(%s)</em>', Format::file_size($att['size']));
 
             $str.=sprintf('<a class="Icon file no-pjax" href="%s?id=%d&h=%s" target="%s">%s</a>%s&nbsp;%s',
-                    $file, $attachment['id'], $hash, $target, Format::htmlchars($attachment['name']), $size, $separator);
+                    $file,
+                    $att['attach_id'],
+                    $att['download'],
+                    $target,
+                    Format::htmlchars($att['name']),
+                    $size,
+                    $separator);
         }
 
         return $str;
diff --git a/include/class.ticket.php b/include/class.ticket.php
index a092fa661e5300e917b3abc657a1365304db8972..9286a2c5c894eeda70da4a889d92ab0c74491ea8 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -197,8 +197,8 @@ class Ticket {
                 ON ( thread.object_id = ticket.ticket_id AND thread.object_type="T" ) '
             .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry
                 ON ( entry.thread_id = thread.id ) '
-            .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach
-                ON ( attach.thread_entry_id = entry.id ) '
+            .' LEFT JOIN '.ATTACHMENT_TABLE.' attach
+                ON ( attach.object_id = entry.id AND attach.`type` = "H") '
             .' WHERE ticket.ticket_id='.db_input($id)
             .' GROUP BY ticket.ticket_id';
 
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 25ceb77835578ee84e655a005131cdc845abf270..3871578ca35d48cbe3fe1ec6929a50a7db1addfd 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -410,12 +410,13 @@ $tcount+= $ticket->getNumNotes();
                 echo $entry['id']; ?>"><div><?php
                 echo $entry['body']->toHtml(); ?></div></td></tr>
             <?php
+            $urls = null;
             if($entry['attachments']
                     && ($tentry = $ticket->getThreadEntry($entry['id']))
                     && ($urls = $tentry->getAttachmentUrls())
                     && ($links = $tentry->getAttachmentsLinks())) {?>
             <tr>
-                <td class="info" colspan="4"><?php echo $tentry->getAttachmentsLinks(); ?></td>
+                <td class="info" colspan="4"><?php echo $links; ?></td>
             </tr> <?php
             }
             if ($urls) { ?>
diff --git a/include/upgrader/streams/core.sig b/include/upgrader/streams/core.sig
index ca8a3dae54ce2f95a30f3729ff58cffbde89ef0b..252eb31ba78793be662ab22a616f2973246af4b4 100644
--- a/include/upgrader/streams/core.sig
+++ b/include/upgrader/streams/core.sig
@@ -1 +1 @@
-36f6b32893c2b97c5104ab5302d2dd2e
+4b4daf9cf5e199673885f5ef58e743d1
diff --git a/include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql b/include/upgrader/streams/core/b26f29a6-4b4daf9c.cleanup.sql
similarity index 84%
rename from include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql
rename to include/upgrader/streams/core/b26f29a6-4b4daf9c.cleanup.sql
index 27dca7f84160f3916b8e4bbb968af9622ae89979..800c8127673c19f3628eb3b4b385a691cac6e96b 100644
--- a/include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql
+++ b/include/upgrader/streams/core/b26f29a6-4b4daf9c.cleanup.sql
@@ -4,6 +4,8 @@ ALTER TABLE `%TABLE_PREFIX%thread`
 ALTER TABLE `%TABLE_PREFIX%thread_entry`
     DROP COLUMN `ticket_id`;
 
+DROP TABLE `%TABLE_PREFIX%ticket_attachment`;
+
 OPTIMIZE TABLE `%TABLE_PREFIX%ticket`;
 OPTIMIZE TABLE `%TABLE_PREFIX%thread`;
 OPTIMIZE TABLE `%TABLE_PREFIX%thread_entry`;
diff --git a/include/upgrader/streams/core/b26f29a6-186868f5.patch.sql b/include/upgrader/streams/core/b26f29a6-4b4daf9c.patch.sql
similarity index 83%
rename from include/upgrader/streams/core/b26f29a6-186868f5.patch.sql
rename to include/upgrader/streams/core/b26f29a6-4b4daf9c.patch.sql
index 7f1898fc6b35b62f35c6af30193337950f81d94f..62280690740e46da12e8f2d052fea4c9a37d3e55 100644
--- a/include/upgrader/streams/core/b26f29a6-186868f5.patch.sql
+++ b/include/upgrader/streams/core/b26f29a6-4b4daf9c.patch.sql
@@ -58,15 +58,18 @@ UPDATE  `%TABLE_PREFIX%ticket` t1
     LEFT JOIN  `%TABLE_PREFIX%thread` t2 ON ( t2.object_id = t1.ticket_id )
     SET t1.thread_id = t2.id;
 
--- convert ticket_attachment to thread_entry_attachment
-ALTER TABLE  `%TABLE_PREFIX%ticket_attachment`
-    CHANGE  `attach_id`  `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT,
-    CHANGE  `ref_id`  `thread_entry_id` INT( 11 ) UNSIGNED NOT NULL DEFAULT  '0';
-    DROP  `ticket_id`;
+-- move records in ticket_attachment to generic attachment table
+ALTER TABLE  `%TABLE_PREFIX%attachment`
+    DROP PRIMARY KEY,
+    ADD  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST,
+    ADD UNIQUE  `file-type` (`object_id`, `file_id`, `type`);
 
-RENAME TABLE `%TABLE_PREFIX%ticket_attachment` TO  `%TABLE_PREFIX%thread_entry_attachment`;
+INSERT INTO `%TABLE_PREFIX%attachment`
+    (`object_id`, `type`, `file_id`, `inline`)
+    SELECT `ref_id`, 'H', `file_id`, `inline`
+    FROM `%TABLE_PREFIX%ticket_attachment`;
 
--- convert ticket_email_info to thread_entry_mid
+-- convert ticket_email_info to thread_entry_email
 ALTER TABLE  `%TABLE_PREFIX%ticket_email_info`
     CHANGE  `thread_id`  `thread_entry_id` INT( 11 ) UNSIGNED NOT NULL,
     CHANGE  `email_mid`  `mid` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
@@ -74,6 +77,8 @@ ALTER TABLE  `%TABLE_PREFIX%ticket_email_info`
 
 RENAME TABLE `%TABLE_PREFIX%ticket_email_info` TO  `%TABLE_PREFIX%thread_entry_email`;
 
+
+
 -- Set new schema signature
 UPDATE `%TABLE_PREFIX%config`
     SET `value` = '2257f6f22ca4b31bea6045b8b7d59d56'
diff --git a/scp/attachment.php b/scp/attachment.php
index 697f9e38a240f38c96ea8e739af3a50f15823911..ab6d45ab14d31d4122c085f40188c125bb74d897 100644
--- a/scp/attachment.php
+++ b/scp/attachment.php
@@ -16,21 +16,21 @@
 require('staff.inc.php');
 require_once(INCLUDE_DIR.'class.attachment.php');
 
-//Basic checks
+// Basic checks
 if (!$thisstaff
         || !$_GET['id']
         || !$_GET['h']
         || !($attachment=Attachment::lookup($_GET['id']))
-        || !($file=$attachment->getFile()))
+        || !($file=$attachment->getFile())
+        || strcasecmp(trim($_GET['h']), $file->getDownloadHash())
+        || !($object=$attachment->getObject())
+        || !$object instanceof ThreadEntry
+        || !($ticket=$object->getThread()->getObject())
+        || !$ticket instanceof Ticket
+        )
     Http::response(404, __('Unknown or invalid file'));
 
-//Validate session access hash - we want to make sure the link is FRESH! and the user has access to the parent ticket!!
-$vhash=md5($attachment->getFileId().session_id().strtolower($file->getKey()));
-if (strcasecmp(trim($_GET['h']), $vhash)
-        || !($thread=$attachment->getThread())
-        || !($object=$thread->getObject())
-        || !$object instanceof Ticket
-        || !$object->checkStaffAccess($thisstaff))
+if (!$ticket->checkStaffAccess($thisstaff))
     die(__('Access Denied'));
 
 //Download the file..
diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql
index 7f968dbd6f542276be62ac09f69150c1d5ff5cdc..d91ce79ab86f5fed2f4d628a84c9a2b5ca1ec40a 100644
--- a/setup/inc/streams/core/install-mysql.sql
+++ b/setup/inc/streams/core/install-mysql.sql
@@ -17,12 +17,14 @@ CREATE TABLE `%TABLE_PREFIX%api_key` (
 
 DROP TABLE IF EXISTS `%TABLE_PREFIX%attachment`;
 CREATE TABLE `%TABLE_PREFIX%attachment` (
+  `id` int(10) unsigned NOT NULL auto_increment,
   `object_id` int(11) unsigned NOT NULL,
   `type` char(1) NOT NULL,
   `file_id` int(11) unsigned NOT NULL,
   `inline` tinyint(1) unsigned NOT NULL DEFAULT '0',
   `lang` varchar(16),
-  PRIMARY KEY (`object_id`,`file_id`,`type`)
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `file-type` (`object_id`,`file_id`,`type`)
 ) DEFAULT CHARSET=utf8;
 
 DROP TABLE IF EXISTS `%TABLE_PREFIX%faq`;
@@ -644,19 +646,6 @@ CREATE TABLE `%TABLE_PREFIX%thread_entry` (
   KEY `type` (`type`)
 ) DEFAULT CHARSET=utf8;
 
-
-DROP TABLE IF EXISTS `%TABLE_PREFIX%thread_entry_attachment`;
-CREATE TABLE `%TABLE_PREFIX%thread_entry_attachment` (
-  `id` int(11) unsigned NOT NULL auto_increment,
-  `file_id` int(10) unsigned NOT NULL default '0',
-  `thread_entry_id` int(11) unsigned NOT NULL default '0',
-  `inline` tinyint(1) NOT NULL default  '0',
-  `created` datetime NOT NULL,
-  PRIMARY KEY  (`id`),
-  KEY `file_id` (`file_id`),
-  KEY `ref_id` (`thread_entry_id`)
-) DEFAULT CHARSET=utf8;
-
 DROP TABLE IF EXISTS `%TABLE_PREFIX%thread_entry_email`;
 CREATE TABLE `%TABLE_PREFIX%thread_entry_email` (
   `id` int(11) unsigned NOT NULL auto_increment,