diff --git a/include/class.category.php b/include/class.category.php
index c4b1ff0d1ab8f2d2c40db18c8ff5fc5980facccc..3b73eb67a2568d8c8b1522dc5997f4eaa2f6a4d1 100644
--- a/include/class.category.php
+++ b/include/class.category.php
@@ -211,7 +211,6 @@ class Category extends VerySimpleModel {
     function delete() {
         try {
             parent::delete();
-            $this->faqs->expunge();
         }
         catch (OrmException $e) {
             return false;
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index f5037503d541b97d6d07974b8cb2e60420da20d1..ca46bed6994d3d4e92a616a639607058bfd1f76c 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -1183,8 +1183,7 @@ class DynamicFormEntry extends VerySimpleModel {
     }
 
     function render($options=array()) {
-        if (is_array($options))
-            $options += array('staff' => true);
+        $options += array('staff' => true);
         return $this->getForm()->render($options);
     }
 
diff --git a/include/class.faq.php b/include/class.faq.php
index 4f1085affc2e1960ecef4f1587f053cbdbe3b912..d3e357cdac53f9352d82e94782c1f140284d9c40 100644
--- a/include/class.faq.php
+++ b/include/class.faq.php
@@ -303,7 +303,7 @@ class FAQ extends VerySimpleModel {
         try {
             parent::delete();
             // Cleanup help topics.
-            $this->topics->delete();
+            $this->topics->expunge();
             // Cleanup attachments.
             $this->attachments->deleteAll();
         }
@@ -393,11 +393,11 @@ class FAQ extends VerySimpleModel {
         $this->notes = Format::sanitize($vars['notes']);
         $this->keywords = ' ';
 
-        $this->updateTopics($vars['topics']);
-
         if (!$this->save())
             return false;
 
+        $this->updateTopics($vars['topics']);
+
         // General attachments (for all languages)
         // ---------------------
         // Delete removed attachments.
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 38ec03f9b44b9305ac94453280c3aae21e6b45d8..d6e0953861a3992419f66f2ba2c3f9f592e2127a 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -718,7 +718,7 @@ class MailFetcher {
                         $body = $this->fetchBody($mid, $info['index'].'.0',
                             $info['encoding']);
                         // Add fake body to make the parser happy
-                        if ($body)
+                        if (!$body)
                              $body.="\n\nJunk";
 
                         $parser = new Mail_Parse($body);
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 948f9fdc4a79f425973e79c9a56b68d119ebb4dc..5a85f79326caeecd6a5b3f3be14a4c5fe5317306 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -152,7 +152,7 @@ class Mail_Parse {
      * the header key. If left as FALSE, only the value given in the last
      * occurance of the header is retained.
      */
-    static  function splitHeaders($headers_text, $as_array=false) {
+    static function splitHeaders($headers_text, $as_array=false) {
         $headers = preg_split("/\r?\n/", $headers_text);
         for ($i=0, $k=count($headers); $i<$k; $i++) {
             // first char might be whitespace (" " or "\t")
diff --git a/include/cli/modules/package.php b/include/cli/modules/package.php
index 0374f27d6f6831bc868fc9f0aa2e743b2260412a..eedc187c2d229609b3ca6470539a186e65b18a25 100644
--- a/include/cli/modules/package.php
+++ b/include/cli/modules/package.php
@@ -108,8 +108,8 @@ class Packager extends Deployment {
         if (!$zip->open($name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true)
             return false;
 
-        $php56 = version_compare(phpversion(), '5.6.0', '>');
-        $addFiles = function($dir) use (&$addFiles, $zip, $path, $php56) {
+        $php56plus = version_compare(phpversion(), '5.6.0', '>');
+        $addFiles = function($dir) use (&$addFiles, $zip, $path, $php56plus) {
             $files = array_diff(scandir($dir), array('.','..'));
             $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
             foreach ($files as $file) {
@@ -122,10 +122,10 @@ class Packager extends Deployment {
                     //      out of OS open file handles
                     $zip->addFromString($local, file_get_contents($full));
                     // This only works on PHP >= v5.6
-                    if ($php56) {
+                    if ($php56plus) {
                         // Set the Unix mode of the file
                         $stat = stat($full);
-                        $zip->setExternalAttributesName($local, ZipArchive::OPSYS_UNIX, $stat['mode']);
+                        $zip->setExternalAttributesName($local, ZipArchive::OPSYS_UNIX, $stat['mode'] << 16);
                     }
             }
         };
diff --git a/scp/categories.php b/scp/categories.php
index bea8e9a24cf8a730471d9ba9c73b3d827aa46627..b408d6955ed2884e439e7dfec9ecb37585d3cf63 100644
--- a/scp/categories.php
+++ b/scp/categories.php
@@ -96,15 +96,23 @@ if($_POST){
                         }
                         break;
                     case 'delete':
-                        $i = Category::objects()->filter(array(
+                        $categories = Category::objects()->filter(array(
                             'category_id__in'=>$_POST['ids']
-                        ))->delete();
+                        ));
+                        foreach ($categories as $c) {
+                            if ($faqs = FAQ::objects()
+                                  ->filter(array('category_id'=>$c->getId()))) {
+                                      foreach ($faqs as $key => $faq)
+                                          $faq->delete();
+                                  }
+                             $c->delete();
+                        }
 
-                        if ($i==$count)
+                        if (count($categories)==$count)
                             $msg = sprintf(__('Successfully deleted %s.'),
                                 _N('selected category', 'selected categories', $count));
-                        elseif ($i > 0)
-                            $warn = sprintf(__('%1$d of %2$d %3$s deleted'), $i, $count,
+                        elseif ($categories > 0)
+                            $warn = sprintf(__('%1$d of %2$d %3$s deleted'), $categories, $count,
                                 _N('selected category', 'selected categories', $count));
                         elseif (!$errors['err'])
                             $errors['err'] = sprintf(__('Unable to delete %s.'),
diff --git a/scp/helptopics.php b/scp/helptopics.php
index 40580549e8b3b1da1c0292f6e279801844d68139..3d52735210261861f616881cd7f909496aea9432 100644
--- a/scp/helptopics.php
+++ b/scp/helptopics.php
@@ -140,15 +140,18 @@ if($_POST){
                         }
                         break;
                     case 'delete':
-                        $i = Topic::objects()->filter(array(
+                        $topics = Topic::objects()->filter(array(
                             'topic_id__in'=>$_POST['ids']
-                        ))->delete();
+                        ));
+
+                        foreach ($topics as $t)
+                            $t->delete();
 
-                        if($i && $i==$count)
+                        if($topics && $topics==$count)
                             $msg = sprintf(__('Successfully deleted %s.'),
                                 _N('selected help topic', 'selected help topics', $count));
-                        elseif($i>0)
-                            $warn = sprintf(__('%1$d of %2$d %3$s deleted'), $i, $count,
+                        elseif($topics>0)
+                            $warn = sprintf(__('%1$d of %2$d %3$s deleted'), $topics, $count,
                                 _N('selected help topic', 'selected help topics', $count));
                         elseif(!$errors['err'])
                             $errors['err']  = sprintf(__('Unable to delete %s.'),