diff --git a/.gitignore b/.gitignore
index 2c0568a588f2c2759a62bc94151c0597f8c09abe..b5c98c948d9c2eb75df122268b315b29f15a9e93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ php53.cgi
 include/ost-config.php
 *.sw[a-z]
 .DS_Store
+.vagrant
+Vagrantfile
diff --git a/assets/default/about-custom-themes.md b/assets/default/about-custom-themes.md
new file mode 100644
index 0000000000000000000000000000000000000000..eecf1bbbed3d3002d3d4abe686f8ec6d82717094
--- /dev/null
+++ b/assets/default/about-custom-themes.md
@@ -0,0 +1,14 @@
+Customizng Your Theme
+====
+
+When modifying the default theme, it is recommended that you do not
+edit the CSS files directly. Instead, you should use the included
+LESS files and recompile the CSS file with your edits.
+
+Even if you decide to edit the CSS directly, we recommend that you
+keep the LESS files, so that you can quickly rebuild the default
+theme should you need to recover it, or for upgrade purposes.
+
+*Please do not submit any CSS edits to the official branch, unless
+they are done within the LESS files.*
+
diff --git a/assets/default/css/print.css b/assets/default/css/print.css
index 9f1c25746ca0486d2524e24ea850b1d2ffcd9e6c..aca3d50f9265e03c3a95d5a5dbbe78aa891b0a21 100644
--- a/assets/default/css/print.css
+++ b/assets/default/css/print.css
@@ -1,29 +1 @@
-#header, #nav, #meta, #footer, #reply, #pagination, .reload, .refresh, form, .thread, hr, #kbAttachments, .back {
-  display: none;
-}
-
-th {
-  text-align: left;
-}
-
-a {
-  color: #000;
-  text-decoration: none;
-}
-
-caption {
-  text-align: left;
-  padding-bottom: 10px;
-  font-weight: bold;
-}
-
-.message, .response {
-  border-bottom: 1px solid #000;
-  margin-bottom: 20px;
-  padding-bottom: 10px;
-}
-.message th, .response th {
-  font-size: 12pt;
-  font-weight: bold;
-  padding-bottom: 5px;
-}
+#header,#nav,#meta,#footer,#reply,#pagination,.reload,.refresh,form,.thread,hr,#kbAttachments,.back{display:none}th{text-align:left}a{color:#000;text-decoration:none}caption{text-align:left;padding-bottom:10px;font-weight:bold}.message,.response{border-bottom:1px solid #000;margin-bottom:20px;padding-bottom:10px}.message th,.response th{font-size:12pt;font-weight:bold;padding-bottom:5px}
\ No newline at end of file
diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css
index b59f6af8955857d2008dff647e8e4d83d4924e72..206cbe9fd0eb86d67fa1d16abae23e9a49aab9ca 100644
--- a/assets/default/css/theme.css
+++ b/assets/default/css/theme.css
@@ -1,31 +1,29 @@
-/* Based on Normalize.css - with tags we won't use removed. */
 html {
   font-size: 100%;
   overflow-y: scroll;
   -webkit-text-size-adjust: 100%;
   -ms-text-size-adjust: 100%;
 }
-
 body {
   margin: 0;
   font-size: 13px;
   line-height: 1.231;
   padding: 0;
 }
-
-body, input, select, textarea {
+body,
+input,
+select,
+textarea {
   font-family: sans-serif;
   color: #000;
 }
-
-b, strong {
+b,
+strong {
   font-weight: bold;
 }
-
 blockquote {
   margin: 1em 40px;
 }
-
 hr {
   display: block;
   height: 1px;
@@ -34,119 +32,120 @@ hr {
   margin: 1em 0;
   padding: 0;
 }
-
 small {
   font-size: 85%;
 }
-
-ul, ol {
+ul,
+ol {
   margin: 1em 0;
   padding: 0 0 0 30px;
 }
-
 img {
   border: 0;
   vertical-align: middle;
 }
-
 form {
   margin: 0;
 }
-
 fieldset {
   border: 0;
   margin: 0;
   padding: 0;
 }
-
 label {
   cursor: pointer;
 }
-
-input, select, textarea {
+input,
+select,
+textarea {
   font-size: 100%;
   margin: 0;
   vertical-align: baseline;
   *vertical-align: middle;
 }
-
 input {
   line-height: normal;
   *overflow: visible;
 }
-
 table input {
   *overflow: auto;
 }
-
-input[type="button"], input[type="reset"], input[type="submit"] {
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
   cursor: pointer;
   -webkit-appearance: button;
 }
-
-input[type="checkbox"], input[type="radio"] {
+input[type="checkbox"],
+input[type="radio"] {
   box-sizing: border-box;
 }
-
 input[type="search"] {
   -webkit-appearance: textfield;
   -moz-box-sizing: content-box;
   -webkit-box-sizing: content-box;
   box-sizing: content-box;
 }
-
 textarea {
   overflow: auto;
   vertical-align: top;
   resize: vertical;
 }
-
 table {
   border-collapse: collapse;
   border-spacing: 0;
 }
-
-th, td {
+th,
+td {
   vertical-align: top;
 }
-
-th { text-align: left; font-weight: normal; }
-
-h1, h2, h3, h4, h5, h6, form, fieldset {
+th {
+  text-align: left;
+  font-weight: normal;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+form,
+fieldset {
   margin: 0;
   padding: 0;
 }
-
 /* Typography */
 a {
   color: #0072bc;
   text-decoration: none;
 }
-
 h1 {
   color: #00AEEF;
   font-weight: normal;
   font-size: 20px;
 }
-
 h3 {
   font-size: 16px;
 }
-
 h2 {
   font-size: 16px;
   color: #999;
 }
-
 /* Helpers */
-.centered { text-align: center;}
-
-.clear { clear:both; height: 1px; visibility: none;}
-
-.hidden { display: none;}
-
-.faded { color:#666;}
-
+.centered {
+  text-align: center;
+}
+.clear {
+  clear: both;
+  height: 1px;
+  visibility: none;
+}
+.hidden {
+  display: none;
+}
+.faded {
+  color: #666;
+}
 /* Pagination */
 #pagination {
   border: 0;
@@ -161,24 +160,26 @@ h2 {
   list-style: none;
   display: inline;
 }
-#pagination a {
+#pagination li a {
   margin-right: 2px;
   display: block;
   float: left;
   padding: 3px 6px;
   text-decoration: none;
 }
-#pagination a:hover {
+#pagination li a:hover {
   color: #ff0084;
 }
-#pagination .previousOff, #pagination .nextOff {
+#pagination .previousOff,
+#pagination .nextOff {
   color: #666;
   display: block;
   float: left;
   font-weight: bold;
   padding: 3px 4px;
 }
-#pagination .next a, #pagination .previous a {
+#pagination .next a,
+#pagination .previous a {
   font-weight: bold;
 }
 #pagination .active {
@@ -190,16 +191,34 @@ h2 {
   padding: 3px 6px;
   text-decoration: none;
 }
-
 /* Alerts & Notices */
-
-#msg_notice { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #0a0; background: url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0; }
-
-#msg_warning { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #f26522; background: url('../images/icons/alert.png') 10px 50% no-repeat #ffffdd; }
-
-#msg_error { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #a00; background: url('../images/icons/error.png') 10px 50% no-repeat #fff0f0; }
-
-
+#msg_notice {
+  margin: 0;
+  padding: 5px 10px 5px 36px;
+  height: 16px;
+  line-height: 16px;
+  margin-bottom: 10px;
+  border: 1px solid #0a0;
+  background: url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0;
+}
+#msg_warning {
+  margin: 0;
+  padding: 5px 10px 5px 36px;
+  height: 16px;
+  line-height: 16px;
+  margin-bottom: 10px;
+  border: 1px solid #f26522;
+  background: url('../images/icons/alert.png') 10px 50% no-repeat #ffffdd;
+}
+#msg_error {
+  margin: 0;
+  padding: 5px 10px 5px 36px;
+  height: 16px;
+  line-height: 16px;
+  margin-bottom: 10px;
+  border: 1px solid #a00;
+  background: url('../images/icons/error.png') 10px 50% no-repeat #fff0f0;
+}
 .warning {
   background: #ffc;
   font-style: italic;
@@ -209,19 +228,64 @@ h2 {
   color: #a00;
   font-style: normal;
 }
-
 .error {
-    color:#f00;
+  color: #f00;
 }
-
 .error input {
-  border:1px solid #f00;}
-
-/* Main layout */
+  border: 1px solid #f00;
+}
+.button,
+.button:visited {
+  background: #222;
+  display: inline-block;
+  font-size: 16px;
+  padding: 8px 16px 6px 16px;
+  width: 160px;
+  text-align: center;
+  color: #fff;
+  font-weight: bold;
+  text-decoration: none;
+  border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-border-radius: 5px;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+  -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+  text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
+  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
+  position: relative;
+  cursor: pointer;
+  font-family: helvetica, arial, sans-serif;
+}
+.button:hover {
+  background-color: #111;
+  color: #fff;
+}
+.button:active {
+  top: 1px;
+  box-shadow: none;
+  -moz-box-shadow: none;
+  -webkit-box-shadow: none;
+}
+.button,
+.button:visited,
+.green.button,
+.green.button:visited {
+  background-color: #91bd09;
+}
+.green.button:hover {
+  background-color: #749a02;
+}
+.blue.button,
+.blue.button:visited {
+  background-color: #00AEEF;
+}
+.blue.button:hover {
+  background-color: #0299d2;
+}
 body {
   background: url('../images/page_bg.png') top left repeat-x #c8c8c8;
 }
-
 #container {
   background: #fff;
   width: 840px;
@@ -230,7 +294,6 @@ body {
   -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
   -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
 }
-
 #header {
   position: relative;
   height: 71px;
@@ -241,7 +304,6 @@ body {
   height: 71px;
   float: left;
 }
-
 #header p {
   width: 400px;
   text-align: right;
@@ -249,16 +311,15 @@ body {
   padding: 10px 0;
   float: right;
 }
-
 #nav {
   margin: 0 20px;
   padding: 2px 10px;
   height: 20px;
   background: url('../images/nav_bg.png') top left repeat-x;
   border-top: 1px solid #aaa;
-  box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
-  -moz-box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
-  -webkit-box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
+  box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
+  -moz-box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
+  -webkit-box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
 }
 #nav li {
   margin: 0;
@@ -282,7 +343,8 @@ body {
   background-position: 10px 50%;
   background-repeat: no-repeat;
 }
-#nav li a.active, #nav li a:hover {
+#nav li a.active,
+#nav li a:hover {
   background-color: #dbefff;
   color: #000;
 }
@@ -305,7 +367,6 @@ body {
 #nav li a.tickets {
   background-image: url('../images/icons/tix.png');
 }
-
 #content {
   padding: 20px 0;
   margin: 0 20px;
@@ -313,7 +374,6 @@ body {
   height: 350px;
   min-height: 350px;
 }
-
 #footer {
   text-align: center;
   font-size: 11px;
@@ -322,7 +382,6 @@ body {
 #footer a {
   color: #333;
 }
-
 #footer p {
   margin: 10px 0 0 0;
 }
@@ -333,45 +392,23 @@ body {
   outline: none;
   text-indent: -9999px;
   margin: 0 auto;
-  background: url('../images/poweredby.png?1319571688') top left no-repeat;
+  background: url('../images/poweredby.png') top left no-repeat;
 }
-
-/* Landing page */
 #landing_page #new_ticket {
   margin-top: 40px;
   width: 295px;
   padding-left: 75px;
   float: left;
-  background: url('../images/new_ticket_icon.png?1319577021') top left no-repeat;
-}
-#landing_page #new_ticket input[type=submit] {
-  background: url('../images/open_ticket_btn.png?1319566422') top left no-repeat;
+  background: url('../images/new_ticket_icon.png') top left no-repeat;
 }
 #landing_page #check_status {
   margin-top: 40px;
   width: 295px;
   padding-left: 75px;
   float: right;
-  background: url('../images/check_status_icon.png?1319577072') top left no-repeat;
-}
-#landing_page #check_status input[type=submit] {
-  background: url('../images/check_status_btn.png?1319571066') top left no-repeat;
+  background: url('../images/check_status_icon.png') top left no-repeat;
 }
-#landing_page form div {
-  margin-bottom: 20px;
-  height: 60px;
-  min-height: 60px;
-}
-#landing_page form input[type=submit] {
-  display: block;
-  width: 192px;
-  height: 38px;
-  border: none;
-  margin: 0;
-  padding: 0;
-  text-indent: -9999px;
-}
-
+/* Landing page FAQ not yet implemented. */
 #faq {
   clear: both;
   margin: 0;
@@ -381,136 +418,129 @@ body {
   font-size: 15px;
   margin-left: 0;
   padding-left: 0;
-  border-top:1px solid #ddd;
+  border-top: 1px solid #ddd;
 }
 #faq ol li {
   list-style: none;
   margin: 0;
-  padding:0;
+  padding: 0;
   color: #999;
 }
 #faq ol li a {
-  display:block;
-  padding:5px 0;
-  height:auto !important;
-  overflow:hidden;
-  margin:0;
-  border-bottom:1px solid #ddd;
+  display: block;
+  padding: 5px 0;
+  height: auto !important;
+  overflow: hidden;
+  margin: 0;
+  border-bottom: 1px solid #ddd;
   line-height: 16px;
   padding-left: 24px;
-  background: url('../images/icons/page.png?1319579499') 0 50% no-repeat;
+  background: url('../images/icons/page.png') 0 50% no-repeat;
 }
 #faq ol li a:hover {
-  background-color:#e9f5ff;
+  background-color: #e9f5ff;
 }
-
-.article-meta {
-  padding:5px;
-  background:#fafafa;
+#faq .article-meta {
+  padding: 5px;
+  background: #fafafa;
 }
-
-/* Knowledgebase */
 #kb {
   margin: 2px 0;
   padding: 5px;
   overflow: hidden;
 }
-
 #kb > li {
-  padding:10px;
-  height:auto !important;
-  overflow:hidden;
-  margin:0;
-  background:url(../images/kb_category_bg.png) bottom left repeat-x;
-  border-bottom:1px solid #ddd;
-}
-
-#kb li i {
-  display:block;
-  width:32px;
-  height:32px;
-  float:left;
-  margin-right:6px;
-  background:url(../images/kb_large_folder.png) top left no-repeat;
-}
-
+  padding: 10px;
+  height: auto !important;
+  overflow: hidden;
+  margin: 0;
+  background: url(../images/kb_category_bg.png) bottom left repeat-x;
+  border-bottom: 1px solid #ddd;
+}
 #kb > li h4 {
-    padding-bottom:3px;
-    margin-bottom:3px;
+  padding-bottom: 3px;
+  margin-bottom: 3px;
 }
-
 #kb > li h4 span {
-    color:#666;
+  color: #666;
 }
-
 #kb > li h4 a {
   font-size: 14px;
 }
-
+#kb li i {
+  display: block;
+  width: 32px;
+  height: 32px;
+  float: left;
+  margin-right: 6px;
+  background: url(../images/kb_large_folder.png) top left no-repeat;
+}
 #kb-search {
-    padding:10px 0;
-    overflow:hidden;
+  padding: 10px 0;
+  overflow: hidden;
 }
-
 #kb-search div {
-    clear:both;
-    overflow:hidden;
-    padding-top:5px;
+  clear: both;
+  overflow: hidden;
+  padding-top: 5px;
 }
-
 #kb-search #query {
-    margin:0;
-    display:inline-block;
-    float:left;
-    width:200px;
-    margin-right:5px;
+  margin: 0;
+  display: inline-block;
+  float: left;
+  width: 200px;
+  margin-right: 5px;
 }
-
 #kb-search #cid {
-    margin:0;
-    display:inline-block;
-    float:left;
-    width:200px;
-    margin-right:5px;
-    position:relative;
-    top:2px;
-}
-
+  margin: 0;
+  display: inline-block;
+  float: left;
+  width: 200px;
+  margin-right: 5px;
+  position: relative;
+  top: 2px;
+}
 #kb-search #topic-id {
-    margin:0;
-    display:inline-block;
-    float:left;
-    width:410px;
+  margin: 0;
+  display: inline-block;
+  float: left;
+  width: 410px;
 }
-
 #kb-search #searchSubmit {
-    margin:0;
-    display:inline-block;
-    float:left;
-    position:relative;
-    top:2px;
-}
-
-#breadcrumbs {
+  margin: 0;
+  display: inline-block;
+  float: left;
+  position: relative;
+  top: 2px;
+}
+#kb-search #breadcrumbs {
   color: #333;
   margin-bottom: 15px;
 }
-#breadcrumbs a {
+#kb-search #breadcrumbs #breadcrumbs a {
   color: #555;
 }
-
-/* New Ticket & Log In Forms */
-#ticketForm div, #clientLogin div {
+#ticketForm div,
+#clientLogin div {
   clear: both;
   padding: 3px 0;
   overflow: hidden;
 }
-#ticketForm div label, #clientLogin div label {
+#ticketForm div label,
+#clientLogin div label {
   display: block;
   width: 140px;
   float: left;
 }
-#ticketForm div input, #ticketForm div textarea, #clientLogin div input, #clientLogin div textarea {
+#ticketForm div label.required,
+#clientLogin div label.required {
+  font-weight: bold;
+  text-align: left;
+}
+#ticketForm div input,
+#clientLogin div input,
+#ticketForm div textarea,
+#clientLogin div textarea {
   width: auto;
   border: 1px solid #aaa;
   background: #fff;
@@ -518,23 +548,40 @@ body {
   display: block;
   float: left;
 }
-
-#ticketForm div input[type=file] {
+#ticketForm div input[type=file],
+#clientLogin div input[type=file] {
   border: 0;
 }
-
-#ticketForm div select, #clientLogin div select {
+#ticketForm div select,
+#clientLogin div select {
   display: block;
   float: left;
 }
-#ticketForm td textarea, #clientLogin div textarea {
+#ticketForm div div.captchaRow,
+#clientLogin div div.captchaRow {
+  line-height: 31px;
+}
+#ticketForm div div.captchaRow input,
+#clientLogin div div.captchaRow input {
+  position: relative;
+  top: 6px;
+}
+#ticketForm td textarea,
+#clientLogin td textarea,
+#ticketForm div textarea,
+#clientLogin div textarea {
   width: 600px;
 }
-
-#ticketForm td em, #clientLogin div em {
+#ticketForm td em,
+#clientLogin td em,
+#ticketForm div em,
+#clientLogin div em {
   color: #777;
 }
-#ticketForm td .captcha, #clientLogin div .captcha {
+#ticketForm td .captcha,
+#clientLogin td .captcha,
+#ticketForm div .captcha,
+#clientLogin div .captcha {
   width: 88px;
   height: 31px;
   background: #000;
@@ -542,44 +589,31 @@ body {
   float: left;
   margin-right: 20px;
 }
-#ticketForm td label.inline, #clientLogin div label.inline {
+#ticketForm td label.inline,
+#clientLogin td label.inline,
+#ticketForm div label.inline,
+#clientLogin div label.inline {
   width: auto;
   padding: 0 10px;
 }
-
-#ticketTable table tr th { 
+#ticketForm div.error input,
+#clientLogin div.error input {
+  border: 1px solid #a00;
+}
+#ticketForm div.error label,
+#clientLogin div.error label {
+  color: #a00;
+}
+#ticketTable th {
   width: 160px;
   font-weight: normal;
   text-align: left;
 }
-
-#ticketForm table th.required, #ticketForm table td.required, #clientLogin div label.required {
+#ticketTable th.required,
+#ticketTable td.required {
   font-weight: bold;
   text-align: left;
 }
-
-
-
-#ticketForm tr.captchaRow, #clientLogin div.captchaRow {
-  line-height: 31px;
-}
-
-.captchaRow td input, #clientLogin div.captchaRow input {
-  position: relative;
-  top: 6px;
-}
-
-#ticketForm div.error input, #clientLogin div.error input {
-  border: 1px solid #a00;
-}
-#ticketForm div.error label, #clientLogin div.error label {
-  color: #a00;
-}
-#clientLogin p {
-  clear: both;
-  text-align: center;
-}
-
 #clientLogin {
   width: 400px;
   margin-top: 20px;
@@ -587,6 +621,10 @@ body {
   border: 1px solid #ccc;
   background: url('../images/lock.png?1319655200') 440px 50% no-repeat #f6f6f6;
 }
+#clientLogin p {
+  clear: both;
+  text-align: center;
+}
 #clientLogin strong {
   font-size: 11px;
   color: #d00;
@@ -601,59 +639,89 @@ body {
   width: 120px;
   margin-right: 0;
 }
-
-/* Ticket List */
+#reply {
+  margin-top: 20px;
+  padding: 10px 5px;
+  background: #f9f9f9;
+  border: 1px solid #ccc;
+}
+#reply h2 {
+  margin-bottom: 10px;
+}
+#reply table {
+  width: 800px;
+}
+#reply table td {
+  vertical-align: top;
+}
+#reply textarea {
+  width: 628px !important;
+}
+#reply input[type=text],
+#reply #response_options textarea {
+  border: 1px solid #aaa;
+  background: #fff;
+}
+#reply .attachments .uploads div {
+  display: inline-block;
+  padding-right: 20px;
+}
+#reply .file {
+  display: inline-block;
+  padding-left: 20px;
+  margin-right: 20px;
+  background: url('../images/icons/file.gif') 0 50% no-repeat;
+}
+.uploads {
+  display: inline-block;
+  padding-right: 20px;
+}
+.uploads label {
+  padding: 3px;
+  padding-right: 10px;
+  width: auto !important;
+}
+/* Ticket icons */
 .Icon {
   width: auto;
   padding-left: 20px;
-  background-position: left center;
+  background-position: top left;
   background-repeat: no-repeat;
   color: #006699;
   text-decoration: none;
 }
-
-a.Icon:hover {
-  text-decoration: underline;
-}
-
 .Icon.Ticket {
-  background: url('../images/icons/ticket.gif?1319654018') 0 0 no-repeat;
+  background-image: url('../images/icons/ticket.gif');
 }
-
 .Icon.webTicket {
-  background: url('../images/icons/ticket_source_web.gif?1319654283') 0 0 no-repeat;
+  background-image: url('../images/icons/ticket_source_web.gif');
 }
-
 .Icon.emailTicket {
-  background: url('../images/icons/ticket_source_email.gif?1319654484') 0 0 no-repeat;
+  background-image: url('../images/icons/ticket_source_email.gif');
 }
-
 .Icon.phoneTicket {
-  background: url('../images/icons/ticket_source_phone.gif?1319654401') 0 0 no-repeat;
+  background-image: url('../images/icons/ticket_source_phone.gif');
 }
-
 .Icon.otherTicket {
-  background: url('../images/icons/ticket_source_other.gif?1319654433') 0 0 no-repeat;
+  background-image: url('../images/icons/ticket_source_other.gif');
 }
-
 .Icon.attachment {
-  background-image: url('../images/icons/attachment.gif?1319556657');
+  background-image: url('../images/icons/attachment.gif');
 }
-
 .Icon.file {
-  background-image: url('../images/icons/attachment.gif?1319556657');
+  background-image: url('../images/icons/attachment.gif');
 }
-
 .Icon.refresh {
-  background-image: url('../images/icons/refresh.gif?1319556657');
+  background-image: url('../images/icons/refresh.gif');
 }
-
 .Icon.thread {
   font-weight: bold;
   font-size: 1em;
   background-image: url('../images/icons/thread.gif?1319556657');
 }
-
+.Icon:hover {
+  text-decoration: underline;
+}
 #ticketTable {
   border: 1px solid #aaa;
   border-left: none;
@@ -688,13 +756,11 @@ a.Icon:hover {
 #ticketTable tr.alt td {
   background: #f9f9f9;
 }
-
 #ticketSearchForm {
   display: inline-block;
   float: left;
   padding: 0 0 5px 0;
 }
-
 a.refresh {
   display: block;
   width: auto;
@@ -708,16 +774,14 @@ a.refresh {
   color: #333;
   background-position: 5px 50%;
   background-repeat: no-repeat;
-  background-image: url('../images/icons/refresh.png?1319653435');
+  background-image: url('../images/icons/refresh.png');
 }
-
 .infoTable {
   background: #F4FAFF;
 }
 .infoTable th {
   text-align: left;
 }
-
 #ticketThread table {
   margin-top: 10px;
   border: 1px solid #aaa;
@@ -729,13 +793,11 @@ a.refresh {
   font-size: 12px;
   padding: 5px;
 }
-
 #ticketThread table th span {
-    font-weight:normal;
-    color:#888;
-    padding-left:20px;
+  font-weight: normal;
+  color: #888;
+  padding-left: 20px;
 }
-
 #ticketThread table td {
   padding: 5px;
 }
@@ -761,76 +823,3 @@ a.refresh {
   background-position: 0 50%;
   background-repeat: no-repeat;
 }
-
-#reply {
-  margin-top: 20px;
-  padding: 10px 5px;
-  background: #f9f9f9;
-  border: 1px solid #ccc;
-}
-#reply h2 {
-  margin-bottom: 10px;
-}
-#reply table {
-  width: 800px;
-}
-#reply table td {
-  vertical-align: top;
-}
-#reply textarea {
-  width: 628px !important;
-}
-#reply input[type=text], #reply #response_options textarea {
-  border: 1px solid #aaa;
-  background: #fff;
-}
-#reply .attachments .uploads div {
-  display: inline-block;
-  padding-right: 20px;
-}
-#reply .file {
-  display: inline-block;
-  padding-left: 20px;
-  margin-right: 20px;
-  background: url('../images/icons/file.gif') 0 50% no-repeat;
-}
-
-.button, .button:visited {
-    background: #222;
-    display: inline-block;
-    font-size: 16px;
-    padding: 8px 16px 6px 16px;
-    width:160px;
-    text-align:center;
-    color: #fff;
-    font-weight:bold;
-    text-decoration: none;
-    border-radius: 5px;
-    -moz-border-radius: 5px;
-    -webkit-border-radius: 5px;
-    box-shadow: 0 1px 3px rgba(0,0,0,0.5);
-    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
-    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
-    text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
-    border-bottom: 1px solid rgba(0,0,0,0.25);
-    position: relative;
-    cursor: pointer;
-    font-family:helvetica, arial, sans-serif;
-}
-
-
-.uploads {
-    display:inline-block;
-    padding-right:20px;
-}
-
-.uploads label { padding:3px; padding-right:10px; width: auto !important }
-
-.button:hover                          { background-color: #111; color: #fff; }
-.button:active                         { top: 1px; box-shadow:none; -moz-box-shadow:none; -webkit-box-shadow:none; }
-.button, .button:visited,
-.green.button, .green.button:visited      { background-color: #91bd09; }
-.green.button:hover                        { background-color: #749a02; }
-.blue.button, .blue.button:visited        { background-color: #00AEEF; }
-.blue.button:hover                         { background-color: #0299d2; }
-
diff --git a/assets/default/css/theme.min.css b/assets/default/css/theme.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..8e747a44528fe4376371c967fd867ec835f01fce
--- /dev/null
+++ b/assets/default/css/theme.min.css
@@ -0,0 +1 @@
+html{font-size:100%;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px;line-height:1.231;padding:0}body,input,select,textarea{font-family:sans-serif;color:#000}b,strong{font-weight:bold}blockquote{margin:1em 40px}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}small{font-size:85%}ul,ol{margin:1em 0;padding:0 0 0 30px}img{border:0;vertical-align:middle}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}input{line-height:normal;*overflow:visible}table input{*overflow:auto}input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}th,td{vertical-align:top}th{text-align:left;font-weight:normal}h1,h2,h3,h4,h5,h6,form,fieldset{margin:0;padding:0}a{color:#0072bc;text-decoration:none}h1{color:#00aeef;font-weight:normal;font-size:20px}h3{font-size:16px}h2{font-size:16px;color:#999}.centered{text-align:center}.clear{clear:both;height:1px;visibility:none}.hidden{display:none}.faded{color:#666}#pagination{border:0;margin:0 0 40px 0;padding:0}#pagination li{border:0;margin:0;padding:0;font-size:11px;list-style:none;display:inline}#pagination li a{margin-right:2px;display:block;float:left;padding:3px 6px;text-decoration:none}#pagination li a:hover{color:#ff0084}#pagination .previousOff,#pagination .nextOff{color:#666;display:block;float:left;font-weight:bold;padding:3px 4px}#pagination .next a,#pagination .previous a{font-weight:bold}#pagination .active{color:#000;font-weight:bold;margin-right:2px;display:block;float:left;padding:3px 6px;text-decoration:none}#msg_notice{margin:0;padding:5px 10px 5px 36px;height:16px;line-height:16px;margin-bottom:10px;border:1px solid #0a0;background:url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0}#msg_warning{margin:0;padding:5px 10px 5px 36px;height:16px;line-height:16px;margin-bottom:10px;border:1px solid #f26522;background:url('../images/icons/alert.png') 10px 50% no-repeat #ffd}#msg_error{margin:0;padding:5px 10px 5px 36px;height:16px;line-height:16px;margin-bottom:10px;border:1px solid #a00;background:url('../images/icons/error.png') 10px 50% no-repeat #fff0f0}.warning{background:#ffc;font-style:italic}.warning strong{text-transform:uppercase;color:#a00;font-style:normal}.error{color:#f00}.error input{border:1px solid #f00}.button,.button:visited{background:#222;display:inline-block;font-size:16px;padding:8px 16px 6px 16px;width:160px;text-align:center;color:#fff;font-weight:bold;text-decoration:none;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;box-shadow:0 1px 3px rgba(0,0,0,0.5);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.5);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.5);text-shadow:0 -1px 1px rgba(0,0,0,0.25);border-bottom:1px solid rgba(0,0,0,0.25);position:relative;cursor:pointer;font-family:helvetica,arial,sans-serif}.button:hover{background-color:#111;color:#fff}.button:active{top:1px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}.button,.button:visited,.green.button,.green.button:visited{background-color:#91bd09}.green.button:hover{background-color:#749a02}.blue.button,.blue.button:visited{background-color:#00aeef}.blue.button:hover{background-color:#0299d2}body{background:url('../images/page_bg.png') top left repeat-x #c8c8c8}#container{background:#fff;width:840px;margin:0 auto;box-shadow:0 0 6px rgba(0,0,0,0.5);-moz-box-shadow:0 0 6px rgba(0,0,0,0.5);-webkit-box-shadow:0 0 6px rgba(0,0,0,0.5)}#header{position:relative;height:71px;padding:0 20px}#header #logo{width:220px;height:71px;float:left}#header p{width:400px;text-align:right;margin:0;padding:10px 0;float:right}#nav{margin:0 20px;padding:2px 10px;height:20px;background:url('../images/nav_bg.png') top left repeat-x;border-top:1px solid #aaa;box-shadow:0 3px 2px rgba(0,0,0,0.4);-moz-box-shadow:0 3px 2px rgba(0,0,0,0.4);-webkit-box-shadow:0 3px 2px rgba(0,0,0,0.4)}#nav li{margin:0;padding:0;list-style:none;display:inline}#nav li a{display:block;width:auto;float:left;height:20px;line-height:20px;text-align:center;padding:0 10px 0 32px;margin-left:10px;color:#333;border-radius:20px;-webkit-border-radius:20px;-moz-border-radius:20px;background-position:10px 50%;background-repeat:no-repeat}#nav li a.active,#nav li a:hover{background-color:#dbefff;color:#000}#nav li a:hover{background-color:#ededed;color:#0054a6}#nav li a.home{background-image:url('../images/icons/home.png')}#nav li a.kb{background-image:url('../images/icons/kb.png')}#nav li a.new{background-image:url('../images/icons/new.png')}#nav li a.status{background-image:url('../images/icons/status.png')}#nav li a.tickets{background-image:url('../images/icons/tix.png')}#content{padding:20px 0;margin:0 20px;height:auto!important;height:350px;min-height:350px}#footer{text-align:center;font-size:11px;color:#333}#footer a{color:#333}#footer p{margin:10px 0 0 0}#footer #poweredBy{display:block;width:126px;height:23px;outline:0;text-indent:-9999px;margin:0 auto;background:url('../images/poweredby.png') top left no-repeat}#landing_page #new_ticket{margin-top:40px;width:295px;padding-left:75px;float:left;background:url('../images/new_ticket_icon.png') top left no-repeat}#landing_page #check_status{margin-top:40px;width:295px;padding-left:75px;float:right;background:url('../images/check_status_icon.png') top left no-repeat}#faq{clear:both;margin:0;padding:5px}#faq ol{font-size:15px;margin-left:0;padding-left:0;border-top:1px solid #ddd}#faq ol li{list-style:none;margin:0;padding:0;color:#999}#faq ol li a{display:block;padding:5px 0;height:auto!important;overflow:hidden;margin:0;border-bottom:1px solid #ddd;line-height:16px;padding-left:24px;background:url('../images/icons/page.png') 0 50% no-repeat}#faq ol li a:hover{background-color:#e9f5ff}#faq .article-meta{padding:5px;background:#fafafa}#kb{margin:2px 0;padding:5px;overflow:hidden}#kb>li{padding:10px;height:auto!important;overflow:hidden;margin:0;background:url(../images/kb_category_bg.png) bottom left repeat-x;border-bottom:1px solid #ddd}#kb>li h4{padding-bottom:3px;margin-bottom:3px}#kb>li h4 span{color:#666}#kb>li h4 a{font-size:14px}#kb li i{display:block;width:32px;height:32px;float:left;margin-right:6px;background:url(../images/kb_large_folder.png) top left no-repeat}#kb-search{padding:10px 0;overflow:hidden}#kb-search div{clear:both;overflow:hidden;padding-top:5px}#kb-search #query{margin:0;display:inline-block;float:left;width:200px;margin-right:5px}#kb-search #cid{margin:0;display:inline-block;float:left;width:200px;margin-right:5px;position:relative;top:2px}#kb-search #topic-id{margin:0;display:inline-block;float:left;width:410px}#kb-search #searchSubmit{margin:0;display:inline-block;float:left;position:relative;top:2px}#kb-search #breadcrumbs{color:#333;margin-bottom:15px}#kb-search #breadcrumbs #breadcrumbs a{color:#555}#ticketForm div,#clientLogin div{clear:both;padding:3px 0;overflow:hidden}#ticketForm div label,#clientLogin div label{display:block;width:140px;float:left}#ticketForm div label.required,#clientLogin div label.required{font-weight:bold;text-align:left}#ticketForm div input,#clientLogin div input,#ticketForm div textarea,#clientLogin div textarea{width:auto;border:1px solid #aaa;background:#fff;margin-right:10px;display:block;float:left}#ticketForm div input[type=file],#clientLogin div input[type=file]{border:0}#ticketForm div select,#clientLogin div select{display:block;float:left}#ticketForm div div.captchaRow,#clientLogin div div.captchaRow{line-height:31px}#ticketForm div div.captchaRow input,#clientLogin div div.captchaRow input{position:relative;top:6px}#ticketForm td textarea,#clientLogin td textarea,#ticketForm div textarea,#clientLogin div textarea{width:600px}#ticketForm td em,#clientLogin td em,#ticketForm div em,#clientLogin div em{color:#777}#ticketForm td .captcha,#clientLogin td .captcha,#ticketForm div .captcha,#clientLogin div .captcha{width:88px;height:31px;background:#000;display:block;float:left;margin-right:20px}#ticketForm td label.inline,#clientLogin td label.inline,#ticketForm div label.inline,#clientLogin div label.inline{width:auto;padding:0 10px}#ticketForm div.error input,#clientLogin div.error input{border:1px solid #a00}#ticketForm div.error label,#clientLogin div.error label{color:#a00}#ticketTable th{width:160px;font-weight:normal;text-align:left}#ticketTable th.required,#ticketTable td.required{font-weight:bold;text-align:left}#clientLogin{width:400px;margin-top:20px;padding:10px 100px 10px 10px;border:1px solid #ccc;background:url('../images/lock.png?1319655200') 440px 50% no-repeat #f6f6f6}#clientLogin p{clear:both;text-align:center}#clientLogin strong{font-size:11px;color:#d00;display:block;padding-left:140px}#clientLogin #email{width:250px;margin-right:0}#clientLogin #ticketno{width:120px;margin-right:0}#reply{margin-top:20px;padding:10px 5px;background:#f9f9f9;border:1px solid #ccc}#reply h2{margin-bottom:10px}#reply table{width:800px}#reply table td{vertical-align:top}#reply textarea{width:628px!important}#reply input[type=text],#reply #response_options textarea{border:1px solid #aaa;background:#fff}#reply .attachments .uploads div{display:inline-block;padding-right:20px}#reply .file{display:inline-block;padding-left:20px;margin-right:20px;background:url('../images/icons/file.gif') 0 50% no-repeat}.uploads{display:inline-block;padding-right:20px}.uploads label{padding:3px;padding-right:10px;width:auto!important}.Icon{width:auto;padding-left:20px;background-position:top left;background-repeat:no-repeat;color:#069;text-decoration:none}.Icon.Ticket{background-image:url('../images/icons/ticket.gif')}.Icon.webTicket{background-image:url('../images/icons/ticket_source_web.gif')}.Icon.emailTicket{background-image:url('../images/icons/ticket_source_email.gif')}.Icon.phoneTicket{background-image:url('../images/icons/ticket_source_phone.gif')}.Icon.otherTicket{background-image:url('../images/icons/ticket_source_other.gif')}.Icon.attachment{background-image:url('../images/icons/attachment.gif')}.Icon.file{background-image:url('../images/icons/attachment.gif')}.Icon.refresh{background-image:url('../images/icons/refresh.gif')}.Icon.thread{font-weight:bold;font-size:1em;background-image:url('../images/icons/thread.gif?1319556657')}.Icon:hover{text-decoration:underline}#ticketTable{border:1px solid #aaa;border-left:none;border-bottom:0}#ticketTable caption{padding:5px;text-align:left;color:#000;background:#ddd;border:1px solid #aaa;border-bottom:0;font-weight:bold}#ticketTable th{height:24px;line-height:24px;background:#e1f2ff;border:1px solid #aaa;border-right:0;border-top:0}#ticketTable th a{color:#000}#ticketTable td{padding:2px;border:1px solid #aaa;border-right:0;border-top:0}#ticketTable tr.alt td{background:#f9f9f9}#ticketSearchForm{display:inline-block;float:left;padding:0 0 5px 0}a.refresh{display:block;width:auto;float:right;height:20px;line-height:20px;text-align:center;padding:0 10px 0 28px;border:1px solid #aaa;margin-left:10px;color:#333;background-position:5px 50%;background-repeat:no-repeat;background-image:url('../images/icons/refresh.png')}.infoTable{background:#f4faff}.infoTable th{text-align:left}#ticketThread table{margin-top:10px;border:1px solid #aaa;border-bottom:2px solid #aaa}#ticketThread table th{text-align:left;border-bottom:1px solid #aaa;font-size:12px;padding:5px}#ticketThread table th span{font-weight:normal;color:#888;padding-left:20px}#ticketThread table td{padding:5px}#ticketThread .message th{background:#d8efff}#ticketThread .response th{background:#ddd}#ticketThread .info{padding:2px;background:#f9f9f9;border-top:1px solid #ddd;height:16px;line-height:16px}#ticketThread .info a{display:inline-block;margin:5px 10px 5px 0;padding-left:24px;height:16px;line-height:16px;background-position:0 50%;background-repeat:no-repeat}
\ No newline at end of file
diff --git a/assets/default/less/base.less b/assets/default/less/base.less
new file mode 100644
index 0000000000000000000000000000000000000000..b6b4681574e7f11178100467eca70ab2ef0fa266
--- /dev/null
+++ b/assets/default/less/base.less
@@ -0,0 +1,131 @@
+/* Typography */
+a {
+  color: #0072bc;
+  text-decoration: none;
+}
+
+h1 {
+  color: #00AEEF;
+  font-weight: normal;
+  font-size: 20px;
+}
+
+h3 {
+  font-size: 16px;
+}
+
+h2 {
+  font-size: 16px;
+  color: #999;
+}
+
+/* Helpers */
+.centered { text-align: center;}
+
+.clear { clear:both; height: 1px; visibility: none;}
+
+.hidden { display: none;}
+
+.faded { color:#666;}
+
+/* Pagination */
+#pagination {
+  border: 0;
+  margin: 0 0 40px 0;
+  padding: 0;
+  li {
+    border: 0;
+    margin: 0;
+    padding: 0;
+    font-size: 11px;
+    list-style: none;
+    display: inline;
+    a {
+      margin-right: 2px;
+      display: block;
+      float: left;
+      padding: 3px 6px;
+      text-decoration: none;
+    }
+    a:hover {
+      color: #ff0084;
+    }
+  }
+  .previousOff, .nextOff {
+    color: #666;
+    display: block;
+    float: left;
+    font-weight: bold;
+    padding: 3px 4px;
+  }
+  .next a, .previous a {
+    font-weight: bold;
+  }
+  .active {
+    color: #000;
+    font-weight: bold;
+    margin-right: 2px;
+    display: block;
+    float: left;
+    padding: 3px 6px;
+    text-decoration: none;
+  }
+}
+
+/* Alerts & Notices */
+
+#msg_notice { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #0a0; background: url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0; }
+
+#msg_warning { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #f26522; background: url('../images/icons/alert.png') 10px 50% no-repeat #ffffdd; }
+
+#msg_error { margin: 0; padding: 5px 10px 5px 36px; height: 16px; line-height: 16px; margin-bottom: 10px; border: 1px solid #a00; background: url('../images/icons/error.png') 10px 50% no-repeat #fff0f0; }
+
+
+.warning {
+  background: #ffc;
+  font-style: italic;
+  strong {
+    text-transform: uppercase;
+    color: #a00;
+    font-style: normal;
+  }
+}
+
+.error {
+  color:#f00;
+  input {
+    border:1px solid #f00;
+  }
+}
+
+
+.button, .button:visited {
+    background: #222;
+    display: inline-block;
+    font-size: 16px;
+    padding: 8px 16px 6px 16px;
+    width:160px;
+    text-align:center;
+    color: #fff;
+    font-weight:bold;
+    text-decoration: none;
+    border-radius: 5px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    box-shadow: 0 1px 3px rgba(0,0,0,0.5);
+    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
+    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
+    text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
+    border-bottom: 1px solid rgba(0,0,0,0.25);
+    position: relative;
+    cursor: pointer;
+    font-family:helvetica, arial, sans-serif;
+}
+
+.button:hover                          { background-color: #111; color: #fff; }
+.button:active                         { top: 1px; box-shadow:none; -moz-box-shadow:none; -webkit-box-shadow:none; }
+.button, .button:visited,
+.green.button, .green.button:visited      { background-color: #91bd09; }
+.green.button:hover                        { background-color: #749a02; }
+.blue.button, .blue.button:visited        { background-color: #00AEEF; }
+.blue.button:hover                         { background-color: #0299d2; }
diff --git a/assets/default/less/kb.less b/assets/default/less/kb.less
new file mode 100644
index 0000000000000000000000000000000000000000..f31faa4d0b99d4decd83dfda5dff3adad24b5bba
--- /dev/null
+++ b/assets/default/less/kb.less
@@ -0,0 +1,88 @@
+#kb {
+  margin: 2px 0;
+  padding: 5px;
+  overflow: hidden;
+
+  > li {
+    padding:10px;
+    height:auto !important;
+    overflow:hidden;
+    margin:0;
+    background:url(../images/kb_category_bg.png) bottom left repeat-x;
+    border-bottom:1px solid #ddd;
+    h4 {
+      padding-bottom:3px;
+      margin-bottom:3px;
+      span {
+        color:#666;
+      }
+      a {
+        font-size: 14px;
+      }
+    }
+  }
+
+  li {
+    i {
+      display:block;
+      width:32px;
+      height:32px;
+      float:left;
+      margin-right:6px;
+      background:url(../images/kb_large_folder.png) top left no-repeat;
+    }
+  }
+}
+
+#kb-search {
+  padding:10px 0;
+  overflow:hidden;
+
+  div {
+    clear:both;
+    overflow:hidden;
+    padding-top:5px;
+  }
+
+  #query {
+    margin:0;
+    display:inline-block;
+    float:left;
+    width:200px;
+    margin-right:5px;
+  }
+
+  #cid {
+    margin:0;
+    display:inline-block;
+    float:left;
+    width:200px;
+    margin-right:5px;
+    position:relative;
+    top:2px;
+  }
+
+  #topic-id {
+    margin:0;
+    display:inline-block;
+    float:left;
+    width:410px;
+  }
+
+  #searchSubmit {
+    margin:0;
+    display:inline-block;
+    float:left;
+    position:relative;
+    top:2px;
+  }
+
+  #breadcrumbs {
+    color: #333;
+    margin-bottom: 15px;
+
+    #breadcrumbs a {
+      color: #555;
+    }
+  }
+}
diff --git a/assets/default/less/landing-page.less b/assets/default/less/landing-page.less
new file mode 100644
index 0000000000000000000000000000000000000000..cfcfcfcbf63ff4b7295372dc49b5124043e80d01
--- /dev/null
+++ b/assets/default/less/landing-page.less
@@ -0,0 +1,58 @@
+#landing_page {
+  #new_ticket {
+    margin-top: 40px;
+    width: 295px;
+    padding-left: 75px;
+    float: left;
+    background: url('../images/new_ticket_icon.png') top left no-repeat;
+  }
+
+  #check_status {
+    margin-top: 40px;
+    width: 295px;
+    padding-left: 75px;
+    float: right;
+    background: url('../images/check_status_icon.png') top left no-repeat;
+  }
+}
+
+/* Landing page FAQ not yet implemented. */
+#faq {
+  clear: both;
+  margin: 0;
+  padding: 5px;
+
+  ol {
+    font-size: 15px;
+    margin-left: 0;
+    padding-left: 0;
+    border-top:1px solid #ddd;
+
+    li {
+      list-style: none;
+      margin: 0;
+      padding:0;
+      color: #999;
+      a {
+        display:block;
+        padding:5px 0;
+        height:auto !important;
+        overflow:hidden;
+        margin:0;
+        border-bottom:1px solid #ddd;
+        line-height: 16px;
+        padding-left: 24px;
+        background: url('../images/icons/page.png') 0 50% no-repeat;
+      }
+
+      a:hover {
+        background-color:#e9f5ff;
+      }
+    }
+  }
+  .article-meta {
+    padding:5px;
+    background:#fafafa;
+  }
+}
+
diff --git a/assets/default/less/main-layout.less b/assets/default/less/main-layout.less
new file mode 100644
index 0000000000000000000000000000000000000000..a40cac090aad2fa4f287fbfa8955d0da04f246de
--- /dev/null
+++ b/assets/default/less/main-layout.less
@@ -0,0 +1,114 @@
+body {
+  background: url('../images/page_bg.png') top left repeat-x #c8c8c8;
+}
+
+#container {
+  background: #fff;
+  width: 840px;
+  margin: 0 auto;
+  box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
+  -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
+  -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
+}
+
+#header {
+  position: relative;
+  height: 71px;
+  padding: 0 20px;
+
+  #logo {
+    width: 220px;
+    height: 71px;
+    float: left;
+  }
+
+  p {
+    width: 400px;
+    text-align: right;
+    margin: 0;
+    padding: 10px 0;
+    float: right;
+  }
+}
+
+#nav {
+  margin: 0 20px;
+  padding: 2px 10px;
+  height: 20px;
+  background: url('../images/nav_bg.png') top left repeat-x;
+  border-top: 1px solid #aaa;
+  box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
+  -moz-box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
+  -webkit-box-shadow:0 3px 2px rgba(0, 0, 0, 0.4);
+
+  li {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    display: inline;
+    a {
+      display: block;
+      width: auto;
+      float: left;
+      height: 20px;
+      line-height: 20px;
+      text-align: center;
+      padding: 0 10px 0 32px;
+      margin-left: 10px;
+      color: #333;
+      border-radius: 20px;
+      -webkit-border-radius: 20px;
+      -moz-border-radius: 20px;
+      background-position: 10px 50%;
+      background-repeat: no-repeat;
+    }
+
+    a.active, a:hover {
+      background-color: #dbefff;
+      color: #000;
+    }
+
+    a:hover {
+      background-color: #ededed;
+      color: #0054a6;
+    }
+
+    a.home    { background-image: url('../images/icons/home.png'); }
+    a.kb      { background-image: url('../images/icons/kb.png'); }
+    a.new     {  background-image: url('../images/icons/new.png'); }
+    a.status  { background-image: url('../images/icons/status.png'); }
+    a.tickets { background-image: url('../images/icons/tix.png'); }
+  }
+}
+
+#content {
+  padding: 20px 0;
+  margin: 0 20px;
+  height: auto !important;
+  height: 350px;
+  min-height: 350px;
+}
+
+#footer {
+  text-align: center;
+  font-size: 11px;
+  color: #333;
+
+  a {
+    color: #333;
+  }
+
+  p {
+    margin: 10px 0 0 0;
+  }
+
+  #poweredBy {
+    display: block;
+    width: 126px;
+    height: 23px;
+    outline: none;
+    text-indent: -9999px;
+    margin: 0 auto;
+    background: url('../images/poweredby.png') top left no-repeat;
+  }
+}
\ No newline at end of file
diff --git a/assets/default/less/print.less b/assets/default/less/print.less
new file mode 100644
index 0000000000000000000000000000000000000000..dbe21bc7e8d2d2f16cbc7f6db5974383903357f7
--- /dev/null
+++ b/assets/default/less/print.less
@@ -0,0 +1,30 @@
+#header, #nav, #meta, #footer, #reply, #pagination, .reload, .refresh, form, .thread, hr, #kbAttachments, .back {
+  display: none;
+}
+
+th {
+  text-align: left;
+}
+
+a {
+  color: #000;
+  text-decoration: none;
+}
+
+caption {
+  text-align: left;
+  padding-bottom: 10px;
+  font-weight: bold;
+}
+
+.message, .response {
+  border-bottom: 1px solid #000;
+  margin-bottom: 20px;
+  padding-bottom: 10px;
+
+  th {
+    font-size: 12pt;
+    font-weight: bold;
+    padding-bottom: 5px;
+  }
+}
diff --git a/assets/default/less/reset.less b/assets/default/less/reset.less
new file mode 100644
index 0000000000000000000000000000000000000000..8cf9581eb2516d2c21e5b7b2be0bf614e85d9592
--- /dev/null
+++ b/assets/default/less/reset.less
@@ -0,0 +1,117 @@
+html {
+  font-size: 100%;
+  overflow-y: scroll;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%;
+}
+
+body {
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.231;
+  padding: 0;
+}
+
+body, input, select, textarea {
+  font-family: sans-serif;
+  color: #000;
+}
+
+b, strong {
+  font-weight: bold;
+}
+
+blockquote {
+  margin: 1em 40px;
+}
+
+hr {
+  display: block;
+  height: 1px;
+  border: 0;
+  border-top: 1px solid #ccc;
+  margin: 1em 0;
+  padding: 0;
+}
+
+small {
+  font-size: 85%;
+}
+
+ul, ol {
+  margin: 1em 0;
+  padding: 0 0 0 30px;
+}
+
+img {
+  border: 0;
+  vertical-align: middle;
+}
+
+form {
+  margin: 0;
+}
+
+fieldset {
+  border: 0;
+  margin: 0;
+  padding: 0;
+}
+
+label {
+  cursor: pointer;
+}
+
+input, select, textarea {
+  font-size: 100%;
+  margin: 0;
+  vertical-align: baseline;
+  *vertical-align: middle;
+}
+
+input {
+  line-height: normal;
+  *overflow: visible;
+}
+
+table input {
+  *overflow: auto;
+}
+
+input[type="button"], input[type="reset"], input[type="submit"] {
+  cursor: pointer;
+  -webkit-appearance: button;
+}
+
+input[type="checkbox"], input[type="radio"] {
+  box-sizing: border-box;
+}
+
+input[type="search"] {
+  -webkit-appearance: textfield;
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+textarea {
+  overflow: auto;
+  vertical-align: top;
+  resize: vertical;
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+th, td {
+  vertical-align: top;
+}
+
+th { text-align: left; font-weight: normal; }
+
+h1, h2, h3, h4, h5, h6, form, fieldset {
+  margin: 0;
+  padding: 0;
+}
\ No newline at end of file
diff --git a/assets/default/less/theme.less b/assets/default/less/theme.less
new file mode 100644
index 0000000000000000000000000000000000000000..c3835f9e608d91533abb782a560b5f4c868cd675
--- /dev/null
+++ b/assets/default/less/theme.less
@@ -0,0 +1,7 @@
+@import 'reset';
+@import 'base';
+@import 'main-layout';
+@import 'landing-page';
+@import 'kb';
+@import 'ticket-forms';
+@import 'ticket';
diff --git a/assets/default/less/ticket-forms.less b/assets/default/less/ticket-forms.less
new file mode 100644
index 0000000000000000000000000000000000000000..96db30b28a692d7db08e3389e2b35317f60b9859
--- /dev/null
+++ b/assets/default/less/ticket-forms.less
@@ -0,0 +1,170 @@
+#ticketForm, #clientLogin {
+  div {
+    clear: both;
+    padding: 3px 0;
+    overflow: hidden;
+
+    label {
+      display: block;
+      width: 140px;
+      float: left;
+    }
+
+    label.required {
+        font-weight: bold;
+        text-align: left;
+    }
+
+    input, textarea {
+      width: auto;
+      border: 1px solid #aaa;
+      background: #fff;
+      margin-right: 10px;
+      display: block;
+      float: left;
+    }
+
+    input[type=file] {
+      border: 0;
+    }
+
+    select {
+      display: block;
+      float: left;
+    }
+    div.captchaRow {
+      line-height: 31px;
+
+      input {
+        position: relative;
+        top: 6px;
+      }
+    }
+
+  }
+
+  td, div {
+    textarea {
+      width: 600px;
+    }
+
+    em {
+      color: #777;
+    }
+
+    .captcha {
+      width: 88px;
+      height: 31px;
+      background: #000;
+      display: block;
+      float: left;
+      margin-right: 20px;
+    }
+
+    label.inline {
+      width: auto;
+      padding: 0 10px;
+    }
+  }
+
+  div.error {
+    input {
+      border: 1px solid #a00;
+    }
+    label {
+      color: #a00;
+    }
+  }
+}
+
+#ticketTable {
+  th {
+    width: 160px;
+    font-weight: normal;
+    text-align: left;
+  }
+  th.required, td.required {
+    font-weight: bold;
+    text-align: left;
+  }
+}
+
+#clientLogin {
+  width: 400px;
+  margin-top: 20px;
+  padding: 10px 100px 10px 10px;
+  border: 1px solid #ccc;
+  background: url('../images/lock.png?1319655200') 440px 50% no-repeat #f6f6f6;
+
+  p {
+    clear: both;
+    text-align: center;
+  }
+
+  strong {
+    font-size: 11px;
+    color: #d00;
+    display: block;
+    padding-left: 140px;
+  }
+
+  #email {
+    width: 250px;
+    margin-right: 0;
+  }
+
+  #ticketno {
+    width: 120px;
+    margin-right: 0;
+  }
+}
+
+#reply {
+  margin-top: 20px;
+  padding: 10px 5px;
+  background: #f9f9f9;
+  border: 1px solid #ccc;
+
+  h2 {
+    margin-bottom: 10px;
+  }
+
+  table {
+    width: 800px;
+
+    td {
+      vertical-align: top;
+    }
+  }
+
+  textarea {
+    width: 628px !important;
+  }
+
+  input[type=text], #response_options textarea {
+    border: 1px solid #aaa;
+    background: #fff;
+  }
+
+  .attachments .uploads div {
+    display: inline-block;
+    padding-right: 20px;
+  }
+  .file {
+    display: inline-block;
+    padding-left: 20px;
+    margin-right: 20px;
+    background: url('../images/icons/file.gif') 0 50% no-repeat;
+  }
+}
+
+.uploads {
+  display:inline-block;
+  padding-right:20px;
+
+  label {
+    padding:3px;
+    padding-right:10px;
+    width: auto !important
+  }
+}
\ No newline at end of file
diff --git a/assets/default/less/ticket.less b/assets/default/less/ticket.less
new file mode 100644
index 0000000000000000000000000000000000000000..d7f2d307930432c2b41e3396f716d77fca5bc3e9
--- /dev/null
+++ b/assets/default/less/ticket.less
@@ -0,0 +1,145 @@
+/* Ticket icons */
+.Icon {
+  width: auto;
+  padding-left: 20px;
+  background-position: top left;
+  background-repeat: no-repeat;
+  color: #006699;
+  text-decoration: none;
+}
+
+.Icon.Ticket { background-image: url('../images/icons/ticket.gif') }
+.Icon.webTicket { background-image: url('../images/icons/ticket_source_web.gif'); }
+.Icon.emailTicket { background-image: url('../images/icons/ticket_source_email.gif'); }
+.Icon.phoneTicket { background-image: url('../images/icons/ticket_source_phone.gif'); }
+.Icon.otherTicket { background-image: url('../images/icons/ticket_source_other.gif'); }
+.Icon.attachment { background-image: url('../images/icons/attachment.gif'); }
+.Icon.file { background-image: url('../images/icons/attachment.gif'); }
+.Icon.refresh { background-image: url('../images/icons/refresh.gif'); }
+
+.Icon.thread {
+  font-weight: bold;
+  font-size: 1em;
+  background-image: url('../images/icons/thread.gif?1319556657');
+}
+
+.Icon:hover {
+  text-decoration: underline;
+}
+
+
+#ticketTable {
+  border: 1px solid #aaa;
+  border-left: none;
+  border-bottom: none;
+
+  caption {
+    padding: 5px;
+    text-align: left;
+    color: #000;
+    background: #ddd;
+    border: 1px solid #aaa;
+    border-bottom: none;
+    font-weight: bold;
+  }
+
+  th {
+    height: 24px;
+    line-height: 24px;
+    background: #e1f2ff;
+    border: 1px solid #aaa;
+    border-right: none;
+    border-top: none;
+
+    a {
+      color: #000;
+    }
+  }
+
+  td {
+    padding: 2px;
+    border: 1px solid #aaa;
+    border-right: none;
+    border-top: none;
+  }
+
+  tr.alt td {
+    background: #f9f9f9;
+  }
+}
+
+#ticketSearchForm {
+  display: inline-block;
+  float: left;
+  padding: 0 0 5px 0;
+}
+
+a.refresh {
+  display: block;
+  width: auto;
+  float: right;
+  height: 20px;
+  line-height: 20px;
+  text-align: center;
+  padding: 0 10px 0 28px;
+  border: 1px solid #aaa;
+  margin-left: 10px;
+  color: #333;
+  background-position: 5px 50%;
+  background-repeat: no-repeat;
+  background-image: url('../images/icons/refresh.png');
+}
+
+.infoTable {
+  background: #F4FAFF;
+  th {
+    text-align: left;
+  }
+}
+
+#ticketThread {
+  table {
+    margin-top: 10px;
+    border: 1px solid #aaa;
+    border-bottom: 2px solid #aaa;
+
+    th {
+      text-align: left;
+      border-bottom: 1px solid #aaa;
+      font-size: 12px;
+      padding: 5px;
+
+      span {
+          font-weight:normal;
+          color:#888;
+          padding-left:20px;
+      }
+    }
+
+    td {
+      padding: 5px;
+    }
+  }
+
+  .message th { background: #d8efff; }
+  .response th { background: #ddd; }
+
+  .info {
+    padding: 2px;
+    background: #f9f9f9;
+    border-top: 1px solid #ddd;
+    height: 16px;
+    line-height: 16px;
+
+    a {
+      display: inline-block;
+      margin: 5px 10px 5px 0;
+      padding-left: 24px;
+      height: 16px;
+      line-height: 16px;
+      background-position: 0 50%;
+      background-repeat: no-repeat;
+    }
+  }
+}
+
diff --git a/include/.htaccess b/include/.htaccess
new file mode 100644
index 0000000000000000000000000000000000000000..3a42882788717c9ed1d5c2fcc3277d21ec13152b
--- /dev/null
+++ b/include/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/include/class.banlist.php b/include/class.banlist.php
index 27729b44a42f45cb0d187f1e8f2a8b731991784e..c620b105033fbc1275b6f0cb82ee69bb2c5306d3 100644
--- a/include/class.banlist.php
+++ b/include/class.banlist.php
@@ -27,7 +27,7 @@ class Banlist {
     }
     
     function isbanned($email) {
-        return EmailFilter::isBanned($email);
+        return TicketFilter::isBanned($email);
     }
 
     function includes($email) {
@@ -50,7 +50,7 @@ class Banlist {
             'name'          => 'SYSTEM BAN LIST',
             'isactive'      => 1,
             'match_all_rules' => false,
-            'reject_email'  => true,
+            'reject_ticket'  => true,
             'rules'         => array(),
             'notes'         => 'Internal list for email banning. Do not remove'
         ), $errors);
diff --git a/include/class.canned.php b/include/class.canned.php
index 52a487529c368bc158777359260d36b808dc1d90..c84950e7d6d19b062dbb3a53c0ccfe95eab96c48 100644
--- a/include/class.canned.php
+++ b/include/class.canned.php
@@ -35,8 +35,10 @@ class Canned {
             .' count(filter.id) as filters '
             .' FROM '.CANNED_TABLE.' canned '
             .' LEFT JOIN '.CANNED_ATTACHMENT_TABLE.' attach ON (attach.canned_id=canned.canned_id) ' 
-            .' LEFT JOIN '.EMAIL_FILTER_TABLE.' filter ON (canned.canned_id = filter.canned_response_id) '
-            .' WHERE canned.canned_id='.db_input($id);
+            .' LEFT JOIN '.FILTER_TABLE.' filter ON (canned.canned_id = filter.canned_response_id) '
+            .' WHERE canned.canned_id='.db_input($id)
+            .' GROUP BY canned.canned_id';
+
         if(!($res=db_query($sql)) ||  !db_num_rows($res))
             return false;
 
@@ -100,7 +102,7 @@ class Canned {
         if (!$this->_filters) {
             $this->_filters = array();
             $res = db_query(
-                  'SELECT name FROM '.EMAIL_FILTER_TABLE
+                  'SELECT name FROM '.FILTER_TABLE
                 .' WHERE canned_response_id = '.db_input($this->getId())
                 .' ORDER BY name');
             while ($row = db_fetch_row($res))
diff --git a/include/class.config.php b/include/class.config.php
index 96674dd3ad296a33088343e2dbe0b2e812c3396e..e6271511239683703825dbdaedc4066e819c5d4b 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -543,35 +543,32 @@ class Config {
         return $this->config['upload_dir'];
     }
     
-    function updateSettings($vars,&$errors) {
+    function updateSettings($vars, &$errors) {
 
         if(!$vars || $errors)
             return false;
         
         switch(strtolower($vars['t'])) {
-            case 'general':
-                return $this->updateGeneralSetting($vars,$errors);
-                break;
-            case 'dates':
-                return $this->updateDateTimeSetting($vars,$errors);
+            case 'system':
+                return $this->updateSystemSettings($vars, $errors);
                 break;
             case 'tickets':
-                return $this->updateTicketsSetting($vars,$errors);
+                return $this->updateTicketsSettings($vars, $errors);
                 break;
             case 'emails':
-                return $this->updateEmailsSetting($vars,$errors);
+                return $this->updateEmailsSettings($vars, $errors);
                 break;
            case 'attachments':
                 return $this->updateAttachmentsSetting($vars,$errors);
                 break;
-           case 'autoresponders':
-                return $this->updateAutoresponderSetting($vars,$errors);
+           case 'autoresp':
+                return $this->updateAutoresponderSettings($vars, $errors);
                 break;
             case 'alerts':
-                return $this->updateAlertsSetting($vars,$errors);
+                return $this->updateAlertsSettings($vars, $errors);
                 break;
             case 'kb':
-                return $this->updateKBSetting($vars,$errors);
+                return $this->updateKBSettings($vars, $errors);
                 break;
             default:
                 $errors['err']='Unknown setting option. Get technical support.';
@@ -580,7 +577,7 @@ class Config {
         return false;
     }
 
-    function updateGeneralSetting($vars, &$errors) {
+    function updateSystemSettings($vars, &$errors) {
 
         $f=array();
         $f['helpdesk_url']=array('type'=>'string',   'required'=>1, 'error'=>'Helpdesk URl required');
@@ -589,6 +586,13 @@ class Config {
         $f['default_template_id']=array('type'=>'int',   'required'=>1, 'error'=>'You must select template.');
         $f['staff_session_timeout']=array('type'=>'int',   'required'=>1, 'error'=>'Enter idle time in minutes');
         $f['client_session_timeout']=array('type'=>'int',   'required'=>1, 'error'=>'Enter idle time in minutes');
+        //Date & Time Options
+        $f['time_format']=array('type'=>'string',   'required'=>1, 'error'=>'Time format required');
+        $f['date_format']=array('type'=>'string',   'required'=>1, 'error'=>'Date format required');
+        $f['datetime_format']=array('type'=>'string',   'required'=>1, 'error'=>'Datetime format required');
+        $f['daydatetime_format']=array('type'=>'string',   'required'=>1, 'error'=>'Day, Datetime format required');
+        $f['default_timezone_id']=array('type'=>'int',   'required'=>1, 'error'=>'Default Timezone required');
+
 
         if(!Validator::process($f, $vars, $errors) || $errors)
             return false;
@@ -610,26 +614,6 @@ class Config {
             .',client_max_logins='.db_input($vars['client_max_logins'])
             .',client_login_timeout='.db_input($vars['client_login_timeout'])
             .',client_session_timeout='.db_input($vars['client_session_timeout'])
-            .',clickable_urls='.db_input(isset($vars['clickable_urls'])?1:0)
-            .',enable_auto_cron='.db_input(isset($vars['enable_auto_cron'])?1:0)
-            .' WHERE id='.db_input($this->getId());
-        
-        return (db_query($sql));
-    }
-
-    function updateDateTimeSetting($vars,&$errors) {
-
-        $f=array();
-        $f['time_format']=array('type'=>'string',   'required'=>1, 'error'=>'Time format required');
-        $f['date_format']=array('type'=>'string',   'required'=>1, 'error'=>'Date format required');
-        $f['datetime_format']=array('type'=>'string',   'required'=>1, 'error'=>'Datetime format required');
-        $f['daydatetime_format']=array('type'=>'string',   'required'=>1, 'error'=>'Day, Datetime format required');
-        $f['default_timezone_id']=array('type'=>'int',   'required'=>1, 'error'=>'Default Timezone required');
-             
-        if(!Validator::process($f,$vars,$errors) || $errors)
-            return false;
-
-        $sql='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
             .',time_format='.db_input($vars['time_format'])
             .',date_format='.db_input($vars['date_format'])
             .',datetime_format='.db_input($vars['datetime_format'])
@@ -641,7 +625,7 @@ class Config {
         return (db_query($sql));
     }
 
-    function updateTicketsSetting($vars,&$errors) {
+    function updateTicketsSettings($vars, &$errors) {
 
 
         $f=array();
@@ -658,7 +642,30 @@ class Config {
                 $errors['enable_captcha']='PNG support required for Image Captcha';
         }
 
-        if(!Validator::process($f,$vars,$errors) || $errors)
+        if($vars['allow_attachments']) {
+
+            if(!ini_get('file_uploads'))
+                $errors['err']='The \'file_uploads\' directive is disabled in php.ini';
+
+            if(!is_numeric($vars['max_file_size']))
+                $errors['max_file_size']='Maximum file size required';
+
+            if(!$vars['allowed_filetypes'])
+                $errors['allowed_filetypes']='Allowed file extentions required';
+
+            if(!($maxfileuploads=ini_get('max_file_uploads')))
+                $maxfileuploads=DEFAULT_MAX_FILE_UPLOADS;
+
+            if(!$vars['max_user_file_uploads'] || $vars['max_user_file_uploads']>$maxfileuploads)
+                $errors['max_user_file_uploads']='Invalid selection. Must be less than '.$maxfileuploads;
+
+            if(!$vars['max_staff_file_uploads'] || $vars['max_staff_file_uploads']>$maxfileuploads)
+                $errors['max_staff_file_uploads']='Invalid selection. Must be less than '.$maxfileuploads;
+        }
+
+
+
+        if(!Validator::process($f, $vars, $errors) || $errors)
             return false;
 
         $sql='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
@@ -676,14 +683,24 @@ class Config {
             .',show_answered_tickets='.db_input(isset($vars['show_answered_tickets'])?1:0)
             .',show_related_tickets='.db_input(isset($vars['show_related_tickets'])?1:0)
             .',show_notes_inline='.db_input(isset($vars['show_notes_inline'])?1:0)
+            .',clickable_urls='.db_input(isset($vars['clickable_urls'])?1:0)
             .',hide_staff_name='.db_input(isset($vars['hide_staff_name'])?1:0)
+            .',allow_attachments='.db_input(isset($vars['allow_attachments'])?1:0)
+            .',allowed_filetypes='.db_input(strtolower(preg_replace("/\n\r|\r\n|\n|\r/", '',trim($vars['allowed_filetypes']))))
+            .',max_file_size='.db_input($vars['max_file_size'])
+            .',max_user_file_uploads='.db_input($vars['max_user_file_uploads'])
+            .',max_staff_file_uploads='.db_input($vars['max_staff_file_uploads'])
+            .',email_attachments='.db_input(isset($vars['email_attachments'])?1:0)
+            .',allow_email_attachments='.db_input(isset($vars['allow_email_attachments'])?1:0)
+            .',allow_online_attachments='.db_input(isset($vars['allow_online_attachments'])?1:0)
+            .',allow_online_attachments_onlogin='.db_input(isset($vars['allow_online_attachments_onlogin'])?1:0)
             .' WHERE id='.db_input($this->getId());
 
         return (db_query($sql));
     }
 
 
-    function updateEmailsSetting($vars,&$errors) {
+    function updateEmailsSettings($vars, &$errors) {
 
         $f=array();
         $f['default_email_id']=array('type'=>'int',   'required'=>1, 'error'=>'Default email required');
@@ -704,6 +721,7 @@ class Config {
             .',alert_email_id='.db_input($vars['alert_email_id'])
             .',default_smtp_id='.db_input($vars['default_smtp_id'])
             .',admin_email='.db_input($vars['admin_email'])
+            .',enable_auto_cron='.db_input(isset($vars['enable_auto_cron'])?1:0)
             .',enable_mail_polling='.db_input(isset($vars['enable_mail_polling'])?1:0)
             .',enable_email_piping='.db_input(isset($vars['enable_email_piping'])?1:0)
             .',strip_quoted_reply='.db_input(isset($vars['strip_quoted_reply'])?1:0)
@@ -756,7 +774,7 @@ class Config {
         return (db_query($sql));
     }
 
-    function updateAutoresponderSetting($vars,&$errors) {
+    function updateAutoresponderSettings($vars, &$errors) {
 
         if($errors) return false;
 
@@ -771,7 +789,7 @@ class Config {
     }
 
 
-    function updateKBSetting($vars,&$errors) {
+    function updateKBSettings($vars, &$errors) {
 
         if($errors) return false;
 
@@ -784,7 +802,7 @@ class Config {
     }
 
 
-    function updateAlertsSetting($vars,&$errors) {
+    function updateAlertsSettings($vars, &$errors) {
 
 
        if($vars['ticket_alert_active']
diff --git a/include/class.filter.php b/include/class.filter.php
index b6c81b42b60d0d4b8c67d3f7b33b1138695fa1e7..ce7d7d92cb273705bc458e32e6c7dd93cf8668e7 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -2,7 +2,7 @@
 /*********************************************************************
     class.filter.php
 
-    Email Filter Class
+    Ticket Filter
 
     Peter Rotich <peter@osticket.com>
     Copyright (c)  2006-2012 osTicket
@@ -18,7 +18,7 @@ class Filter {
     var $id;
     var $ht;
 
-    function Filter($id){
+    function Filter($id) {
         $this->id=0;
         $this->load($id);
     }
@@ -29,8 +29,8 @@ class Filter {
             return false;
 
         $sql='SELECT filter.*,count(rule.id) as rule_count '
-            .' FROM '.EMAIL_FILTER_TABLE.' filter '
-            .' LEFT JOIN '.EMAIL_FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '
+            .' FROM '.FILTER_TABLE.' filter '
+            .' LEFT JOIN '.FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '
             .' WHERE filter.id='.db_input($id)
             .' GROUP BY filter.id';
 
@@ -47,27 +47,31 @@ class Filter {
         return $this->load($this->getId());
     }
 
-    function getId(){
+    function getId() {
         return $this->id;
     }
 
-    function getName(){
+    function getTarget() {
+        return $this->ht['target'];
+    }
+
+    function getName() {
         return $this->ht['name'];
     }
 
-    function getNotes(){
+    function getNotes() {
         return $this->ht['notes'];
     }
 
-    function getInfo(){
+    function getInfo() {
         return  $this->ht;
     }
 
-    function getNumRules(){
+    function getNumRules() {
         return $this->ht['rule_count'];
     }
 
-    function getExecOrder(){
+    function getExecOrder() {
         return $this->ht['execorder'];
     }
 
@@ -75,7 +79,7 @@ class Filter {
         return $this->ht['email_id'];
     }
 
-    function isActive(){
+    function isActive() {
         return ($this->ht['isactive']);
     }
 
@@ -83,23 +87,23 @@ class Filter {
         return !strcasecmp($this->getName(),'SYSTEM BAN LIST');
     }
 
-    function getDeptId(){
+    function getDeptId() {
         return $this->ht['dept_id'];
     }
 
-    function getPriorityId(){
+    function getPriorityId() {
         return $this->ht['priority_id'];
     }
 
-    function getSLAId(){
+    function getSLAId() {
         return $this->ht['sla_id'];
     }
 
-    function getStaffId(){
+    function getStaffId() {
         return $this->ht['staff_id'];
     }
 
-    function getTeamId(){
+    function getTeamId() {
         return $this->ht['team_id'];
     }
 
@@ -107,36 +111,36 @@ class Filter {
         return $this->ht['canned_response_id'];
     }
 
-    function stopOnMatch(){
+    function stopOnMatch() {
         return ($this->ht['stop_on_match']);
     }
 
-    function matchAllRules(){
+    function matchAllRules() {
         return ($this->ht['match_all_rules']);
     }
 
-    function rejectEmail(){
-        return ($this->ht['reject_email']);
+    function rejectOnMatch() {
+        return ($this->ht['reject_ticket']);
     }
 
-    function useReplyToEmail(){
+    function useReplyToEmail() {
         return ($this->ht['use_replyto_email']);
     }
 
-    function disableAlerts(){
+    function disableAlerts() {
         return ($this->ht['disable_autoresponder']);
     }
      
-    function sendAlerts(){
+    function sendAlerts() {
         return (!$this->disableAlerts());
     }
 
-    function getRules(){
+    function getRules() {
         if (!$this->ht['rules']) {
             $rules=array();
             //We're getting the rules...live because it gets cleared on update.
-            $sql='SELECT * FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($this->getId());
-            if(($res=db_query($sql)) && db_num_rows($res)){
+            $sql='SELECT * FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($this->getId());
+            if(($res=db_query($sql)) && db_num_rows($res)) {
                 while($row=db_fetch_array($res))
                     $rules[]=array('w'=>$row['what'],'h'=>$row['how'],'v'=>$row['val']);
             }
@@ -145,11 +149,11 @@ class Filter {
         return $this->ht['rules'];
     }
 
-    function getFlatRules(){ //Format used on html... I'm ashamed 
+    function getFlatRules() { //Format used on html... I'm ashamed 
 
         $info=array();
-        if(($rules=$this->getRules())){
-            foreach($rules as $k=>$rule){
+        if(($rules=$this->getRules())) {
+            foreach($rules as $k=>$rule) {
                 $i=$k+1;
                 $info["rule_w$i"]=$rule['w'];
                 $info["rule_h$i"]=$rule['h'];
@@ -169,7 +173,7 @@ class Filter {
 
     function removeRule($what, $how, $val) {
 
-        $sql='DELETE FROM '.EMAIL_FILTER_RULE_TABLE
+        $sql='DELETE FROM '.FILTER_RULE_TABLE
             .' WHERE filter_id='.db_input($this->getId())
             .' AND what='.db_input($what)
             .' AND how='.db_input($how)
@@ -187,17 +191,19 @@ class Filter {
     }
 
     function containsRule($what, $how, $val) {
+        $val = trim($val);
         if (isset($this->ht['rules'])) {
+            $match = array("w"=>$what, "h"=>$how, "v"=>$val);
             foreach ($this->ht['rules'] as $rule) {
-                if (array("w"=>$what, "h"=>$how, "v"=>$val) == $rule) {
-                    return True;
-                }
+                if ($match == $rule)
+                    return true;
             }
-            return False;
+            return false;
+
         } else {
             # Fetch from database
             return 0 != db_count(
-                "SELECT COUNT(*) FROM ".EMAIL_FILTER_RULE_TABLE
+                "SELECT COUNT(*) FROM ".FILTER_RULE_TABLE
                ." WHERE filter_id=".db_input($this->id)
                ." AND what=".db_input($what)." AND how=".db_input($how)
                ." AND val=".db_input($val)
@@ -208,35 +214,41 @@ class Filter {
      * Simple true/false if the rules defined for this filter match the
      * incoming email
      *
-     * $email is an ARRAY, which has valid keys
-     *  *from - email address of sender
-     *   name - name of sender
-     *   subject - subject line of the email
-     *   body - body content of the email (no attachments, please)
+     * $info is an ARRAY, which has valid keys
+     *   email - FROM email address of the ticket owner
+     *   name - name of ticket owner
+     *   subject - subject line of the ticket
+     *   body - body content of the message (no attachments, please)
      *   reply-to - reply-to email address
      *   reply-to-name - name of sender to reply-to
      *   headers - array of email headers
-     *   emailid - osTicket email id of recipient
+     *   emailId - osTicket system email id 
      */
-    function matches($email) {
+    function matches($info) {
+
+        if(!$info || !is_array($info)) return false;
+
         $what = array(
-            "email"     => $email['email'],
-            "subject"   => $email['subject'],
+            'email'     => $info['email'],
+            'subject'   => $info['subject'],
             # XXX: Support reply-to too ?
-            "name"      => $email['name'],
-            "body"      => $email['message']
+            'name'      => $info['name'],
+            'body'      => $info['message']
             # XXX: Support headers
         );
         $how = array(
             # how => array(function, null or === this, null or !== this)
-            "equal"     => array("strcmp", 0),
-            "not_equal" => array("strcmp", null, 0),
-            "contains"  => array("strpos", null, false),
-            "dn_contain"=> array("strpos", false)
+            'equal'     => array('strcmp', 0),
+            'not_equal' => array('strcmp', null, 0),
+            'contains'  => array('strpos', null, false),
+            'dn_contain'=> array('strpos', false)
         );
+
         $match = false;
         # Respect configured filter email-id
-        if ($this->getEmailId() && $this->getEmailId() != $email['emailId'])
+        if ($this->getEmailId() 
+                && !strcasecmp($this->getTarget(), 'Email')
+                && $this->getEmailId() != $info['emailId'])
             return false;
 
         foreach ($this->getRules() as $rule) {
@@ -265,7 +277,7 @@ class Filter {
      * If the matches() method returns TRUE, send the initial ticket to this
      * method to apply the filter actions defined
      */
-    function apply(&$ticket, $email=null) {
+    function apply(&$ticket, $info=null) {
         # TODO: Disable alerting
         # XXX: Does this imply turning it on as well? (via ->sendAlerts())
         if ($this->disableAlerts()) $ticket['autorespond']=false;
@@ -279,22 +291,24 @@ class Filter {
         #       XXX: Unset the other (of staffId or teamId) (?)
         if ($this->getStaffId())    $ticket['staffId']=$this->getStaffId();
         elseif ($this->getTeamId()) $ticket['teamId']=$this->getTeamId();
-        #       Override name with reply-to information from the EmailFilter
+        #       Override name with reply-to information from the TicketFilter
         #       match
-        if ($this->useReplyToEmail() && $email['reply-to']) {
-            $ticket['email'] = $email['reply-to'];
-            if ($email['reply-to-name']) 
-                $ticket['name'] = $email['reply-to-name'];
+        if ($this->useReplyToEmail() && $info['reply-to']) {
+            $ticket['email'] = $info['reply-to'];
+            if ($info['reply-to-name']) 
+                $ticket['name'] = $info['reply-to-name'];
         }
+
+        # Use canned response.
         if ($this->getCannedResponse())
             $ticket['cannedResponseId'] = $this->getCannedResponse();
     }
     /* static */ function getSupportedMatches() {
         return array(
-            'name'=>    "Sender's Name",
-            'email'=>   "Sender's Email",
-            'subject'=> 'Email Subject',
-            'body'=>    'Email Body/Text'
+            'name'=>    'Name',
+            'email'=>   'Email',
+            'subject'=> 'Subject',
+            'body'=>    'Body/Text'
         );
     }
     /* static */ function getSupportedMatchTypes() {
@@ -306,7 +320,7 @@ class Filter {
         );
     }
 
-    function update($vars,&$errors){
+    function update($vars,&$errors) {
 
         if(!Filter::save($this->getId(),$vars,$errors))
             return false;
@@ -316,47 +330,55 @@ class Filter {
         return true;
     }
 
-    function delete(){
+    function delete() {
         
         $id=$this->getId();
-        $sql='DELETE FROM '.EMAIL_FILTER_TABLE.' WHERE id='.db_input($id).' LIMIT 1';
-        if(db_query($sql) && ($num=db_affected_rows())){
-            db_query('DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id));
+        $sql='DELETE FROM '.FILTER_TABLE.' WHERE id='.db_input($id).' LIMIT 1';
+        if(db_query($sql) && ($num=db_affected_rows())) {
+            db_query('DELETE FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id));
         }
 
         return $num;
     }
 
     /** static functions **/
-    function create($vars,&$errors){
+    function getTargets() {
+        return array(
+                'Any' => 'Any',
+                'Web' => 'Web Forms',
+                'API' => 'API Calls',
+                'Email' => 'Emails');
+    }
+
+    function create($vars,&$errors) {
         return Filter::save(0,$vars,$errors);
     }
 
-    function getIdByName($name){
+    function getIdByName($name) {
 
-        $sql='SELECT id FROM '.EMAIL_FILTER_TABLE.' WHERE name='.db_input($name);
+        $sql='SELECT id FROM '.FILTER_TABLE.' WHERE name='.db_input($name);
         if(($res=db_query($sql)) && db_num_rows($res))
             list($id)=db_fetch_row($res);
 
         return $id;
     }
 
-    function lookup($id){
+    function lookup($id) {
         return ($id && is_numeric($id) && ($f= new Filter($id)) && $f->getId()==$id)?$f:null;
     }
 
-    function validate_rules($vars,&$errors){
+    function validate_rules($vars,&$errors) {
         return self::save_rules(0,$vars,$errors);
     }
 
-    function save_rules($id,$vars,&$errors){
+    function save_rules($id,$vars,&$errors) {
 
         $matches=array('name','email','subject','body','header');
         $types=array('equal','not_equal','contains','dn_contain');
 
         $rules=array();
         for($i=1; $i<=25; $i++) { //Expecting no more than 25 rules...
-            if($vars["rule_w$i"] || $vars["rule_h$i"]){
+            if($vars["rule_w$i"] || $vars["rule_h$i"]) {
                 if(!$vars["rule_w$i"] || !in_array($vars["rule_w$i"],$matches))
                     $errors["rule_$i"]='Invalid match selection';
                 elseif(!$vars["rule_h$i"] || !in_array($vars["rule_h$i"],$types))
@@ -367,7 +389,7 @@ class Filter {
                     $errors["rule_$i"]='Valid email required for the match type';
                 else //for everything-else...we assume it's valid.
                     $rules[]=array('w'=>$vars["rule_w$i"],'h'=>$vars["rule_h$i"],'v'=>$vars["rule_v$i"]);
-            }elseif($vars["rule_v$i"]){
+            }elseif($vars["rule_v$i"]) {
                 $errors["rule_$i"]='Incomplete selection';
             }
         }
@@ -383,7 +405,7 @@ class Filter {
         if(!$id) return true; //When ID is 0 then assume it was just validation...
 
         //Clear existing rules...we're doing mass replace on each save!! 
-        db_query('DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id));
+        db_query('DELETE FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id));
         $num=0;
         foreach($rules as $rule) {
             $rule['filter_id']=$id;
@@ -394,39 +416,52 @@ class Filter {
         return $num; 
     }
 
-    function save($id,$vars,&$errors){
+    function save($id,$vars,&$errors) {
 
 
         if(!$vars['execorder'])
-            $errors['execorder']='Order required';
+            $errors['execorder'] = 'Order required';
         elseif(!is_numeric($vars['execorder']))
-            $errors['execorder']='Must be numeric value';
+            $errors['execorder'] = 'Must be numeric value';
             
         if(!$vars['name'])
-            $errors['name']='Name required';
+            $errors['name'] = 'Name required';
         elseif(($sid=self::getIdByName($vars['name'])) && $sid!=$id)
-            $errors['name']='Name already in-use';
+            $errors['name'] = 'Name already in-use';
 
         if(!$errors && !self::validate_rules($vars,$errors) && !$errors['rules'])
-            $errors['rules']='Unable to validate rules as entered';
+            $errors['rules'] = 'Unable to validate rules as entered';
+
+        $targets = self::getTargets();
+        if(!$vars['target'])
+            $errors['target'] = 'Target required';
+        else if(!is_numeric($vars['target']) && !$targets[$vars['target']])
+            $errors['target'] = 'Unknown or invalid target';
 
         if($errors) return false;
 
-        $sql=' updated=NOW() '.
-             ',isactive='.db_input($vars['isactive']).
-             ',name='.db_input($vars['name']).
-             ',execorder='.db_input($vars['execorder']).
-             ',email_id='.db_input($vars['email_id']).
-             ',dept_id='.db_input($vars['dept_id']).
-             ',priority_id='.db_input($vars['priority_id']).
-             ',sla_id='.db_input($vars['sla_id']).
-             ',match_all_rules='.db_input($vars['match_all_rules']).
-             ',stop_onmatch='.db_input(isset($vars['stop_onmatch'])?1:0).
-             ',reject_email='.db_input(isset($vars['reject_email'])?1:0).
-             ',use_replyto_email='.db_input(isset($vars['use_replyto_email'])?1:0).
-             ',disable_autoresponder='.db_input(isset($vars['disable_autoresponder'])?1:0).
-             ',canned_response_id='.db_input($vars['canned_response_id']).
-             ',notes='.db_input($vars['notes']);
+        $emailId = 0;
+        if(is_numeric($vars['target'])) {
+            $emailId = $vars['target'];
+            $vars['target'] = 'Email';
+        }
+
+        $sql=' updated=NOW() '
+            .',isactive='.db_input($vars['isactive'])
+            .',target='.db_input($vars['target'])
+            .',name='.db_input($vars['name'])
+            .',execorder='.db_input($vars['execorder'])
+            .',email_id='.db_input($emailId)
+            .',dept_id='.db_input($vars['dept_id'])
+            .',priority_id='.db_input($vars['priority_id'])
+            .',sla_id='.db_input($vars['sla_id'])
+            .',match_all_rules='.db_input($vars['match_all_rules'])
+            .',stop_onmatch='.db_input(isset($vars['stop_onmatch'])?1:0)
+            .',reject_ticket='.db_input(isset($vars['reject_ticket'])?1:0)
+            .',use_replyto_email='.db_input(isset($vars['use_replyto_email'])?1:0)
+            .',disable_autoresponder='.db_input(isset($vars['disable_autoresponder'])?1:0)
+            .',canned_response_id='.db_input($vars['canned_response_id'])
+            .',notes='.db_input($vars['notes']);
        
 
         //Auto assign ID is overloaded...
@@ -438,11 +473,11 @@ class Filter {
             $sql.=',staff_id=0,team_id=0 '; //no auto-assignment!
 
         if($id) {
-            $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET '.$sql.' WHERE id='.db_input($id);
+            $sql='UPDATE '.FILTER_TABLE.' SET '.$sql.' WHERE id='.db_input($id);
             if(!db_query($sql))
                 $errors['err']='Unable to update the filter. Internal error occurred';
         }else{
-            $sql='INSERT INTO '.EMAIL_FILTER_TABLE.' SET '.$sql.',created=NOW() ';
+            $sql='INSERT INTO '.FILTER_TABLE.' SET '.$sql.',created=NOW() ';
             if(!db_query($sql) || !($id=db_insert_id()))
                 $errors['err']='Unable to add filter. Internal error';
         }
@@ -464,14 +499,14 @@ class FilterRule {
 
     var $filter;
 
-    function FilterRule($id,$filterId=0){
+    function FilterRule($id,$filterId=0) {
         $this->id=0;
         $this->load($id,$filterId);
     }
 
     function load($id,$filterId=0) {
 
-        $sql='SELECT rule.* FROM '.EMAIL_FILTER_RULE_TABLE.' rule '
+        $sql='SELECT rule.* FROM '.FILTER_RULE_TABLE.' rule '
             .' WHERE rule.id='.db_input($id);
         if($filterId)
             $sql.=' AND rule.filter_id='.db_input($filterId);
@@ -529,9 +564,9 @@ class FilterRule {
         return true;
     }
 
-    function delete(){
+    function delete() {
         
-        $sql='DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE id='.db_input($this->getId()).' AND filter_id='.db_input($this->getFilterId());
+        $sql='DELETE FROM '.FILTER_RULE_TABLE.' WHERE id='.db_input($this->getId()).' AND filter_id='.db_input($this->getFilterId());
 
         return (db_query($sql) && db_affected_rows());
     }
@@ -559,12 +594,12 @@ class FilterRule {
             $sql.=',notes='.db_input($vars['notes']);
 
         if($id) {
-            $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET '.$sql.' WHERE id='.db_input($id).' AND filter_id='.db_input($vars['filter_id']);
+            $sql='UPDATE '.FILTER_RULE_TABLE.' SET '.$sql.' WHERE id='.db_input($id).' AND filter_id='.db_input($vars['filter_id']);
             if(db_query($sql))
                 return true;
 
         } else {
-            $sql='INSERT INTO '.EMAIL_FILTER_RULE_TABLE.' SET created=NOW(), filter_id='.db_input($vars['filter_id']).', '.$sql;
+            $sql='INSERT INTO '.FILTER_RULE_TABLE.' SET created=NOW(), filter_id='.db_input($vars['filter_id']).', '.$sql;
             if(db_query($sql) && ($id=db_insert_id()))
                 return $id;
         }
@@ -579,50 +614,65 @@ class FilterRule {
 }
 
 /**
- * Applies rules defined in the staff control panel "Email Filters". Each
+ * Applies rules defined in the admin control panel > Settings tab > "Ticket Filters". Each
  * filter can have up to 25 rules (*currently). This will attempt to match
- * the incoming email against the defined rules, and, if the email matches,
- * the ticket will be modified as described in the filter
+ * the incoming tickets against the defined rules, and, if the email matches,
+ * the ticket will be modified as described in the filter actions.
  */
-class EmailFilter {
+class TicketFilter {
+
+    var $target;
+    var $vars;
+
     /**
-     * Construct a list of filters to handle a new ticket generated from an
-     * email or something with information common to email (such as API
-     * calls, etc).
+     * Construct a list of filters to handle a new ticket
+     * taking into account the source/origin of the ticket.
      *
-     * $email is an ARRAY, which has valid keys
-     *  *email - email address of sender
-     *   name - name of sender
-     *   subject - subject line of the email
-     *   email-id - id of osTicket email recipient address
+     * $vars is an ARRAY, which has valid keys
+     *  *email - email address of user
+     *   name - name of user
+     *   subject - subject of the ticket
+     *   emailId - id of osTicket's system email (for emailed tickets)
      *  ---------------
      *  @see Filter::matches() for a complete list of supported keys
      *
-     * $slow - if TRUE, every (active) filter will be fetched from the
-     *         database and matched against the email. Otherwise, a subset
-     *         of filters from the database that appear to have rules that
-     *         deal with the data in the email will be considered. @see
-     *         ::quickList() for more information.
+     *  IF $vars is not provided, every (active) filter will be fetched from the
+     *  database and matched against the incoming ticket. Otherwise, a subset
+     *  of filters from the database that appear to have rules that
+     *  deal with the data in the incoming ticket (based on $vars) will be considered.
+     *  @see ::quickList() for more information.
      */
-    function EmailFilter($email, $slow=false) {
-        $this->email = $email;
-        if ($slow) {
-            $this->build($this->getAllActive());
-        } else {
-            $this->build(
-                $this->quickList($email['email'], $email['name'],
-                    $email['subject'], $email['emailId']));
-        }
+    function TicketFilter($origin, $vars=null) {
+        
+        $this->target = self::origin2target($origin);
+        $this->vars = ($vars && is_array($vars))?array_filter(array_map('trim', $vars)):null;
+       
+        //Init filters.
+        $this->build();
     }
-    
-    function build($res) {
+
+    function build() {
+        
+        //Clear any memoized filters
         $this->filters = array();
-        while (list($id) = db_fetch_row($res))
-            array_push($this->filters, new Filter($id));
+        $this->short_list = array();
+
+        //Query DB for "possibly" matching filters.
+        $res = $this->vars?$this->quickList():$this->getAllActive();
+        if($res) {
+            while (list($id) = db_fetch_row($res))
+                array_push($this->filters, new Filter($id));
+        }
+
         return $this->filters;
     }
+
+    function getTarget() {
+        return $this->target;
+    }
+
     /**
-     * Fetches the short list of filters that match the email received in the
+     * Fetches the short list of filters that match the ticket vars received in the
      * constructor. This function is memoized so subsequent calls will
      * return immediately.
      */
@@ -630,17 +680,18 @@ class EmailFilter {
         if (!isset($this->short_list)) {
             $this->short_list = array();
             foreach ($this->filters as $filter)
-                if ($filter->matches($this->email))
+                if ($filter->matches($this->vars))
                     $this->short_list[] = $filter;
         }
+
         return $this->short_list;
     }
     /**
-     * Determine if the filters that match the received email indicate that
+     * Determine if the filters that match the received vars indicate that
      * the email should be rejected
      *
      * Returns FALSE if the email should be acceptable. If the email should
-     * be rejected, the first filter that matches and has rejectEmail set is
+     * be rejected, the first filter that matches and has reject ticket set is
      * returned.
      */
     function shouldReject() {
@@ -649,7 +700,7 @@ class EmailFilter {
             # be blocked; however, don't unset $reject, because if it
             # was set by another rule that did not set stopOnMatch(), we
             # should still honor its configuration
-            if ($filter->rejectEmail()) return $filter;
+            if ($filter->rejectOnMatch()) return $filter;
         }
         return false;
     }
@@ -659,17 +710,21 @@ class EmailFilter {
      */
     function apply(&$ticket) {
         foreach ($this->getMatchingFilterList() as $filter) {
-            $filter->apply($ticket, $this->email);
+            $filter->apply($ticket, $this->vars);
             if ($filter->stopOnMatch()) break;
         }
     }
     
     /* static */ function getAllActive() {
-        $sql="SELECT id FROM ".EMAIL_FILTER_TABLE." WHERE isactive"
-           ." ORDER BY execorder";
+
+        $sql='SELECT id FROM '.FILTER_TABLE
+            .' WHERE isactive=1 '
+            .'  AND target IN ("Any", '.db_input($this->getTarget()).') '
+            .' ORDER BY execorder';
 
         return db_query($sql);
     }
+
     /**
      * Fast lookup function to all filters that have at least one rule that
      * matches the received address or name or is not defined to match based
@@ -693,45 +748,55 @@ class EmailFilter {
      * information from the database. Whether the filter will completely
      * match or not is determined in the Filter::matches() method.
      */
-    /* static */ function quickList($addr, $name=false, $subj=false, 
-            $emailid=0) {
-        $sql="SELECT DISTINCT filter_id FROM ".EMAIL_FILTER_RULE_TABLE." rule"
-           ." INNER JOIN ".EMAIL_FILTER_TABLE." filter"
-           ." ON (filter.id=rule.filter_id)"
-           ." WHERE filter.isactive";
-        # Filter by recipient email-id if specified
-        if ($emailid) #TODO: Fix the logic here...
-            $sql.=" AND filter.email_id=".db_input($emailid);
+     function quickList() {
+
+        if(!$this->vars || !$this->vars['email'])
+            return $this->getAllActive();
+
+        $sql='SELECT DISTINCT filter_id FROM '.FILTER_RULE_TABLE.' rule '
+            .' INNER JOIN '.FILTER_TABLE.' filter '
+            .' ON (filter.id=rule.filter_id) '
+            .' WHERE filter.isactive '
+            ."  AND filter.target IN ('Any', ".db_input($this->getTarget()).') ';
+
+        # Filter by system's email-id if specified
+        if($this->vars['emailId'])
+            $sql.=' AND (filter.email_id=0 OR filter.email_id='.db_input($this->vars['emailId']).')';
+        
         # Include rules for sender-email, sender-name and subject as
         # requested
-        $sql.=" AND ((what='email' AND LOCATE(val,".db_input($addr)."))";
-        if ($name) 
-            $sql.=" OR (what='name' AND LOCATE(val,".db_input($name)."))";
-        if ($subj) 
-            $sql.=" OR (what='subject' AND LOCATE(val,".db_input($subj)."))";
+        $sql.=" AND ((what='email' AND LOCATE(val, ".db_input($this->vars['email']).'))';
+        if($this->vars['name']) 
+            $sql.=" OR (what='name' AND LOCATE(val, ".db_input($this->vars['name']).'))';
+        if($this->vars['subject']) 
+            $sql.=" OR (what='subject' AND LOCATE(val, ".db_input($this->vars['subject']).'))';
         # Also include filters that do not have any rules concerning either
         # sender-email-addresses or sender-names or subjects
         $sql.=") OR filter.id IN ("
                ." SELECT filter_id "
-               ." FROM ".EMAIL_FILTER_RULE_TABLE." rule"
-               ." INNER JOIN ".EMAIL_FILTER_TABLE." filter"
+               ." FROM ".FILTER_RULE_TABLE." rule"
+               ." INNER JOIN ".FILTER_TABLE." filter"
                ." ON (rule.filter_id=filter.id)"
+               ." WHERE filter.isactive"
+               ." AND filter.target IN('Any', ".db_input($this->getTarget()).")"
                ." GROUP BY filter_id"
                ." HAVING COUNT(*)-COUNT(NULLIF(what,'email'))=0";
-        if ($name!==false) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'name'))=0";
-        if ($subj!==false) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'subject'))=0";
+        if (!$this->vars['name']) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'name'))=0";
+        if (!$this->vars['subject']) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'subject'))=0";
         # Also include filters that do not have match_all_rules set to and
         # have at least one rule 'what' type that wasn't considered
         $sql.=") OR filter.id IN ("
                ." SELECT filter_id"
-               ." FROM ".EMAIL_FILTER_RULE_TABLE." rule"
-               ." INNER JOIN ".EMAIL_FILTER_TABLE." filter"
+               ." FROM ".FILTER_RULE_TABLE." rule"
+               ." INNER JOIN ".FILTER_TABLE." filter"
                ." ON (rule.filter_id=filter.id)"
-               ." WHERE what NOT IN ('email'"
+               ." WHERE filter.isactive"
+               ." AND filter.target IN ('Any', ".db_input($this->getTarget()).")"
+               ." AND what NOT IN ('email'"
         # Handle sender-name and subject if specified
-               .(($name!==false)?",'name'":"")
-               .(($subj!==false)?",'subject'":"")
-               .") AND filter.match_all_rules = false"
+               .((!$this->vars['name'])?",'name'":"")
+               .((!$this->vars['subject'])?",'subject'":"")
+               .") AND filter.match_all_rules = 0 "
         # Return filters in declared execution order
             .") ORDER BY filter.execorder";
         
@@ -751,10 +816,10 @@ class EmailFilter {
     /* static */ function isBanned($addr) {
 
         $sql='SELECT filter.id, what, how, UPPER(val) '
-            .' FROM '.EMAIL_FILTER_TABLE.' filter'
-            .' INNER JOIN '.EMAIL_FILTER_RULE_TABLE.' rule'
+            .' FROM '.FILTER_TABLE.' filter'
+            .' INNER JOIN '.FILTER_RULE_TABLE.' rule'
             .' ON (filter.id=rule.filter_id)'
-            .' WHERE filter.reject_email'
+            .' WHERE filter.reject_ticket'
             .'   AND filter.match_all_rules=0'
             .'   AND filter.email_id=0'
             .'   AND filter.isactive'
@@ -762,20 +827,22 @@ class EmailFilter {
             .'   AND rule.what="email"'
             .'   AND LOCATE(rule.val,'.db_input($addr).')';
 
+        if(!($res=db_query($sql)) || !db_num_rows($res))
+            return false;
+
         # XXX: Use MB_xxx function for proper unicode support
         $addr = strtoupper($addr);
         $how=array('equal'      => array('strcmp', 0),
                    'contains'   => array('strpos', null, false));
-
-        if ($res=db_query($sql)) {
-            while ($row=db_fetch_array($res)) {
-                list($func, $pos, $neg) = $how[$row['how']];
-                if (!$func) continue;
-                $res = call_user_func($func, $addr, $row['val']);
-                if (($neg === null && $res === $pos) || $res !== $neg)
-                    return $row['id'];
-            }
+            
+        while ($row=db_fetch_array($res)) {
+            list($func, $pos, $neg) = $how[$row['how']];
+            if (!$func) continue;
+            $result = call_user_func($func, $addr, $row['val']);
+            if (($neg === null && $result === $pos) || $result !== $neg)
+                return $row['id'];
         }
+
         return false;
     }
 
@@ -814,5 +881,15 @@ class EmailFilter {
         }
         return false;
     }
+
+    /** 
+     * Normalize ticket source to supported filter target 
+     *
+     */
+    function origin2target($origin) {
+        $sources=array('web' => 'Web', 'email' => 'Email', 'phone' => 'Web', 'staff' => 'Web', 'api' => 'API');
+    
+        return $sources[strtolower($origin)];
+    }
 }
 ?>
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index fb8402169e83b39c258118329215d2459d7547a2..5a4e7e0f73e2edbe006f485f9dbe50b6d69809ce 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -376,7 +376,7 @@ class MailFetcher {
             return true; //Reporting success so the email can be moved or deleted.
 
 	    //Is the email address banned?
-        if($mailinfo['email'] && EmailFilter::isBanned($mailinfo['email'])) {
+        if($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) {
 	        //We need to let admin know...
             $ost->logWarning('Ticket denied', 'Banned email - '.$mailinfo['email']);
 	        return true; //Report success (moved or delete)
diff --git a/include/class.nav.php b/include/class.nav.php
index 0d5fddcbf3a48772db052a71363bfe0fb3b64ad5..eb66293770888faa572cce786b2d2b22c868ed67 100644
--- a/include/class.nav.php
+++ b/include/class.nav.php
@@ -43,7 +43,7 @@ class StaffNav {
         return (!$this->isAdminPanel());
     }
 
-    function setTabActive($tab){
+    function setTabActive($tab, $menu=''){
 
         if($this->tabs[$tab]){
             $this->tabs[$tab]['active']=true;
@@ -51,6 +51,7 @@ class StaffNav {
                  $this->tabs[$this->activetab]['active']=false;
 
             $this->activetab=$tab;
+            if($menu) $this->setActiveSubMenu($menu, $tab);
 
             return true;
         }
@@ -58,16 +59,25 @@ class StaffNav {
         return false;
     }
 
-    function setActiveTab($tab){
-        return $this->setTabActive($tab);
+    function setActiveTab($tab, $menu=''){
+        return $this->setTabActive($tab, $menu);
     }
 
     function getActiveTab(){
         return $this->activetab;
     }
 
-    function setActiveSubMenu($mid) {
-        $this->activeMenu = $mid;
+    function setActiveSubMenu($mid, $tab='') {
+        if(is_numeric($mid))
+            $this->activeMenu = $mid;
+        elseif($mid && $tab && ($subNav=$this->getSubNav($tab))) {
+            foreach($subNav as $k => $menu) {
+                if(strcasecmp($mid, $menu['href'])) continue;
+
+                $this->activeMenu = $k+1;
+                break;
+            }
+        }
     }
 
     function getActiveMenu() {
@@ -162,12 +172,11 @@ class AdminNav extends StaffNav{
         if(!$this->tabs){
 
             $tabs=array();
-            $tabs['dashboard']=array('desc'=>'Dashboard','href'=>'admin.php','title'=>'Admin Dashboard');
+            $tabs['dashboard']=array('desc'=>'Dashboard','href'=>'logs.php','title'=>'Admin Dashboard');
             $tabs['settings']=array('desc'=>'Settings','href'=>'settings.php','title'=>'System Settings');
+            $tabs['manage']=array('desc'=>'Manage','href'=>'helptopics.php','title'=>'Manage Options');
             $tabs['emails']=array('desc'=>'Emails','href'=>'emails.php','title'=>'Email Settings');
-            $tabs['topics']=array('desc'=>'Help&nbsp;Topics','href'=>'helptopics.php','title'=>'Help Topics');
-            $tabs['staff']=array('desc'=>'Staff','href'=>'staff.php','title'=>'Staff Members');
-            $tabs['depts']=array('desc'=>'Departments','href'=>'departments.php','title'=>'Departments');
+            $tabs['staff']=array('desc'=>'Staff','href'=>'staff.php','title'=>'Manage Staff');
             $this->tabs=$tabs;
         }
 
@@ -184,37 +193,32 @@ class AdminNav extends StaffNav{
                     $subnav[]=array('desc'=>'System&nbsp;Logs','href'=>'logs.php','iconclass'=>'logs');
                     break;
                 case 'settings':
-                    $subnav[]=array('desc'=>'Settings&nbsp;&amp;&nbsp;Preferences','href'=>'settings.php','iconclass'=>'preferences');
+                    $subnav[]=array('desc'=>'System&nbsp;Preferences','href'=>'settings.php?t=system','iconclass'=>'preferences');
+                    $subnav[]=array('desc'=>'Tickets','href'=>'settings.php?t=tickets','iconclass'=>'ticket-settings');
+                    $subnav[]=array('desc'=>'Emails','href'=>'settings.php?t=emails','iconclass'=>'email-settings');
+                    $subnav[]=array('desc'=>'Knowledgebase','href'=>'settings.php?t=kb','iconclass'=>'kb-settings');
+                    $subnav[]=array('desc'=>'Autoresponder','href'=>'settings.php?t=autoresp','iconclass'=>'email-autoresponders');
+                    $subnav[]=array('desc'=>'Alerts&nbsp;&amp;&nbsp;Notices','href'=>'settings.php?t=alerts','iconclass'=>'alert-settings');
+                    break;
+                case 'manage':
+                    $subnav[]=array('desc'=>'Help&nbsp;Topics','href'=>'helptopics.php','iconclass'=>'helpTopics');
+                    $subnav[]=array('desc'=>'Ticket&nbsp;Filters','href'=>'filters.php',
+                                        'title'=>'Ticket&nbsp;Filters','iconclass'=>'ticketFilters');
                     $subnav[]=array('desc'=>'SLA&nbsp;Plans','href'=>'slas.php','iconclass'=>'sla');
                     $subnav[]=array('desc'=>'API&nbsp;Keys','href'=>'apikeys.php','iconclass'=>'api');
                     break;
                 case 'emails':
-                    $subnav[]=array('desc'=>'Email&nbsp;Addresses','href'=>'emails.php','iconclass'=>'emailSettings');
-                    $subnav[]=array('desc'=>'Email&nbsp;Filters','href'=>'filters.php',
-                                        'title'=>'Email&nbsp;Filters','iconclass'=>'emailFilters');
-                    $subnav[]=array('desc'=>'Email&nbsp;Banlist','href'=>'banlist.php',
+                    $subnav[]=array('desc'=>'Emails','href'=>'emails.php', 'title'=>'Email Addresses', 'iconclass'=>'emailSettings');
+                    $subnav[]=array('desc'=>'Banlist','href'=>'banlist.php',
                                         'title'=>'Banned&nbsp;Emails','iconclass'=>'emailDiagnostic');
-                    $subnav[]=array('desc'=>'Email&nbsp;Templates','href'=>'templates.php','title'=>'Email Templates','iconclass'=>'emailTemplates');
-                    $subnav[]=array('desc'=>'Email&nbsp;Diagnostic','href'=>'emailtest.php','iconclass'=>'emailDiagnostic');
-                    break;
-                case 'topics':
-                    $subnav[]=array('desc'=>'Help&nbsp;Topics','href'=>'helptopics.php','iconclass'=>'helpTopics');
-                    $subnav[]=array('desc'=>'Add&nbsp;New&nbsp;Help&nbsp;Topics',
-                                    'href'=>'helptopics.php?a=add',
-                                    'iconclass'=>'newHelpTopic',
-                                    'droponly'=>true);
+                    $subnav[]=array('desc'=>'Templates','href'=>'templates.php','title'=>'Email Templates','iconclass'=>'emailTemplates');
+                    $subnav[]=array('desc'=>'Diagnostic','href'=>'emailtest.php', 'title'=>'Email Diagnostic', 'iconclass'=>'emailDiagnostic');
                     break;
                 case 'staff':
                     $subnav[]=array('desc'=>'Staff&nbsp;Members','href'=>'staff.php','iconclass'=>'users');
                     $subnav[]=array('desc'=>'Teams','href'=>'teams.php','iconclass'=>'teams');
                     $subnav[]=array('desc'=>'Groups','href'=>'groups.php','iconclass'=>'groups');
-                    break;
-                case 'depts':
                     $subnav[]=array('desc'=>'Departments','href'=>'departments.php','iconclass'=>'departments');
-                    $subnav[]=array('desc'=>'Add&nbsp;New&nbsp;Department',
-                                    'href'=>'departments.php?a=add',
-                                    'iconclass'=>'newDepartment',
-                                    'droponly'=>true);
                     break;
             }
             if($subnav)
diff --git a/include/class.pdf.php b/include/class.pdf.php
index 2257dcc17aa6641fabeeac32a3fcecc28bd7b2c0..17c2e05886538028468952af9518e2695e51793f 100644
--- a/include/class.pdf.php
+++ b/include/class.pdf.php
@@ -82,12 +82,24 @@ class Ticket2PDF extends FPDF
 		$this->Cell(0, 7, 'Page ' . ($this->PageNo() - $this->pageOffset), 0, 0, 'R');
 	}
 
+    function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') {
+        parent::Cell($w, $h, $this->_utf8($txt), $border, $ln, $align, $fill, $link);
+    }
+
     function WriteText($w, $text, $border) {
 
         $this->SetFont('Times','',11);
         $this->MultiCell($w, 5, $text, $border, 'L');
 
     }
+
+    function _utf8($text) {
+
+        if(function_exists('iconv'))
+            return iconv('UTF-8', 'windows-1252', $text);
+        
+        return utf8_encode($text);
+    }
     
     function _print() {
 
@@ -95,7 +107,7 @@ class Ticket2PDF extends FPDF
             return;
 
         $w =(($this->w/2)-$this->lMargin);
-        $l = 40;
+        $l = 35;
         $c = $w-$l;
         $this->SetDrawColor(220, 220, 220);
         $this->SetFillColor(244, 250, 255);
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 8b9581d532a1e94c8076d3eca0b82bcfe88d7d0e..fc7eb1c520d45dfaab47ee3d7cd61db4f78f2eba 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1331,7 +1331,7 @@ class Ticket{
         if($newticket) return $msgid; //Our work is done...
 
         $autorespond = true;
-        if ($autorespond && $headers && EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($headers)))
+        if ($autorespond && $headers && TicketFilter::isAutoResponse(Mail_Parse::splitHeaders($headers)))
             $autorespond=false;
 
         $this->onMessage($autorespond); //must be called b4 sending alerts to staff.
@@ -1845,7 +1845,7 @@ class Ticket{
         if ($vars['email']  && Validator::is_email($vars['email'])) {
 
             //Make sure the email address is not banned
-            if(EmailFilter::isBanned($vars['email'])) {
+            if(TicketFilter::isBanned($vars['email'])) {
                 $errors['err']='Ticket denied. Error #403';
                 $ost->logWarning('Ticket denied', 'Banned email - '.$vars['email']);
                 return 0;
@@ -1865,12 +1865,15 @@ class Ticket{
                 return 0;
             }
         }
+
+        //Init ticket filters...
+        $ticket_filter = new TicketFilter($origin, $vars);
         // Make sure email contents should not be rejected
-        if (($email_filter=new EmailFilter($vars))
-                && ($filter=$email_filter->shouldReject())) {
+        if($ticket_filter 
+                && ($filter=$ticket_filter->shouldReject())) {
             $errors['err']='Ticket denied. Error #403';
             $ost->logWarning('Ticket denied', 
-                    sprintf('Banned email - %s by filter "%s"', 
+                    sprintf('Ticket rejected ( %s) by filter "%s"', 
                         $vars['email'], $filter->getName()));
 
             return 0;
@@ -1915,7 +1918,7 @@ class Ticket{
         }
 
         //Make sure the due date is valid
-        if($vars['duedate']){
+        if($vars['duedate']) {
             if(!$vars['time'] || strpos($vars['time'],':')===false)
                 $errors['time']='Select time';
             elseif(strtotime($vars['duedate'].' '.$vars['time'])===false)
@@ -1924,16 +1927,16 @@ class Ticket{
                 $errors['duedate']='Due date must be in the future';
         }
 
-        # Perform email filter actions on the new ticket arguments XXX: Move filter to the top and check for reject...
-        if (!$errors && $email_filter) $email_filter->apply($vars);
+        //Any error above is fatal.
+        if($errors)  return 0;
+
+        # Perform ticket filter actions on the new ticket arguments
+        if ($ticket_filter) $ticket_filter->apply($vars);
 
         # Some things will need to be unpacked back into the scope of this
         # function
         if (isset($vars['autorespond'])) $autorespond=$vars['autorespond'];
 
-        //Any error above is fatal.
-        if($errors)  return 0;
-        
         // OK...just do it.
         $deptId=$vars['deptId']; //pre-selected Dept if any.
         $priorityId=$vars['priorityId'];
@@ -1951,11 +1954,7 @@ class Ticket{
             if($autorespond) $autorespond=$email->autoRespond();
             $email=null;
             $source='Email';
-        }elseif($vars['deptId']){ //Opened by staff.
-            $deptId=$vars['deptId'];
-            $source=ucfirst($vars['source']);
         }
-
         //Last minute checks
         $priorityId=$priorityId?$priorityId:$cfg->getDefaultPriorityId();
         $deptId=$deptId?$deptId:$cfg->getDefaultDeptId();
@@ -2019,7 +2018,7 @@ class Ticket{
         # Messages that are clearly auto-responses from email systems should
         # not have a return 'ping' message
         if ($autorespond && $vars['header'] &&
-                EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) {
+                TicketFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) {
             $autorespond=false;
         }
 
diff --git a/include/client/header.inc.php b/include/client/header.inc.php
index da763a7bbf7b1e5b9481b8d26a0dfca2c79a9997..81191f98b7dacefb7bc34ba03d6b53920d9d16a7 100644
--- a/include/client/header.inc.php
+++ b/include/client/header.inc.php
@@ -10,7 +10,7 @@ header("Content-Type: text/html; charset=UTF-8\r\n");
     <meta name="description" content="customer support platform">
     <meta name="keywords" content="osTicket, Customer support system, support ticket system">
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-    <link rel="stylesheet" href="<?php echo ASSETS_PATH; ?>css/theme.css" media="screen">
+    <link rel="stylesheet" href="<?php echo ASSETS_PATH; ?>css/theme.min.css" media="screen">
     <link rel="stylesheet" href="<?php echo ASSETS_PATH; ?>css/print.css" media="print">
     <script src="<?php echo ROOT_PATH; ?>js/jquery-1.7.2.min.js"></script>
     <script src="<?php echo ROOT_PATH; ?>js/jquery.multifile.js"></script>
diff --git a/include/staff/banlist.inc.php b/include/staff/banlist.inc.php
index 0b61d1e8b779edaf48c448c82eb38c3d1ce3deed..b2b37b284b0ae4de0750650b2feb9fae2135cf5d 100644
--- a/include/staff/banlist.inc.php
+++ b/include/staff/banlist.inc.php
@@ -3,7 +3,7 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$filter)
 
 $qstr='';
 $select='SELECT rule.* ';
-$from='FROM '.EMAIL_FILTER_RULE_TABLE.' rule ';
+$from='FROM '.FILTER_RULE_TABLE.' rule ';
 $where='WHERE rule.filter_id='.db_input($filter->getId());
 $search=false;
 if($_REQUEST['q'] && strlen($_REQUEST['q'])>3) {
diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php
index c2aad0bcf4456d5bade4fa323a4ba3c991c39929..36186838bd93cdba6977add500645becba4d673e 100644
--- a/include/staff/filter.inc.php
+++ b/include/staff/filter.inc.php
@@ -33,7 +33,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
         <tr>
             <th colspan="2">
                 <h4><?php echo $title; ?></h4>
-                <em>Filters are executed based on execution order.</em>
+                <em>Filters are executed based on execution order. Filter can target specific ticket source.</em>
             </th>
         </tr>
     </thead>
@@ -71,31 +71,37 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
         </tr>
         <tr>
-            <td width="180">
-                To Email Address:
+            <td width="180" class="required">
+                Target:
             </td>
             <td>
-                <select name="email_id">
-                    <option value="0">&mdash; Filter applies to ALL incoming emails &dash;</option>
-                    <?php
+                <select name="target">
+                   <option value="">&mdash; Select a Target &dash;</option>
+                   <?php
+                   foreach(Filter::getTargets() as $k => $v) {
+                       echo sprintf('<option value="%s" %s>%s</option>',
+                               $k, (($k==$info['target'])?'selected="selected"':''), $v);
+                    }
                     $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE.' email ORDER by name';
-                    if(($res=db_query($sql)) && db_num_rows($res)){
-                        while(list($id,$email,$name)=db_fetch_row($res)){
+                    if(($res=db_query($sql)) && db_num_rows($res)) {
+                        echo '<OPTGROUP label="Specific System Email">';
+                        while(list($id,$email,$name)=db_fetch_row($res)) {
                             $selected=($info['email_id'] && $id==$info['email_id'])?'selected="selected"':'';
                             if($name)
                                 $email=Format::htmlchars("$name <$email>");
                             echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$email);
                         }
+                        echo '</OPTGROUP>';
                     }
                     ?>
                 </select>
-                <br><em>(Highly recommended if the filter is specific to one incoming email address)</em>
+                &nbsp;
+                <span class="error">*&nbsp;<?php echo $errors['target']; ?></span>
             </td>
         </tr>
         <tr>
             <th colspan="2">
-                <em><strong>Filter Rules</strong>: Rules are applied based on the criteria.&nbsp;
-                    <span class="error">*&nbsp;<?php echo $errors['rules']; ?></span></em>
+                <em><strong>Filter Rules</strong>: Rules are applied based on the criteria.&nbsp;<span class="error">*&nbsp;<?php echo $errors['rules']; ?></span></em>
             </th>
         </tr>
         <tr>
@@ -156,11 +162,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
         </tr>
         <tr>
             <td width="180">
-                Ban Email:
+                Reject Ticket:
             </td>
             <td>
-                <input type="checkbox" name="reject_email" value="1" <?php echo $info['reject_email']?'checked="checked"':''; ?> >
-                    <strong><font class="error">Reject email</font></strong> <em>(All other actions, rules and filters are ignored)</em>
+                <input type="checkbox" name="reject_ticket" value="1" <?php echo $info['reject_ticket']?'checked="checked"':''; ?> >
+                    <strong><font class="error">Reject Ticket</font></strong> <em>(All other actions and filters are ignored)</em>
             </td>
         </tr>
         <tr>
diff --git a/include/staff/filters.inc.php b/include/staff/filters.inc.php
index 7f3aab393f56cb3b1eb3f8dc3da0113204d35e41..7573eceec7d3a82950a52e9e04ce2fce213754e8 100644
--- a/include/staff/filters.inc.php
+++ b/include/staff/filters.inc.php
@@ -1,13 +1,13 @@
 <?php
 if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied');
-
+$targets = Filter::getTargets();
 $qstr='';
 $sql='SELECT filter.*,count(rule.id) as rules '.
-     'FROM '.EMAIL_FILTER_TABLE.' filter '.
-     'LEFT JOIN '.EMAIL_FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '.
+     'FROM '.FILTER_TABLE.' filter '.
+     'LEFT JOIN '.FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '.
      'GROUP BY filter.id';
 $sortOptions=array('name'=>'filter.name','status'=>'filter.isactive','order'=>'filter.execorder','rules'=>'rules',
-                   'created'=>'filter.created','updated'=>'filter.updated');
+                   'target'=>'filter.target', 'created'=>'filter.created','updated'=>'filter.updated');
 $orderWays=array('DESC'=>'DESC','ASC'=>'ASC');
 $sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name';
 //Sorting options...
@@ -28,7 +28,7 @@ $x=$sort.'_sort';
 $$x=' class="'.strtolower($order).'" ';
 $order_by="$order_column $order ";
 
-$total=db_count('SELECT count(*) FROM '.EMAIL_FILTER_TABLE.' filter ');
+$total=db_count('SELECT count(*) FROM '.FILTER_TABLE.' filter ');
 $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1;
 $pageNav=new Pagenate($total, $page, PAGE_LIMIT);
 $pageNav->setURL('filters.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order']));
@@ -44,7 +44,7 @@ else
 ?>
 
 <div style="width:700;padding-top:5px; float:left;">
- <h2>Email Filters</h2>
+ <h2>Ticket Filters</h2>
 </div>
 <div style="float:right;text-align:right;padding-top:5px;padding-right:5px;">
  <b><a href="filters.php?a=add" class="Icon newEmailFilter">Add New Filter</a></b></div>
@@ -58,9 +58,10 @@ else
         <tr>
             <th width="7">&nbsp;</th>        
             <th width="320"><a <?php echo $name_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=name">Name</a></th>
-            <th width="100"><a  <?php echo $status_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=status">Status</a></th>
+            <th width="80"><a  <?php echo $status_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=status">Status</a></th>
             <th width="80" style="text-align:center;"><a  <?php echo $order_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=order">Order</a></th>
             <th width="80" style="text-align:center;"><a  <?php echo $rules_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=rules">Rules</a></th>
+            <th width="100"><a  <?php echo $target_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=target">Target</a></th>
             <th width="120" nowrap><a  <?php echo $created_sort; ?>href="filters.php?<?php echo $qstr; ?>&sort=created">Date Added</a></th>
             <th width="150" nowrap><a  <?php echo $updated_sort; ?>href="filters.php?<?php echo $qstr; ?>&sort=updated">Last Updated</a></th>
         </tr>
@@ -85,6 +86,7 @@ else
                 <td><?php echo $row['isactive']?'Active':'<b>Disabled</b>'; ?></td>
                 <td style="text-align:right;padding-right:25px;"><?php echo $row['execorder']; ?>&nbsp;</td>
                 <td style="text-align:right;padding-right:25px;"><?php echo $row['rules']; ?>&nbsp;</td>
+                <td>&nbsp;<?php echo Format::htmlchars($targets[$row['target']]); ?></td>
                 <td>&nbsp;<?php echo Format::db_date($row['created']); ?></td>
                 <td>&nbsp;<?php echo Format::db_datetime($row['updated']); ?></td>
             </tr>
@@ -93,7 +95,7 @@ else
         endif; ?>
     <tfoot>
      <tr>
-        <td colspan="7">
+        <td colspan="8">
             <?php if($res && $num){ ?>
             Select:&nbsp;
             <a href="#" onclick="return select_all(document.forms['filters'],true)">All</a>&nbsp;&nbsp;
diff --git a/include/staff/login.tpl.php b/include/staff/login.tpl.php
index 2d8a41f650601c2ec8396ecb89a8ea5ac90a4790..2b4d21ad015f1e2d6124c8a3422572bcce53d91e 100644
--- a/include/staff/login.tpl.php
+++ b/include/staff/login.tpl.php
@@ -9,6 +9,12 @@
     <meta http-equiv="cache-control" content="no-cache" />
     <meta http-equiv="pragma" content="no-cache" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <script type="text/javascript" src="../js/jquery-1.7.2.min.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function() {
+            $("input:not(.dp):visible:enabled:first").focus();
+         });
+    </script>
 </head>
 <body id="loginBody">
 <div id="loginBox">
diff --git a/include/staff/settings-alerts.inc.php b/include/staff/settings-alerts.inc.php
index 5bb5d393246ede7266440c30a7e9f5e41df8cc8e..cc91ffdf804fce3dad988a6e11139a1b259d60c8 100644
--- a/include/staff/settings-alerts.inc.php
+++ b/include/staff/settings-alerts.inc.php
@@ -1,102 +1,177 @@
+<h2>Alerts and Notices</h2>
 <form action="settings.php?t=alerts" method="post" id="save">
 <?php csrf_token(); ?>
 <input type="hidden" name="t" value="alerts" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
         <tr>
-            <th colspan="2">
-                <h4>Alerts and Notices Setting</h4>
-                <em>Alerts sent to staff on ticket "events". Staff assignment takes precedence over team assignment.</em>
+            <th>
+                <h4>Alerts and Notices sent to staff on ticket "events"</h4>
             </th>
         </tr>
     </thead>
     <tbody>
+        <tr><th><em><b>New Ticket Alert</b>: Alert sent out on new tickets</em></th></tr>
         <tr>
-            <td width="160">New Ticket Alert:</td>
-            <td>
+            <td><em><b>Status:</b></em> &nbsp;
                 <input type="radio" name="ticket_alert_active"  value="1"   <?php echo $config['ticket_alert_active']?'checked':''; ?> />Enable
                 <input type="radio" name="ticket_alert_active"  value="0"   <?php echo !$config['ticket_alert_active']?'checked':''; ?> />Disable
-                &nbsp;&nbsp;<em>Alert sent out on new tickets <font class="error">&nbsp;<?php echo $errors['ticket_alert_active']; ?></font></em><br>
-                <strong>Recipients</strong>:&nbsp;
-                <input type="checkbox" name="ticket_alert_admin" <?php echo $config['ticket_alert_admin']?'checked':''; ?>> Admin Email
+                &nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['ticket_alert_active']; ?></font></em>
+             </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="checkbox" name="ticket_alert_admin" <?php echo $config['ticket_alert_admin']?'checked':''; ?>> Admin Email <em>(<?php echo $cfg->getAdminEmail(); ?>)</em>
+            </td>
+        </tr>
+        <tr>    
+            <td>
                 <input type="checkbox" name="ticket_alert_dept_manager" <?php echo $config['ticket_alert_dept_manager']?'checked':''; ?>> Department Manager
-                <input type="checkbox" name="ticket_alert_dept_members" <?php echo $config['ticket_alert_dept_members']?'checked':''; ?>> Department Members (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">New Message Alert:</td>
             <td>
+                <input type="checkbox" name="ticket_alert_dept_members" <?php echo $config['ticket_alert_dept_members']?'checked':''; ?>> Department Members <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>New Message Alert</b>: Alert sent out when a new message, from the user, is appended to an existing ticket</em></th></tr>
+        <tr>
+            <td><em><b>Status:</b></em> &nbsp; 
               <input type="radio" name="message_alert_active"  value="1"   <?php echo $config['message_alert_active']?'checked':''; ?> />Enable
+              &nbsp;&nbsp;
               <input type="radio" name="message_alert_active"  value="0"   <?php echo !$config['message_alert_active']?'checked':''; ?> />Disable
-              &nbsp;&nbsp;<em>Alert sent out when a new message is appended to an existing ticket <font class="error">&nbsp;<?php echo $errors['message_alert_active']; ?></font></em><br>
-              <strong>Recipients</strong>:&nbsp;
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="message_alert_laststaff" <?php echo $config['message_alert_laststaff']?'checked':''; ?>> Last Respondent
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="message_alert_assigned" <?php echo $config['message_alert_assigned']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox" name="message_alert_dept_manager" <?php echo $config['message_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">New Internal Note Alert:</td>
             <td>
+              <input type="checkbox" name="message_alert_dept_manager" <?php echo $config['message_alert_dept_manager']?'checked':''; ?>> Department Manager <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>New Internal Note Alert</b>: Alert sent out when a new internal note is posted.</em></th></tr>
+        <tr>
+            <td><em><b>Status:</b></em> &nbsp;
               <input type="radio" name="note_alert_active"  value="1"   <?php echo $config['note_alert_active']?'checked':''; ?> />Enable
+              &nbsp;&nbsp;
               <input type="radio" name="note_alert_active"  value="0"   <?php echo !$config['note_alert_active']?'checked':''; ?> />Disable
-               &nbsp;&nbsp;<em>Alert sent out when a new internal note is posted &nbsp;<font class="error">&nbsp;<?php echo $errors['note_alert_active']; ?></font></em><br>
-              <strong>Recipients</strong>:&nbsp;
+              &nbsp;&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['note_alert_active']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="note_alert_laststaff" <?php echo $config['note_alert_laststaff']?'checked':''; ?>> Last Respondent
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="note_alert_assigned" <?php echo $config['note_alert_assigned']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox" name="note_alert_dept_manager" <?php echo $config['note_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">Ticket Assignment Alert:</td>
             <td>
+              <input type="checkbox" name="note_alert_dept_manager" <?php echo $config['note_alert_dept_manager']?'checked':''; ?>> Department Manager <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>Ticket Assignment Alert</b>: Alert sent out to staff on ticket assignment.</em></th></tr>
+        <tr>
+            <td><em><b>Status: </b></em> &nbsp;
               <input name="assigned_alert_active" value="1" checked="checked" type="radio">Enable
+              &nbsp;&nbsp;
               <input name="assigned_alert_active" value="0" type="radio">Disable
-               &nbsp;&nbsp;<em>Alert sent out to staff on ticket assignment &nbsp;<font class="error">&nbsp;<?php echo $errors['assigned_alert_active']; ?></font></em><br>
-              <strong>Recipients</strong>:&nbsp;
+               &nbsp;&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['assigned_alert_active']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="assigned_alert_staff" <?php echo $config['assigned_alert_staff']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox"name="assigned_alert_team_lead" <?php echo $config['assigned_alert_team_lead']?'checked':''; ?>>Team Lead (Team assignment)
-              <input type="checkbox"name="assigned_alert_team_members" <?php echo $config['assigned_alert_team_members']?'checked':''; ?>>
-                Team Members (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">Ticket Transfer Alert:</td>
             <td>
+              <input type="checkbox"name="assigned_alert_team_lead" <?php echo $config['assigned_alert_team_lead']?'checked':''; ?>>Team Lead <em>(On team assignment)</em>
+            </td>
+        </tr>
+        <tr>
+            <td>
+              <input type="checkbox"name="assigned_alert_team_members" <?php echo $config['assigned_alert_team_members']?'checked':''; ?>>
+                Team Members <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>Ticket Transfer Alert</b>: Alert sent out to staff of the target department on ticket transfer.</em></th></tr>
+        <tr>
+            <td><em><b>Status:</b></em> &nbsp;
               <input type="radio" name="transfer_alert_active"  value="1"   <?php echo $config['transfer_alert_active']?'checked':''; ?> />Enable
               <input type="radio" name="transfer_alert_active"  value="0"   <?php echo !$config['transfer_alert_active']?'checked':''; ?> />Disable
-              &nbsp;&nbsp;<em>Alert sent out to staff on ticket transfer&nbsp;<font class="error">&nbsp;
-<?php echo $errors['alert_alert_active']; ?></font></em><br>
-              <strong>Recipients</strong>:&nbsp;
+              &nbsp;&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['alert_alert_active']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="transfer_alert_assigned" <?php echo $config['transfer_alert_assigned']?'checked':''; ?>> Assigned Staff/Team
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="transfer_alert_dept_manager" <?php echo $config['transfer_alert_dept_manager']?'checked':''; ?>> Department Manager
-              <input type="checkbox" name="transfer_alert_dept_members" <?php echo $config['transfer_alert_dept_members']?'checked':''; ?>> Department Members
- (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">Overdue Ticket Alert:</td>
             <td>
+              <input type="checkbox" name="transfer_alert_dept_members" <?php echo $config['transfer_alert_dept_members']?'checked':''; ?>>
+                Department Members <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>Overdue Ticket Alert</b>: Alert sent out when a ticket becomes overdue - admin email gets an alert by default.</em></th></tr>
+        <tr>
+            <td><em><b>Status:</b></em> &nbsp;
               <input type="radio" name="overdue_alert_active"  value="1"   <?php echo $config['overdue_alert_active']?'checked':''; ?> />Enable
               <input type="radio" name="overdue_alert_active"  value="0"   <?php echo !$config['overdue_alert_active']?'checked':''; ?> />Disable
-              &nbsp;&nbsp;<em>Alert sent out when a ticket becomes overdue - admin email gets an alert by default. &nbsp;<font class="error">&nbsp;<?php echo $errors['overdue_alert_active']; ?></font></em><br>
-              <strong>Recipients</strong>:&nbsp;
+              &nbsp;&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['overdue_alert_active']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="overdue_alert_assigned" <?php echo $config['overdue_alert_assigned']?'checked':''; ?>> Assigned Staff/Team
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="overdue_alert_dept_manager" <?php echo $config['overdue_alert_dept_manager']?'checked':''; ?>> Department Manager
-              <input type="checkbox" name="overdue_alert_dept_members" <?php echo $config['overdue_alert_dept_members']?'checked':''; ?>> Department Members (spammy)
             </td>
         </tr>
         <tr>
-            <td width="160">System Alerts:</td>
-            <td><em><b>Enabled</b>: Errors are sent to system admin email (<?php echo $cfg->getAdminEmail(); ?>)</em><br>
+            <td>
+              <input type="checkbox" name="overdue_alert_dept_members" <?php echo $config['overdue_alert_dept_members']?'checked':''; ?>> Department Members <em>(spammy)</em>
+            </td>
+        </tr>
+        <tr><th><em><b>System Alerts</b>: Enabled by default. Errors are sent to system admin email (<?php echo $cfg->getAdminEmail(); ?>)</em></th></tr>
+        <tr>
+            <td>
               <input type="checkbox" name="send_sys_errors" checked="checked" disabled="disabled">System Errors
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="send_sql_errors" <?php echo $config['send_sql_errors']?'checked':''; ?>>SQL errors
+            </td>
+        </tr>
+        <tr>
+            <td>
               <input type="checkbox" name="send_login_errors" <?php echo $config['send_login_errors']?'checked':''; ?>>Excessive Login attempts
             </td>
         </tr>
     </tbody>
 </table>
-<p style="padding-left:200px;">
+<p style="padding-left:350px;">
     <input class="button" type="submit" name="submit" value="Save Changes">
     <input class="button" type="reset" name="reset" value="Reset Changes">
 </p>
diff --git a/include/staff/settings-attachments.inc.php b/include/staff/settings-attachments.inc.php
deleted file mode 100644
index b381fa40d334f9f2c9077f91698c6ec90aa31491..0000000000000000000000000000000000000000
--- a/include/staff/settings-attachments.inc.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-if(!($maxfileuploads=ini_get('max_file_uploads')))
-    $maxfileuploads=DEFAULT_MAX_FILE_UPLOADS;
-
-?>
-<form action="settings.php?t=attachments" method="post" id="save">
-<?php csrf_token(); ?>
-<input type="hidden" name="t" value="attachments" >
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4>Attachments Settings</h4>
-                <em> Before enabling attachments make sure you understand PHP file upload settings and security issues related to file upload.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="180">Allow Attachments:</td>
-            <td>
-              <input type="checkbox" name="allow_attachments" <?php echo $config['allow_attachments']?'checked="checked"':''; ?>><b>Allow Attachments</b>
-                &nbsp; <em>(Global Setting)</em>
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['allow_attachments']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Emailed Attachments:</td>
-            <td>
-                <input type="checkbox" name="allow_email_attachments" <?php echo $config['allow_email_attachments']?'checked="checked"':''; ?>> Accept emailed files
-                    &nbsp;<font class="error">&nbsp;<?php echo $errors['allow_email_attachments']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Online Attachments:</td>
-            <td>
-                <input type="checkbox" name="allow_online_attachments" <?php echo $config['allow_online_attachments']?'checked="checked"':''; ?> >
-                    Allow web upload &nbsp;&nbsp;&nbsp;&nbsp;
-                <input type="checkbox" name="allow_online_attachments_onlogin" <?php echo $config['allow_online_attachments_onlogin'] ?'checked="checked"':''; ?> >
-                    Limit to authenticated users only. <em>(User must be logged in to upload files)</em>
-                    <font class="error">&nbsp;<?php echo $errors['allow_online_attachments']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td>Max. User File Uploads:</td>
-            <td>
-                <select name="max_user_file_uploads">
-                    <?php
-                    for($i = 1; $i <=$maxfileuploads; $i++) {
-                        ?>
-                        <option <?php echo $config['max_user_file_uploads']==$i?'selected="selected"':''; ?> value="<?php echo $i; ?>">
-                            <?php echo $i; ?>&nbsp;<?php echo ($i>1)?'files':'file'; ?></option>
-                        <?php
-                    } ?>
-                </select>
-                <em>(Number of files the user is allowed to upload simultaneously)</em>
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['max_user_file_uploads']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td>Max. Staff File Uploads:</td>
-            <td>
-                <select name="max_staff_file_uploads">
-                    <?php
-                    for($i = 1; $i <=$maxfileuploads; $i++) {
-                        ?>
-                        <option <?php echo $config['max_staff_file_uploads']==$i?'selected="selected"':''; ?> value="<?php echo $i; ?>">
-                            <?php echo $i; ?>&nbsp;<?php echo ($i>1)?'files':'file'; ?></option>
-                        <?php
-                    } ?>
-                </select>
-                <em>(Number of files the staff is allowed to upload simultaneously)</em>
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['max_staff_file_uploads']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Maximum File Size:</td>
-            <td>
-                <input type="text" name="max_file_size" value="<?php echo $config['max_file_size']; ?>"> in bytes.
-                    <em>(Max <?php echo Format::file_size(ini_get('upload_max_filesize')); ?>)</em>
-                    <font class="error">&nbsp;<?php echo $errors['max_file_size']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Ticket Response Files:</td>
-            <td>
-                <input type="checkbox" name="email_attachments" <?php echo $config['email_attachments']?'checked="checked"':''; ?> >Email attachments to the user
-            </td>
-        </tr>
-        <tr>
-            <th colspan="2">
-                <em><strong>Accepted File Types</strong>: Limit the type of files users are allowed to upload.
-                <font class="error">&nbsp;<?php echo $errors['allowed_filetypes']; ?></font></em>
-            </th>
-        </tr>
-        <tr>
-            <td colspan="2">
-                <em>Enter allowed file extensions separated by a comma. e.g .doc, .pdf. To accept all files enter wildcard <b><i>.*</i></b>&nbsp;i.e dotStar (NOT Recommended).</em><br>
-                <textarea name="allowed_filetypes" cols="21" rows="4" style="width: 65%;" wrap="hard" ><?php echo $config['allowed_filetypes']; ?></textarea>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<p style="padding-left:210px;">
-    <input class="button" type="submit" name="submit" value="Save Changes">
-    <input class="button" type="reset" name="reset" value="Reset Changes">
-</p>
-</form>
diff --git a/include/staff/settings-autoresponders.inc.php b/include/staff/settings-autoresp.inc.php
similarity index 93%
rename from include/staff/settings-autoresponders.inc.php
rename to include/staff/settings-autoresp.inc.php
index 106e7f3f4d7063a6bcb4835cdbd07006b6f16b5c..b5815915fc346bb97fbfa318db9416bda6bfccce 100644
--- a/include/staff/settings-autoresponders.inc.php
+++ b/include/staff/settings-autoresp.inc.php
@@ -1,6 +1,7 @@
-<form action="settings.php?t=autoresponders" method="post" id="save">
+<h2>Autoresponder Settings</h2>
+<form action="settings.php?t=autoresp" method="post" id="save">
 <?php csrf_token(); ?>
-<input type="hidden" name="t" value="autoresponders" >
+<input type="hidden" name="t" value="autoresp" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
         <tr>
diff --git a/include/staff/settings-dates.inc.php b/include/staff/settings-dates.inc.php
deleted file mode 100644
index 9aa493a7573f535b2d49e087158625c8173b0af7..0000000000000000000000000000000000000000
--- a/include/staff/settings-dates.inc.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-$gmtime=Misc::gmtime();
-
-?>
-<form action="settings.php?t=dates" method="post" id="save">
-<?php csrf_token(); ?>
-<input type="hidden" name="t" value="dates" >
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4>Date and Time Options</h4>
-                <em>Please refer to <a href="http://php.net/date" target="_blank">PHP Manual</a> for supported parameters.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr><td width="220" class="required">Time Format:</td>
-            <td>
-                <input type="text" name="time_format" value="<?php echo $config['time_format']; ?>">
-                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['time_format']; ?></font>
-                    <em><?php echo Format::date($config['time_format'],$gmtime,$config['tz_offset'],$config['enable_daylight_saving']); ?></em></td>
-        </tr>
-        <tr><td width="220" class="required">Date Format:</td>
-            <td><input type="text" name="date_format" value="<?php echo $config['date_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['date_format']; ?></font>
-                        <em><?php echo Format::date($config['date_format'],$gmtime,$config['tz_offset'],$config['enable_daylight_saving']); ?></em>
-            </td>
-        </tr>
-        <tr><td width="220" class="required">Date &amp; Time Format:</td>
-            <td><input type="text" name="datetime_format" value="<?php echo $config['datetime_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['datetime_format']; ?></font>
-                        <em><?php echo Format::date($config['datetime_format'],$gmtime,$config['tz_offset'],$config['enable_daylight_saving']); ?></em>
-            </td>
-        </tr>
-        <tr><td width="220" class="required">Day, Date &amp; Time Format:</td>
-            <td><input type="text" name="daydatetime_format" value="<?php echo $config['daydatetime_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['daydatetime_format']; ?></font>
-                        <em><?php echo Format::date($config['daydatetime_format'],$gmtime,$config['tz_offset'],$config['enable_daylight_saving']); ?></em>
-            </td>
-        </tr>
-        <tr><td width="220" class="required">Default Time Zone:</td>
-            <td>
-                <select name="default_timezone_id">
-                    <option value="">&mdash; Select Default Time Zone &mdash;</option>
-                    <?php
-                    $sql='SELECT id, offset,timezone FROM '.TIMEZONE_TABLE.' ORDER BY id';
-                    if(($res=db_query($sql)) && db_num_rows($res)){
-                        while(list($id,$offset, $tz)=db_fetch_row($res)){
-                            $sel=($config['default_timezone_id']==$id)?'selected="selected"':'';
-                            echo sprintf('<option value="%d" %s>GMT %s - %s</option>',$id,$sel,$offset,$tz);
-                        }
-                    }
-                    ?>
-                </select>
-                &nbsp;<font class="error">*&nbsp;<?php echo $errors['default_timezone_id']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">Daylight Saving:</td>
-            <td>
-                <input type="checkbox" name="enable_daylight_saving" <?php echo $config['enable_daylight_saving'] ? 'checked="checked"': ''; ?>>Observe daylight savings
-            </td>
-        </tr>
-    </tbody>
-</table>
-<p style="padding-left:250px;">
-    <input class="button" type="submit" name="submit" value="Save Changes">
-    <input class="button" type="reset" name="reset" value="Reset Changes">
-</p>
-</form>
diff --git a/include/staff/settings-emails.inc.php b/include/staff/settings-emails.inc.php
index e4ccaf3a4e69329c15d474bfd3f136f9a8fe17f9..f8674095d49cfe25102ef682e64bb9df59e1614a 100644
--- a/include/staff/settings-emails.inc.php
+++ b/include/staff/settings-emails.inc.php
@@ -1,110 +1,118 @@
-<form action="settings.php?t=emails" method="post" id="save">
+<?php
+if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) die('Access Denied');
+?>
+<h2>Email Settings and Options</h2>
+<form action="settings.php?t=emails" method="post" id="save">
 <?php csrf_token(); ?>
-<input type="hidden" name="t" value="emails" >
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4>Email Settings</h4>
-                <em>Note that some of the global settings can be overwritten at department/email level.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="180" class="required">Default System Email:</td>
-            <td>
-                <select name="default_email_id">
-                    <option value=0 disabled>Select One</option>
+<input type="hidden" name="t" value="emails" >
+<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
+    <thead>
+        <tr>
+            <th colspan="2">
+                <h4>Email Settings</h4>
+                <em>Note that some of the global settings can be overwritten at department/email level.</em>
+            </th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <td width="180" class="required">Default System Email:</td>
+            <td>
+                <select name="default_email_id">
+                    <option value=0 disabled>Select One</option>
                     <?php
-                    $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE;
-                    if(($res=db_query($sql)) && db_num_rows($res)){
-                        while (list($id,$email,$name) = db_fetch_row($res)){
-                            $email=$name?"$name &lt;$email&gt;":$email;
-                            ?>
-                            <option value="<?php echo $id; ?>"<?php echo ($config['default_email_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
+                    $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE;
+                    if(($res=db_query($sql)) && db_num_rows($res)){
+                        while (list($id,$email,$name) = db_fetch_row($res)){
+                            $email=$name?"$name &lt;$email&gt;":$email;
+                            ?>
+                            <option value="<?php echo $id; ?>"<?php echo ($config['default_email_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
                         <?php
-                        }
-                    } ?>
-                 </select>
-                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['default_email_id']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180" class="required">Default Alert Email:</td>
-            <td>
-                <select name="alert_email_id">
-                    <option value="0" selected="selected">Use Default System Email (above)</option>
+                        }
+                    } ?>
+                 </select>
+                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['default_email_id']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180" class="required">Default Alert Email:</td>
+            <td>
+                <select name="alert_email_id">
+                    <option value="0" selected="selected">Use Default System Email (above)</option>
                     <?php
-                    $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE.' WHERE email_id != '.db_input($config['default_email_id']);
-                    if(($res=db_query($sql)) && db_num_rows($res)){
-                        while (list($id,$email,$name) = db_fetch_row($res)){
-                            $email=$name?"$name &lt;$email&gt;":$email;
-                            ?>
-                            <option value="<?php echo $id; ?>"<?php echo ($config['alert_email_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
+                    $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE.' WHERE email_id != '.db_input($config['default_email_id']);
+                    if(($res=db_query($sql)) && db_num_rows($res)){
+                        while (list($id,$email,$name) = db_fetch_row($res)){
+                            $email=$name?"$name &lt;$email&gt;":$email;
+                            ?>
+                            <option value="<?php echo $id; ?>"<?php echo ($config['alert_email_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
                         <?php
-                        }
-                    } ?>
-                 </select>
-                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['alert_email_id']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180" class="required">Admin Email Address:</td>
-            <td>
-                <input type="text" size=40 name="admin_email" value="<?php echo $config['admin_email']; ?>">
-                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['admin_email']; ?></font></td>
-        </tr>
-        <tr><th colspan=2><em><strong>Incoming Emails</strong>: For mail fetcher (POP/IMAP) to work you must set a cron job or enable auto-cron</em></th>
-        <tr>
-            <td width="180">Email Polling:</td>
-            <td><input type="checkbox" name="enable_mail_polling" value=1 <?php echo $config['enable_mail_polling']? 'checked="checked"': ''; ?>  > Enable POP/IMAP
-                 &nbsp;&nbsp;<em>(Global setting which can be disabled at email level)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Email Piping:</td>
-            <td><input type="checkbox" name="enable_email_piping" value=1 <?php echo $config['enable_email_piping']? 'checked="checked"': ''; ?>> Enable email piping
-                 &nbsp;&nbsp;<em>(You pipe we accept policy)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Strip Quoted Reply:</td>
-            <td>
-                <input type="checkbox" name="strip_quoted_reply" <?php echo $config['strip_quoted_reply'] ? 'checked="checked"':''; ?>>
-                <em>(depends on the reply separator tag set below)</em>
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['strip_quoted_reply']; ?></font>
-            </td>
-        </tr>
-        <tr>
-            <td width="180">Reply Separator Tag:</td>
-            <td><input type="text" name="reply_separator" value="<?php echo $config['reply_separator']; ?>">
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['reply_separator']; ?></font>
-            </td>
-        </tr>
-        <tr><th colspan=2><em><strong>Outgoing Emails</strong>: Default email only applies to outgoing emails without SMTP setting.</em></th></tr>
-        <tr><td width="180">Default Outgoing Email:</td>
-            <td>
-                <select name="default_smtp_id">
-                    <option value=0 selected="selected">None: Use PHP mail function</option>
+                        }
+                    } ?>
+                 </select>
+                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['alert_email_id']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180" class="required">Admin's Email Address:</td>
+            <td>
+                <input type="text" size=40 name="admin_email" value="<?php echo $config['admin_email']; ?>">
+                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['admin_email']; ?></font>
+                &nbsp;&nbsp;<em>(System administrator's email)</em> 
+            </td>
+        </tr>
+        <tr><th colspan=2><em><strong>Incoming Emails</strong>: For mail fetcher (polling) to work you must set an external cron job or enable auto-cron</em></th>
+        <tr>
+            <td width="180">Email Polling:</td>
+            <td><input type="checkbox" name="enable_mail_polling" value=1 <?php echo $config['enable_mail_polling']? 'checked="checked"': ''; ?>  > Enable POP/IMAP polling
+                 &nbsp;&nbsp;
+                 <input type="checkbox" name="enable_auto_cron" <?php echo $config['enable_auto_cron']?'checked="checked"':''; ?>>
+                 Enable Auto-Cron <em>(Poll based on staff activity - NOT recommended)</em>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Email Piping:</td>
+            <td><input type="checkbox" name="enable_email_piping" value=1 <?php echo $config['enable_email_piping']? 'checked="checked"': ''; ?>> Enable email piping
+                 &nbsp;&nbsp;<em>(You pipe we accept policy)</em>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Strip Quoted Reply:</td>
+            <td>
+                <input type="checkbox" name="strip_quoted_reply" <?php echo $config['strip_quoted_reply'] ? 'checked="checked"':''; ?>>
+                <em>(depends on the reply separator tag set below)</em>
+                &nbsp;<font class="error">&nbsp;<?php echo $errors['strip_quoted_reply']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Reply Separator Tag:</td>
+            <td><input type="text" name="reply_separator" value="<?php echo $config['reply_separator']; ?>">
+                &nbsp;<font class="error">&nbsp;<?php echo $errors['reply_separator']; ?></font>
+            </td>
+        </tr>
+        <tr><th colspan=2><em><strong>Outgoing Emails</strong>: Default email only applies to outgoing emails without SMTP setting.</em></th></tr>
+        <tr><td width="180">Default Outgoing Email:</td>
+            <td>
+                <select name="default_smtp_id">
+                    <option value=0 selected="selected">None: Use PHP mail function</option>
                     <?php
-                    $sql='SELECT email_id,email,name,smtp_host FROM '.EMAIL_TABLE.' WHERE smtp_active=1';
-
-                    if(($res=db_query($sql)) && db_num_rows($res)) {
-                        while (list($id,$email,$name,$host) = db_fetch_row($res)){
-                            $email=$name?"$name &lt;$email&gt;":$email;
-                            ?>
-                            <option value="<?php echo $id; ?>"<?php echo ($config['default_smtp_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
+                    $sql='SELECT email_id,email,name,smtp_host FROM '.EMAIL_TABLE.' WHERE smtp_active=1';
+
+                    if(($res=db_query($sql)) && db_num_rows($res)) {
+                        while (list($id,$email,$name,$host) = db_fetch_row($res)){
+                            $email=$name?"$name &lt;$email&gt;":$email;
+                            ?>
+                            <option value="<?php echo $id; ?>"<?php echo ($config['default_smtp_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
                         <?php
-                        }
-                    } ?>
-                 </select>&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['default_smtp_id']; ?></font>
-           </td>
-       </tr>
-    </tbody>
-</table>
-<p style="padding-left:250px;">
-    <input class="button" type="submit" name="submit" value="Save Changes">
-    <input class="button" type="reset" name="reset" value="Reset Changes">
-</p>
-</form>
+                        }
+                    } ?>
+                 </select>&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['default_smtp_id']; ?></font>
+           </td>
+       </tr>
+    </tbody>
+</table>
+<p style="padding-left:250px;">
+    <input class="button" type="submit" name="submit" value="Save Changes">
+    <input class="button" type="reset" name="reset" value="Reset Changes">
+</p>
+</form>
diff --git a/include/staff/settings-kb.inc.php b/include/staff/settings-kb.inc.php
index 6fe8433f5ee580c5a201a42518652106af63d313..0ab2ec09449a07f8f7efa78f8602683534b7666a 100644
--- a/include/staff/settings-kb.inc.php
+++ b/include/staff/settings-kb.inc.php
@@ -1,3 +1,7 @@
+<?php
+if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) die('Access Denied');
+?>
+<h2>Knowledge Base Settings and Options</h2>
 <form action="settings.php?t=kb" method="post" id="save">
 <?php csrf_token(); ?>
 <input type="hidden" name="t" value="kb" >
@@ -5,25 +9,25 @@
     <thead>
         <tr>
             <th colspan="2">
-                <h4>Knowledgebase Settings</h4>
-                <em>Disabling knowledgebase disables user's knowledgebase interface.</em>
+                <h4>Knowledge Base Settings</h4>
+                <em>Disabling knowledge base disables clients'interface.</em>
             </th>
         </tr>
     </thead>
     <tbody>
         <tr>
-            <td width="180">Knowledgebase Status:</td>
+            <td width="180">Knowledge base status:</td>
             <td>
               <input type="checkbox" name="enable_kb" value="1" <?php echo $config['enable_kb']?'checked="checked"':''; ?>>
-              Enable Knowledgebase&nbsp;<em>(Client Interface)</em>
+              Enable Knowledge base&nbsp;<em>(Client interface)</em>
               &nbsp;<font class="error">&nbsp;<?php echo $errors['enable_kb']; ?></font>
             </td>
         </tr>
         <tr>
-            <td width="180">Premade Responses:</td>
+            <td width="180">Canned Responses:</td>
             <td>
                 <input type="checkbox" name="enable_premade" value="1" <?php echo $config['enable_premade']?'checked="checked"':''; ?> >
-                Enable premade/canned responses&nbsp;<em>(Available on ticket reply)</em>
+                Enable canned responses&nbsp;<em>(Available on ticket reply)</em>
                 &nbsp;<font class="error">&nbsp;<?php echo $errors['enable_premade']; ?></font>
             </td>
         </tr>
diff --git a/include/staff/settings-general.inc.php b/include/staff/settings-system.inc.php
similarity index 66%
rename from include/staff/settings-general.inc.php
rename to include/staff/settings-system.inc.php
index 20bbd94866960d2e06ae4d3451825d5752c853ac..3fba7f15977390d6882f00894523b90d92d4aced 100644
--- a/include/staff/settings-general.inc.php
+++ b/include/staff/settings-system.inc.php
@@ -1,12 +1,18 @@
-<form action="settings.php?t=general" method="post" id="save">
+<?php
+if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) die('Access Denied');
+
+$gmtime = Misc::gmtime();
+?>
+<h2>System Settings and Preferences - <span>osTicket (v<?php echo $cfg->getVersion(); ?>)</span></h2>
+<form action="settings.php?t=system" method="post" id="save">
 <?php csrf_token(); ?>
-<input type="hidden" name="t" value="general" >
+<input type="hidden" name="t" value="system" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
         <tr>
             <th colspan="2">
-                <h4>General Settings</h4>
-                <em>Offline mode will disable client interface and only allow admins to login to Staff Control Panel</em>
+                <h4>System Settings & Preferences</h4>
+                <em><b>General Settings</b>: Offline mode will disable client interface and only allow admins to login to Staff Control Panel</em>
             </th>
         </tr>
     </thead>
@@ -39,7 +45,7 @@
                     <?php
                     $sql='SELECT dept_id,dept_name FROM '.DEPT_TABLE.' WHERE ispublic=1';
                     if(($res=db_query($sql)) && db_num_rows($res)){
-                        while (list($id,$name) = db_fetch_row($res)){
+                        while (list($id, $name) = db_fetch_row($res)){
                             $selected = ($config['default_dept_id']==$id)?'selected="selected"':''; ?>
                             <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?> Dept</option>
                         <?php
@@ -56,7 +62,7 @@
                     <?php
                     $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' WHERE isactive=1 AND cfg_id='.db_input($cfg->getId()).' ORDER BY name';
                     if(($res=db_query($sql)) && db_num_rows($res)){
-                        while (list($id,$name) = db_fetch_row($res)){
+                        while (list($id, $name) = db_fetch_row($res)){
                             $selected = ($config['default_template_id']==$id)?'selected="selected"':''; ?>
                             <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?></option>
                         <?php
@@ -113,26 +119,32 @@
                   <?php
                     for ($i = 1; $i <= 12; $i++) {
                         echo sprintf('<option value="%d" %s>%s%s</option>',
-                                $i,(($config['passwd_reset_period']==$i)?'selected="selected"':''),$i>1?"Every $i ":'',$i>1?' Months':'Monthly');
+                                $i,(($config['passwd_reset_period']==$i)?'selected="selected"':''), $i>1?"Every $i ":'', $i>1?' Months':'Monthly');
                     }
                     ?>
                 </select>
                 &nbsp;<font class="error">&nbsp;<?php echo $errors['passwd_reset_period']; ?></font>
             </td>
         </tr>
+        <tr><td>Bind Staff Session to IP:</td>
+            <td>
+              <input type="checkbox" name="staff_ip_binding" <?php echo $config['staff_ip_binding']?'checked="checked"':''; ?>>
+              <em>(binds staff session to originating IP address upon login)</em>
+            </td>
+        </tr>
         <tr><td>Staff Excessive Logins:</td>
             <td>
                 <select name="staff_max_logins">
                   <?php
                     for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['staff_max_logins']==$i)?'selected="selected"':''),$i);
+                        echo sprintf('<option value="%d" %s>%d</option>', $i,(($config['staff_max_logins']==$i)?'selected="selected"':''), $i);
                     }
                     ?>
                 </select> failed login attempt(s) allowed before a
                 <select name="staff_login_timeout">
                   <?php
                     for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['staff_login_timeout']==$i)?'selected="selected"':''),$i);
+                        echo sprintf('<option value="%d" %s>%d</option>', $i,(($config['staff_login_timeout']==$i)?'selected="selected"':''), $i);
                     }
                     ?>
                 </select> minute lock-out is enforced.
@@ -144,18 +156,12 @@
                 Maximum idle time in minutes before a staff member must log in again (enter 0 to disable).
             </td>
         </tr>
-       <tr><td>Bind Staff Session to IP:</td>
-            <td>
-              <input type="checkbox" name="staff_ip_binding" <?php echo $config['staff_ip_binding']?'checked="checked"':''; ?>>
-              <em>(binds staff session to originating IP address upon login)</em>
-            </td>
-        </tr>
         <tr><td>Client Excessive Logins:</td>
             <td>
                 <select name="client_max_logins">
                   <?php
                     for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['client_max_logins']==$i)?'selected="selected"':''),$i);
+                        echo sprintf('<option value="%d" %s>%d</option>', $i,(($config['client_max_logins']==$i)?'selected="selected"':''), $i);
                     }
 
                     ?>
@@ -163,7 +169,7 @@
                 <select name="client_login_timeout">
                   <?php
                     for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['client_login_timeout']==$i)?'selected="selected"':''),$i);
+                        echo sprintf('<option value="%d" %s>%d</option>', $i,(($config['client_login_timeout']==$i)?'selected="selected"':''), $i);
                     }
                     ?>
                 </select> minute lock-out is enforced. 
@@ -176,16 +182,56 @@
                 &nbsp;Maximum idle time in minutes before a client must log in again (enter 0 to disable).
             </td>
         </tr>
-        <tr><td>Clickable URLs:</td>
+        <tr>
+            <th colspan="2">
+                <em><b>Date and Time Options</b>: Please refer to <a href="http://php.net/date" target="_blank">PHP Manual</a> for supported parameters.</em>
+            </th>
+        </tr>
+        <tr><td width="220" class="required">Time Format:</td>
+            <td>
+                <input type="text" name="time_format" value="<?php echo $config['time_format']; ?>">
+                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['time_format']; ?></font>
+                    <em><?php echo Format::date($config['time_format'], $gmtime, $config['tz_offset'], $config['enable_daylight_saving']); ?></em></td>
+        </tr>
+        <tr><td width="220" class="required">Date Format:</td>
+            <td><input type="text" name="date_format" value="<?php echo $config['date_format']; ?>">
+                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['date_format']; ?></font>
+                        <em><?php echo Format::date($config['date_format'], $gmtime, $config['tz_offset'], $config['enable_daylight_saving']); ?></em>
+            </td>
+        </tr>
+        <tr><td width="220" class="required">Date &amp; Time Format:</td>
+            <td><input type="text" name="datetime_format" value="<?php echo $config['datetime_format']; ?>">
+                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['datetime_format']; ?></font>
+                        <em><?php echo Format::date($config['datetime_format'], $gmtime, $config['tz_offset'], $config['enable_daylight_saving']); ?></em>
+            </td>
+        </tr>
+        <tr><td width="220" class="required">Day, Date &amp; Time Format:</td>
+            <td><input type="text" name="daydatetime_format" value="<?php echo $config['daydatetime_format']; ?>">
+                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['daydatetime_format']; ?></font>
+                        <em><?php echo Format::date($config['daydatetime_format'], $gmtime, $config['tz_offset'], $config['enable_daylight_saving']); ?></em>
+            </td>
+        </tr>
+        <tr><td width="220" class="required">Default Time Zone:</td>
             <td>
-              <input type="checkbox" name="clickable_urls" <?php echo $config['clickable_urls']?'checked="checked"':''; ?>>
-               <em>(converts URLs in messages to clickable links)</em>
+                <select name="default_timezone_id">
+                    <option value="">&mdash; Select Default Time Zone &mdash;</option>
+                    <?php
+                    $sql='SELECT id, offset,timezone FROM '.TIMEZONE_TABLE.' ORDER BY id';
+                    if(($res=db_query($sql)) && db_num_rows($res)){
+                        while(list($id, $offset, $tz)=db_fetch_row($res)){
+                            $sel=($config['default_timezone_id']==$id)?'selected="selected"':'';
+                            echo sprintf('<option value="%d" %s>GMT %s - %s</option>', $id, $sel, $offset, $tz);
+                        }
+                    }
+                    ?>
+                </select>
+                &nbsp;<font class="error">*&nbsp;<?php echo $errors['default_timezone_id']; ?></font>
             </td>
         </tr>
-        <tr><td>Enable Auto Cron:</td>
+        <tr>
+            <td width="220">Daylight Saving:</td>
             <td>
-              <input type="checkbox" name="enable_auto_cron" <?php echo $config['enable_auto_cron']?'checked="checked"':''; ?>>
-                <em>(executes cron jobs based on staff activity - not recommended)</em>
+                <input type="checkbox" name="enable_daylight_saving" <?php echo $config['enable_daylight_saving'] ? 'checked="checked"': ''; ?>>Observe daylight savings
             </td>
         </tr>
     </tbody>
@@ -195,4 +241,3 @@
     <input class="button" type="reset" name="reset" value="Reset Changes">
 </p>
 </form>
-
diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php
index 280abca08ea44d698e0a41b56b1d8d0a62cd1693..992e9900425c19d708f7cb35d75a59f7b18c36bf 100644
--- a/include/staff/settings-tickets.inc.php
+++ b/include/staff/settings-tickets.inc.php
@@ -1,3 +1,9 @@
+<?php
+if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) die('Access Denied');
+if(!($maxfileuploads=ini_get('max_file_uploads')))
+    $maxfileuploads=DEFAULT_MAX_FILE_UPLOADS;
+?>
+<h2>Ticket Settings and Options</h2>
 <form action="settings.php?t=tickets" method="post" id="save">
 <?php csrf_token(); ?>
 <input type="hidden" name="t" value="tickets" >
@@ -5,7 +11,7 @@
     <thead>
         <tr>
             <th colspan="2">
-                <h4>Ticket Settings and Options</h4>
+                <h4>Ticket Settings</h4>
                 <em>Global ticket settings and options.</em>
             </th>
         </tr>
@@ -55,53 +61,59 @@
              </td>
         </tr>
         <tr>
-            <td width="180">Web Tickets Priority</td>
+            <td>Maximum <b>Open</b> Tickets:</td>
             <td>
-                <input type="checkbox" name="allow_priority_change" value="1" <?php echo $config['allow_priority_change'] ?'checked="checked"':''; ?>>
-                <em>(Allow user to overwrite/set priority)</em>
+                <input type="text" name="max_open_tickets" size=4 value="<?php echo $config['max_open_tickets']; ?>">
+                per email/user. <em>(Helps with spam and email flood control - enter 0 for unlimited)</em>
             </td>
         </tr>
         <tr>
-            <td width="180">Emailed Tickets Priority</td>
+            <td>Ticket Auto-lock Time:</td>
             <td>
-                <input type="checkbox" name="use_email_priority" value="1" <?php echo $config['use_email_priority'] ?'checked="checked"':''; ?> >
-                <em>(Use email priority when available)</em>
+                <input type="text" name="autolock_minutes" size=4 value="<?php echo $config['autolock_minutes']; ?>">
+                <font class="error"><?php echo $errors['autolock_minutes']; ?></font>
+                <em>(Minutes to lock a ticket on activity - enter 0 to disable locking)</em>
+            </td>
+        </tr>
+        <tr>
+                    <td width="180">Web Tickets Priority:</td>
+                    <td>
+                        <input type="checkbox" name="allow_priority_change" value="1" <?php echo $config['allow_priority_change'] ?'checked="checked"':''; ?>>
+                        <em>(Allow user to overwrite/set priority)</em>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="180">Emailed Tickets Priority:</td>
+                    <td>
+                        <input type="checkbox" name="use_email_priority" value="1" <?php echo $config['use_email_priority'] ?'checked="checked"':''; ?> >
+                        <em>(Use email priority when available)</em>
             </td>
         </tr>
         <tr>
-            <td width="180">Show Related Tickets</td>
+            <td width="180">Show Related Tickets:</td>
             <td>
                 <input type="checkbox" name="show_related_tickets" value="1" <?php echo $config['show_related_tickets'] ?'checked="checked"':''; ?> >
                 <em>(Show all related tickets on user login - otherwise access is restricted to one ticket view per login)</em>
             </td>
         </tr>        
         <tr>
-            <td width="180">Show Notes Inline</td>
+            <td width="180">Show Notes Inline:</td>
             <td>
                 <input type="checkbox" name="show_notes_inline" value="1" <?php echo $config['show_notes_inline'] ?'checked="checked"':''; ?> >
                 <em>(Show internal notes  inline)</em>
               </td>
-        </tr>  
-        <tr>
-            <td>Human Verification:</td>
-            <td>
-                <input type="checkbox" name="enable_captcha" <?php echo $config['enable_captcha']?'checked="checked"':''; ?>>
-                Enable CAPTCHA on new web tickets.<em>(requires GDLib)</em> &nbsp;<font class="error">&nbsp;<?php echo $errors['enable_captcha']; ?></font><br/>
-            </td>
         </tr>
-        <tr>
-            <td>Maximum <b>Open</b> Tickets:</td>
+        <tr><td>Clickable URLs:</td>
             <td>
-                <input type="text" name="max_open_tickets" size=4 value="<?php echo $config['max_open_tickets']; ?>">
-                per email/user. <em>(Helps with spam and email flood control - enter 0 for unlimited)</em>
+              <input type="checkbox" name="clickable_urls" <?php echo $config['clickable_urls']?'checked="checked"':''; ?>>
+               <em>(converts URLs in ticket thread to clickable links)</em>
             </td>
         </tr>
         <tr>
-            <td>Ticket Auto-lock Time:</td>
+            <td>Human Verification:</td>
             <td>
-                <input type="text" name="autolock_minutes" size=4 value="<?php echo $config['autolock_minutes']; ?>">
-                <font class="error"><?php echo $errors['autolock_minutes']; ?></font>
-                <em>(Minutes to lock a ticket on activity - enter 0 to disable locking)</em>
+                <input type="checkbox" name="enable_captcha" <?php echo $config['enable_captcha']?'checked="checked"':''; ?>>
+                Enable CAPTCHA on new web tickets.<em>(requires GDLib)</em> &nbsp;<font class="error">&nbsp;<?php echo $errors['enable_captcha']; ?></font><br/>
             </td>
         </tr>
         <tr>
@@ -139,6 +151,94 @@
                 Hide staff's name on responses.
             </td>
         </tr>
+        <tr>
+            <th colspan="2">
+                <em><b>Attachments</b>:  Size setting mainly apply to web tickets.</em>
+            </th>
+        </tr>
+        <tr>
+            <td width="180">Allow Attachments:</td>
+            <td>
+              <input type="checkbox" name="allow_attachments" <?php echo $config['allow_attachments']?'checked="checked"':''; ?>><b>Allow Attachments</b>
+                &nbsp; <em>(Global Setting)</em>
+                &nbsp;<font class="error">&nbsp;<?php echo $errors['allow_attachments']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Emailed Attachments:</td>
+            <td>
+                <input type="checkbox" name="allow_email_attachments" <?php echo $config['allow_email_attachments']?'checked="checked"':''; ?>> Accept emailed files
+                    &nbsp;<font class="error">&nbsp;<?php echo $errors['allow_email_attachments']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Online Attachments:</td>
+            <td>
+                <input type="checkbox" name="allow_online_attachments" <?php echo $config['allow_online_attachments']?'checked="checked"':''; ?> >
+                    Allow web upload &nbsp;&nbsp;&nbsp;&nbsp;
+                <input type="checkbox" name="allow_online_attachments_onlogin" <?php echo $config['allow_online_attachments_onlogin'] ?'checked="checked"':''; ?> >
+                    Limit to authenticated users only. <em>(User must be logged in to upload files)</em>
+                    <font class="error">&nbsp;<?php echo $errors['allow_online_attachments']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>Max. User File Uploads:</td>
+            <td>
+                <select name="max_user_file_uploads">
+                    <?php
+                    for($i = 1; $i <=$maxfileuploads; $i++) {
+                        ?>
+                        <option <?php echo $config['max_user_file_uploads']==$i?'selected="selected"':''; ?> value="<?php echo $i; ?>">
+                            <?php echo $i; ?>&nbsp;<?php echo ($i>1)?'files':'file'; ?></option>
+                        <?php
+                    } ?>
+                </select>
+                <em>(Number of files the user is allowed to upload simultaneously)</em>
+                &nbsp;<font class="error">&nbsp;<?php echo $errors['max_user_file_uploads']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td>Max. Staff File Uploads:</td>
+            <td>
+                <select name="max_staff_file_uploads">
+                    <?php
+                    for($i = 1; $i <=$maxfileuploads; $i++) {
+                        ?>
+                        <option <?php echo $config['max_staff_file_uploads']==$i?'selected="selected"':''; ?> value="<?php echo $i; ?>">
+                            <?php echo $i; ?>&nbsp;<?php echo ($i>1)?'files':'file'; ?></option>
+                        <?php
+                    } ?>
+                </select>
+                <em>(Number of files the staff is allowed to upload simultaneously)</em>
+                &nbsp;<font class="error">&nbsp;<?php echo $errors['max_staff_file_uploads']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Maximum File Size:</td>
+            <td>
+                <input type="text" name="max_file_size" value="<?php echo $config['max_file_size']; ?>"> in bytes.
+                    <em>(System Max. <?php echo Format::file_size(ini_get('upload_max_filesize')); ?>)</em>
+                    <font class="error">&nbsp;<?php echo $errors['max_file_size']; ?></font>
+            </td>
+        </tr>
+        <tr>
+            <td width="180">Ticket Response Files:</td>
+            <td>
+                <input type="checkbox" name="email_attachments" <?php echo $config['email_attachments']?'checked="checked"':''; ?> >Email attachments to the user
+            </td>
+        </tr>
+        <tr>
+            <th colspan="2">
+                <em><strong>Accepted File Types</strong>: Limit the type of files users are allowed to submit.
+                <font class="error">&nbsp;<?php echo $errors['allowed_filetypes']; ?></font></em>
+            </th>
+        </tr>
+        <tr>
+            <td colspan="2">
+                <em>Enter allowed file extensions separated by a comma. e.g .doc, .pdf. To accept all files enter wildcard <b><i>.*</i></b>&nbsp;i.e dotStar (NOT Recommended).</em><br>
+                <textarea name="allowed_filetypes" cols="21" rows="4" style="width: 65%;" wrap="hard" ><?php echo $config['allowed_filetypes']; ?></textarea>
+            </td>
+        </tr>
     </tbody>
 </table>
 <p style="padding-left:250px;">
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index a58206963acf4deb36fd48bf17d80c2ea63020aa..ddd2839b24a720341841edd2c9b81e4efd218164 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -27,7 +27,7 @@ if($ticket->isAssigned() && (
     $warn.='&nbsp;&nbsp;<span class="Icon assignedTicket">Ticket is assigned to '.implode('/', $ticket->getAssignees()).'</span>';
 if(!$errors['err'] && ($lock && $lock->getStaffId()!=$thisstaff->getId()))
     $errors['err']='This ticket is currently locked by '.$lock->getStaffName();
-if(!$errors['err'] && ($emailBanned=EmailFilter::isBanned($ticket->getEmail())))
+if(!$errors['err'] && ($emailBanned=TicketFilter::isBanned($ticket->getEmail())))
     $errors['err']='Email is in banlist! Must be removed before any reply/response';
 
 $unbannable=($emailBanned) ? BanList::includes($ticket->getEmail()) : false;
diff --git a/include/upgrader/sql/1da1bcba-15b30765.patch.sql b/include/upgrader/sql/1da1bcba-15b30765.patch.sql
new file mode 100644
index 0000000000000000000000000000000000000000..cb37a02f4af2e3c86f0367674454b22554973c3b
--- /dev/null
+++ b/include/upgrader/sql/1da1bcba-15b30765.patch.sql
@@ -0,0 +1,11 @@
+/**
+ * @version v1.7 RC2+
+ * @signature 15b3076533123ff617801d89861136c8
+ *
+ * Transitional patch.
+ *  
+ */
+
+-- Finished with patch
+UPDATE `%TABLE_PREFIX%config`
+    SET `schema_signature`='15b3076533123ff617801d89861136c8';
diff --git a/include/upgrader/sql/c00511c7-7be60a84.patch.sql b/include/upgrader/sql/c00511c7-7be60a84.patch.sql
index 638248b976019a670c773578b564d99a3daacc6a..fdefd09bea960de619fc5a1feac8bd69d3c77b8e 100644
--- a/include/upgrader/sql/c00511c7-7be60a84.patch.sql
+++ b/include/upgrader/sql/c00511c7-7be60a84.patch.sql
@@ -63,7 +63,7 @@ ALTER TABLE `%TABLE_PREFIX%config`
     ADD `transfer_alert_dept_manager` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '1' AFTER `transfer_alert_assigned` ,
     ADD `transfer_alert_dept_members` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `transfer_alert_dept_manager`,
     ADD `send_sys_errors` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `enable_email_piping`,
-    ADD `enable_kb` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `use_email_priority`,
+    ADD `enable_kb` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `use_email_priority`,
     ADD `enable_premade` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `enable_kb`,
     ADD `show_related_tickets` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `auto_assign_reopened_tickets`,
     ADD `schema_signature` CHAR( 32 ) NOT NULL AFTER `ostversion`;
diff --git a/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql b/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3d3bda68e2fd49293e1a73545506416c7a1cc126
--- /dev/null
+++ b/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql
@@ -0,0 +1,23 @@
+/**
+ * @version v1.7 RC3
+ * @signature 1da1bcbafcedc65efef58f142a48ac91
+ *
+ *  Upgrade from 1.6 RC3 + filters
+ *  
+ */
+
+RENAME TABLE  `%TABLE_PREFIX%email_filter` TO  `%TABLE_PREFIX%filter`;
+
+RENAME TABLE  `%TABLE_PREFIX%email_filter_rule` TO  `%TABLE_PREFIX%filter_rule`;
+
+ALTER TABLE  `%TABLE_PREFIX%filter` CHANGE  `reject_email`  `reject_ticket` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT  '0';
+
+ALTER TABLE  `%TABLE_PREFIX%filter` 
+    ADD  `target` ENUM(  'Any',  'Web',  'Email',  'API' ) NOT NULL DEFAULT  'Any' AFTER  `sla_id` ,
+    ADD INDEX (  `target` );
+
+UPDATE `%TABLE_PREFIX%filter` SET `target` = 'Email' WHERE `email_id` != 0;
+
+-- Finished with patch
+UPDATE `%TABLE_PREFIX%config`
+    SET `schema_signature`='1da1bcbafcedc65efef58f142a48ac91';
diff --git a/main.inc.php b/main.inc.php
index abcbfeabdaee005bdd83abb7719ac163e0e531af..8ce3946696c8bb959200e3ea2366805eff58efa5 100644
--- a/main.inc.php
+++ b/main.inc.php
@@ -62,9 +62,8 @@
     /*############## Do NOT monkey with anything else beyond this point UNLESS you really know what you are doing ##############*/
 
     #Current version && schema signature (Changes from version to version)
-    define('THIS_VERSION','1.7-RC2'); //Shown on admin panel
-    define('SCHEMA_SIGNATURE','d0e37dca324648f1ce2d10528a6026d4'); //MD5 signature of the db schema. (used to trigger upgrades)
-
+    define('THIS_VERSION','1.7-RC2+'); //Shown on admin panel
+    define('SCHEMA_SIGNATURE','15b3076533123ff617801d89861136c8'); //MD5 signature of the db schema. (used to trigger upgrades)
     #load config info
     $configfile='';
     if(file_exists(ROOT_DIR.'ostconfig.php')) //Old installs prior to v 1.6 RC5
@@ -159,8 +158,10 @@
   
     define('EMAIL_TABLE',TABLE_PREFIX.'email');
     define('EMAIL_TEMPLATE_TABLE',TABLE_PREFIX.'email_template');
-    define('EMAIL_FILTER_TABLE',TABLE_PREFIX.'email_filter');
-    define('EMAIL_FILTER_RULE_TABLE',TABLE_PREFIX.'email_filter_rule');
+
+    define('FILTER_TABLE',TABLE_PREFIX.'filter');
+    define('FILTER_RULE_TABLE',TABLE_PREFIX.'filter_rule');
+    
     define('BANLIST_TABLE',TABLE_PREFIX.'email_banlist'); //Not in use anymore....as of v 1.7
 
     define('SLA_TABLE',TABLE_PREFIX.'sla');
diff --git a/scp/apikeys.php b/scp/apikeys.php
index e393a31c5f2bea0647a238240ba5e9021ad3c9ab..1e17675442066356a077041f03357fa0c3913414 100644
--- a/scp/apikeys.php
+++ b/scp/apikeys.php
@@ -96,7 +96,7 @@ $page='apikeys.inc.php';
 if($api || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
     $page='apikey.inc.php';
 
-$nav->setTabActive('settings');
+$nav->setTabActive('manage');
 require(STAFFINC_DIR.'header.inc.php');
 require(STAFFINC_DIR.$page);
 include(STAFFINC_DIR.'footer.inc.php');
diff --git a/scp/banlist.php b/scp/banlist.php
index 081fde9b4ed0cd18713cab78e795c2e0eaf1df1b..a31d91d7e8d2392c2d7e23dba570a07257532ec8 100644
--- a/scp/banlist.php
+++ b/scp/banlist.php
@@ -68,7 +68,7 @@ if($_POST && !$errors && $filter){
             }else{
                 $count=count($_POST['ids']);
                 if($_POST['enable']){
-                    $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET isactive=1 WHERE filter_id='.
+                    $sql='UPDATE '.FILTER_RULE_TABLE.' SET isactive=1 WHERE filter_id='.
                             db_input($filter->getId()).
                          ' AND id IN ('.
                             implode(',', db_input($_POST['ids'])).')';
@@ -81,7 +81,7 @@ if($_POST && !$errors && $filter){
                         $errors['err']='Unable to enable selected emails';
                     }
                 }elseif($_POST['disable']){
-                    $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET isactive=0 WHERE filter_id='.
+                    $sql='UPDATE '.FILTER_RULE_TABLE.' SET isactive=0 WHERE filter_id='.
                             db_input($filter->getId()).
                          ' AND id IN ('.
                             implode(',', db_input($_POST['ids'])).')';
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 0042ed4306a406337f3a3deec2811467c06a325d..fd4faed6dc77cb4e1ebee9ca0c1a8d71b661dab6 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -247,6 +247,13 @@ a.attachment { background:url(../images/icons/attachment.gif ) }
 a.api { background:url(../images/icons/api.png) }
 a.newapi { background:url(../images/icons/new_api.png) }
 
+a.ticket-settings { background:url(../images/icons/ticket-settings.gif) }
+a.email-settings { background:url(../images/icons/email-settings.gif) }
+a.kb-settings { background:url(../images/icons/kb-settings.gif) }
+a.alert-settings { background:url(../images/icons/alert-settings.gif) }
+a.email-autoresponders { background:url(../images/icons/email-autoresponders.gif) }
+
+
 a.sla { background:url(../images/icons/slas.png) }
 a.newsla { background:url(../images/icons/new_sla.png) }
 
@@ -259,7 +266,8 @@ a.emailTemplates { background:url(../images/icons/email_templates.png) }
 a.newEmailTemplate { background:url(../images/icons/new_email_template.png) }
 
 a.emailFilters { background:url(../images/icons/email_filters.png) }
-a.newEmailFilter { background:url(../images/icons/new_email_filter.png) }
+a.ticketFilters { background:url(../images/icons/ticket_filters.png) }
+a.newTicketFilter { background:url(../images/icons/new_ticket_filter.png) }
 
 a.emailSettings { background:url(../images/icons/emails.png) }
 a.emailDiagnostic { background:url(../images/icons/email_diagnostic.gif) }
@@ -1292,7 +1300,7 @@ time {
 #advanced-search input[type="reset"],
 #advanced-search input[type="button"],
 #print-options input[type="reset"],
-#print-options input[type="button"] { 
+#print-options input[type="button"] {
     opacity:0.7;
 }
 
diff --git a/scp/departments.php b/scp/departments.php
index ef1acb12d62adcaa3c6285a210e7aa9d3f57fc29..31fc4c6df5602f5959d9f4585517a8ebf04fc008 100644
--- a/scp/departments.php
+++ b/scp/departments.php
@@ -104,7 +104,7 @@ $page='departments.inc.php';
 if($dept || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
     $page='department.inc.php';
 
-$nav->setTabActive('depts');
+$nav->setTabActive('staff');
 require(STAFFINC_DIR.'header.inc.php');
 require(STAFFINC_DIR.$page);
 include(STAFFINC_DIR.'footer.inc.php');
diff --git a/scp/filters.php b/scp/filters.php
index 4ce0f30765f5192617f22345c00571f26d206af2..29045410fe685f10a86a362942f34259a6401edd 100644
--- a/scp/filters.php
+++ b/scp/filters.php
@@ -49,7 +49,7 @@ if($_POST){
             }else{
                 $count=count($_POST['ids']);
                 if($_POST['enable']){
-                    $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET isactive=1 WHERE id IN ('.
+                    $sql='UPDATE '.FILTER_TABLE.' SET isactive=1 WHERE id IN ('.
                         implode(',', db_input($_POST['ids'])).')';
                     if(db_query($sql) && ($num=db_affected_rows())){
                         if($num==$count)
@@ -60,7 +60,7 @@ if($_POST){
                         $errors['err']='Unable to enable selected filters';
                     }
                 }elseif($_POST['disable']){
-                    $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET isactive=0  WHERE id IN ('.
+                    $sql='UPDATE '.FILTER_TABLE.' SET isactive=0  WHERE id IN ('.
                         implode(',', db_input($_POST['ids'])).')';
                     if(db_query($sql) && ($num=db_affected_rows())) {
                         if($num==$count)
@@ -100,7 +100,7 @@ $page='filters.inc.php';
 if($filter || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
     $page='filter.inc.php';
 
-$nav->setTabActive('emails');
+$nav->setTabActive('manage');
 require(STAFFINC_DIR.'header.inc.php');
 require(STAFFINC_DIR.$page);
 include(STAFFINC_DIR.'footer.inc.php');
diff --git a/scp/helptopics.php b/scp/helptopics.php
index 5bd1ded7048f26307f2cd18d09d6b3a946f13f65..37e865b22057483bc87595023ad92ce9be1bb306 100644
--- a/scp/helptopics.php
+++ b/scp/helptopics.php
@@ -96,7 +96,7 @@ $page='helptopics.inc.php';
 if($topic || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
     $page='helptopic.inc.php';
 
-$nav->setTabActive('topics');
+$nav->setTabActive('manage');
 require(STAFFINC_DIR.'header.inc.php');
 require(STAFFINC_DIR.$page);
 include(STAFFINC_DIR.'footer.inc.php');
diff --git a/scp/images/icons/alert-settings.gif b/scp/images/icons/alert-settings.gif
new file mode 100644
index 0000000000000000000000000000000000000000..3c8a0b1debd05f87bb53b0d43fb10f153738df1d
Binary files /dev/null and b/scp/images/icons/alert-settings.gif differ
diff --git a/scp/images/icons/email-autoresponders.gif b/scp/images/icons/email-autoresponders.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5c118b46b3daf67261a92bd252a97ae4a34b4153
Binary files /dev/null and b/scp/images/icons/email-autoresponders.gif differ
diff --git a/scp/images/icons/email-settings.gif b/scp/images/icons/email-settings.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6dc8aa0023e6d69355200e53ac492d61346f83d3
Binary files /dev/null and b/scp/images/icons/email-settings.gif differ
diff --git a/scp/images/icons/kb-settings.gif b/scp/images/icons/kb-settings.gif
new file mode 100644
index 0000000000000000000000000000000000000000..991f3c812f0216eb0957d619a92da2e55d22131c
Binary files /dev/null and b/scp/images/icons/kb-settings.gif differ
diff --git a/scp/images/icons/new_ticket_filter.png b/scp/images/icons/new_ticket_filter.png
new file mode 100644
index 0000000000000000000000000000000000000000..00c091ebff2b5c2f20729f4f0b16a6405022b5ea
Binary files /dev/null and b/scp/images/icons/new_ticket_filter.png differ
diff --git a/scp/images/icons/ticket-settings.gif b/scp/images/icons/ticket-settings.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f5d5234a95f4b5d26e7a8eed41054a9377077d90
Binary files /dev/null and b/scp/images/icons/ticket-settings.gif differ
diff --git a/scp/images/icons/ticket_filters.png b/scp/images/icons/ticket_filters.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f2065212f29d70d1f17f316de5f6b8a77b3f950
Binary files /dev/null and b/scp/images/icons/ticket_filters.png differ
diff --git a/scp/images/icons/ticket_source_other.png b/scp/images/icons/ticket_source_other.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7a78f27412669beb75c2371d035d5aa104bdce4
Binary files /dev/null and b/scp/images/icons/ticket_source_other.png differ
diff --git a/scp/settings.php b/scp/settings.php
index 9058fe42ca52c4f9b428bbc52f2ed2cb61f80a8a..0a3f97a912d8fdf6d92dc42ddf035f36bc61b12f 100644
--- a/scp/settings.php
+++ b/scp/settings.php
@@ -15,49 +15,28 @@
 **********************************************************************/
 require('admin.inc.php');
 $errors=array();
-$SettingOptions=array('general'=>'General Settings',
-               'dates'=>'Date and Time Options',
-               'tickets'=>'Ticket Settings and Options',
-               'emails'=>'Email Settings',
-               'attachments'=>'Attachments Settings',
-               'kb'=>'Knowledgebase Settings',
-               'autoresponders'=>'Autoresponder Settings',
-               'alerts'=>'Alerts and Notices Settings');
-
+$settingOptions=array(
+                'system' => 'System Settings',
+                'tickets' => 'Ticket Settings and Options',
+                'emails' => 'Email Settings',
+                'kb' => 'Knowledgebase Settings',
+                'autoresp' => 'Autoresponder Settings',
+                'alerts' => 'Alerts and Notices Settings');
 //Handle a POST.
-if($_POST && !$errors){
-    $errors=array();
-    if($cfg && $cfg->updateSettings($_POST,$errors)){
-        $msg=Format::htmlchars($SettingOptions[$_POST['t']]).' Updated Successfully';
+if($_POST && !$errors) {
+    if($cfg && $cfg->updateSettings($_POST,$errors)) {
+        $msg=Format::htmlchars($settingOptions[$_POST['t']]).' Updated Successfully';
         $cfg->reload();
-    }elseif(!$errors['err']){
-        $errors['err']='Unable to update system settings - correct any errors below and try again';
+    } elseif(!$errors['err']) {
+        $errors['err']='Unable to update settings - correct errors below and try again';
     }
 }
 
-$target=($_REQUEST['t'] && $SettingOptions[$_REQUEST['t']])?$_REQUEST['t']:'general';
-
-$nav->setTabActive('settings');
-require(STAFFINC_DIR.'header.inc.php');
-?>
-<h2>System Preferences and Settings - <span>osTicket (v<?php echo $cfg->getVersion(); ?>)</span></h2>
-<div style="padding-top:10px;padding-bottom:5px;">
-    <form method="get" action="settings.php">
-    Setting Option: 
-    <select id="setting_options" name="t" style="width:300px;">
-        <option value="">&mdash; Select Setting Group &mdash;</option>
-        <?php
-        foreach($SettingOptions as $k=>$v) {
-            $sel=($target==$k)?'selected="selected"':'';
-            echo sprintf('<option value="%s" %s>%s</option>',$k,$sel,$v);
-        }
-        ?>
-    </select>
-    <input type="submit" value="Go">
-    </form>
-</div>
-<?php
+$target=($_REQUEST['t'] && $settingOptions[$_REQUEST['t']])?$_REQUEST['t']:'system';
 $config=($errors && $_POST)?Format::input($_POST):Format::htmlchars($cfg->getConfigInfo());
+
+$nav->setTabActive('settings', ('settings.php?t='.$target));
+require_once(STAFFINC_DIR.'header.inc.php');
 include_once(STAFFINC_DIR."settings-$target.inc.php");
 include_once(STAFFINC_DIR.'footer.inc.php');
 ?>
diff --git a/scp/slas.php b/scp/slas.php
index 8f3b0f75ca331381beb6a348f46c2a703853b229..8dd5b86c90b33b6cf2e88558f9ac679f63af77be 100644
--- a/scp/slas.php
+++ b/scp/slas.php
@@ -96,7 +96,7 @@ $page='slaplans.inc.php';
 if($sla || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
     $page='slaplan.inc.php';
 
-$nav->setTabActive('settings');
+$nav->setTabActive('manage');
 require(STAFFINC_DIR.'header.inc.php');
 require(STAFFINC_DIR.$page);
 include(STAFFINC_DIR.'footer.inc.php');
diff --git a/scp/tickets.php b/scp/tickets.php
index 8c799a2a6a02a26c4185afece329ffc5e57cdcf4..77eec14eab39caed7e1c235ffa079bdeaa658ace 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -52,7 +52,7 @@ if($_POST && !$errors):
                 $errors['err']='Action Denied. Ticket is locked by someone else!';
             
             //Make sure the email is not banned
-            if(!$errors['err'] && EmailFilter::isBanned($ticket->getEmail()))
+            if(!$errors['err'] && TicketFilter::isBanned($ticket->getEmail()))
                 $errors['err']='Email is in banlist. Must be removed to reply.';
 
             $wasOpen =($ticket->isOpen());
diff --git a/setup/inc/sql/osTicket-mysql.sql b/setup/inc/sql/osTicket-mysql.sql
index 5cfba00d6538506e29e136f188610df4508551cb..6ac95bb523a74be12a537d09a5983e550e49e473 100644
--- a/setup/inc/sql/osTicket-mysql.sql
+++ b/setup/inc/sql/osTicket-mysql.sql
@@ -91,7 +91,7 @@ CREATE TABLE `%TABLE_PREFIX%config` (
   `clickable_urls` tinyint(1) unsigned NOT NULL default '1',
   `allow_priority_change` tinyint(1) unsigned NOT NULL default '0',
   `use_email_priority` tinyint(1) unsigned NOT NULL default '0',
-  `enable_kb` tinyint(1) unsigned NOT NULL default '1',
+  `enable_kb` tinyint(1) unsigned NOT NULL default '0',
   `enable_premade` tinyint(1) unsigned NOT NULL default '1',
   `enable_captcha` tinyint(1) unsigned NOT NULL default '0',
   `enable_auto_cron` tinyint(1) unsigned NOT NULL default '0',
@@ -228,14 +228,14 @@ CREATE TABLE `%TABLE_PREFIX%email` (
   KEY `dept_id` (`dept_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
-DROP TABLE IF EXISTS `%TABLE_PREFIX%email_filter`;
-CREATE TABLE `%TABLE_PREFIX%email_filter` (
+DROP TABLE IF EXISTS `%TABLE_PREFIX%filter`;
+CREATE TABLE `%TABLE_PREFIX%filter` (
   `id` int(11) unsigned NOT NULL auto_increment,
   `execorder` int(10) unsigned NOT NULL default '99',
   `isactive` tinyint(1) unsigned NOT NULL default '1',
   `match_all_rules` tinyint(1) unsigned NOT NULL default '0',
   `stop_onmatch` tinyint(1) unsigned NOT NULL default '0',
-  `reject_email` tinyint(1) unsigned NOT NULL default '0',
+  `reject_ticket` tinyint(1) unsigned NOT NULL default '0',
   `use_replyto_email` tinyint(1) unsigned NOT NULL default '0',
   `disable_autoresponder` tinyint(1) unsigned NOT NULL default '0',
   `canned_response_id` int(11) unsigned NOT NULL default '0',
@@ -245,21 +245,23 @@ CREATE TABLE `%TABLE_PREFIX%email_filter` (
   `staff_id` int(10) unsigned NOT NULL default '0',
   `team_id` int(10) unsigned NOT NULL default '0',
   `sla_id` int(10) unsigned NOT NULL default '0',
+  `target` ENUM(  'Any',  'Web',  'Email',  'API' ) NOT NULL DEFAULT  'Any',
   `name` varchar(32) NOT NULL default '',
   `notes` text,
   `created` datetime NOT NULL,
   `updated` datetime NOT NULL,
   PRIMARY KEY  (`id`),
+  KEY `target` (`target`),
   KEY `email_id` (`email_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 
-INSERT INTO `%TABLE_PREFIX%email_filter` (
-  `id`,`isactive`,`execorder`,`reject_email`,`name`,`notes`,`created`)
+INSERT INTO `%TABLE_PREFIX%filter` (
+  `id`,`isactive`,`execorder`,`reject_ticket`,`name`,`notes`,`created`)
     VALUES (1, 1, 99, 1, 'SYSTEM BAN LIST', 'Internal list for email banning. Do not remove', NOW());
 
-DROP TABLE IF EXISTS `%TABLE_PREFIX%email_filter_rule`;
-CREATE TABLE `%TABLE_PREFIX%email_filter_rule` (
+DROP TABLE IF EXISTS `%TABLE_PREFIX%filter_rule`;
+CREATE TABLE `%TABLE_PREFIX%filter_rule` (
   `id` int(11) unsigned NOT NULL auto_increment,
   `filter_id` int(10) unsigned NOT NULL default '0',
   `what` enum('name','email','subject','body','header') NOT NULL,
@@ -274,7 +276,7 @@ CREATE TABLE `%TABLE_PREFIX%email_filter_rule` (
   UNIQUE `filter` (`filter_id`, `what`, `how`, `val`) 
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
-INSERT INTO `%TABLE_PREFIX%email_filter_rule` (
+INSERT INTO `%TABLE_PREFIX%filter_rule` (
   `id`, `filter_id`, `isactive`, `what`,`how`,`val`,`created`)
     VALUES (1, 1, 1, 'email', 'equal', 'test@example.com',NOW());
 
diff --git a/setup/inc/sql/osTicket-mysql.sql.md5 b/setup/inc/sql/osTicket-mysql.sql.md5
index 63d2ce443b0448ca776ebc37b298a3c4ff93c387..11c872a50b9a27b95388705d17ad0d7a43566ad1 100644
--- a/setup/inc/sql/osTicket-mysql.sql.md5
+++ b/setup/inc/sql/osTicket-mysql.sql.md5
@@ -1 +1 @@
-d0e37dca324648f1ce2d10528a6026d4
+15b3076533123ff617801d89861136c8
diff --git a/setup/setup.inc.php b/setup/setup.inc.php
index 07b86c6ffa43e13338f3b1f6c176e0cee2f53316..f2d0bb5e1095ca82d1a148b11b25f73e9193edf1 100644
--- a/setup/setup.inc.php
+++ b/setup/setup.inc.php
@@ -15,10 +15,16 @@
 **********************************************************************/
 
 #This  version - changed on every release
-define('THIS_VERSION', '1.7-RC2');
+define('THIS_VERSION', '1.7-RC2+');
 
-#inits
-error_reporting(E_ALL ^ E_NOTICE); //turn on errors??
+#inits - error reporting.
+$error_reporting = E_ALL & ~E_NOTICE;
+if (defined('E_STRICT')) # 5.4.0
+    $error_reporting &= ~E_STRICT;
+if (defined('E_DEPRECATED')) # 5.3.0
+    $error_reporting &= ~(E_DEPRECATED | E_USER_DEPRECATED);
+
+error_reporting($error_reporting); 
 ini_set('magic_quotes_gpc', 0);
 ini_set('session.use_trans_sid', 0);
 ini_set('session.cache_limiter', 'nocache');