diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css
index 73a76e4aa4e4089bda6264ea9d4fd07ab65448cc..8adafc32edbd4b7335de5e75769d25a46a86bfda 100644
--- a/assets/default/css/theme.css
+++ b/assets/default/css/theme.css
@@ -6,7 +6,7 @@ html {
 }
 body {
   margin: 0;
-  font-size: 13px;
+  font-size: 14px;
   line-height: 1.231;
   padding: 0;
 }
@@ -14,7 +14,7 @@ body,
 input,
 select,
 textarea {
-  font-family: sans-serif;
+  font-family: "Helvetica Neue", sans-serif;
   color: #000;
 }
 b,
@@ -201,7 +201,7 @@ h2, .subject {
   border: 1px solid #0a0;
   background: url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0;
 }
-#msg_warning {
+#msg_warning, .warning-banner {
   margin: 0;
   padding: 5px 10px 5px 36px;
   height: 16px;
@@ -413,8 +413,8 @@ body {
 }
 .front-page-button {
 }
-#landing_page .welcome {
-  width: 560px;
+.main-content {
+  width: 565px;
 }
 #landing_page #new_ticket {
   margin-top: 40px;
@@ -528,10 +528,10 @@ body {
     overflow: hidden;
 }
 .article-title {
-    font-weight: 400;
+    font-weight: 500;
 }
 .faq-content .article-title {
-    font-size: 16pt;
+    font-size: 17pt;
     margin-top: 15px;
 }
 #kb-search {
@@ -727,12 +727,14 @@ label.required, span.required {
 }
 #reply {
   margin-top: 20px;
-  padding: 10px 5px;
+  padding: 10px;
   background: #f9f9f9;
   border: 1px solid #ccc;
 }
 #reply h2 {
   margin-bottom: 10px;
+  padding-bottom: 5px;
+  border-bottom: 2px dotted rgba(0,0,0,0.1);
 }
 #reply > table {
   width: auto;
@@ -851,6 +853,7 @@ a.refresh {
 }
 .infoTable th {
   text-align: left;
+  padding: 3px 8px;
 }
 #ticketThread table.response,
 #ticketThread table.message {
@@ -885,7 +888,6 @@ a.refresh {
 #ticketThread .info a {
   display: inline-block;
   margin: 5px 10px 5px 0;
-  padding-left: 24px;
   height: 16px;
   line-height: 16px;
   background-position: 0 50%;
@@ -903,7 +905,6 @@ a.refresh {
   border: 1px solid #aaa;
   cursor: pointer;
   font-size: 11px;
-  height: 18px;
   overflow: hidden;
   background-color: #dddddd;
   background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #efefef), color-stop(100% #dddddd));
@@ -915,7 +916,6 @@ a.refresh {
   padding: 0 5px;
   text-decoration: none;
   line-height:18px;
-  float:right;
   margin-left:5px;
 }
 .action-button span,
@@ -985,9 +985,7 @@ img.sign-in-image {
 .sidebar {
     margin-bottom: 20px;
     margin-left: 20px;
-}
-#landing_page .sidebar {
-    width: 220px;
+    width: 215px;
 }
 .rtl .sidebar {
     margin-left: 0;
@@ -996,15 +994,19 @@ img.sign-in-image {
 .sidebar .content {
     padding: 10px; border: 1px solid #C8DDFA; background: #F7FBFE;
 }
+.sidebar .content:empty {
+    display: none;
+}
 
 .sidebar section .header {
     font-weight: bold;
+    margin-bottom: 0.3em;
 }
 .sidebar section + section {
     margin-top: 15px;
 }
 .search-form {
-    padding: 12px 0px 20px 0;
+    padding-top: 12px;
 }
 .searchbar .search,
 .search-form .search {
@@ -1029,13 +1031,13 @@ img.sign-in-image {
 }
 .span4 {
     display: inline-block;
-    width: 30.5%;
+    width: 29.5%;
     margin: 0 1%;
     vertical-align: top;
 }
 .span8 {
     display: inline-block;
-    width: 64.5%;
+    width: 66.5%;
     margin: 0 1%;
     vertical-align: top;
 }
@@ -1047,3 +1049,33 @@ img.sign-in-image {
     overflow: hidden;
     text-overflow: ellipsis;
 }
+.image-hover a.action-button:hover,
+.image-hover a.action-button {
+    color: initial !important;
+    text-decoration: none;
+}
+table.custom-data {
+    margin-top: 10px;
+}
+table.custom-data th {
+    width: 25%;
+}
+table.custom-data th {
+    background-color: #F4FAFF;
+    padding: 3px 8px;
+}
+table .headline,
+table.custom-data .headline {
+    border-bottom: 2px solid #ddd;
+    border-bottom: 2px solid rgba(0,0,0,0.15);
+    font-weight: bold;
+    background-color: white;
+}
+#ticketInfo h1 {
+    padding-bottom: 10px;
+    margin-bottom: 5px;
+    border-bottom: 2px dotted rgba(0, 0, 0, 0.15);
+}
+#ticketInfo h1 small {
+    font-weight: normal;
+}
diff --git a/css/chosen-sprite.png b/css/chosen-sprite.png
deleted file mode 100644
index c57da70b4b5b1e08a6977ddde182677af0e5e1b8..0000000000000000000000000000000000000000
Binary files a/css/chosen-sprite.png and /dev/null differ
diff --git a/css/chosen-sprite@2x.png b/css/chosen-sprite@2x.png
deleted file mode 100644
index 6b50545202cb4770039362c55025b0b9824663ad..0000000000000000000000000000000000000000
Binary files a/css/chosen-sprite@2x.png and /dev/null differ
diff --git a/css/chosen.min.css b/css/chosen.min.css
deleted file mode 100644
index 8bfa3c8b0bc07a7448e0659ebcc4f655c26e7a1f..0000000000000000000000000000000000000000
--- a/css/chosen.min.css
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
-
-.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container a:hover{text-decoration:none} .chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:25px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;padding:0 5px;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
diff --git a/css/redactor.css b/css/redactor.css
index 46c298067f23b37c16b14b0a3163dff317062cd1..a3dc978446c5ec6be163994270f9a5698f438495 100644
--- a/css/redactor.css
+++ b/css/redactor.css
@@ -17,7 +17,8 @@
 .redactor-box {
   position: relative;
   overflow: visible;
-  background: #fff;
+  overflow-x: hidden;
+  background: #ddd;
 }
 .redactor-box textarea {
   display: block;
@@ -41,8 +42,7 @@
 /*
 	Z-index setup
 */
-.redactor-editor,
-.redactor-box {
+.redactor-editor {
   background: #fff;
 }
 .redactor-editor,
@@ -109,6 +109,7 @@ body .redactor-box-fullscreen {
   font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
   font-size: 14px;
   line-height: 1.6em;
+  box-shadow: 5px 0 10px -8px rgba(0,0,0,0.5);
 }
 .redactor-editor:focus {
   outline: none;
@@ -124,16 +125,16 @@ body .redactor-box-fullscreen {
 }
 .redactor-placeholder:after {
   position: absolute;
-  top: 20px;
-  left: 20px;
+  top: 10px;
+  left: 10px;
   content: attr(placeholder);
   color: #999 !important;
   font-weight: normal !important;
 }
 /* Placeholder in linebreaks mode */
 .redactor-linebreaks.redactor-placeholder:after {
-  top: 20px;
-  left: 20px;
+  top: 10px;
+  left: 10px;
 }
 /*
 	Toolbar
@@ -148,8 +149,9 @@ body .redactor-box-fullscreen {
   font-size: 14px !important;
   line-height: 1 !important;
   background: #fff;
-  border: none;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+  border: 1px solid rgba(0,0,0,0.05);
+  border-bottom: 0;
+  box-shadow: 0 1px 4px -2px rgba(0, 0, 0, 0.4);
 }
 .redactor-toolbar:after {
   content: "";
diff --git a/css/select2.min.css b/css/select2.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..1c7234426a473d3e017340ecda88f880dc1e3476
--- /dev/null
+++ b/css/select2.min.css
@@ -0,0 +1 @@
+.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle;}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px;}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap;}.select2-container .select2-search--inline{float:left;}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051;}.select2-results{display:block;}.select2-results__options{list-style:none;margin:0;padding:0;}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none;}.select2-results__option[aria-selected]{cursor:pointer;}.select2-container--open .select2-dropdown{left:0;}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-search--dropdown{display:block;padding:4px;}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box;}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-search--dropdown.select2-search--hide{display:none;}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0);}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px;}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px;}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto;}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none;}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%;}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left;}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder{float:right;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0;}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none;}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0;}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa;}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--default .select2-results__option[role=group]{padding:0;}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999;}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd;}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em;}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white;}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic .select2-selection--single{background-color:#f6f6f6;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:-o-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:linear-gradient(to bottom, #ffffff 50%, #eeeeee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px;}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#cccccc', GradientType=0);}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto;}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:-o-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:linear-gradient(to bottom, #ffffff 0%, #eeeeee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #ffffff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0;}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none;}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0;}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;}.select2-container--classic .select2-dropdown{background-color:white;border:1px solid transparent;}.select2-container--classic .select2-dropdown--above{border-bottom:none;}.select2-container--classic .select2-dropdown--below{border-top:none;}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--classic .select2-results__option[role=group]{padding:0;}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey;}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:white;}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb;}
\ No newline at end of file
diff --git a/css/thread.css b/css/thread.css
index 6fe012353f3137d0629f15d4ac73667694460c16..233f283158c5e8f98a67e1dad072bfac756e343d 100644
--- a/css/thread.css
+++ b/css/thread.css
@@ -208,15 +208,15 @@
 }
 .thread-body h1,
 .thread-body .h1 {
-  font-size: 36px;
+  font-size: 30px;
 }
 .thread-body h2,
 .thread-body .h2 {
-  font-size: 30px;
+  font-size: 25px;
 }
 .thread-body h3,
 .thread-body .h3 {
-  font-size: 24px;
+  font-size: 21px;
 }
 .thread-body h4,
 .thread-body .h4 {
diff --git a/file.php b/file.php
index 22cc8094be840bc25b322a6d571921f697beb8f8..fda45974ed942b2e342a9a1efc8c0eaa06ce99c1 100644
--- a/file.php
+++ b/file.php
@@ -29,11 +29,16 @@ if (!$_GET['key']
 // Validate session access hash - we want to make sure the link is FRESH!
 // and the user has access to the parent ticket!!
 if ($file->verifySignature($_GET['signature'], $_GET['expires'])) {
-    if (($s = @$_GET['s']) && strpos($file->getType(), 'image/') === 0)
-        return $file->display($s);
+    try {
+        if (($s = @$_GET['s']) && strpos($file->getType(), 'image/') === 0)
+            return $file->display($s);
 
-    // Download the file..
-    $file->download(@$_GET['disposition'] ?: false, $_GET['expires']);
+        // Download the file..
+        $file->download(@$_GET['disposition'] ?: false, $_GET['expires']);
+    }
+    catch (Exception $x) {
+        Http::response(500, 'Unable to find that file: '.$ex->getMessage());
+    }
 }
 // else
 Http::response(404, __('Unknown or invalid file'));
diff --git a/include/ajax.config.php b/include/ajax.config.php
index c263bd4a253993240b27e4557060b1fadc689ae1..a4e11bf22ab1ea5bebbab361604edbf71e569065 100644
--- a/include/ajax.config.php
+++ b/include/ajax.config.php
@@ -46,7 +46,7 @@ class ConfigAjaxAPI extends AjaxController {
               'has_rtl'         => $rtl,
               'lang_flag'       => strtolower($info['flag'] ?: $locale ?: $sl),
               'primary_lang_flag' => strtolower($primary_info['flag'] ?: $primary_locale ?: $primary_sl),
-              'primary_language' => $primary,
+              'primary_language' => Internationalization::rfc1766($primary),
               'secondary_languages' => $cfg->getSecondaryLanguages(),
               'page_size'       => $thisstaff->getPageLimit(),
         );
@@ -70,7 +70,7 @@ class ConfigAjaxAPI extends AjaxController {
             'lang'            => $lang,
             'short_lang'      => $sl,
             'has_rtl'         => $rtl,
-            'primary_language' => $cfg->getPrimaryLanguage(),
+            'primary_language' => Internationalization::rfc1766($cfg->getPrimaryLanguage()),
             'secondary_languages' => $cfg->getSecondaryLanguages(),
         );
 
diff --git a/include/ajax.draft.php b/include/ajax.draft.php
index b01054ed8b9d6bf8c193e8420e4d54769c1cfce2..9fa61635d730f8e1a67a4ebe18ea35271bf7eee0 100644
--- a/include/ajax.draft.php
+++ b/include/ajax.draft.php
@@ -94,6 +94,10 @@ class DraftAjaxAPI extends AjaxController {
                     ))
                 );
 
+            // Paste uploads in Chrome will have a name of 'blob'
+            if ($file[0]['name'] == 'blob')
+                $file[0]['name'] = 'screenshot-'.Misc::randCode(4);
+
             if (isset($file[0]['tmp_name'])) {
               $ids = $draft->attachments->upload($file);
             }
@@ -381,19 +385,20 @@ class DraftAjaxAPI extends AjaxController {
     function _findDraftBody($vars) {
         if (isset($vars['name'])) {
             $parts = array();
+            // Support nested `name`, like trans[lang]
             if (preg_match('`(\w+)(?:\[(\w+)\])?(?:\[(\w+)\])?`', $_POST['name'], $parts)) {
                 array_shift($parts);
                 $focus = $vars;
                 foreach ($parts as $p)
                     $focus = $focus[$p];
-                return urldecode($focus);
+                return $focus;
             }
         }
         $field_list = array('response', 'note', 'answer', 'body',
              'message', 'issue', 'description');
         foreach ($field_list as $field) {
             if (isset($vars[$field])) {
-                return urldecode($vars[$field]);
+                return $vars[$field];
             }
         }
 
diff --git a/include/ajax.reports.php b/include/ajax.reports.php
index 6dbf60df52322a91d8b513fb530e2246eb9c0ede..6086e3cb0b65fb214c14dd141d874976c25c0916 100644
--- a/include/ajax.reports.php
+++ b/include/ajax.reports.php
@@ -19,6 +19,7 @@
 if(!defined('INCLUDE_DIR')) die('403');
 
 include_once(INCLUDE_DIR.'class.ticket.php');
+include_once(INCLUDE_DIR.'class.report.php');
 
 /**
  * Overview Report
@@ -174,11 +175,7 @@ class OverviewReportAjaxAPI extends AjaxController {
             $stop = $this->get('period', 'now');
         }
 
-        if ($start != 'last month')
-            $start = DateTime::createFromFormat($cfg->getDateFormat(),
-                $start)->format('U');
-        else
-            $start = strtotime($start);
+       $start = strtotime($start);
 
         if (substr($stop, 0, 1) == '+')
             $stop = strftime('%Y-%m-%d ', $start) . $stop;
diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php
index 8181b4eaea1646aba8e229a96a6ac8fd9d2755b2..e0330dc98daf11ec850e10a6ac859c4916c67271 100644
--- a/include/ajax.tasks.php
+++ b/include/ajax.tasks.php
@@ -119,7 +119,7 @@ class TasksAjaxAPI extends AjaxController {
             Http::response(404, __('Unknown action'));
 
 
-        $errors = $e = array();
+        $info = $errors = $e = array();
         $inc = null;
         $i = $count = 0;
         if ($_POST) {
diff --git a/include/ajax.thread.php b/include/ajax.thread.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a8b72016d69ce2ff4565d5026134b380f6e0649
--- /dev/null
+++ b/include/ajax.thread.php
@@ -0,0 +1,305 @@
+<?php
+/*********************************************************************
+    ajax.thread.php
+
+    AJAX interface for thread
+
+    Peter Rotich <peter@osticket.com>
+    Copyright (c)  2015 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+
+if(!defined('INCLUDE_DIR')) die('403');
+
+include_once(INCLUDE_DIR.'class.ticket.php');
+require_once(INCLUDE_DIR.'class.ajax.php');
+require_once(INCLUDE_DIR.'class.note.php');
+include_once INCLUDE_DIR . 'class.thread_actions.php';
+
+class ThreadAjaxAPI extends AjaxController {
+
+    function lookup() {
+        global $thisstaff;
+
+        if(!is_numeric($_REQUEST['q']))
+            return self::lookupByEmail();
+
+
+        $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
+        $tickets=array();
+
+        $visibility = Q::any(array(
+            'staff_id' => $thisstaff->getId(),
+            'team_id__in' => $thisstaff->teams->values_flat('team_id'),
+        ));
+        if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) {
+            $visibility->add(array('dept_id__in' => $depts));
+        }
+
+
+        $hits = TicketModel::objects()
+            ->filter(Q::any(array(
+                'number__startswith' => $_REQUEST['q'],
+            )))
+            ->filter($visibility)
+            ->values('number', 'user__emails__address')
+            ->annotate(array('tickets' => SqlAggregate::COUNT('ticket_id')))
+            ->order_by('-created')
+            ->limit($limit);
+
+        foreach ($hits as $T) {
+            $tickets[] = array('id'=>$T['number'], 'value'=>$T['number'],
+                'info'=>"{$T['number']} — {$T['user__emails__address']}",
+                'matches'=>$_REQUEST['q']);
+        }
+        if (!$tickets)
+            return self::lookupByEmail();
+
+        return $this->json_encode($tickets);
+    }
+
+
+    function addRemoteCollaborator($tid, $bk, $id) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, 'No such thread');
+        elseif (!$bk || !$id)
+            Http::response(422, 'Backend and user id required');
+        elseif (!($backend = StaffAuthenticationBackend::getBackend($bk)))
+            Http::response(404, 'User not found');
+
+        $user_info = $backend->lookup($id);
+        $form = UserForm::getUserForm()->getForm($user_info);
+        $info = array();
+        if (!$user_info)
+            $info['error'] = __('Unable to find user in directory');
+
+        return self::_addcollaborator($thread, null, $form, $info);
+    }
+
+    //Collaborators utils
+    function addCollaborator($tid, $uid=0) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, __('No such thread'));
+
+
+        $user = $uid? User::lookup($uid) : null;
+
+        //If not a post then assume new collaborator form
+        if(!$_POST)
+            return self::_addcollaborator($thread, $user);
+
+        $user = $form = null;
+        if (isset($_POST['id']) && $_POST['id']) { //Existing user/
+            $user =  User::lookup($_POST['id']);
+        } else { //We're creating a new user!
+            $form = UserForm::getUserForm()->getForm($_POST);
+            $user = User::fromForm($form);
+        }
+
+        $errors = $info = array();
+        if ($user) {
+            // FIXME: Refuse to add ticket owner??
+            if (($c=$thread->addCollaborator($user,
+                            array('isactive'=>1), $errors))) {
+                $note = Format::htmlchars(sprintf(__('%s <%s> added as a collaborator'),
+                            Format::htmlchars($c->getName()), $c->getEmail()));
+
+                $thread->getObject()->postThreadEntry('N',
+                        array(
+                            'title' => __('New Collaborator Added'),
+                            'note' => $note
+                            ),
+                        array(
+                            'poster' => $thisstaff,
+                            'alert' => false
+                            )
+                        );
+                $info = array('msg' => sprintf(__('%s added as a collaborator'),
+                            Format::htmlchars($c->getName())));
+                return self::_collaborators($thread, $info);
+            }
+        }
+
+        if($errors && $errors['err']) {
+            $info +=array('error' => $errors['err']);
+        } else {
+            $info +=array('error' =>__('Unable to add collaborator. Internal error'));
+        }
+
+        return self::_addcollaborator($thread, $user, $form, $info);
+    }
+
+    function updateCollaborator($tid, $cid) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(405, 'No such thread');
+
+
+        if (!($c=Collaborator::lookup(array(
+                            'id' => $cid,
+                            'thread_id' => $thread->getId())))
+                || !($user=$c->getUser()))
+            Http::response(406, 'Unknown collaborator');
+
+        $errors = array();
+        if(!$user->updateInfo($_POST, $errors))
+            return self::_collaborator($c ,$user->getForms($_POST), $errors);
+
+        $info = array('msg' => sprintf('%s updated successfully',
+                    Format::htmlchars($c->getName())));
+
+        return self::_collaborators($thread, $info);
+    }
+
+    function viewCollaborator($tid, $cid) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, 'No such thread');
+
+
+        if (!($collaborator=Collaborator::lookup(array(
+                            'id' => $cid,
+                            'thread_id' => $thread->getId()))))
+            Http::response(404, 'Unknown collaborator');
+
+        return self::_collaborator($collaborator);
+    }
+
+    function showCollaborators($tid) {
+        global $thisstaff;
+
+        if(!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, 'No such thread');
+
+        if ($thread->getCollaborators())
+            return self::_collaborators($thread);
+
+        return self::_addcollaborator($thread);
+    }
+
+    function previewCollaborators($tid) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, 'No such thread');
+
+        ob_start();
+        include STAFFINC_DIR . 'templates/collaborators-preview.tmpl.php';
+        $resp = ob_get_contents();
+        ob_end_clean();
+
+        return $resp;
+    }
+
+    function _addcollaborator($thread, $user=null, $form=null, $info=array()) {
+        global $thisstaff;
+
+        $info += array(
+                    'title' => __('Add a collaborator'),
+                    'action' => sprintf('#thread/%d/add-collaborator',
+                        $thread->getId()),
+                    'onselect' => sprintf('ajax.php/thread/%d/add-collaborator/',
+                        $thread->getId()),
+                    );
+
+        ob_start();
+        include STAFFINC_DIR . 'templates/user-lookup.tmpl.php';
+        $resp = ob_get_contents();
+        ob_end_clean();
+
+        return $resp;
+    }
+
+    function updateCollaborators($tid) {
+        global $thisstaff;
+
+        if (!($thread=Thread::lookup($tid))
+                || !($object=$thread->getObject())
+                || !$object->checkStaffPerm($thisstaff))
+            Http::response(404, 'No such thread');
+
+        $errors = $info = array();
+        if ($thread->updateCollaborators($_POST, $errors))
+            Http::response(201, sprintf('Recipients (%d of %d)',
+                        $thread->getNumActiveCollaborators(),
+                        $thread->getNumCollaborators()));
+
+        if($errors && $errors['err'])
+            $info +=array('error' => $errors['err']);
+
+        return self::_collaborators($thread, $info);
+    }
+
+
+
+    function _collaborator($collaborator, $form=null, $info=array()) {
+        global $thisstaff;
+
+        $info += array('action' => sprintf('#thread/%d/collaborators/%d',
+                    $collaborator->thread_id, $collaborator->getId()));
+
+        $user = $collaborator->getUser();
+
+        ob_start();
+        include(STAFFINC_DIR . 'templates/user.tmpl.php');
+        $resp = ob_get_contents();
+        ob_end_clean();
+
+        return $resp;
+    }
+
+    function _collaborators($thread, $info=array()) {
+
+        ob_start();
+        include(STAFFINC_DIR . 'templates/collaborators.tmpl.php');
+        $resp = ob_get_contents();
+        ob_end_clean();
+
+        return $resp;
+    }
+
+    function triggerThreadAction($ticket_id, $thread_id, $action) {
+        $thread = ThreadEntry::lookup($thread_id);
+        if (!$thread)
+            Http::response(404, 'No such ticket thread entry');
+        if ($thread->getThread()->getObjectId() != $ticket_id)
+            Http::response(404, 'No such ticket thread entry');
+
+        $valid = false;
+        foreach ($thread->getActions() as $group=>$list) {
+            foreach ($list as $name=>$A) {
+                if ($A->getId() == $action) {
+                    $valid = true; break;
+                }
+            }
+        }
+        if (!$valid)
+            Http::response(400, 'Not a valid action for this thread');
+
+        $thread->triggerAction($action);
+    }
+}
+?>
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index d1ea440c0495351edb894f76acccb13599d670be..1e95dde3ec1c033f51fb70b13456739aafea7cfb 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -192,189 +192,6 @@ class TicketsAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/ticket-preview.tmpl.php';
     }
 
-    function addRemoteCollaborator($tid, $bk, $id) {
-        global $thisstaff;
-
-        if (!($ticket=Ticket::lookup($tid))
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, 'No such ticket');
-        elseif (!$bk || !$id)
-            Http::response(422, 'Backend and user id required');
-        elseif (!($backend = StaffAuthenticationBackend::getBackend($bk)))
-            Http::response(404, 'User not found');
-
-        $user_info = $backend->lookup($id);
-        $form = UserForm::getUserForm()->getForm($user_info);
-        $info = array();
-        if (!$user_info)
-            $info['error'] = __('Unable to find user in directory');
-
-        return self::_addcollaborator($ticket, null, $form, $info);
-    }
-
-    //Collaborators utils
-    function addCollaborator($tid, $uid=0) {
-        global $thisstaff;
-
-        if (!($ticket=Ticket::lookup($tid))
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, __('No such ticket'));
-
-
-        $user = $uid? User::lookup($uid) : null;
-
-        //If not a post then assume new collaborator form
-        if(!$_POST)
-            return self::_addcollaborator($ticket, $user);
-
-        $user = $form = null;
-        if (isset($_POST['id']) && $_POST['id']) { //Existing user/
-            $user =  User::lookup($_POST['id']);
-        } else { //We're creating a new user!
-            $form = UserForm::getUserForm()->getForm($_POST);
-            $user = User::fromForm($form);
-        }
-
-        $errors = $info = array();
-        if ($user) {
-            if ($user->getId() == $ticket->getOwnerId())
-                $errors['err'] = sprintf(__('Ticket owner, %s, is a collaborator by default!'),
-                        Format::htmlchars($user->getName()));
-            elseif (($c=$ticket->addCollaborator($user,
-                            array('isactive'=>1), $errors))) {
-                $note = Format::htmlchars(sprintf(__('%s <%s> added as a collaborator'),
-                            Format::htmlchars($c->getName()), $c->getEmail()));
-                $ticket->logNote(__('New Collaborator Added'), $note,
-                    $thisstaff, false);
-                $info = array('msg' => sprintf(__('%s added as a collaborator'),
-                            Format::htmlchars($c->getName())));
-                return self::_collaborators($ticket, $info);
-            }
-        }
-
-        if($errors && $errors['err']) {
-            $info +=array('error' => $errors['err']);
-        } else {
-            $info +=array('error' =>__('Unable to add collaborator. Internal error'));
-        }
-
-        return self::_addcollaborator($ticket, $user, $form, $info);
-    }
-
-    function updateCollaborator($cid) {
-        global $thisstaff;
-
-        if(!($c=Collaborator::lookup($cid))
-                || !($user=$c->getUser())
-                || !($ticket=$c->getTicket())
-                || !$ticket->checkStaffPerm($thisstaff)
-                )
-            Http::response(404, 'Unknown collaborator');
-
-        $errors = array();
-        if(!$user->updateInfo($_POST, $errors))
-            return self::_collaborator($c ,$user->getForms($_POST), $errors);
-
-        $info = array('msg' => sprintf('%s updated successfully',
-                    Format::htmlchars($c->getName())));
-
-        return self::_collaborators($ticket, $info);
-    }
-
-    function viewCollaborator($cid) {
-        global $thisstaff;
-
-        if(!($collaborator=Collaborator::lookup($cid))
-                || !($ticket=$collaborator->getTicket())
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, 'Unknown collaborator');
-
-        return self::_collaborator($collaborator);
-    }
-
-    function showCollaborators($tid) {
-        global $thisstaff;
-
-        if(!($ticket=Ticket::lookup($tid))
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, 'No such ticket');
-
-        if($ticket->getCollaborators())
-            return self::_collaborators($ticket);
-
-        return self::_addcollaborator($ticket);
-    }
-
-    function previewCollaborators($tid) {
-        global $thisstaff;
-
-        if (!($ticket=Ticket::lookup($tid))
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, 'No such ticket');
-
-        ob_start();
-        include STAFFINC_DIR . 'templates/collaborators-preview.tmpl.php';
-        $resp = ob_get_contents();
-        ob_end_clean();
-
-        return $resp;
-    }
-
-    function _addcollaborator($ticket, $user=null, $form=null, $info=array()) {
-
-        $info += array(
-                    'title' => sprintf(__('Ticket #%s: Add a collaborator'), $ticket->getNumber()),
-                    'action' => sprintf('#tickets/%d/add-collaborator', $ticket->getId()),
-                    'onselect' => sprintf('ajax.php/tickets/%d/add-collaborator/', $ticket->getId()),
-                    );
-        return self::_userlookup($user, $form, $info);
-    }
-
-
-    function updateCollaborators($tid) {
-        global $thisstaff;
-
-        if(!($ticket=Ticket::lookup($tid))
-                || !$ticket->checkStaffPerm($thisstaff))
-            Http::response(404, 'No such ticket');
-
-        $errors = $info = array();
-        if ($ticket->updateCollaborators($_POST, $errors))
-            Http::response(201, sprintf('Recipients (%d of %d)',
-                        $ticket->getNumActiveCollaborators(),
-                        $ticket->getNumCollaborators()));
-
-        if($errors && $errors['err'])
-            $info +=array('error' => $errors['err']);
-
-        return self::_collaborators($ticket, $info);
-    }
-
-
-
-    function _collaborator($collaborator, $form=null, $info=array()) {
-
-        $info += array('action' => '#collaborators/'.$collaborator->getId());
-
-        $user = $collaborator->getUser();
-
-        ob_start();
-        include(STAFFINC_DIR . 'templates/user.tmpl.php');
-        $resp = ob_get_contents();
-        ob_end_clean();
-
-        return $resp;
-    }
-
-    function _collaborators($ticket, $info=array()) {
-
-        ob_start();
-        include(STAFFINC_DIR . 'templates/collaborators.tmpl.php');
-        $resp = ob_get_contents();
-        ob_end_clean();
-
-        return $resp;
-    }
 
     function viewUser($tid) {
         global $thisstaff;
diff --git a/include/class.attachment.php b/include/class.attachment.php
index 748266003819edd0fbde1f248b0afdf15657a8a8..3247d06912d8baafaa895843556b6236f809a35d 100644
--- a/include/class.attachment.php
+++ b/include/class.attachment.php
@@ -22,10 +22,10 @@ class Attachment extends VerySimpleModel {
         'pk' => array('id'),
         'select_related' => array('file'),
         'joins' => array(
-            'thread_entry' => array(
+            'draft' => array(
                 'constraint' => array(
-                    'type' => "'H'",
-                    'object_id' => 'ThreadEntry.id',
+                    'type' => "'D'",
+                    'object_id' => 'Draft.id',
                 ),
             ),
             'file' => array(
@@ -33,6 +33,12 @@ class Attachment extends VerySimpleModel {
                     'file_id' => 'AttachmentFile.id',
                 ),
             ),
+            'thread_entry' => array(
+                'constraint' => array(
+                    'type' => "'H'",
+                    'object_id' => 'ThreadEntry.id',
+                ),
+            ),
         ),
     );
 
diff --git a/include/class.client.php b/include/class.client.php
index 25b03281b9abd31d359d265592dcdc7058061a24..eb4ef00a870c62a6355d3269ec5b6c0476ed27c5 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -245,6 +245,19 @@ class  EndUser extends BaseAuthenticatedUser {
         return ($stats=$this->getTicketStats())?$stats['closed']:0;
     }
 
+    function getNumOrganizationTickets() {
+        if (!($stats=$this->getTicketStats()))
+            return 0;
+
+        return $stats['org-open']+$stats['org-closed'];
+    }
+    function getNumOpenOrganizationTickets() {
+        return ($stats=$this->getTicketStats())?$stats['org-open']:0;
+    }
+    function getNumClosedOrganizationTickets() {
+        return ($stats=$this->getTicketStats())?$stats['org-closed']:0;
+    }
+
     function getAccount() {
         if ($this->_account === false)
             $this->_account =
@@ -263,6 +276,8 @@ class  EndUser extends BaseAuthenticatedUser {
         $where = ' WHERE ticket.user_id = '.db_input($this->getId())
                 .' OR collab.user_id = '.db_input($this->getId()).' ';
 
+        $where2 = ' WHERE user.org_id > 0 AND user.org_id = '.db_input($this->getOrgId()).' ';
+
         $join  =  'LEFT JOIN '.THREAD_TABLE.' thread
                     ON (ticket.ticket_id = thread.object_id and thread.object_type = \'T\')
                    LEFT JOIN '.THREAD_COLLABORATOR_TABLE.' collab
@@ -283,7 +298,25 @@ class  EndUser extends BaseAuthenticatedUser {
                     ON (ticket.status_id=status.id
                             AND status.state=\'closed\' ) '
                 . $join
-                . $where;
+                . $where
+
+                .'UNION SELECT \'org-open\', count( ticket.ticket_id ) AS tickets '
+                .'FROM ' . TICKET_TABLE . ' ticket '
+                .'INNER JOIN '.USER_TABLE.' user ON (ticket.user_id = user.id) '
+                .'INNER JOIN '.TICKET_STATUS_TABLE. ' status
+                    ON (ticket.status_id=status.id
+                            AND status.state=\'open\' ) '
+                . $join
+                . $where2
+
+                .'UNION SELECT \'org-closed\', count( ticket.ticket_id ) AS tickets '
+                .'FROM ' . TICKET_TABLE . ' ticket '
+                .'INNER JOIN '.USER_TABLE.' user ON (ticket.user_id = user.id) '
+                .'INNER JOIN '.TICKET_STATUS_TABLE. ' status
+                    ON (ticket.status_id=status.id
+                            AND status.state=\'closed\' ) '
+                . $join
+                . $where2;
 
         $res = db_query($sql);
         $stats = array();
diff --git a/include/class.collaborator.php b/include/class.collaborator.php
index c457f1cd3cf4feac927e6076a428bc6a90ca4766..205b5200b151911c757611483fae9560f041bb27 100644
--- a/include/class.collaborator.php
+++ b/include/class.collaborator.php
@@ -51,6 +51,10 @@ implements EmailContact, ITicketUser {
         return $this->created;
     }
 
+    function getThreadId() {
+        return $this->thread_id;
+    }
+
     function getTicketId() {
         if ($this->thread->object_type == ObjectModel::OBJECT_TYPE_TICKET)
             return $this->thread->object_id;
@@ -140,18 +144,5 @@ implements EmailContact, ITicketUser {
         return false;
     }
 
-    static function forThread($tid, $criteria=array()) {
-
-        $collaborators = static::objects()
-            ->filter(array('thread_id' => $tid));
-
-        if (isset($criteria['isactive']))
-            $collaborators->filter(array('isactive' => $criteria['isactive']));
-
-        // TODO: sort by name of the user
-        $collaborators->order_by('user__name');
-
-        return $collaborators;
-    }
 }
 ?>
diff --git a/include/class.config.php b/include/class.config.php
index a85fc696263e4316da1f0181e6ccf6a4ea6921ce..cb1f15d5c4f96447db712798a2a6a8bcfbd548ec 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -999,12 +999,6 @@ class OsticketConfig extends Config {
             case 'access':
                 return $this->updateAccessSettings($vars, $errors);
                 break;
-            case 'autoresp':
-                return $this->updateAutoresponderSettings($vars, $errors);
-                break;
-            case 'alerts':
-                return $this->updateAlertsSettings($vars, $errors);
-                break;
             case 'kb':
                 return $this->updateKBSettings($vars, $errors);
                 break;
@@ -1114,6 +1108,9 @@ class OsticketConfig extends Config {
         if (!preg_match('`(?!<\\\)#`', $vars['ticket_number_format']))
             $errors['ticket_number_format'] = 'Ticket number format requires at least one hash character (#)';
 
+        $this->updateAutoresponderSettings($vars, $errors);
+        $this->updateAlertsSettings($vars, $errors);
+
         if(!Validator::process($f, $vars, $errors) || $errors)
             return false;
 
diff --git a/include/class.dept.php b/include/class.dept.php
index 8343d6f6690c9917a8fbe8f4e145d7a5f08e03bd..4e42d9335fca4fe40f339266012c8f400868100e 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -159,6 +159,7 @@ implements TemplateVariable {
 
         if (!$this->_members || $criteria) {
             $members = Staff::objects()
+                ->distinct('staff_id')
                 ->filter(Q::any(array(
                     'dept_id' => $this->getId(),
                     new Q(array(
diff --git a/include/class.draft.php b/include/class.draft.php
index 5b2d8462bc5515eec588df3fed2c05aa8fe7294d..1938064f8bfe5dd605bfc1c56077f0be58e06bd1 100644
--- a/include/class.draft.php
+++ b/include/class.draft.php
@@ -167,14 +167,12 @@ class Draft extends VerySimpleModel {
      * are cleaned up.
      */
     static function deleteForNamespace($namespace, $staff_id=false) {
-        $sql = 'DELETE attach FROM '.ATTACHMENT_TABLE.' attach
-                INNER JOIN '.DRAFT_TABLE.' draft
-                ON (attach.object_id = draft.id AND attach.`type`=\'D\')
-                WHERE draft.`namespace` LIKE '.db_input($namespace);
+        $attachments = Attachment::objects()
+            ->filter(array('draft__namespace__like' => $namespace));
         if ($staff_id)
-            $sql .= ' AND draft.staff_id='.db_input($staff_id);
-        if (!db_query($sql))
-            return false;
+            $attachments->filter(array('draft__staff_id' => $staff_id));
+
+        $attachments->delete();
 
         $criteria = array('namespace__like'=>$namespace);
         if ($staff_id)
@@ -183,11 +181,10 @@ class Draft extends VerySimpleModel {
     }
 
     static function cleanup() {
-        // Keep client drafts for two weeks (14 days)
+        // Keep drafts for two weeks (14 days)
         $sql = 'DELETE FROM '.DRAFT_TABLE
-            ." WHERE `namespace` LIKE 'ticket.client.%'
-            AND ((updated IS NULL AND datediff(now(), created) > 14)
-                OR datediff(now(), updated) > 14)";
+            ." WHERE (updated IS NULL AND datediff(now(), created) > 14)
+                OR datediff(now(), updated) > 14";
         return db_query($sql);
     }
 }
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index ca2b3f2c8fa2a649f5b9cfa2e55a786737339f38..43ae645c765a97524d7479e6995c5261319d522d 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -153,6 +153,14 @@ class DynamicForm extends VerySimpleModel {
         return $inst;
     }
 
+    function disableFields(array $ids) {
+        foreach ($this->getFields() as $F) {
+            if (in_array($F->get('id'), $ids)) {
+                $F->disable();
+            }
+        }
+    }
+
     function getTranslateTag($subtag) {
         return _H(sprintf('form.%s.%s', $subtag, $this->id));
     }
@@ -236,7 +244,7 @@ class DynamicForm extends VerySimpleModel {
         // New translations (?)
         if ($vars['trans'] && is_array($vars['trans'])) {
             foreach ($vars['trans'] as $lang=>$parts) {
-                if (!Internationalization::isLanguageInstalled($lang))
+                if (!Internationalization::isLanguageEnabled($lang))
                     continue;
                 foreach ($parts as $T => $content) {
                     $content = trim($content);
@@ -471,7 +479,8 @@ class TicketForm extends DynamicForm {
         // field.id=ans.field_id
         // where entry.object_type='T' group by entry.object_id;
         $sql = 'CREATE TABLE `'.TABLE_PREFIX.'ticket__cdata` (PRIMARY KEY
-                (ticket_id)) AS ' . static::getCrossTabQuery('T', 'ticket_id');
+            (ticket_id)) DEFAULT CHARSET=utf8 AS '
+            . static::getCrossTabQuery('T', 'ticket_id');
         db_query($sql);
     }
 
@@ -985,15 +994,18 @@ class DynamicFormEntry extends VerySimpleModel {
     function getForm() {
         if (!isset($this->_form)) {
             // XXX: Should source be $this?
-            $form = new SimpleForm($this->getFields(), $this->getSource(),
+            $fields = $this->getFields();
+            if (isset($this->extra)) {
+                $x = JsonDataParser::decode($this->extra) ?: array();
+                foreach ($x['disable'] ?: array() as $id) {
+                    unset($fields[$id]);
+                }
+            }
+            $form = new SimpleForm($fields, $this->getSource(),
             array(
                 'title' => $this->getTitle(),
                 'instructions' => $this->getInstructions(),
             ));
-            if (isset($this->extra)) {
-                $x = JsonDataParser::decode($this->extra) ?: array();
-                $form->disableFields($x['disable'] ?: array());
-            }
             $this->_form = $form;
         }
         return $this->_form;
diff --git a/include/class.export.php b/include/class.export.php
index 447435b41e8cf7d99a979b3702c966e0dc9f32d8..acdc333582c6d7d54b35c0fd17d4db5ccd5ec473 100644
--- a/include/class.export.php
+++ b/include/class.export.php
@@ -110,6 +110,10 @@ class Export {
         return false;
     }
 
+    static function saveTasks($sql, $filename, $how='csv') {
+        return false;
+    }
+
     static function saveUsers($sql, $filename, $how='csv') {
 
         $exclude = array('name', 'email');
diff --git a/include/class.faq.php b/include/class.faq.php
index 20474c7331078190ecf8fed65cc755db21dd96b3..f2d42355bff78ea3781f62a4b1ca4b9b8e663421 100644
--- a/include/class.faq.php
+++ b/include/class.faq.php
@@ -316,8 +316,8 @@ class FAQ extends VerySimpleModel {
 
     function getVisibleAttachments() {
         return array_merge(
-            $this->attachments->getSeparates() ?: array(),
-            $this->getLocalAttachments());
+            $this->attachments->getSeparates()->all() ?: array(),
+            $this->getLocalAttachments()->all());
     }
 
     function getAttachmentsLinks($separator=' ',$target='') {
diff --git a/include/class.file.php b/include/class.file.php
index 78cbed9c8e9d634cf828a34d5ab28c532804c3fb..5f4013ff762f85b780c61bc746d84190deba714b 100644
--- a/include/class.file.php
+++ b/include/class.file.php
@@ -437,6 +437,10 @@ class AttachmentFile extends VerySimpleModel {
         return $f;
     }
 
+    static function __create($file, &$errors) {
+        return static::create($file);
+    }
+
     /**
      * Migrate this file from the current backend to the backend specified.
      *
diff --git a/include/class.format.php b/include/class.format.php
index 06a07f5065e5ad5bcc5357833817eb9d37544fdd..cd9b27f24657c5c95ff59699d9706912c38ae36b 100644
--- a/include/class.format.php
+++ b/include/class.format.php
@@ -366,7 +366,7 @@ class Format {
             },
             'schemes' => 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https; src: cid, http, https, data',
             'elements' => '*+iframe',
-            'spec' => 'span=data-src,width,height',
+            'spec' => 'span=data-src,width,height;img=data-cid',
         );
         return Format::html($text, $config);
     }
@@ -441,9 +441,12 @@ class Format {
             $strftimeFallback, $timezone, $user=false) {
         global $cfg;
 
-        if ($timestamp && $fromDb) {
+        if (!$timestamp)
+            return '';
+
+        if ($fromDb)
             $timestamp = Misc::db2gmtime($timestamp);
-        }
+
         if (class_exists('IntlDateFormatter')) {
             $formatter = new IntlDateFormatter(
                 Internationalization::getCurrentLocale($user),
diff --git a/include/class.forms.php b/include/class.forms.php
index 9b8de17b2bee8cf3f49853c3823cd36a1adcaa63..0b6da8f275f0f5a75fc08c3f618279bdd2aff058 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -56,7 +56,7 @@ class Form {
 
     function setFields($fields) {
 
-        if (!is_array($fields))
+        if (!is_array($fields) && !$fields instanceof Traversable)
             return;
 
         $this->fields = $fields;
@@ -127,14 +127,6 @@ class Form {
         return $this->_clean;
     }
 
-    function disableFields(array $ids) {
-        foreach ($this->getFields() as $F) {
-            if (in_array($F->get('id'), $ids)) {
-                $F->disable();
-            }
-        }
-    }
-
     function errors($formOnly=false) {
         return ($formOnly) ? $this->_errors['form'] : $this->_errors;
     }
@@ -438,7 +430,7 @@ class FormField {
         return $this->_errors;
     }
     function addError($message, $index=false) {
-        if ($field)
+        if ($index)
             $this->_errors[$index] = $message;
         else
             $this->_errors[] = $message;
@@ -1622,6 +1614,14 @@ class ThreadEntryField extends FormField {
         return false;
     }
 
+    function getMedia() {
+        $config = $this->getConfiguration();
+        $media = parent::getMedia() ?: array();
+        if ($config['attachments'])
+            $media = array_merge_recursive($media, FileUploadWidget::$media);
+        return $media;
+    }
+
     function getConfigurationOptions() {
         global $cfg;
 
@@ -2576,10 +2576,17 @@ class TextboxWidget extends Widget {
             $disabled = 'disabled="disabled"';
         if (isset($config['translatable']) && $config['translatable'])
             $translatable = 'data-translate-tag="'.$config['translatable'].'"';
+        $type = static::$input_type;
+        $types = array(
+            'email' => 'email',
+            'phone' => 'tel',
+        );
+        if ($type == 'text' && isset($types[$config['validator']]))
+            $type = $types[$config['validator']];
         $placeholder = sprintf('placeholder="%s"', $this->field->getLocal('placeholder',
             $config['placeholder']));
         ?>
-        <input type="<?php echo static::$input_type; ?>"
+        <input type="<?php echo $type; ?>"
             id="<?php echo $this->id; ?>"
             <?php echo implode(' ', array_filter(array(
                 $size, $maxlength, $classes, $autocomplete, $disabled,
@@ -2669,7 +2676,7 @@ class PhoneNumberWidget extends Widget {
         $config = $this->field->getConfiguration();
         list($phone, $ext) = explode("X", $this->value);
         ?>
-        <input id="<?php echo $this->id; ?>" type="text" name="<?php echo $this->name; ?>" value="<?php
+        <input id="<?php echo $this->id; ?>" type="tel" name="<?php echo $this->name; ?>" value="<?php
         echo Format::htmlchars($phone); ?>"/><?php
         // Allow display of extension field even if disabled if the phone
         // number being edited has an extension
@@ -2745,13 +2752,13 @@ class ChoicesWidget extends Widget {
             id="<?php echo $this->id; ?>"
             data-placeholder="<?php echo $prompt; ?>"
             <?php if ($config['multiselect'])
-                echo ' multiple="multiple" class="chosen-select"'; ?>>
+                echo ' multiple="multiple"'; ?>>
             <?php if (!$have_def && !$config['multiselect']) { ?>
             <option value="<?php echo $def_key; ?>">&mdash; <?php
                 echo $def_val; ?> &mdash;</option>
 <?php
         }
-        $this->emitChoices($choices, $values); ?>
+        $this->emitChoices($choices, $values, $have_def, $def_key); ?>
         </select>
         <?php
         if ($config['multiselect']) {
@@ -2759,17 +2766,17 @@ class ChoicesWidget extends Widget {
         <script type="text/javascript">
         $(function() {
             $("#<?php echo $this->id; ?>")
-            .chosen({'disable_search_threshold':10, 'width': '250px'});
+            .select2({'minimumResultsForSearch':10, 'width': '350px'});
         });
         </script>
        <?php
         }
     }
 
-    function emitChoices($choices, $values=array()) {
+    function emitChoices($choices, $values=array(), $have_def=false, $def_key=null) {
         reset($choices);
         if (is_array(current($choices)) || current($choices) instanceof Traversable)
-            return $this->emitComplexChoices($choices, $values);
+            return $this->emitComplexChoices($choices, $values, $have_def, $def_key);
 
         foreach ($choices as $key => $name) {
             if (!$have_def && $key == $def_key)
@@ -2781,7 +2788,7 @@ class ChoicesWidget extends Widget {
         }
     }
 
-    function emitComplexChoices($choices, $values=array()) {
+    function emitComplexChoices($choices, $values=array(), $have_def=false, $def_key=null) {
         foreach ($choices as $label => $group) { ?>
             <optgroup label="<?php echo $label; ?>"><?php
             foreach ($group as $key => $name) {
@@ -3307,7 +3314,7 @@ class AssignmentForm extends Form {
                     'default'=>'',
                     'configuration' => array(
                         'html' => true,
-                        'size' => 'large',
+                        'size' => 'small',
                         'placeholder' => __('Optional reason for the assignment'),
                         ),
                     )
diff --git a/include/class.i18n.php b/include/class.i18n.php
index c6e4bfc61b50973d19a3a2ad38d140178c2ef49f..5d5000b2a9b06bafbdad7025ea918f2308d7560e 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -66,7 +66,7 @@ class Internationalization {
             'role.yaml' =>          'Role::__create',
             // Note that group requires department
             'group.yaml' =>         'Group::__create',
-            'file.yaml' =>          'AttachmentFile::create',
+            'file.yaml' =>          'AttachmentFile::__create',
             'sequence.yaml' =>      'Sequence::__create',
         );
 
@@ -255,18 +255,28 @@ class Internationalization {
         return isset($langs[strtolower($code)]);
     }
 
+    static function isLanguageEnabled($code) {
+        $langs = self::getConfiguredSystemLanguages();
+        return isset($langs[$code]);
+    }
+
     static function getConfiguredSystemLanguages() {
         global $cfg;
+        static $langs;
 
         if (!$cfg)
             return self::availableLanguages();
 
-        $pri = $cfg->getPrimaryLanguage();
-        $langs = array($pri => self::getLanguageInfo($pri));
+        if (!isset($langs)) {
+            $pri = $cfg->getPrimaryLanguage();
+            if ($info = self::getLanguageInfo($pri))
+                $langs = array($pri => $info);
 
-        // Honor sorting preference of ::availableLanguages()
-        foreach ($cfg->getSecondaryLanguages() as $l) {
-            $langs[$l] = self::getLanguageInfo($l);
+            // Honor sorting preference of ::availableLanguages()
+            foreach ($cfg->getSecondaryLanguages() as $l) {
+                if ($info = self::getLanguageInfo($l))
+                    $langs[$l] = $info;
+            }
         }
         return $langs;
     }
@@ -362,19 +372,15 @@ class Internationalization {
 
     static function getCurrentLanguage($user=false) {
         global $thisstaff, $thisclient;
-        static $session = null;
-
-        if (!isset($session))
-            $session = &$_SESSION['::lang'];
 
         $user = $user ?: $thisstaff ?: $thisclient;
         if ($user && method_exists($user, 'getLanguage'))
-            if ($lang = $user->getLanguage())
+            if (($lang = $user->getLanguage()) && self::isLanguageEnabled($lang))
                 return $lang;
 
         // Support the flag buttons for guests
-        if ((!$user || $user != $thisstaff) && $session)
-            return $session;
+        if ((!$user || $user != $thisstaff) && $_SESSION['::lang'])
+            return $_SESSION['::lang'];
 
         return self::getDefaultLanguage();
     }
@@ -398,6 +404,15 @@ class Internationalization {
         return $locale;
     }
 
+    static function rfc1766($what) {
+        if (is_array($what))
+            return array_map(array(get_called_class(), 'rfc1766'), $what);
+
+        $lr = explode('_', $what);
+        if (isset($lr[1]))
+            $lr[1] = strtoupper($lr[1]);
+        return implode('-', $lr);
+    }
 
     static function getTtfFonts() {
         if (!class_exists('Phar'))
diff --git a/include/class.mailer.php b/include/class.mailer.php
index 412428eccdf11d370951141fc91e3cd358ab5386..83f097050624924326e9da6b22e90eeb041f5deb 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -509,6 +509,8 @@ class Mailer {
 
         //No SMTP or it failed....use php's native mail function.
         $mail = mail::factory('mail');
+        // Ensure the To: header is properly encoded.
+        $to = $headers['To'];
         return PEAR::isError($mail->send($to, $headers, $body))?false:$messageId;
 
     }
diff --git a/include/class.nav.php b/include/class.nav.php
index 7d3c119b753d515ddf3e24a76359627eec9723c2..e6df1e897ea390b2d59b4dc38de5edfcdf11ae18 100644
--- a/include/class.nav.php
+++ b/include/class.nav.php
@@ -249,8 +249,6 @@ class AdminNav extends StaffNav{
                     $subnav[]=array('desc'=>__('Tasks'),'href'=>'settings.php?t=tasks','iconclass'=>'lists');
                     $subnav[]=array('desc'=>__('Access'),'href'=>'settings.php?t=access','iconclass'=>'users');
                     $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 and Notices'),'href'=>'settings.php?t=alerts','iconclass'=>'alert-settings');
                     break;
                 case 'manage':
                     $subnav[]=array('desc'=>__('Help Topics'),'href'=>'helptopics.php','iconclass'=>'helpTopics');
diff --git a/include/class.orm.php b/include/class.orm.php
index 38e1d931d49db8057591de5d9d250e911519d3f0..57029871265b38038f32d5726038a724d39d3de0 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -47,10 +47,10 @@ class ModelMeta implements ArrayAccess {
 
         if (!$meta['table'])
             throw new OrmConfigurationException(
-                __('Model does not define meta.table'), $model);
+                sprintf(__('%s: Model does not define meta.table'), $model));
         elseif (!$meta['pk'])
             throw new OrmConfigurationException(
-                __('Model does not define meta.pk'), $model);
+                sprintf(__('%s: Model does not define meta.pk'), $model));
 
         // Ensure other supported fields are set and are arrays
         foreach (array('pk', 'ordering', 'defer') as $f) {
@@ -141,7 +141,20 @@ class ModelMeta implements ArrayAccess {
     }
 
     function inspectFields() {
-        return DbEngine::getCompiler()->inspectTable($this['table']);
+        static $cache;
+        if (!isset($cache))
+            $cache = function_exists('apc_fetch');
+        if ($cache) {
+            $key = md5(SECRET_SALT . GIT_VERSION . $this['table']);
+            if ($fields = apc_fetch($key)) {
+                return $fields;
+            }
+        }
+        $fields = DbEngine::getCompiler()->inspectTable($this['table']);
+        if ($cache) {
+            apc_store($key, $fields);
+        }
+        return $fields;
     }
 }
 
@@ -172,10 +185,17 @@ class VerySimpleModel {
             $j = static::$meta['joins'][$field];
             // Support instrumented lists and such
             if (isset($j['list']) && $j['list']) {
-                $fkey = $j['fkey'];
+                $class = $j['fkey'][0];
+                $fkey = array();
+                // Localize the foreign key constraint
+                foreach ($j['constraint'] as $local=>$foreign) {
+                    list($_klas,$F) = $foreign;
+                    $fkey[$F ?: $_klas] = ($local[0] == "'")
+                        ? trim($local, "'") : $this->ht[$local];
+                }
                 $v = $this->ht[$field] = new InstrumentedList(
-                    // Send Model, Foriegn-Field, Local-Id
-                    array($fkey[0], $fkey[1], $this->get($j['local']))
+                    // Send Model, [Foriegn-Field => Local-Id]
+                    array($class, $fkey)
                 );
                 return $v;
             }
@@ -1349,29 +1369,32 @@ class HashArrayIterator extends ResultSet {
 
 class InstrumentedList extends ModelInstanceManager {
     var $key;
-    var $id;
     var $model;
 
     function __construct($fkey, $queryset=false) {
-        list($model, $this->key, $this->id) = $fkey;
+        list($model, $this->key) = $fkey;
         if (!$queryset)
-            $queryset = $model::objects()->filter(array($this->key=>$this->id));
+            $queryset = $model::objects()->filter($this->key);
         parent::__construct($queryset);
         $this->model = $model;
-        if (!$this->id)
-            $this->resource = null;
     }
 
     function add($object, $at=false) {
         if (!$object || !$object instanceof $this->model)
             throw new Exception(__('Attempting to add invalid object to list'));
 
-        $object->set($this->key, $this->id);
+        foreach ($this->key as $field=>$value)
+            $object->set($field, $value);
+
+        if (!$object->__new__)
+            $object->save();
 
         if ($at !== false)
             $this->cache[$at] = $object;
         else
             $this->cache[] = $object;
+
+        return $object;
     }
     function remove($object, $delete=true) {
         if ($delete)
@@ -2298,6 +2321,10 @@ class MySqlExecutor {
                 $types .= 's';
                 $p = $p->format('Y-m-d h:i:s');
             }
+            elseif (is_object($p)) {
+                $types .= 's';
+                $p = (string) $p;
+            }
             // TODO: Emit error if param is null
             $ps[] = &$p;
         }
diff --git a/include/class.osticket.php b/include/class.osticket.php
index 75a247c1072a7cf3143c8929a4ef46e13b228d1b..2f06453973fc318c303a76edb18cb5b3195ff745 100644
--- a/include/class.osticket.php
+++ b/include/class.osticket.php
@@ -270,6 +270,10 @@ class osTicket {
             $e->getTraceAsString());
         $error .= nl2br("\n\n---- "._S('Backtrace')." ----\n".$bt);
 
+        // Prevent recursive loops through this code path
+        if (substr_count($bt, __FUNCTION__) > 1)
+            return;
+
         return $this->log(LOG_ERR, $title, $error, $alert);
     }
 
diff --git a/include/class.search.php b/include/class.search.php
index d41f0a59a3a6a871fef236d018cbdde2d3555ffb..b319b0a587bfa08b6f5acf8f4a3a1a7cca38fe76 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -82,16 +82,19 @@ class SearchInterface {
     }
 
     function update($model, $id, $content, $new=false, $attrs=array()) {
-        if (!$this->backend)
-            return;
-
-        $this->backend->update($model, $id, $content, $new, $attrs);
+        if ($this->backend)
+            $this->backend->update($model, $id, $content, $new, $attrs);
     }
 
     function createModel($model) {
         return $this->updateModel($model, true);
     }
 
+    function deleteModel($model) {
+        if ($this->backend)
+            $this->backend->delete($model);
+    }
+
     function updateModel($model, $new=false) {
         // The MySQL backend does not need to index attributes of the
         // various models, because those other attributes are available in
@@ -104,11 +107,10 @@ class SearchInterface {
                 break;
 
             $this->update($model, $model->getId(),
-                $model->getBody()->getSearchable(), $new,
+                $model->getBody()->getSearchable(),
+                $new === true,
                 array(
                     'title' =>      $model->getTitle(),
-                    //TODO: send attribute of object_id
-                    'ticket_id' =>  $model->getThread()->getObjectId(),
                     'created' =>    $model->getCreateDate(),
                 )
             );
@@ -121,7 +123,7 @@ class SearchInterface {
                     $cdata[] = $v;
             $this->update($model, $model->getId(),
                 trim(implode("\n", $cdata)),
-                $new,
+                $new === true,
                 array(
                     'title'=>       Format::searchable($model->getSubject()),
                     'number'=>      $model->getNumber(),
@@ -148,7 +150,7 @@ class SearchInterface {
                         $cdata[] = $v;
             $this->update($model, $model->getId(),
                 trim(implode("\n", $cdata)),
-                $new,
+                $new === true,
                 array(
                     'title'=>       Format::searchable($model->getFullName()),
                     'emails'=>      $model->emails->asArray(),
@@ -166,7 +168,7 @@ class SearchInterface {
                         $cdata[] = $v;
             $this->update($model, $model->getId(),
                 trim(implode("\n", $cdata)),
-                $new,
+                $new === true,
                 array(
                     'title'=>       Format::searchable($model->getName()),
                     'created'=>     $model->getCreateDate(),
@@ -177,7 +179,7 @@ class SearchInterface {
         case $model instanceof FAQ:
             $this->update($model, $model->getId(),
                 $model->getSearchableAnswer(),
-                $new,
+                $new === true,
                 array(
                     'title'=>       Format::searchable($model->getQuestion()),
                     'keywords'=>    $model->getKeywords(),
@@ -219,7 +221,7 @@ class SearchInterface {
         Signal::connect('model.created', array($this, 'createModel'), 'FAQ');
 
         Signal::connect('model.updated', array($this, 'updateModel'));
-        #Signal::connect('model.deleted', array($this, 'deleteModel'));
+        Signal::connect('model.deleted', array($this, 'deleteModel'));
     }
 }
 
@@ -239,6 +241,7 @@ class MysqlSearchBackend extends SearchBackend {
     // Only index 20 batches per cron run
     var $max_batches = 60;
     var $_reindexed = 0;
+    var $SEARCH_TABLE;
 
     function __construct() {
         $this->SEARCH_TABLE = TABLE_PREFIX . '_search';
@@ -257,8 +260,6 @@ class MysqlSearchBackend extends SearchBackend {
     }
 
     function update($model, $id, $content, $new=false, $attrs=array()) {
-
-
         if (!($type=ObjectModel::getType($model)))
             return;
 
@@ -271,6 +272,8 @@ class MysqlSearchBackend extends SearchBackend {
 
         if (!$content && !$title)
             return;
+        if (!$id)
+            return;
 
         $sql = 'REPLACE INTO '.$this->SEARCH_TABLE
             . ' SET object_type='.db_input($type)
@@ -280,6 +283,26 @@ class MysqlSearchBackend extends SearchBackend {
         return db_query($sql);
     }
 
+    function delete($model) {
+        switch (true) {
+        case $model instanceof Thread:
+            $sql = 'DELETE s.* FROM '.$this->SEARCH_TABLE
+                . " s JOIN ".THREAD_ENTRY_TABLE." h ON (h.id = s.object_id) "
+                . " WHERE s.object_type='H'"
+                . ' AND h.thread_id='.db_input($model->getId());
+            return db_query($sql);
+
+        default:
+            if (!($type = ObjectModel::getType($model)))
+                return;
+
+            $sql = 'DELETE FROM '.$this->SEARCH_TABLE
+                . ' WHERE object_type='.db_input($type)
+                . ' AND object_id='.db_input($model->getId());
+            return db_query($sql);
+        }
+    }
+
     // Quote things like email addresses
     function quote($query) {
         $parts = array();
diff --git a/include/class.staff.php b/include/class.staff.php
index 8362656a1370ba407e864baa49b0510cc995b25d..b573eaa6efcc7da49c0cc3a71b979a80cff9f40b 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -49,7 +49,6 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
 
     var $authkey;
     var $departments;
-    var $timezone;
     var $stats = array();
     var $_extra;
     var $passwd_change;
@@ -604,9 +603,6 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
 
         if($errors) return false;
 
-        $_SESSION['staff:lang'] = null;
-        TextDomain::configureForUser($this);
-
         $this->firstname = $vars['firstname'];
         $this->lastname = $vars['lastname'];
         $this->email = $vars['email'];
@@ -623,6 +619,9 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         $this->default_paper_size = $vars['default_paper_size'];
         $this->lang = $vars['lang'];
 
+        $_SESSION['::lang'] = null;
+        TextDomain::configureForUser($this);
+
         return $this->save();
     }
 
diff --git a/include/class.task.php b/include/class.task.php
index c629379f6e88470408ab6eab9e36467576a38958..dd7fadcbd25f560b55904ea994f1862f59273919 100644
--- a/include/class.task.php
+++ b/include/class.task.php
@@ -181,7 +181,7 @@ class TaskModel extends VerySimpleModel {
 RolePermission::register(/* @trans */ 'Tasks', TaskModel::getPermissions());
 
 
-class Task extends TaskModel {
+class Task extends TaskModel implements Threadable {
     var $form;
     var $entry;
 
@@ -269,6 +269,10 @@ class Task extends TaskModel {
         return $assignees ? implode($glue, $assignees):'';
     }
 
+    function getThreadId() {
+        return $this->thread->getId();
+    }
+
     function getThread() {
         return $this->thread;
     }
@@ -284,6 +288,17 @@ class Task extends TaskModel {
         return $thread;
     }
 
+    function postThreadEntry($type, $vars, $options=array()) {
+        $errors = array();
+        $poster = isset($options['poster']) ? $options['poster'] : null;
+        $alert = isset($options['alert']) ? $options['alert'] : true;
+        switch ($type) {
+        case 'N':
+        default:
+            return $this->postNote($vars, $errors, $poster, $alert);
+        }
+    }
+
     function getForm() {
         if (!isset($this->form)) {
             // Look for the entry first
diff --git a/include/class.thread.php b/include/class.thread.php
index bd50ecb20c48a8c7e3a2e935cfdf878042c07748..75d5a14a396bf1830b0708f89f6a6d0f7caeb72d 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -46,6 +46,7 @@ class Thread extends VerySimpleModel {
     );
 
     var $_object;
+    var $_collaborators; // Cache for collabs
 
     function getId() {
         return $this->id;
@@ -89,6 +90,108 @@ class Thread extends VerySimpleModel {
         return $base;
     }
 
+    // Collaborators
+    function getNumCollaborators() {
+        return $this->collaborators->count();
+    }
+
+    function getNumActiveCollaborators() {
+
+        if (!isset($this->ht['active_collaborators']))
+            $this->ht['active_collaborators'] = count($this->getActiveCollaborators());
+
+        return $this->ht['active_collaborators'];
+    }
+
+    function getActiveCollaborators() {
+        return $this->getCollaborators(array('isactive'=>1));
+    }
+
+    function getCollaborators($criteria=array()) {
+
+        if ($this->_collaborators && !$criteria)
+            return $this->_collaborators;
+
+        $collaborators = $this->collaborators
+            ->filter(array('thread_id' => $this->getId()));
+
+        if (isset($criteria['isactive']))
+            $collaborators->filter(array('isactive' => $criteria['isactive']));
+
+        // TODO: sort by name of the user
+        $collaborators->order_by('user__name');
+
+        if (!$criteria)
+            $this->_collaborators = $collaborators;
+
+        return $collaborators;
+    }
+
+    function addCollaborator($user, $vars, &$errors) {
+
+        if (!$user)
+            return null;
+
+        $vars = array_merge(array(
+                'threadId' => $this->getId(),
+                'userId' => $user->getId()), $vars);
+        if (!($c=Collaborator::add($vars, $errors)))
+            return null;
+
+        $this->_collaborators = null;
+
+        return $c;
+    }
+
+    function updateCollaborators($vars, &$errors) {
+        global $thisstaff;
+
+        if (!$thisstaff) return;
+
+        //Deletes
+        if($vars['del'] && ($ids=array_filter($vars['del']))) {
+            $collabs = array();
+            foreach ($ids as $k => $cid) {
+                if (($c=Collaborator::lookup($cid))
+                        && $c->getThreadId() == $this->getId()
+                        && $c->delete())
+                     $collabs[] = $c;
+            }
+
+            $this->getObject()->postThreadEntry('N',
+                    array(
+                        'title' => _S('Collaborators Removed'),
+                        'note' => implode("<br>", $collabs)));
+        }
+
+        //statuses
+        $cids = null;
+        if($vars['cid'] && ($cids=array_filter($vars['cid']))) {
+            $this->collaborators->filter(array(
+                'thread_id' => $this->getId(),
+                'id__in' => $cids
+            ))->update(array(
+                'updated' => SqlFunction::NOW(),
+                'isactive' => 1,
+            ));
+        }
+
+        if ($cids) {
+            $this->collaborators->filter(array(
+                'thread_id' => $this->getId(),
+                Q::not(array('id__in' => $cids))
+            ))->update(array(
+                'updated' => SqlFunction::NOW(),
+                'isactive' => 0,
+            ));
+        }
+
+        unset($this->ht['active_collaborators']);
+        $this->_collaborators = null;
+
+        return true;
+    }
+    // Render thread
     function render($type=false) {
 
         $entries = $this->getEntries();
@@ -1878,6 +1981,8 @@ abstract class ThreadEntryAction {
 }
 
 interface Threadable {
-    function postThreadEntry($type, $vars);
+    function getThreadId();
+    function getThread();
+    function postThreadEntry($type, $vars, $options=array());
 }
 ?>
diff --git a/include/class.thread_actions.php b/include/class.thread_actions.php
index 30ddc810c056e7edfee8949820f4f2665d9501a3..15758498fdabb968929300fded2c0402f3af7610 100644
--- a/include/class.thread_actions.php
+++ b/include/class.thread_actions.php
@@ -155,6 +155,8 @@ JS
         ) {
             // Replace previous edit --------------------------
             $original = $old->getParent();
+            // Link the new entry to the old id
+            $entry->pid = $old->pid;
             // Drop the previous edit, and base this edit off the original
             $old->delete();
             $old = $original;
@@ -221,9 +223,11 @@ class TEA_OrigThreadEntry extends ThreadEntryAction {
     }
 
     private function trigger__get() {
-        $entry = $this->entry->getParent();
-        if (!$entry)
+        global $thisstaff;
+
+        if (!$this->entry->getParent())
             Http::response(404, 'No history for this entry');
+        $entry = $this->entry;
         include STAFFINC_DIR . 'templates/thread-entry-view.tmpl.php';
     }
 }
diff --git a/include/class.ticket.php b/include/class.ticket.php
index d114d1664665c5444e6ddd3c41c692f88f25b83e..605758114102bcc1dfe959abec689b933a8e4fb9 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -883,35 +883,6 @@ implements RestrictedAccess, Threadable, TemplateVariable {
         return $entries;
     }
 
-    //Collaborators
-    function getNumCollaborators() {
-        return count($this->getCollaborators());
-    }
-
-    function getNumActiveCollaborators() {
-
-        if (!isset($this->ht['active_collaborators']))
-            $this->ht['active_collaborators'] = count($this->getActiveCollaborators());
-
-        return $this->ht['active_collaborators'];
-    }
-
-    function getActiveCollaborators() {
-        return $this->getCollaborators(array('isactive'=>1));
-    }
-
-
-    function getCollaborators($criteria=array()) {
-
-        if ($criteria)
-            return Collaborator::forThread($this->getThreadId(), $criteria);
-
-        if (!isset($this->collaborators))
-            $this->collaborators = Collaborator::forThread($this->getThreadId());
-
-        return $this->collaborators;
-    }
-
     //UserList of recipients  (owner + collaborators)
     function getRecipients() {
 
@@ -1836,7 +1807,7 @@ implements RestrictedAccess, Threadable, TemplateVariable {
                     return new FormattedDate($this->getCloseDate());
                 break;
             case 'last_update':
-                return new FormattedDate($upd);
+                return new FormattedDate($this->last_update);
             case 'user':
                 return $this->getOwner();
             default:
@@ -2534,7 +2505,7 @@ implements RestrictedAccess, Threadable, TemplateVariable {
     }
 
     // Threadable interface
-    function postThreadEntry($type, $vars) {
+    function postThreadEntry($type, $vars, $options=array()) {
         $errors = array();
         switch ($type) {
         case 'M':
@@ -3123,7 +3094,7 @@ implements RestrictedAccess, Threadable, TemplateVariable {
         if ($vars['topicId']) {
             if ($topic=Topic::lookup($vars['topicId'])) {
                 foreach ($topic_forms as $topic_form) {
-                    $TF = $topic_form->getForm()->getForm($vars);
+                    $TF = $topic_form->getForm($vars);
                     if (!$TF->isValid($field_filter('topic')))
                         $errors = array_merge($errors, $TF->errors());
                 }
diff --git a/include/class.user.php b/include/class.user.php
index 960588dae4853e7a8f1952b7c4ac4d3885450104..1b4e309d8af92aae4aef4e277ae23df2c0ffb894 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -685,7 +685,7 @@ implements TemplateVariable {
         if (!($mails = Mail_RFC822::parseAddressList($this->address)) || PEAR::isError($mails))
             return '';
 
-        if (!$list && count($mails) > 1)
+        if (count($mails) > 1)
             return '';
 
         $info = $mails[0];
diff --git a/include/client/header.inc.php b/include/client/header.inc.php
index db6e4006c2b72d9d8a06036189b3f35b65c6634f..9d39fba5fac3eac0f12d152673b12fc5c8522a5a 100644
--- a/include/client/header.inc.php
+++ b/include/client/header.inc.php
@@ -8,11 +8,17 @@ $signout_url = ROOT_PATH . "logout.php?auth=".$ost->getLinkToken();
 header("Content-Type: text/html; charset=UTF-8");
 ?>
 <!DOCTYPE html>
-<html <?php
+<html<?php
 if (($lang = Internationalization::getCurrentLanguage())
         && ($info = Internationalization::getLanguageInfo($lang))
         && (@$info['direction'] == 'rtl'))
-    echo 'dir="rtl" class="rtl"';
+    echo ' dir="rtl" class="rtl"';
+if ($lang) {
+    $langs = array_unique(array($lang, $cfg->getPrimaryLanguage()));
+    $langs = Internationalization::rfc1766($langs);
+    echo ' lang="' . $lang . '"';
+    header("Content-Language: ".implode(', ', $langs));
+}
 ?>>
 <head>
     <meta charset="utf-8">
@@ -33,7 +39,7 @@ if (($lang = Internationalization::getCurrentLanguage())
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/font-awesome.min.css">
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/flags.css">
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/rtl.css"/>
-    <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/chosen.min.css">
+    <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/select2.min.css">
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-1.11.2.min.js"></script>
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-ui-1.10.3.custom.min.js"></script>
     <script src="<?php echo ROOT_PATH; ?>js/osticket.js"></script>
@@ -43,11 +49,30 @@ if (($lang = Internationalization::getCurrentLanguage())
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script>
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script>
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-fonts.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/chosen.jquery.min.js"></script>
+    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/select2.full.min.js"></script>
     <?php
     if($ost && ($headers=$ost->getExtraHeaders())) {
         echo "\n\t".implode("\n\t", $headers)."\n";
     }
+
+    // Offer alternate links for search engines
+    // @see https://support.google.com/webmasters/answer/189077?hl=en
+    if (($all_langs = Internationalization::getConfiguredSystemLanguages())
+        && (count($all_langs) > 1)
+    ) {
+        $langs = Internationalization::rfc1766(array_keys($all_langs));
+        $qs = array();
+        parse_str($_SERVER['QUERY_STRING'], $qs);
+        foreach ($langs as $L) {
+            $qs['lang'] = $L; ?>
+        <link rel="alternate" href="//<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>?<?php
+            echo http_build_query($qs); ?>" hreflang="<?php echo $L; ?>" />
+<?php
+        } ?>
+        <link rel="alternate" href="//<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>"
+            hreflang="x-default";
+<?php
+    }
     ?>
 </head>
 <body>
diff --git a/include/client/profile.inc.php b/include/client/profile.inc.php
index 553005bd994f947cdb7baaeb80c3184558daef61..713551110b2acfdcb8f4cd26b0c65043e3fcf933 100644
--- a/include/client/profile.inc.php
+++ b/include/client/profile.inc.php
@@ -25,18 +25,14 @@ if ($acct = $thisclient->getAccount()) {
             <?php echo __('Time Zone');?>:
         </td>
         <td>
-            <select name="timezone" class="chosen-select" id="timezone-dropdown">
-                <option value=""><?php echo __('System Default'); ?></option>
-<?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                <option value="<?php echo $zone; ?>" <?php
-                if ($info['timezone'] == $zone)
-                    echo 'selected="selected"';
-                ?>><?php echo str_replace('/', ' / ', $zone); ?></option>
-<?php } ?>
-            </select>
+            <?php
+            $TZ_NAME = 'timezone';
+            $TZ_TIMEZONE = $info['timezone'];
+            include INCLUDE_DIR.'staff/templates/timezone.tmpl.php'; ?>
             <div class="error"><?php echo $errors['timezone']; ?></div>
         </td>
     </tr>
+<?php if ($cfg->getSecondaryLanguages()) { ?>
     <tr>
         <td width="180">
             <?php echo __('Preferred Language'); ?>:
@@ -55,7 +51,8 @@ $selected = ($info['lang'] == $l['code']) ? 'selected="selected"' : ''; ?>
             <span class="error">&nbsp;<?php echo $errors['lang']; ?></span>
         </td>
     </tr>
-<?php if ($acct->isPasswdResetEnabled()) { ?>
+<?php }
+      if ($acct->isPasswdResetEnabled()) { ?>
 <tr>
     <td colspan=2">
         <div><hr><h3><?php echo __('Access Credentials'); ?></h3></div>
@@ -101,10 +98,3 @@ $selected = ($info['lang'] == $l['code']) ? 'selected="selected"' : ''; ?>
         window.location.href='index.php';"/>
 </p>
 </form>
-<script type="text/javascript">
-$('#timezone-dropdown').chosen({
-    header: <?php echo JsonDataEncoder::encode(__('Time Zones')); ?>,
-    allow_single_deselect: true,
-    width: '350px'
-});
-</script>
diff --git a/include/client/register.inc.php b/include/client/register.inc.php
index 6ac754b8a07b412a43fa1f931c32504337d3f1ef..bf6830952a22b1ca359f5259343784e02edfcec5 100644
--- a/include/client/register.inc.php
+++ b/include/client/register.inc.php
@@ -40,16 +40,10 @@ $info = Format::htmlchars(($errors && $_POST)?$_POST:$info);
             <?php echo __('Time Zone');?>:
         </td>
         <td>
-            <select name="timezone" class="chosen-select" id="timezone-dropdown"
-                data-placeholder="<?php echo __('System Default'); ?>">
-                <option value=""></option>
-<?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                <option value="<?php echo $zone; ?>" <?php
-                if ($info['timezone'] == $zone)
-                    echo 'selected="selected"';
-                ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-<?php } ?>
-            </select>
+            <?php
+            $TZ_NAME = 'timezone';
+            $TZ_TIMEZONE = $info['timezone'];
+            include INCLUDE_DIR.'staff/templates/timezone.tmpl.php'; ?>
             <div class="error"><?php echo $errors['timezone']; ?></div>
         </td>
     </tr>
@@ -103,19 +97,13 @@ $info = Format::htmlchars(($errors && $_POST)?$_POST:$info);
         window.location.href='index.php';"/>
 </p>
 </form>
-<script type="text/javascript">
-$('#timezone-dropdown').chosen({
-    allow_single_deselect: true,
-    width: '350px'
-});
-</script>
 <?php if (!isset($info['timezone'])) { ?>
 <!-- Auto detect client's timezone where possible -->
 <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jstz.min.js"></script>
 <script type="text/javascript">
 $(function() {
     var zone = jstz.determine();
-    $('#timezone-dropdown').val(zone.name()).trigger('chosen:updated');
+    $('#timezone-dropdown').val(zone.name()).trigger('change');
 });
 </script>
 <?php }
diff --git a/include/client/templates/sidebar.tmpl.php b/include/client/templates/sidebar.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3f15419e63894162ccfece5e99c3362910d6fda
--- /dev/null
+++ b/include/client/templates/sidebar.tmpl.php
@@ -0,0 +1,43 @@
+<?php
+$BUTTONS = isset($BUTTONS) ? $BUTTONS : true;
+?>
+    <div class="sidebar pull-right">
+<?php if ($BUTTONS) { ?>
+        <div class="front-page-button flush-right">
+<p>
+            <a href="open.php" style="display:block" class="blue button"><?php
+                echo __('Open a New Ticket');?></a>
+</p>
+<?php   if ($cfg && !$cfg->isKnowledgebaseEnabled()) { ?>
+<p>
+            <a href="view.php" style="display:block" class="green button"><?php
+                echo __('Check Ticket Status');?></a>
+</p>
+<?php   } ?>
+        </div>
+<?php } ?>
+        <div class="content"><?php
+    $faqs = FAQ::getFeatured()->select_related('category')->limit(5);
+    if ($faqs->all()) { ?>
+            <section><div class="header"><?php echo __('Featured Questions'); ?></div>
+<?php   foreach ($faqs as $F) { ?>
+            <div><a href="<?php echo ROOT_PATH; ?>/kb/faq.php?id=<?php
+                echo urlencode($F->getId());
+                ?>"><?php echo $F->getLocalQuestion(); ?></a></div>
+<?php   } ?>
+            </section>
+<?php
+    }
+    $resources = Page::getActivePages()->filter(array('type'=>'other'));
+    if ($resources->all()) { ?>
+            <section><div class="header"><?php echo __('Other Resources'); ?></div>
+<?php   foreach ($resources as $page) { ?>
+            <div><a href="<?php echo ROOT_PATH; ?>pages/<?php echo $page->getNameAsSlug();
+            ?>"><?php echo $page->getLocalName(); ?></a></div>
+<?php   } ?>
+            </section>
+<?php
+    }
+        ?></div>
+    </div>
+
diff --git a/include/client/templates/ticket-print.tmpl.php b/include/client/templates/ticket-print.tmpl.php
index a1173b217b48111ebc8857129cd9c8e4fe74a56a..d8a4f164316118f40779af197123df8eff9c6026 100644
--- a/include/client/templates/ticket-print.tmpl.php
+++ b/include/client/templates/ticket-print.tmpl.php
@@ -160,14 +160,10 @@ div.hr {
 <?php
 foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) {
     // Skip core fields shown earlier in the ticket view
-    // TODO: Rewrite getAnswers() so that one could write
-    //       ->getAnswers()->filter(not(array('field__name__in'=>
-    //           array('email', ...))));
-    $answers = array_filter($form->getAnswers(), function ($a) {
-        return !in_array($a->getField()->get('name'),
-                array('email','subject','name','priority'))
-            && !$a->getField()->get('private');
-        });
+    $answers = $form->getAnswers()->exclude(Q::any(array(
+        'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED | DynamicFormField::FLAG_CLIENT_VIEW,
+        'field__name__in' => array('subject', 'priority'),
+    )));
     if (count($answers) == 0)
         continue;
     ?>
diff --git a/include/client/view.inc.php b/include/client/view.inc.php
index 249f3058bbf7a5981116c86528ca0776ebaf2751..4f96855d7fe0822a3c14c7a27877d9c26bd601b3 100644
--- a/include/client/view.inc.php
+++ b/include/client/view.inc.php
@@ -31,7 +31,8 @@ if ($thisclient && $thisclient->isGuest()
     <tr>
         <td colspan="2" width="100%">
             <h1>
-                <?php echo sprintf(__('Ticket #%s'), $ticket->getNumber()); ?> &nbsp;
+                <b><?php echo $ticket->getSubject(); ?></b>
+                <small>#<?php echo $ticket->getNumber(); ?></small>
                 <a href="tickets.php?id=<?php echo $ticket->getId(); ?>" title="<?php echo __('Reload'); ?>"><span class="Icon refresh">&nbsp;</span></a>
 <div class="pull-right">
     <a class="action-button" href="tickets.php?a=print&id=<?php
@@ -39,7 +40,7 @@ if ($thisclient && $thisclient->isGuest()
 <?php if ($ticket->hasClientEditableFields()
         // Only ticket owners can edit the ticket details (and other forms)
         && $thisclient->getId() == $ticket->getUserId()) { ?>
-                <a class="action-button pull-right" href="tickets.php?a=edit&id=<?php
+                <a class="action-button" href="tickets.php?a=edit&id=<?php
                      echo $ticket->getId(); ?>"><i class="icon-edit"></i> <?php echo __('Edit'); ?></a>
 <?php } ?>
 </div>
@@ -49,6 +50,11 @@ if ($thisclient && $thisclient->isGuest()
     <tr>
         <td width="50%">
             <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
+                <thead>
+                    <tr><td class="headline" colspan="2">
+                        <?php echo __('Basic Ticket Information'); ?>
+                    </td></tr>
+                </thead>
                 <tr>
                     <th width="100"><?php echo __('Ticket Status');?>:</th>
                     <td><?php echo ($S = $ticket->getStatus()) ? $S->getLocalName() : ''; ?></td>
@@ -65,6 +71,11 @@ if ($thisclient && $thisclient->isGuest()
        </td>
        <td width="50%">
            <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
+                <thead>
+                    <tr><td class="headline" colspan="2">
+                        <?php echo __('User Information'); ?>
+                    </td></tr>
+                </thead>
                <tr>
                    <th width="100"><?php echo __('Name');?>:</th>
                    <td><?php echo mb_convert_case(Format::htmlchars($ticket->getName()), MB_CASE_TITLE); ?></td>
@@ -81,32 +92,40 @@ if ($thisclient && $thisclient->isGuest()
        </td>
     </tr>
     <tr>
+        <td colspan="2">
+<!-- Custom Data -->
 <?php
-foreach (DynamicFormEntry::forTicket($ticket->getId()) as $idx=>$form) {
-    $answers = $form->getAnswers();
-    if ($idx > 0 and $idx % 2 == 0) { ?>
-        </tr><tr>
-    <?php } ?>
-    <td width="50%">
-        <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
-    <?php foreach ($answers as $answer) {
-        if (in_array($answer->getField()->get('name'), array('name', 'email', 'subject')))
-            continue;
-        elseif (!$answer->getField()->isVisibleToUsers())
-            continue;
-        ?>
-        <tr>
-        <th width="100"><?php echo $answer->getField()->get('label');
-            ?>:</th>
-        <td><?php echo $answer->display(); ?></td>
-        </tr>
-    <?php } ?>
-    </table></td>
-<?php } ?>
+foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) {
+    // Skip core fields shown earlier in the ticket view
+    $answers = $form->getAnswers()->exclude(Q::any(array(
+        'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED,
+        'field__name__in' => array('subject', 'priority'),
+        Q::not(array('field__flags__hasbit' => DynamicFormField::FLAG_CLIENT_VIEW)),
+    )));
+    if (count($answers) == 0)
+        continue;
+    ?>
+        <table class="custom-data" cellspacing="0" cellpadding="4" width="100%" border="0">
+        <tr><td colspan="2" class="headline flush-left"><?php echo $form->getTitle(); ?></th></tr>
+        <?php foreach($answers as $a) {
+            if (!($v = $a->display())) continue; ?>
+            <tr>
+                <th><?php
+    echo $a->getField()->get('label');
+                ?>:</th>
+                <td><?php
+    echo $v;
+                ?></td>
+            </tr>
+            <?php } ?>
+        </table>
+    <?php
+    $idx++;
+} ?>
+    </td>
 </tr>
 </table>
 <br>
-<div class="subject"><?php echo __('Subject'); ?>: <strong><?php echo Format::htmlchars($ticket->getSubject()); ?></strong></div>
 <div id="ticketThread">
 <?php
 if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) {
@@ -128,16 +147,27 @@ if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) {
             </th></tr>
             <tr><td class="thread-body"><div><?php echo Format::clickableurls($entry->getBody()->toHtml()); ?></div></td></tr>
             <?php
-            if($entry->has_attachments
-                    && ($urls = $entry->getAttachmentUrls())
-                    && ($links = $entry->getAttachmentsLinks())) { ?>
-                <tr><td class="info"><?php echo $links; ?></td></tr>
-<?php       }
-            if ($urls) { ?>
-                <script type="text/javascript">
-                    $(function() { showImagesInline(<?php echo
-                        JsonDataEncoder::encode($urls); ?>); });
-                </script>
+            $urls = null;
+            if ($entry->has_attachments
+                && ($urls = $entry->getAttachmentUrls())) { ?>
+            <tr>
+                <td class="info"><?php
+                    foreach ($entry->attachments as $A) {
+                        if ($A->inline) continue;
+                        $size = '';
+                        if ($A->file->size)
+                            $size = sprintf('<em>(%s)</em>',
+                                Format::file_size($A->file->size));
+?>
+                &nbsp; <i class="icon-paperclip"></i>
+                <a class="no-pjax" href="<?php echo $A->file->getDownloadUrl();
+                    ?>" download="<?php echo Format::htmlchars($A->file->name); ?>"
+                        target="_blank">
+                <?php echo Format::htmlchars($A->file->name);
+                ?></a><?php echo $size;?>&nbsp;
+<?php               } ?>
+                </td>
+            </tr>
 <?php       } ?>
         </table>
     <?php
@@ -152,46 +182,37 @@ if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) {
     <div id="msg_notice"><?php echo $msg; ?></div>
 <?php }elseif($warn) { ?>
     <div id="msg_warning"><?php echo $warn; ?></div>
-<?php } ?>
-
-<?php
+<?php }
 
 if (!$ticket->isClosed() || $ticket->isReopenable()) { ?>
-<form id="reply" action="tickets.php?id=<?php echo $ticket->getId(); ?>#reply" name="reply" method="post" enctype="multipart/form-data">
+<form id="reply" action="tickets.php?id=<?php echo $ticket->getId();
+?>#reply" name="reply" method="post" enctype="multipart/form-data">
     <?php csrf_token(); ?>
     <h2><?php echo __('Post a Reply');?></h2>
     <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
     <input type="hidden" name="a" value="reply">
-    <table border="0" cellspacing="0" cellpadding="3" style="width:100%">
-        <tr>
-            <td colspan="2">
-                <?php
-                if($ticket->isClosed()) {
-                    $msg='<b>'.__('Ticket will be reopened on message post').'</b>';
-                } else {
-                    $msg=__('To best assist you, we request that you be specific and detailed');
-                }
-                ?>
-                <span id="msg"><em><?php echo $msg; ?> </em></span><font class="error">*&nbsp;<?php echo $errors['message']; ?></font>
-                <br/>
-                <textarea name="message" id="message" cols="50" rows="9" wrap="soft"
-                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
-                        ?> draft" <?php
-    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.client', $ticket->getId(), $info['message']);
-    echo $attrs; ?>><?php echo $draft ?: $info['message'];
-                ?></textarea>
-        <?php
-        if ($messageField->isAttachmentsEnabled()) { ?>
-<?php
-            print $attachments->render(array('client'=>true));
-            print $attachments->getForm()->getMedia();
-?>
-        <?php
-        } ?>
-            </td>
-        </tr>
-    </table>
-    <p style="padding-left:165px;">
+    <div>
+        <p><em><?php
+         echo __('To best assist you, we request that you be specific and detailed'); ?></em>
+        <font class="error">*&nbsp;<?php echo $errors['message']; ?></font>
+        </p>
+        <textarea name="message" id="message" cols="50" rows="9" wrap="soft"
+            class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                ?> draft" <?php
+list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.client', $ticket->getId(), $info['message']);
+echo $attrs; ?>><?php echo $draft ?: $info['message'];
+            ?></textarea>
+    <?php
+    if ($messageField->isAttachmentsEnabled()) {
+        print $attachments->render(array('client'=>true));
+    } ?>
+    </div>
+<?php if ($ticket->isClosed()) { ?>
+    <div class="warning-banner">
+        <?php echo __('Ticket will be reopened on message post'); ?>
+    </div>
+<?php } ?>
+    <p style="text-align:center">
         <input type="submit" value="<?php echo __('Post Reply');?>">
         <input type="reset" value="<?php echo __('Reset');?>">
         <input type="button" value="<?php echo __('Cancel');?>" onClick="history.go(-1)">
@@ -199,3 +220,18 @@ if (!$ticket->isClosed() || $ticket->isReopenable()) { ?>
 </form>
 <?php
 } ?>
+<script type="text/javascript">
+<?php
+// Hover support for all inline images
+$urls = array();
+foreach (AttachmentFile::objects()->filter(array(
+    'attachments__thread_entry__thread__id' => $ticket->getThreadId(),
+    'attachments__inline' => true,
+)) as $file) {
+    $urls[strtolower($file->getKey())] = array(
+        'download_url' => $file->getDownloadUrl(),
+        'filename' => $file->name,
+    );
+} ?>
+showImagesInline(<?php echo JsonDataEncoder::encode($urls); ?>);
+</script>
diff --git a/include/i18n/en_US/config.yaml b/include/i18n/en_US/config.yaml
index 35e5a830b4273a84e875c74a3fa92912ed40178e..c849302f40086e18fa46a4bf47143faedf075622 100644
--- a/include/i18n/en_US/config.yaml
+++ b/include/i18n/en_US/config.yaml
@@ -4,10 +4,10 @@
 #
 ---
 core:
-    time_format: 'h:i A'
-    date_format: 'm/d/Y'
-    datetime_format: 'm/d/Y g:i a'
-    daydatetime_format: 'D, M j Y g:ia'
+    time_format: 'hh:mm a'
+    date_format: 'MM/dd/y'
+    datetime_format: 'MM/dd/y h:mm a'
+    daydatetime_format: 'EEE, MMM d y h:mm a'
     default_priority_id: 2
     enable_daylight_saving: 0
 
diff --git a/include/i18n/en_US/file.yaml b/include/i18n/en_US/file.yaml
index 0464b6a23d6f2e600b2242880089133d65fdc214..d77bcd3e9da33e29462550b07c4c2efabca5f4c4 100644
--- a/include/i18n/en_US/file.yaml
+++ b/include/i18n/en_US/file.yaml
@@ -3,7 +3,7 @@
 #
 # Files initially inserted into the system. Canned responses have their own
 # method for attachments; however, this file will make it easier to add
-# thinkgs like inline images.
+# things like inline images.
 #
 # NOTE: If the files aren't attached to something by the installer, they
 # bill be cleaned up shortly after installation (by the autocron).
diff --git a/include/i18n/en_US/help_topic.yaml b/include/i18n/en_US/help_topic.yaml
index d54cdf3d702e391fea43737d8d455595a00eedf1..ab9c195eb21cf4b828f1d37f4d30c02a782eae84 100644
--- a/include/i18n/en_US/help_topic.yaml
+++ b/include/i18n/en_US/help_topic.yaml
@@ -23,6 +23,7 @@
   ispublic: 1
   dept_id: 1
   priority_id: 2
+  forms: [2]
   topic: General Inquiry
   notes: |
     Questions about products or services
@@ -31,6 +32,7 @@
   ispublic: 1
   dept_id: 1
   priority_id: 1
+  forms: [2]
   topic: Feedback
   notes: |
     Tickets that primarily concern the sales and billing departments
@@ -40,6 +42,7 @@
   ispublic: 1
   dept_id: 1
   priority_id: 2
+  forms: [2]
   topic: Report a Problem
   notes: |
     Product, service, or equipment related issues
@@ -50,6 +53,7 @@
   dept_id: 1
   sla_id: 1
   priority_id: 3
+  forms: [2]
   topic: Access Issue
   notes: |
     Report an inability access a physical or virtual asset
diff --git a/include/i18n/en_US/role.yaml b/include/i18n/en_US/role.yaml
index 4e3a15e839dc06621146f12a3ca46e1f24ed2e3f..ec55b154de8ee10dd0e10c977f323439c5132466 100644
--- a/include/i18n/en_US/role.yaml
+++ b/include/i18n/en_US/role.yaml
@@ -32,9 +32,10 @@
     task.close,
     task.delete,
     kb.premade,
-    kb.faq,
+    faq.manage,
     stats.agents,
     emails.banlist,
+    user.create,
     user.edit,
     user.delete,
     user.manage,
@@ -64,9 +65,10 @@
     task.reply,
     task.close,
     kb.premade,
-    kb.faq,
+    faq.manage,
     stats.agents,
     emails.banlist,
+    user.create,
     user.edit,
     user.delete,
     user.manage,
diff --git a/include/staff/apikey.inc.php b/include/staff/apikey.inc.php
index fdf30da4bc844ed0cbdef37c3902a3916eca2716..5096c5150de3f59caf061b2830802909aca0460a 100644
--- a/include/staff/apikey.inc.php
+++ b/include/staff/apikey.inc.php
@@ -70,7 +70,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
             <td>
                 <span>
-                <input type="text" size="30" name="ipaddr" value="<?php echo $info['ipaddr']; ?>">
+                <input type="text" size="30" name="ipaddr" value="<?php echo $info['ipaddr']; ?>"i
+                    autofocus>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['ipaddr']; ?></span>
                 <i class="help-tip icon-question-sign" href="#ip_addr"></i>
                 </span>
diff --git a/include/staff/banlist.inc.php b/include/staff/banlist.inc.php
index 3fd33ed5a98840bf6136ed1b10b9c06f96ffa6b3..4093439573edb4df326db69e7b5c9763c4a63944 100644
--- a/include/staff/banlist.inc.php
+++ b/include/staff/banlist.inc.php
@@ -55,8 +55,9 @@ $query="$select $from $where ORDER BY $order_by LIMIT ".$pageNav->getStart().","
     <form action="banlist.php" method="GET" name="filter">
      <input type="hidden" name="a" value="filter" >
      <div>
-       <?php echo __('Query');?>: <input name="q" type="text" size="20" value="<?php echo Format::htmlchars($_REQUEST['q']); ?>">
-        &nbsp;&nbsp;
+       <?php echo __('Query');?>:
+            <input name="q" type="search" size="30" autofocus
+            value="<?php echo Format::htmlchars($_REQUEST['q']); ?>">
         <input type="submit" name="submit" value="<?php echo __('Search');?>"/>
      </div>
     </form>
diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php
index db23768ef4cfc9b2e8020fa34241c7777647e0fd..826c2ab2eee407c314b3bd39aedfa12d111649b4 100644
--- a/include/staff/department.inc.php
+++ b/include/staff/department.inc.php
@@ -32,7 +32,7 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
  <h2><?php echo __('Department');?></h2>
 <br>
-<ul class="tabs">
+<ul class="clean tabs">
     <li class="active"><a href="#settings">
         <i class="icon-file"></i> <?php echo __('Settings'); ?></a></li>
     <li><a href="#access">
@@ -72,7 +72,8 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
             </td>
             <td>
                 <input data-translate-tag="<?php echo $dept ? $dept->getTranslateTag() : '';
-                ?>" type="text" size="30" name="name" value="<?php echo $info['name']; ?>">
+                ?>" type="text" size="30" name="name" value="<?php echo $info['name']; ?>"
+                autofocus>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/dynamic-form.inc.php b/include/staff/dynamic-form.inc.php
index e194d4d8561b4d0a35fb365a85e8c7ca356ca6d3..ed2ec1e4cf53b9281ec75c12883c6f1ae5bf8a00 100644
--- a/include/staff/dynamic-form.inc.php
+++ b/include/staff/dynamic-form.inc.php
@@ -15,7 +15,7 @@ if($form && $_REQUEST['a']!='add') {
     $translations = CustomDataTranslation::allTranslations($trans, 'phrase');
     $_keys = array_flip($trans);
     foreach ($translations as $t) {
-        if (!Internationalization::isLanguageInstalled($t->lang))
+        if (!Internationalization::isLanguageEnabled($t->lang))
             continue;
         // Create keys of [trans][de_DE][title] for instance
         $info['trans'][$t->lang][$_keys[$t->object_hash]]
@@ -73,7 +73,7 @@ if ($form && count($langs) > 1) { ?>
             lang="<?php echo $cfg->getPrimaryLanguage(); ?>">
             <div class="required"><?php echo __('Title'); ?>:</div>
             <div>
-            <input type="text" name="title" size="60"
+            <input type="text" name="title" size="60" autofocus
                 value="<?php echo $info['title']; ?>"/>
                 <i class="help-tip icon-question-sign" href="#form_title"></i>
                 <div class="error"><?php
@@ -289,7 +289,7 @@ if ($form && count($langs) > 1) { ?>
 </p>
 
 <div style="display:none;" class="draggable dialog" id="delete-confirm">
-    <h3><i class="icon-trash"></i> <?php echo __('Remove Existing Data?'); ?></h3>
+    <h3 class="drag-handle"><i class="icon-trash"></i> <?php echo __('Remove Existing Data?'); ?></h3>
     <a class="close" href=""><i class="icon-remove-circle"></i></a>
     <hr/>
     <p>
diff --git a/include/staff/dynamic-list.inc.php b/include/staff/dynamic-list.inc.php
index ed7030ff611136393d2e5b5889d5aba1c63c8788..3755f2e38b8e030b051c34c4fd8b0fbe3a6fc246 100644
--- a/include/staff/dynamic-list.inc.php
+++ b/include/staff/dynamic-list.inc.php
@@ -27,7 +27,7 @@ $info=Format::htmlchars(($errors && $_POST) ? array_merge($info,$_POST) : $info)
     <h2><?php echo __('Custom List'); ?>
     <?php echo $list ? $list->getName() : __('Add new list'); ?></h2>
 
-<ul class="tabs" id="list-tabs">
+<ul class="clean tabs" id="list-tabs">
     <li class="active"><a href="#definition">
         <i class="icon-plus"></i> <?php echo __('Definition'); ?></a></li>
     <li><a href="#items">
@@ -57,7 +57,7 @@ $info=Format::htmlchars(($errors && $_POST) ? array_merge($info,$_POST) : $info)
                     echo $list->getName();
                 else {
                     echo sprintf('<input size="50" type="text" name="name"
-                            data-translate-tag="%s"
+                            data-translate-tag="%s" autofocus
                             value="%s"/> <span
                             class="error">*<br/>%s</span>',
                             $trans['name'], $info['name'], $errors['name']);
diff --git a/include/staff/email.inc.php b/include/staff/email.inc.php
index 8958d43a0fcb022d51445ebe93d2d4a665638a9d..5cc183baab6d05f5ce14e60d7d8feb6ed5219c39 100644
--- a/include/staff/email.inc.php
+++ b/include/staff/email.inc.php
@@ -55,7 +55,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php echo __('Email Address');?>
             </td>
             <td>
-                <input type="text" size="35" name="email" value="<?php echo $info['email']; ?>">
+                <input type="text" size="35" name="email" value="<?php echo $info['email']; ?>"
+                    autofocus>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['email']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/faq-categories.inc.php b/include/staff/faq-categories.inc.php
index d66c24470c1475e5d3b05697f1d23ae1ebcfb796..52d4f8d49cdc81e7eaaf92e3590a473da3b2d14a 100644
--- a/include/staff/faq-categories.inc.php
+++ b/include/staff/faq-categories.inc.php
@@ -6,7 +6,8 @@ if(!defined('OSTSTAFFINC') || !$thisstaff) die('Access Denied');
 <form id="kbSearch" action="kb.php" method="get">
     <input type="hidden" name="a" value="search">
     <div>
-        <input id="query" type="text" size="20" name="q" value="<?php echo Format::htmlchars($_REQUEST['q']); ?>">
+        <input id="query" type="search" size="20" name="q" autofocus
+            value="<?php echo Format::htmlchars($_REQUEST['q']); ?>">
         <select name="cid" id="cid">
             <option value="">&mdash; <?php echo __('All Categories');?> &mdash;</option>
             <?php
diff --git a/include/staff/faq.inc.php b/include/staff/faq.inc.php
index cb6ffed91153a90876b202ca5d9a55bfaababfb3..9fcde9571c961625907edebd59e4c8e2f5b6e1e6 100644
--- a/include/staff/faq.inc.php
+++ b/include/staff/faq.inc.php
@@ -89,7 +89,7 @@ if ($topics = Topic::getAllHelpTopics()) {
     <?php } ?>
     </select>
     <script type="text/javascript">
-        $(function() { $("#help-topic-selection").chosen(); });
+        $(function() { $("#help-topic-selection").select2(); });
     </script>
 <?php } ?>
     </div>
diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php
index 3c0f8f49ada7acf811697b500ee1fd104b447b1f..144d0321a3e572ffca09003921c5cef8fce4f0a1 100644
--- a/include/staff/filter.inc.php
+++ b/include/staff/filter.inc.php
@@ -42,7 +42,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
               <?php echo __('Filter Name');?>:
             </td>
             <td>
-                <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>">
+                <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>"
+                    autofocus>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/footer.inc.php b/include/staff/footer.inc.php
index 141a859dd530c066a5e3403d2f0e75955a96bc6f..ec372c7c7b364c487d038b30dabf24d743cab578 100644
--- a/include/staff/footer.inc.php
+++ b/include/staff/footer.inc.php
@@ -40,16 +40,26 @@ if(is_object($thisstaff) && $thisstaff->isStaff()) { ?>
     <div class="clear"></div>
 </div>
 
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery.pjax.js"></script>
+<script type="text/javascript" src="./js/scp.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-ui-1.10.3.custom.min.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/filedrop.field.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/select2.full.min.js"></script>
+<script type="text/javascript" src="./js/tips.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor.min.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script>
+<script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script>
+<script type="text/javascript" src="./js/bootstrap-typeahead.js"></script>
+<script type="text/javascript" src="./js/jquery.translatable.js"></script>
+<script type="text/javascript" src="./js/jquery.dropdown.js"></script>
+<script type="text/javascript" src="./js/bootstrap-tooltip.js"></script>
+<link type="text/css" rel="stylesheet" href="./css/tooltip.css">
 <script type="text/javascript">
-if ($.support.pjax) {
-  $(document).on('click', 'a', function(event) {
-    var $this = $(this);
-    if (!$this.hasClass('no-pjax')
-        && !$this.closest('.no-pjax').length
-        && $this.attr('href')[0] != '#')
-      $.pjax.click(event, {container: $this.data('pjaxContainer') || $('#pjax-container'), timeout: 2000});
-  })
-}
+    getConfig().resolve(<?php
+        include INCLUDE_DIR . 'ajax.config.php';
+        $api = new ConfigAjaxAPI();
+        print $api->scp(false);
+    ?>);
 </script>
 <?php
 if ($thisstaff
diff --git a/include/staff/group.inc.php b/include/staff/group.inc.php
index e8006cade91f1a065cbd54b3a0c1ec9d5849b18e..d13205385c286281d85558dc028d42571b1ce781 100644
--- a/include/staff/group.inc.php
+++ b/include/staff/group.inc.php
@@ -30,7 +30,7 @@ $roles = Role::getActiveRoles();
     <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
 <h2> <?php echo $group ?: __('New Group'); ?></h2>
 <br>
-<ul class="tabs">
+<ul class="clean tabs">
     <li class="active"><a href="#group">
         <i class="icon-file"></i> <?php echo __('Group'); ?></a></li>
     <li><a href="#departments">
@@ -54,7 +54,7 @@ $roles = Role::getActiveRoles();
             <td width="180" class="required"><?php echo __('Name'); ?>:</td>
             <td>
                 <input size="50" type="text" name="name" value="<?php echo $info['name']; ?>"
-                data-translate-tag="<?php echo $trans['name']; ?>"/>
+                autofocus data-translate-tag="<?php echo $trans['name']; ?>"/>
                 <span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/header.inc.php b/include/staff/header.inc.php
index 0945a916441d42a0b97f7034ced1bca34036983f..8ceef837a5488e15199e1d04402ae495ffb94b5f 100644
--- a/include/staff/header.inc.php
+++ b/include/staff/header.inc.php
@@ -2,11 +2,14 @@
 header("Content-Type: text/html; charset=UTF-8");
 if (!isset($_SERVER['HTTP_X_PJAX'])) { ?>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html <?php
+<html<?php
 if (($lang = Internationalization::getCurrentLanguage())
         && ($info = Internationalization::getLanguageInfo($lang))
         && (@$info['direction'] == 'rtl'))
-    echo 'dir="rtl" class="rtl"';
+    echo ' dir="rtl" class="rtl"';
+if ($lang) {
+    echo ' lang="' . Internationalization::rfc1766($lang) . '"';
+}
 ?>>
 <head>
     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
@@ -21,17 +24,6 @@ if (($lang = Internationalization::getCurrentLanguage())
     </style>
     <![endif]-->
     <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-1.11.2.min.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-ui-1.10.3.custom.min.js"></script>
-    <script type="text/javascript" src="./js/scp.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery.pjax.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/filedrop.field.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/chosen.jquery.min.js"></script>
-    <script type="text/javascript" src="./js/tips.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor.min.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script>
-    <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script>
-    <script type="text/javascript" src="./js/bootstrap-typeahead.js"></script>
-    <script type="text/javascript" src="./js/jquery.translatable.js"></script>
     <link rel="stylesheet" href="<?php echo ROOT_PATH ?>css/thread.css" media="all">
     <link rel="stylesheet" href="./css/scp.css" media="all">
     <link rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/redactor.css" media="screen">
@@ -45,10 +37,9 @@ if (($lang = Internationalization::getCurrentLanguage())
     <link type="text/css" rel="stylesheet" href="./css/dropdown.css">
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/loadingbar.css"/>
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/flags.css">
-    <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/chosen.min.css">
+    <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/select2.min.css">
     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/rtl.css"/>
     <link type="text/css" rel="stylesheet" href="./css/translatable.css"/>
-    <script type="text/javascript" src="./js/jquery.dropdown.js"></script>
 
     <?php
     if($ost && ($headers=$ost->getExtraHeaders())) {
diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php
index 7df72585c1efdc152630af9438bf53a09419106d..f6dbcfe7bb813d619ccbf60043e9ab2a940457fb 100644
--- a/include/staff/helptopic.inc.php
+++ b/include/staff/helptopic.inc.php
@@ -32,7 +32,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 
 <br/>
 
-<ul class="tabs" id="topic-tabs">
+<ul class="clean tabs" id="topic-tabs">
     <li class="active"><a href="#info"><i class="icon-info-sign"></i> Help Topic Information</a></li>
     <li><a href="#routing"><i class="icon-ticket"></i> New ticket options</a></li>
     <li><a href="#forms"><i class="icon-paste"></i> Forms</a></li>
@@ -54,7 +54,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
             <td>
                 <input type="text" size="30" name="topic" value="<?php echo $info['topic']; ?>"
-                data-translate-tag="<?php echo $trans['name']; ?>"/>
+                autofocus data-translate-tag="<?php echo $trans['name']; ?>"/>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['topic']; ?></span> <i class="help-tip icon-question-sign" href="#topic"></i>
             </td>
         </tr>
@@ -370,7 +370,7 @@ foreach ($forms as $F) {
             <th><?php echo __('Variable'); ?></th>
         </tr>
     <?php
-        foreach ($F->getFields() as $f) { ?>
+        foreach ($F->getDynamicFields() as $f) { ?>
         <tr>
             <td><input type="checkbox" name="fields[]" value="<?php
                 echo $f->get('id'); ?>" <?php
@@ -440,21 +440,20 @@ $(function() {
             }
         });
     });
-
+    $('table#topic-forms').sortable({
+      items: 'tbody',
+      handle: 'td.handle',
+      tolerance: 'pointer',
+      forcePlaceholderSize: true,
+      helper: function(e, ui) {
+        ui.children().each(function() {
+          $(this).children().each(function() {
+            $(this).width($(this).width());
+          });
+        });
+        ui=ui.clone().css({'background-color':'white', 'opacity':0.8});
+        return ui;
+      }
+    }).disableSelection();
 });
-$('table#topic-forms').sortable({
-  items: 'tbody',
-  handle: 'td.handle',
-  tolerance: 'pointer',
-  forcePlaceholderSize: true,
-  helper: function(e, ui) {
-    ui.children().each(function() {
-      $(this).children().each(function() {
-        $(this).width($(this).width());
-      });
-    });
-    ui=ui.clone().css({'background-color':'white', 'opacity':0.8});
-    return ui;
-  }
-}).disableSelection();
 </script>
diff --git a/include/staff/login.tpl.php b/include/staff/login.tpl.php
index cbb5b589499552516ea20f60b8bd90917ff2d445..296b76af92e4ba5b9d00793e62fb53190d8168e8 100644
--- a/include/staff/login.tpl.php
+++ b/include/staff/login.tpl.php
@@ -13,7 +13,9 @@ $info = ($_POST && $errors)?Format::htmlchars($_POST):array();
         <?php csrf_token(); ?>
         <input type="hidden" name="do" value="scplogin">
         <fieldset>
-        <input type="text" name="userid" id="name" value="<?php echo $info['userid']; ?>" placeholder="<?php echo __('Email or Username'); ?>" autocorrect="off" autocapitalize="off">
+        <input type="text" name="userid" id="name" value="<?php
+            echo $info['userid']; ?>" placeholder="<?php echo __('Email or Username'); ?>"
+            autofocus autocorrect="off" autocapitalize="off">
         <input type="password" name="passwd" id="pass" placeholder="<?php echo __('Password'); ?>" autocorrect="off" autocapitalize="off">
             <?php if ($show_reset && $cfg->allowPasswordReset()) { ?>
             <h3 style="display:inline"><a href="pwreset.php"><?php echo __('Forgot my password'); ?></a></h3>
diff --git a/include/staff/org-view.inc.php b/include/staff/org-view.inc.php
index 492a5b86c51a9725f0a4a34de459afe66aa8cd7f..94e658d24c39cb02253dfb2d2538be5d6f369421 100644
--- a/include/staff/org-view.inc.php
+++ b/include/staff/org-view.inc.php
@@ -75,7 +75,7 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path')
 </table>
 <br>
 <div class="clear"></div>
-<ul class="tabs" id="orgtabs">
+<ul class="clean tabs" id="orgtabs">
     <li class="active"><a href="#users"><i
     class="icon-user"></i>&nbsp;<?php echo __('Users'); ?></a></li>
     <li><a href="#tickets"><i
diff --git a/include/staff/orgs.inc.php b/include/staff/orgs.inc.php
index 84288aeda3ad643af8183b1e1a5a37c84ca4ccf6..bc41711ff8b59016163c65248071aef835107011 100644
--- a/include/staff/orgs.inc.php
+++ b/include/staff/orgs.inc.php
@@ -78,8 +78,9 @@ $_SESSION['orgs_qs_'.$qhash] = $query;
         <input type="hidden" name="a" value="search">
         <table>
             <tr>
-                <td><input type="text" id="basic-org-search" name="query" size=30 value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"
-                autocomplete="off" autocorrect="off" autocapitalize="off"></td>
+                <td><input type="search" id="basic-org-search" name="query"
+                    autofocus size="30" value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"
+                    autocomplete="off" autocorrect="off" autocapitalize="off"></td>
                 <td><input type="submit" name="basic_search" class="button" value="<?php echo __('Search'); ?>"></td>
                 <!-- <td>&nbsp;&nbsp;<a href="" id="advanced-user-search">[advanced]</a></td> -->
             </tr>
diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php
index ea373533c886b1b9bd7d11f8cd651e461dca1072..1a959a4c8a3c50f0f03efc507db103266b641add 100644
--- a/include/staff/page.inc.php
+++ b/include/staff/page.inc.php
@@ -62,7 +62,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
             <td>
                 <input type="text" size="40" name="name" value="<?php echo $info['name']; ?>"
-                data-translate-tag="<?php echo $trans['name']; ?>"/>
+                    autofocus data-translate-tag="<?php echo $trans['name']; ?>"/>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
@@ -111,7 +111,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
         </tr>
         <tr>
             <td colspan="2">
-                <ul class="tabs">
+                <ul class="tabs clean">
                     <li class="active"><a href="#content"><?php echo __('Page Content'); ?></a></li>
                     <li><a href="#notes"><?php echo __('Internal Notes'); ?></a></li>
                 </ul>
@@ -131,7 +131,14 @@ if ($page && count($langs) > 1) { ?>
 <?php } ?>
     </ul>
 <?php
-} ?>
+}
+
+// For landing page, constrain to the diplayed width of 565px;
+if ($info['type'] == 'landing')
+    $width = '565px';
+else
+    $width = '100%';
+?>
 </td>
 <td id="translations_container" style="padding-left: 10px">
     <div id="msg_info">
@@ -143,7 +150,8 @@ if ($page && count($langs) > 1) { ?>
 
         <div id="translation-<?php echo $cfg->getPrimaryLanguage(); ?>" class="tab_content"
             lang="<?php echo $cfg->getPrimaryLanguage(); ?>">
-        <textarea name="body" cols="21" rows="12" style="width:100%" class="richtext draft"
+        <textarea name="body" cols="21" rows="12" class="richtext draft"
+            data-width="<?php echo $width; ?>"
 <?php
     if (!$info['type'] || $info['type'] == 'thank-you') echo 'data-root-context="thank-you"';
     list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'], $info['body']);
@@ -154,11 +162,11 @@ if ($page && count($langs) > 1) { ?>
     foreach ($langs as $tag=>$nfo) {
         if ($tag == $cfg->getPrimaryLanguage())
             continue; ?>
-        <div id="translation-<?php echo $tag; ?>" class="tab_content"
-            style="display:none;" lang="<?php echo $tag; ?>">
+        <div id="translation-<?php echo $tag; ?>" class="tab_content hidden"
+            lang="<?php echo $tag; ?>">
         <textarea name="trans[<?php echo $tag; ?>][body]" cols="21" rows="12"
 <?php if ($info['type'] == 'thank-you') echo 'data-root-context="thank-you"'; ?>
-            style="width:100%" class="richtext draft"
+            style="width:100%" class="richtext draft" data-width="<?php echo $width; ?>"
 <?php
     list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'].'.'.$tag, $info['trans'][$tag]);
     echo $attrs; ?>><?php echo $draft ?: $info['trans'][$tag]; ?></textarea>
diff --git a/include/staff/profile.inc.php b/include/staff/profile.inc.php
index 5ef77f8707d4573e7aca06e4e22cefcfef5909d7..a8ba88a3ecce4a8a2aece8139c10ba1774c67104 100644
--- a/include/staff/profile.inc.php
+++ b/include/staff/profile.inc.php
@@ -85,31 +85,14 @@ $info['id']=$staff->getId();
                 <?php echo __('Time Zone');?>:
             </td>
             <td>
-                <select name="timezone" class="chosen-select" id="timezone-dropdown"
-                    data-placeholder="<?php echo __('System Default'); ?>">
-                    <option value=""></option>
-<?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                    <option value="<?php echo $zone; ?>" <?php
-                    if ($info['timezone'] == $zone)
-                        echo 'selected="selected"';
-                    ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-<?php } ?>
-                </select>
-                <button class="action-button" onclick="javascript:
-    $('head').append($('<script>').attr('src', '<?php
-        echo ROOT_PATH; ?>js/jstz.min.js'));
-    var recheck = setInterval(function() {
-        if (window.jstz !== undefined) {
-            clearInterval(recheck);
-            var zone = jstz.determine();
-            $('#timezone-dropdown').val(zone.name()).trigger('chosen:updated');
-
-        }
-    }, 200);
-    return false;"><i class="icon-map-marker"></i> <?php echo __('Auto Detect'); ?></button>
+                <?php
+                $TZ_NAME = 'timezone';
+                $TZ_TIMEZONE = $info['timezone'];
+                include STAFFINC_DIR.'templates/timezone.tmpl.php'; ?>
                 <div class="error"><?php echo $errors['timezone']; ?></div>
             </td>
         </tr>
+<?php if ($cfg->getSecondaryLanguages()) { ?>
         <tr>
             <td width="180">
                 <?php echo __('Preferred Language'); ?>:
@@ -128,6 +111,7 @@ $info['id']=$staff->getId();
                 <span class="error">&nbsp;<?php echo $errors['lang']; ?></span>
             </td>
         </tr>
+<?php } ?>
         <tr><td width="220"><?php echo __('Preferred Locale');?>:</td>
             <td>
                 <select name="locale">
@@ -273,11 +257,3 @@ $info['id']=$staff->getId();
     <input type="button" name="cancel" value="<?php echo __('Cancel Changes');?>" onclick='window.location.href="index.php"'>
 </p>
 </form>
-<script type="text/javascript">
-!(function() {
-    $('#timezone-dropdown').chosen({
-        allow_single_deselect: true,
-        width: '350px'
-    });
-})();
-</script>
diff --git a/include/staff/role.inc.php b/include/staff/role.inc.php
index 309d26d7bd86dfb74c6deb1fc8ffd020a0a3a92b..7730ea551f005c0f70dd72f021173b17ddcada52 100644
--- a/include/staff/role.inc.php
+++ b/include/staff/role.inc.php
@@ -25,7 +25,7 @@ $info = Format::htmlchars(($errors && $_POST) ? array_merge($info, $_POST) : $in
     <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
 <h2> <?php echo $role ?: __('New Role'); ?></h2>
 <br>
-<ul class="tabs">
+<ul class="clean tabs">
     <li class="active"><a href="#definition">
         <i class="icon-file"></i> <?php echo __('Definition'); ?></a></li>
     <li><a href="#permissions">
@@ -49,7 +49,8 @@ $info = Format::htmlchars(($errors && $_POST) ? array_merge($info, $_POST) : $in
             <td width="180" class="required"><?php echo __('Name'); ?>:</td>
             <td>
                 <input size="50" type="text" name="name" value="<?php echo
-                $info['name']; ?>" data-translate-tag="<?php echo $trans['name']; ?>"/>
+                $info['name']; ?>" data-translate-tag="<?php echo $trans['name']; ?>"
+                autofocus/>
                 <span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/settings-access.inc.php b/include/staff/settings-access.inc.php
index 5efac16cf87fe95a258cd6fd3b181d31856507eb..c7cbc5034e79f4347a99778595c6c20f3a2cbc4c 100644
--- a/include/staff/settings-access.inc.php
+++ b/include/staff/settings-access.inc.php
@@ -168,14 +168,13 @@ $manage_content = function($title, $content) use ($contents) {
     $notes = explode('. ', $notes);
     $notes = $notes[0];
     ?><tr><td colspan="2">
-    <div style="display:inline-block;margin:0 36px">
-    <i class="icon-file-text pull-left icon-2x" style="color:#bbb;margin:0 -36px"></i>
+    <div style="padding:2px 5px">
     <a href="#ajax.php/content/<?php echo $id; ?>/manage"
     onclick="javascript:
         $.dialog($(this).attr('href').substr(1), 201);
     return false;" class="pull-left"><i class="icon-file-text icon-2x"
         style="color:#bbb;"></i> </a>
-    <span style="display:inline-block;width:90%;padding-left:10px;line-height:1.2em">
+    <span style="display:inline-block;width:90%;width:calc(100% - 32px);padding-left:10px;line-height:1.2em">
     <a href="#ajax.php/content/<?php echo $id; ?>/manage"
     onclick="javascript:
         $.dialog($(this).attr('href').substr(1), 201);
diff --git a/include/staff/settings-alerts.inc.php b/include/staff/settings-alerts.inc.php
index 3a9326bc4127343b57831a14a81b8d50f1b5c5bb..03168d557c872843ce65ae83c41daa2d8fb12c34 100644
--- a/include/staff/settings-alerts.inc.php
+++ b/include/staff/settings-alerts.inc.php
@@ -1,8 +1,3 @@
-<h2><?php echo __('Alerts and Notices'); ?>
-    <i class="help-tip icon-question-sign" href="#page_title"></i></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>
@@ -233,8 +228,3 @@
         </tr>
     </tbody>
 </table>
-<p style="text-align:center;">
-    <input class="button" type="submit" name="submit" value="<?php echo __('Save Changes'); ?>">
-    <input class="button" type="reset" name="reset" value="<?php echo __('Reset Changes'); ?>">
-</p>
-</form>
diff --git a/include/staff/settings-autoresp.inc.php b/include/staff/settings-autoresp.inc.php
index 0a59f4b9d215589b6f1cd2ad2540854dc4cb4c7c..42a52de40eee2b35f5836ef7639aae04e7b63f5e 100644
--- a/include/staff/settings-autoresp.inc.php
+++ b/include/staff/settings-autoresp.inc.php
@@ -1,7 +1,3 @@
-<h2><?php echo __('Autoresponder Settings'); ?></h2>
-<form action="settings.php?t=autoresp" method="post" id="save">
-<?php csrf_token(); ?>
-<input type="hidden" name="t" value="autoresp" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
         <tr>
@@ -60,8 +56,3 @@ echo $config['overlimit_notice_active'] ? 'checked="checked"' : ''; ?>/>
         </tr>
     </tbody>
 </table>
-<p style="padding-left:200px;">
-    <input class="button" type="submit" name="submit" value="<?php echo __('Save Changes'); ?>">
-    <input class="button" type="reset" name="reset" value="<?php echo __('Reset Changes'); ?>">
-</p>
-</form>
diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php
index 9d6e325c41ff0f3e7a1725ecb749ef0191177448..e9a261a213de2326fa45359c5f204f9387956d35 100644
--- a/include/staff/settings-system.inc.php
+++ b/include/staff/settings-system.inc.php
@@ -145,29 +145,12 @@ $gmtime = Misc::gmtime();
         </tr>
         <tr><td width="220" class="required"><?php echo __('Default Time Zone');?>:</td>
             <td>
-                <select name="default_timezone" id="timezone-dropdown">
                 <?php
-                foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                    <option value="<?php echo $zone; ?>" <?php
-                    if ($config['default_timezone'] == $zone)
-                        echo 'selected="selected"';
-                    ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-
-                <?php
-                } ?>
-                </select>
-                <button class="action-button" onclick="javascript:
-    $('head').append($('<script>').attr('src', '<?php
-        echo ROOT_PATH; ?>js/jstz.min.js'));
-    var recheck = setInterval(function() {
-        if (window.jstz !== undefined) {
-            clearInterval(recheck);
-            var zone = jstz.determine();
-            $('#timezone-dropdown').val(zone.name()).trigger('chosen:updated');
-
-        }
-    }, 200);
-    return false;"><i class="icon-map-marker"></i> <?php echo __('Auto Detect'); ?></button>
+                $TZ_TIMEZONE = $config['default_timezone'];
+                $TZ_NAME = 'default_timezone';
+                $TZ_ALLOW_DEFAULT = false;
+                include STAFFINC_DIR.'templates/timezone.tmpl.php'; ?>
+                <div class="error"><?php echo $errors['default_timezone']; ?></div>
             </td>
         </tr>
         <tr><td width="220" class="required"><?php echo __('Date and Time Format');?>:</td>
@@ -291,13 +274,9 @@ $gmtime = Misc::gmtime();
 </p>
 </form>
 <script type="text/javascript">
-(function() {
-    $('#timezone-dropdown').chosen({
-        allow_single_deselect: true,
-        width: '350px'
+$(function() {
+    $('#secondary_langs').sortable({
+        cursor: 'move'
     });
-})();
-$('#secondary_langs').sortable({
-    cursor: 'move'
 });
 </script>
diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php
index 8e1c23723176dc71d50d3bccfcb6f23262741b8a..c2cf0f20077069397f978c21df38c73d4f8072af 100644
--- a/include/staff/settings-tickets.inc.php
+++ b/include/staff/settings-tickets.inc.php
@@ -7,6 +7,17 @@ if(!($maxfileuploads=ini_get('max_file_uploads')))
 <form action="settings.php?t=tickets" method="post" id="save">
 <?php csrf_token(); ?>
 <input type="hidden" name="t" value="tickets" >
+
+<ul class="clean tabs">
+    <li class="active"><a href="#settings"><i class="icon-asterisk"></i>
+        <?php echo __('Settings'); ?></a></li>
+    <li><a href="#autoresp"><i class="icon-mail-reply-all"></i>
+        <?php echo __('Autoresponder'); ?></a></li>
+    <li><a href="#alerts"><i class="icon-bell-alt"></i>
+        <?php echo __('Alerts and Notices'); ?></a></li>
+</ul>
+
+<div class="tab_content" id="settings">
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
         <tr>
@@ -279,6 +290,16 @@ if(!($maxfileuploads=ini_get('max_file_uploads')))
         <?php } ?>
     </tbody>
 </table>
+</div>
+<div class="hidden tab_content" id="autoresp"
+    data-tip-namespace="settings.autoresponder">
+    <?php include STAFFINC_DIR . 'settings-autoresp.inc.php'; ?>
+</div>
+<div class="hidden tab_content" id="alerts"
+    data-tip-namespace="settings.alerts">
+    <?php include STAFFINC_DIR . 'settings-alerts.inc.php'; ?>
+</div>
+
 <p style="padding-left:250px;">
     <input class="button" type="submit" name="submit" value="<?php echo __('Save Changes');?>">
     <input class="button" type="reset" name="reset" value="<?php echo __('Reset Changes');?>">
diff --git a/include/staff/slaplan.inc.php b/include/staff/slaplan.inc.php
index 3ca424c3044aea1d524f6ef8032b9671cfe04aca..484778e8bb49b76ddbe3abae7603a8675c907ec1 100644
--- a/include/staff/slaplan.inc.php
+++ b/include/staff/slaplan.inc.php
@@ -42,7 +42,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
             <td>
                 <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>"
-                data-translate-tag="<?php echo $trans['name']; ?>"/>
+                    autofocus data-translate-tag="<?php echo $trans['name']; ?>"/>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>&nbsp;<i class="help-tip icon-question-sign" href="#name"></i>
             </td>
         </tr>
diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php
index e1e8fb461b01334a541d727c1948c86dab392e19..b18b7cd772b11206c46962cd0a2937f204163789 100644
--- a/include/staff/staff.inc.php
+++ b/include/staff/staff.inc.php
@@ -50,7 +50,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             </td>
             <td>
                 <input type="text" size="30" class="staff-username typeahead"
-                     name="username" value="<?php echo $info['username']; ?>">
+                     autofocus name="username" value="<?php echo $info['username']; ?>">
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['username']; ?></span>&nbsp;<i class="help-tip icon-question-sign" href="#username"></i>
             </td>
         </tr>
@@ -286,17 +286,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php echo __('Time Zone');?>:
             </td>
             <td>
-                <select name="timezone" class="chosen-select" id="timezone-dropdown"
-                    data-placeholder="<?php echo __('System Default'); ?>">
-                    <option value=""></option>
-<?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                    <option value="<?php echo $zone; ?>" <?php
-                    if ($info['timezone'] == $zone)
-                        echo 'selected="selected"';
-                    ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-<?php } ?>
-                </select>
-                &nbsp;<span class="error">*&nbsp;<?php echo $errors['timezone']; ?></span>
+                <?php
+                $TZ_NAME = 'timezone';
+                $TZ_TIMEZONE = $info['timezone'];
+                include STAFFINC_DIR.'templates/timezone.tmpl.php'; ?>
+                <div class="error"><?php echo $errors['timezone']; ?></div>
             </td>
         </tr>
         <tr>
@@ -364,11 +358,3 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
     <input type="button" name="cancel" value="<?php echo __('Cancel');?>" onclick='window.location.href="staff.php"'>
 </p>
 </form>
-<script type="text/javascript">
-!(function() {
-    $('#timezone-dropdown').chosen({
-        allow_single_deselect: true,
-        width: '350px'
-    });
-})();
-</script>
diff --git a/include/staff/tasks.inc.php b/include/staff/tasks.inc.php
index cd07dfa21bbd3edb44012f34cba80a06ecc9dd37..e74a543994d0823b9cabd010c021e293c36d1769 100644
--- a/include/staff/tasks.inc.php
+++ b/include/staff/tasks.inc.php
@@ -86,10 +86,19 @@ $tasks->filter(Q::any($visibility));
 
 // Add in annotations
 $tasks->annotate(array(
-    //'collab_count' => SqlAggregate::COUNT('collaborators'),
-    'attachment_count' => SqlAggregate::COUNT('thread__entries__attachments'),
-    'thread_count' => SqlAggregate::COUNT('thread__entries'),
-    // 'isopen' => new SqlExpr(array('flags__hasbit' => TaskModel::ISOPEN)),
+    'collab_count' => SqlAggregate::COUNT('thread__collaborators', true),
+    'attachment_count' => SqlAggregate::COUNT(SqlCase::N()
+       ->when(new SqlField('thread__entries__attachments__inline'), null)
+       ->otherwise(new SqlField('thread__entries__attachments')),
+        true
+    ),
+    'thread_count' => SqlAggregate::COUNT(SqlCase::N()
+        ->when(
+            new Q(array('thread__entries__flags__hasbit'=>ThreadEntry::FLAG_HIDDEN)),
+            null)
+        ->otherwise(new SqlField('thread__entries__id')),
+       true
+    ),
 ));
 
 $tasks->values('id', 'number', 'created', 'staff_id', 'team_id',
diff --git a/include/staff/team.inc.php b/include/staff/team.inc.php
index f851fdc3a9c789277eece37f62b60436530bd984..93719667251ffef9ff2ac99ea041907eb62a1add 100644
--- a/include/staff/team.inc.php
+++ b/include/staff/team.inc.php
@@ -31,7 +31,7 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
     <i class="help-tip icon-question-sign" href="#teams"></i>
     </h2>
 <br>
-<ul class="tabs">
+<ul class="clean tabs">
     <li class="active"><a href="#team">
         <i class="icon-file"></i> <?php echo __('Team'); ?></a></li>
     <?php
@@ -58,7 +58,7 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
             </td>
             <td>
                 <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>"
-                data-translate-tag="<?php echo $trans['name']; ?>"/>
+                    autofocus data-translate-tag="<?php echo $trans['name']; ?>"/>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
diff --git a/include/staff/templates/advanced-search.tmpl.php b/include/staff/templates/advanced-search.tmpl.php
index e9f275f027eb8093a9cf383db3b9b5a07aad354c..bb6153383b2f41063dc7084ce67ae281f4e5c1b7 100644
--- a/include/staff/templates/advanced-search.tmpl.php
+++ b/include/staff/templates/advanced-search.tmpl.php
@@ -2,7 +2,7 @@
   $ff_uid = FormField::$uid;
 ?>
 <div id="advanced-search">
-<h3><?php echo __('Advanced Ticket Search');?></h3>
+<h3 class="drag-handle"><?php echo __('Advanced Ticket Search');?></h3>
 <a class="close" href=""><i class="icon-remove-circle"></i></a>
 <hr/>
 <form action="#tickets/search" method="post" name="search">
diff --git a/include/staff/templates/collaborators-preview.tmpl.php b/include/staff/templates/collaborators-preview.tmpl.php
index 964c225e7db174f8e0a614889104378f14d7e312..e7fb4f5985d6b46472e49e9453081d325c927b44 100644
--- a/include/staff/templates/collaborators-preview.tmpl.php
+++ b/include/staff/templates/collaborators-preview.tmpl.php
@@ -2,7 +2,7 @@
 <table border="0" cellspacing="" cellpadding="1">
 <colgroup><col style="min-width: 250px;"></col></colgroup>
 <?php
-if (($users=$ticket->getCollaborators())) {?>
+if (($users=$thread->getCollaborators())) {?>
 <?php
     foreach($users as $user) {
         echo sprintf('<tr><td %s><i class="icon-%s"></i> %s <em>&lt;%s&gt;</em></td></tr>',
@@ -12,16 +12,16 @@ if (($users=$ticket->getCollaborators())) {?>
                 $user->getEmail());
     }
 }  else {
-    echo "<strong>".__("Ticket doesn't have any collaborators.")."</strong>";
+    echo "<strong>".__("Thread doesn't have any collaborators.")."</strong>";
 }?>
 </table>
 <?php
 $options = array();
 
 $options[] = sprintf(
-        '<a class="collaborators" id="managecollab" href="#tickets/%d/collaborators">%s</a>',
-        $ticket->getId(),
-        $ticket->getNumCollaborators()
+        '<a class="collaborators" id="managecollab" href="#thread/%d/collaborators">%s</a>',
+        $thread->getId(),
+        $thread->getNumCollaborators()
         ? __('Manage Collaborators') : __('Add Collaborator')
         );
 
diff --git a/include/staff/templates/collaborators.tmpl.php b/include/staff/templates/collaborators.tmpl.php
index d8d339c882dae25b1f5592f43a40c95420e76f66..c49b1b266edaf1118a5f058ab8cb2f67fa5dc8cb 100644
--- a/include/staff/templates/collaborators.tmpl.php
+++ b/include/staff/templates/collaborators.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Ticket Collaborators'); ?></h3>
+<h3 class="drag-handle"><?php echo __('Collaborators'); ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <?php
 if($info && $info['msg']) {
@@ -6,9 +6,9 @@ if($info && $info['msg']) {
 } ?>
 <hr/>
 <?php
-if(($users=$ticket->getCollaborators())) {?>
+if(($users=$thread->getCollaborators())) {?>
 <div id="manage_collaborators">
-<form method="post" class="collaborators" action="#tickets/<?php echo $ticket->getId(); ?>/collaborators">
+<form method="post" class="collaborators" action="#thread/<?php echo $thread->getId(); ?>/collaborators">
     <table border="0" cellspacing="1" cellpadding="1" width="100%">
     <?php
     foreach($users as $user) {
@@ -16,7 +16,7 @@ if(($users=$ticket->getCollaborators())) {?>
         echo sprintf('<tr>
                         <td>
                             <input type="checkbox" name="cid[]" id="c%d" value="%d" %s>
-                            <a class="collaborator" href="#collaborators/%d/view">%s</a>
+                            <a class="collaborator" href="#thread/%d/collaborators/%d/view">%s</a>
                             <span class="faded"><em>%s</em></span></td>
                         <td width="10">
                             <input type="hidden" name="del[]" id="d%d" value="">
@@ -26,6 +26,7 @@ if(($users=$ticket->getCollaborators())) {?>
                     $user->getId(),
                     $user->getId(),
                     $checked,
+                    $thread->getId(),
                     $user->getId(),
                     Format::htmlchars($user->getName()),
                     $user->getEmail(),
@@ -36,7 +37,7 @@ if(($users=$ticket->getCollaborators())) {?>
     </table>
     <hr style="margin-top:1em"/>
     <div><a class="collaborator"
-        href="#tickets/<?php echo $ticket->getId(); ?>/add-collaborator"
+        href="#thread/<?php echo $thread->getId(); ?>/add-collaborator"
         ><i class="icon-plus-sign"></i> <?php echo __('Add New Collaborator'); ?></a></div>
     <div id="savewarning" style="display:none; padding-top:2px;"><p
     id="msg_warning"><?php echo __('You have made changes that you need to save.'); ?></p></div>
@@ -57,15 +58,22 @@ if(($users=$ticket->getCollaborators())) {?>
     echo __("Bro, not sure how you got here!");
 }
 
-if ($_POST && $ticket && $ticket->getNumCollaborators()) {
+if ($_POST && $thread && $thread->getNumCollaborators()) {
+
+    $collaborators = sprintf('Participants (%d)',
+            $thread->getNumCollaborators());
+
     $recipients = sprintf(__('Recipients (%d of %d)'),
-          $ticket->getNumActiveCollaborators(),
-          $ticket->getNumCollaborators());
+          $thread->getNumActiveCollaborators(),
+          $thread->getNumCollaborators());
     ?>
     <script type="text/javascript">
         $(function() {
             $('#emailcollab').show();
-            $('#recipients').html('<?php echo $recipients; ?>');
+            $('#t<?php echo $thread->getId(); ?>-recipients')
+            .html('<?php echo $recipients; ?>');
+            $('#t<?php echo $thread->getId(); ?>-collaborators')
+            .html('<?php echo $collaborators; ?>');
             });
     </script>
 <?php
diff --git a/include/staff/templates/content-manage.tmpl.php b/include/staff/templates/content-manage.tmpl.php
index 3fa4e8fcbd8c1554649c576d84f3ba74e74e4eca..9009a4e45d157b292d25b9a233985e5b52c9aa7b 100644
--- a/include/staff/templates/content-manage.tmpl.php
+++ b/include/staff/templates/content-manage.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Manage Content'); ?> &mdash; <?php echo Format::htmlchars($content->getName()); ?></h3>
+<h3 class="drag-handle"><?php echo __('Manage Content'); ?> &mdash; <?php echo Format::htmlchars($content->getName()); ?></h3>
 <a class="close" href=""><i class="icon-remove-circle"></i></a>
 <hr/>
 
@@ -27,7 +27,8 @@ if (count($langs) > 1) { ?>
         class="tab_content left-tabs" style="padding:0" lang="<?php echo $cfg->getPrimaryLanguage(); ?>">
     <div class="error"><?php echo $errors['name']; ?></div>
     <input type="text" style="width: 100%; font-size: 14pt" name="name" value="<?php
-        echo Format::htmlchars($info['title']); ?>" />
+    echo Format::htmlchars($info['title']); ?>" spellcheck="true"
+        lang="<?php echo $cfg->getPrimaryLanguage(); ?>" />
     <div style="margin-top: 5px">
     <div class="error"><?php echo $errors['body']; ?></div>
     <textarea class="richtext no-bar" name="body"
@@ -46,7 +47,8 @@ if (count($langs) > 1) { ?>
     <input type="text" style="width: 100%; font-size: 14pt"
         name="trans[<?php echo $tag; ?>][title]" value="<?php
         echo Format::htmlchars($trans['title']); ?>"
-        placeholder="<?php echo __('Title'); ?>" />
+        placeholder="<?php echo __('Title'); ?>"  spellcheck="true"
+        lang="<?php echo $tag; ?>" />
     <div style="margin-top: 5px">
     <textarea class="richtext no-bar" data-direction=<?php echo $nfo['direction']; ?>
         data-root-context="<?php echo $content->getType(); ?>"
diff --git a/include/staff/templates/dynamic-field-config.tmpl.php b/include/staff/templates/dynamic-field-config.tmpl.php
index f2e66643197866939fdb95fe1147c7b66ee1bca5..780fe18dec545d8d3ca8d760bcf1d21f31f3ad4a 100644
--- a/include/staff/templates/dynamic-field-config.tmpl.php
+++ b/include/staff/templates/dynamic-field-config.tmpl.php
@@ -1,4 +1,4 @@
-    <h3><?php echo __('Field Configuration'); ?> &mdash; <?php echo $field->get('label') ?></h3>
+    <h3 class="drag-handle"><?php echo __('Field Configuration'); ?> &mdash; <?php echo $field->get('label') ?></h3>
     <a class="close" href=""><i class="icon-remove-circle"></i></a>
     <hr/>
     <form method="post" action="#form/field-config/<?php
diff --git a/include/staff/templates/form-manage.tmpl.php b/include/staff/templates/form-manage.tmpl.php
index e002ef1654dc3273938aed81383ac5fe2ad4be20..4ad941887886ed77102a1b868d828e1fd79c5796 100644
--- a/include/staff/templates/form-manage.tmpl.php
+++ b/include/staff/templates/form-manage.tmpl.php
@@ -1,4 +1,4 @@
-<h3><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></i></h3>
+<h3 class="drag-handle"><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></i></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/><?php echo __(
 'Sort the forms on this ticket by click and dragging on them. Use the box below the forms list to add new forms to the ticket.'
diff --git a/include/staff/templates/list-import.tmpl.php b/include/staff/templates/list-import.tmpl.php
index b3c38a99d66b83973de5459acc6285769e02f625..bf367c76ce58d10d762aea0631f0fa03d034c06f 100644
--- a/include/staff/templates/list-import.tmpl.php
+++ b/include/staff/templates/list-import.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/list-item-properties.tmpl.php b/include/staff/templates/list-item-properties.tmpl.php
index 706c9484cb171e959788ce13a5c5cedb0624008e..61ef1b8f6ba3c0d25c3cfed5ceefd3040a1b8f18 100644
--- a/include/staff/templates/list-item-properties.tmpl.php
+++ b/include/staff/templates/list-item-properties.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo $list->getName(); ?> &mdash; <?php
+<h3 class="drag-handle"><?php echo $list->getName(); ?> &mdash; <?php
     echo $item ? $item->getValue() : __('Add New List Item'); ?></h3>
 <a class="close" href=""><i class="icon-remove-circle"></i></a>
 <hr/>
diff --git a/include/staff/templates/org-delete.tmpl.php b/include/staff/templates/org-delete.tmpl.php
index 16e06c83b556e6bb2a034ba46d38c5c4834e3ec7..290d20e121932c75e3de195b957915e5bc378eac 100644
--- a/include/staff/templates/org-delete.tmpl.php
+++ b/include/staff/templates/org-delete.tmpl.php
@@ -6,7 +6,7 @@ if (!$info['title'])
 $info['warn'] = __('Deleted organization CANNOT be recovered');
 
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/org-lookup.tmpl.php b/include/staff/templates/org-lookup.tmpl.php
index 10a4ce28fbf75916ba718e52e45bd0c9f38ae25a..377cf53470893526e4664732d2f273e0c2ae1bef 100644
--- a/include/staff/templates/org-lookup.tmpl.php
+++ b/include/staff/templates/org-lookup.tmpl.php
@@ -9,7 +9,7 @@ if ($info['search'] === false)
 
 ?>
 <div id="the-lookup-form">
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <div><p id="msg_info"><i class="icon-info-sign"></i>&nbsp; <?php echo $msg_info; ?></p></div>
@@ -17,7 +17,8 @@ if ($info['search'] === false)
 if ($info['search'] !== false) { ?>
 <div style="margin-bottom:10px;">
     <input type="text" class="search-input" style="width:100%;"
-    placeholder="Search by name" id="org-search" autocorrect="off" autocomplete="off"/>
+    placeholder="Search by name" id="org-search"
+    autofocus autocorrect="off" autocomplete="off"/>
 </div>
 <?php
 }
diff --git a/include/staff/templates/org-profile.tmpl.php b/include/staff/templates/org-profile.tmpl.php
index c73a4f5a34d503a05a2ff8a2c2a5394bcdf1fdd7..90420dab8b8909fac2d7a53d1ed0e28a31b85376 100644
--- a/include/staff/templates/org-profile.tmpl.php
+++ b/include/staff/templates/org-profile.tmpl.php
@@ -4,7 +4,7 @@ $info=($_POST && $errors)?Format::input($_POST):@Format::htmlchars($org->getInfo
 if (!$info['title'])
     $info['title'] = Format::htmlchars($org->getName());
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
@@ -170,6 +170,6 @@ $(function() {
         $('div#org-profile').fadeIn();
         return false;
     });
-    $("#primary_contacts").chosen({width: '300px'});
+    $("#primary_contacts").select2({width: '300px'});
 });
 </script>
diff --git a/include/staff/templates/org.tmpl.php b/include/staff/templates/org.tmpl.php
index 41fcec1ee8d99b60b51446b7ea83e1216e10e16d..4b8bc97fa31cd6a8585bc944efb0d770c92f7532 100644
--- a/include/staff/templates/org.tmpl.php
+++ b/include/staff/templates/org.tmpl.php
@@ -2,7 +2,7 @@
 if (!$info['title'])
     $info['title'] = Format::htmlchars($org->getName());
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/sequence-manage.tmpl.php b/include/staff/templates/sequence-manage.tmpl.php
index 10ac7391ba63dba74a9f07ccb21fbe15e2dfba58..d349605eecf985f516438e075318ea5076b83f2b 100644
--- a/include/staff/templates/sequence-manage.tmpl.php
+++ b/include/staff/templates/sequence-manage.tmpl.php
@@ -1,4 +1,4 @@
-<h3><i class="icon-wrench"></i> <?php echo __('Manage Sequences'); ?></i></h3>
+<h3 class="drag-handle"><i class="icon-wrench"></i> <?php echo __('Manage Sequences'); ?></i></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/><?php echo __(
 'Sequences are used to generate sequential numbers. Various sequences can be
diff --git a/include/staff/templates/task-assign.tmpl.php b/include/staff/templates/task-assign.tmpl.php
index 7019fa49a2b1d12fdb03039921f0f65b7f9d367c..1c0feca3a503dd433867579484d9751dbe16f846 100644
--- a/include/staff/templates/task-assign.tmpl.php
+++ b/include/staff/templates/task-assign.tmpl.php
@@ -7,7 +7,7 @@ if (!$info[':title'])
     $info[':title'] = sprintf(__('%s Selected Tasks'),
             __('Assign'));
 ?>
-<h3><?php echo $info[':title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info[':title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
diff --git a/include/staff/templates/task-delete.tmpl.php b/include/staff/templates/task-delete.tmpl.php
index 9a9191e4cc5134849fee8d60a5b4e0aa5d82c21a..eea44e19cc1710543a5febab3fefb648e20cb3b3 100644
--- a/include/staff/templates/task-delete.tmpl.php
+++ b/include/staff/templates/task-delete.tmpl.php
@@ -5,7 +5,7 @@ if (!$info[':title'])
             __('Delete'),
             _N('selected task', 'selected tasks', $count));
 ?>
-<h3><?php echo $info[':title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info[':title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
diff --git a/include/staff/templates/task-edit.tmpl.php b/include/staff/templates/task-edit.tmpl.php
index a77079e251be82ab85d584083a05a540fe2eb977..b90d545f823a2e812da24300225643d69c70ed55 100644
--- a/include/staff/templates/task-edit.tmpl.php
+++ b/include/staff/templates/task-edit.tmpl.php
@@ -10,7 +10,7 @@ $action = $info['action'] ?: ('#tasks/'.$task->getId().'/edit');
 
 ?>
 <div id="task-form">
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/task-preview.tmpl.php b/include/staff/templates/task-preview.tmpl.php
index d6968f49a42da80daa6ccc8f730d548edbd519b0..5203956880e919bd708714227f1af258bb5206d5 100644
--- a/include/staff/templates/task-preview.tmpl.php
+++ b/include/staff/templates/task-preview.tmpl.php
@@ -23,6 +23,13 @@ echo '<ul class="tabs" id="task-preview">';
 echo '
         <li class="active"><a href="#summary"
             ><i class="icon-list-alt"></i>&nbsp;'.__('Task Summary').'</a></li>';
+if ($task->getThread()->getNumCollaborators()) {
+    echo sprintf('
+        <li><a id="collab_tab" href="#collab"
+            ><i class="icon-fixed-width icon-group
+            faded"></i>&nbsp;'.__('Collaborators (%d)').'</a></li>',
+            $task->getThread()->getNumCollaborators());
+}
 echo '</ul>';
 echo '<div id="task-preview_container">';
 echo '<div class="tab_content" id="summary">';
@@ -72,9 +79,37 @@ echo '
     </table>';
 echo '</div>';
 ?>
-</div>
 <?php
 //TODO: add link to view if the user has permission
-
-echo '</div>';
 ?>
+<div class="hidden tab_content" id="collab">
+    <table border="0" cellspacing="" cellpadding="1">
+        <colgroup><col style="min-width: 250px;"></col></colgroup>
+        <?php
+        if (($collabs=$task->getThread()->getCollaborators())) {?>
+        <?php
+            foreach($collabs as $collab) {
+                echo sprintf('<tr><td %s><i class="icon-%s"></i>
+                        <a href="users.php?id=%d" class="no-pjax">%s</a> <em>&lt;%s&gt;</em></td></tr>',
+                        ($collab->isActive()? '' : 'class="faded"'),
+                        ($collab->isActive()? 'comments' :  'comment-alt'),
+                        $collab->getUserId(),
+                        $collab->getName(),
+                        $collab->getEmail());
+            }
+        }  else {
+            echo __("Task doesn't have any collaborators.");
+        }?>
+    </table>
+    <br>
+    <?php
+    echo sprintf('<span><a class="collaborators"
+                            href="#thread/%d/collaborators">%s</a></span>',
+                            $task->getThreadId(),
+                            $task->getThread()->getNumCollaborators()
+                                ? __('Manage Collaborators') : __('Add Collaborator')
+                                );
+    ?>
+</div>
+</div>
+</div>
diff --git a/include/staff/templates/task-status.tmpl.php b/include/staff/templates/task-status.tmpl.php
index b711e6f91c71f2e8b46a6d353ca5ef2e859d5e39..d741aaafce72089c65299c2e83efd605a85c9086 100644
--- a/include/staff/templates/task-status.tmpl.php
+++ b/include/staff/templates/task-status.tmpl.php
@@ -5,7 +5,7 @@ if (!$info[':title'])
     $info[':title'] = __('Change Tasks Status');
 
 ?>
-<h3><?php echo $info[':title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info[':title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
diff --git a/include/staff/templates/task-transfer.tmpl.php b/include/staff/templates/task-transfer.tmpl.php
index a45311f7f991b4fba4e0522272401edde44c376b..b199be14fcfcf90118081d4f4bb09d6861624e10 100644
--- a/include/staff/templates/task-transfer.tmpl.php
+++ b/include/staff/templates/task-transfer.tmpl.php
@@ -7,7 +7,7 @@ if (!$info[':title'])
     $info[':title'] = sprintf(__('%s Selected Tasks'),
             __('Tranfer'));
 ?>
-<h3><?php echo $info[':title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info[':title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php
index 7cd928b8a15e05921fe7e612fffd2e477fde94a2..0e3f509268b1b5dcded6377b5a137af6be80a029 100644
--- a/include/staff/templates/task-view.tmpl.php
+++ b/include/staff/templates/task-view.tmpl.php
@@ -61,22 +61,36 @@ if ($task->isOverdue())
 ?>
 <table width="940" cellpadding="2" cellspacing="0" border="0">
     <tr>
-        <td width="20%" class="has_bottom_border">
-            <h2><a
-                id="reload-task"
-                href="tasks.php?id=<?php echo $task->getId(); ?>"
-                <?php
-                if ($ticket) {
+        <td width="<?php echo $ticket ? '70%' : '20%'; ?>" class="has_bottom_border">
+            <?php
+            if ($ticket) { ?>
+                <strong>
+                <a id="tasks" href="#"> All Tasks (<?php echo $ticket->getNumTasks(); ?>)</a>
+                &nbsp;/&nbsp;
+                <?php echo $task->getTitle(); ?>
+                &nbsp;&mdash;&nbsp;
+                <a
+                    id="reload-task" class="preview"
+                    <?php
                     echo ' class="preview" ';
                     echo sprintf('data-preview="#tasks/%d/preview" ', $task->getId());
                     echo sprintf('href="#tasks/%d" ', $task->getId());
-                } else { ?>
-                    href="tasks.php?id=<?php echo $task->getId(); ?>"
-                <?php
-                } ?>
+                    ?>
+                ><?php
+                echo sprintf('#%s', $task->getNumber()); ?></a>
+                </strong>
+            <?php
+            } else { ?>
+               <h2>
+                <a
+                id="reload-task"
+                href="tasks.php?id=<?php echo $task->getId(); ?>"
+                href="tasks.php?id=<?php echo $task->getId(); ?>"
                 ><i class="icon-refresh"></i> <?php
                 echo sprintf(__('Task #%s'), $task->getNumber()); ?></a>
-            </h2>
+               </h2>
+            <?php
+            } ?>
         </td>
         <td width="auto" class="flush-right has_bottom_border">
             <?php
@@ -88,7 +102,7 @@ if ($task->isOverdue())
                 <a class="task-action"
                     href="#task-options"><i
                     class="icon-reorder"></i> <?php
-                    echo __('Options'); ?></a>
+                    echo __('Actions'); ?></a>
             </span>
             <div id="action-dropdown-task-options"
                 class="action-dropdown anchor-right">
@@ -143,6 +157,34 @@ if (!$ticket) { ?>
                         <th width="100"><?php echo __('Status');?>:</th>
                         <td><?php echo $task->getStatus(); ?></td>
                     </tr>
+
+                    <tr>
+                        <th><?php echo __('Create Date');?>:</th>
+                        <td><?php echo Format::datetime($task->getCreateDate()); ?></td>
+                    </tr>
+                    <?php
+                    if($task->isOpen()){ ?>
+                    <tr>
+                        <th><?php echo __('Due Date');?>:</th>
+                        <td><?php echo $task->duedate ?
+                        Format::datetime($task->duedate) : '<span
+                        class="faded">&mdash; '.__('None').' &mdash;</span>'; ?></td>
+                    </tr>
+                    <?php
+                    }else { ?>
+                    <tr>
+                        <th><?php echo __('Close Date');?>:</th>
+                        <td><?php echo 0 ?
+                        Format::datetime($task->getCloseDate()) : ''; ?></td>
+                    </tr>
+                    <?php
+                    }
+                    ?>
+                </table>
+            </td>
+            <td width="50%" style="vertical-align:top">
+                <table cellspacing="0" cellpadding="4" width="100%" border="0">
+
                     <tr>
                         <th><?php echo __('Department');?>:</th>
                         <td><?php echo Format::htmlchars($task->dept->getName()); ?></td>
@@ -175,36 +217,24 @@ if (!$ticket) { ?>
                     </tr>
                     <?php
                     } ?>
-                </table>
-            </td>
-            <td width="50%" style="vertical-align:top">
-                <table cellspacing="0" cellpadding="4" width="100%" border="0">
-                    <tr>
-                        <th><?php echo __('SLA Plan');?>:</th>
-                        <td><?php echo $sla?Format::htmlchars($sla->getName()):'<span class="faded">&mdash; '.__('None').' &mdash;</span>'; ?></td>
-                    </tr>
-                    <tr>
-                        <th><?php echo __('Create Date');?>:</th>
-                        <td><?php echo Format::datetime($task->getCreateDate()); ?></td>
-                    </tr>
-                    <?php
-                    if($task->isOpen()){ ?>
                     <tr>
-                        <th><?php echo __('Due Date');?>:</th>
-                        <td><?php echo $task->duedate ?
-                        Format::datetime($task->duedate) : '<span
-                        class="faded">&mdash; '.__('None').' &mdash;</span>'; ?></td>
-                    </tr>
-                    <?php
-                    }else { ?>
-                    <tr>
-                        <th><?php echo __('Close Date');?>:</th>
-                        <td><?php echo 0 ?
-                        Format::datetime($task->getCloseDate()) : ''; ?></td>
+                        <th><?php echo __('Collaborators');?>:</th>
+                        <td>
+                            <?php
+                            $collaborators = __('Add Participants');
+                            if ($task->getThread()->getNumCollaborators())
+                                $collaborators = sprintf(__('Participants (%d)'),
+                                        $task->getThread()->getNumCollaborators());
+
+                            echo sprintf('<span><a class="collaborators preview"
+                                    href="#thread/%d/collaborators"><span
+                                    id="t%d-collaborators">%s</span></a></span>',
+                                    $task->getThreadId(),
+                                    $task->getThreadId(),
+                                    $collaborators);
+                           ?>
+                        </td>
                     </tr>
-                    <?php
-                    }
-                    ?>
                 </table>
             </td>
         </tr>
@@ -337,7 +367,7 @@ else
 
 <script type="text/javascript">
 $(function() {
-    $(document).on('click', 'li.active a#ticket_tasks', function(e) {
+    $(document).on('click', 'li.active a#ticket_tasks, a#tasks', function(e) {
         e.preventDefault();
         $('div#task_content').hide().empty();
         $('div#tasks_content').show();
diff --git a/include/staff/templates/task.tmpl.php b/include/staff/templates/task.tmpl.php
index d92da014f9f53e7367f67daecbfe3f41b517c45b..1271318ba3a5e48b7715ec5577987882e5fa1056 100644
--- a/include/staff/templates/task.tmpl.php
+++ b/include/staff/templates/task.tmpl.php
@@ -9,7 +9,7 @@ if ($ticket)
 
 ?>
 <div id="task-form">
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/thread-email-headers.tmpl.php b/include/staff/templates/thread-email-headers.tmpl.php
index a84216ab46be6c4816a679ada4a1e77ff96e5216..631d43c2e225c09d0531e57fa589990dd134bb62 100644
--- a/include/staff/templates/thread-email-headers.tmpl.php
+++ b/include/staff/templates/thread-email-headers.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Raw Email Headers'); ?></h3>
+<h3 class="drag-handle"><?php echo __('Raw Email Headers'); ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 
diff --git a/include/staff/templates/thread-entries.tmpl.php b/include/staff/templates/thread-entries.tmpl.php
index 821c1c50ca4416860e4350507fa730b744d6a2e9..2e7da2c389cf2b276b139a5573e040fb0e6590a9 100644
--- a/include/staff/templates/thread-entries.tmpl.php
+++ b/include/staff/templates/thread-entries.tmpl.php
@@ -35,7 +35,13 @@ if ($entries) {
             </div>
 <?php           } ?>
                 <span style="vertical-align:middle">
-                    <span style="vertical-align:middle;" class="textra"></span>
+                    <span style="vertical-align:middle;" class="textra">
+        <?php if ($entry->flags & ThreadEntry::FLAG_EDITED) { ?>
+                <span class="label label-bare" title="<?php
+        echo sprintf(__('Edited on %s by %s'), Format::datetime($entry->updated), 'You');
+                ?>"><?php echo __('Edited'); ?></span>
+        <?php } ?>
+                    </span>
                     <span style="vertical-align:middle;"
                         class="tmeta faded title"><?php
                         echo Format::htmlchars($entry->getName()); ?></span>
@@ -60,7 +66,8 @@ if ($entries) {
                             Format::file_size($A->file->size));
 ?>
             <a class="Icon file no-pjax" href="<?php echo $A->file->getDownloadUrl();
-                ?>" target="_blank"><?php echo Format::htmlchars($A->file->name);
+                ?>" download="<?php echo Format::htmlchars($A->file->name); ?>"
+                target="_blank"><?php echo Format::htmlchars($A->file->name);
             ?></a><?php echo $size;?>&nbsp;
 <?php               } ?>
             </td>
diff --git a/include/staff/templates/thread-entry-edit.tmpl.php b/include/staff/templates/thread-entry-edit.tmpl.php
index e1ed1f81c9e062f8c0a45bc4a1bc6c925759681f..24e63230e1c8bf91730369ed35907c5096eabfeb 100644
--- a/include/staff/templates/thread-entry-edit.tmpl.php
+++ b/include/staff/templates/thread-entry-edit.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Edit Thread Entry'); ?></h3>
+<h3 class="drag-handle"><?php echo __('Edit Thread Entry'); ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 
diff --git a/include/staff/templates/thread-entry-resend.tmpl.php b/include/staff/templates/thread-entry-resend.tmpl.php
index 8a3e283c6418c0cdadd26b3db34a4fbc8c59f440..f5bc8eb9aa222b8a3569d357abf66bf9fcceb7f1 100644
--- a/include/staff/templates/thread-entry-resend.tmpl.php
+++ b/include/staff/templates/thread-entry-resend.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Resend Entry'); ?></h3>
+<h3 class="drag-handle"><?php echo __('Resend Entry'); ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 
diff --git a/include/staff/templates/thread-entry-view.tmpl.php b/include/staff/templates/thread-entry-view.tmpl.php
index 2b76d851f3611a89e452492117593ebf17203b37..51a0a10da8bc411507c049337ee7cc2b92a86e5b 100644
--- a/include/staff/templates/thread-entry-view.tmpl.php
+++ b/include/staff/templates/thread-entry-view.tmpl.php
@@ -1,4 +1,4 @@
-<h3><?php echo __('Original Thread Entry'); ?></h3>
+<h3 class="drag-handle"><?php echo __('Original Thread Entry'); ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 
@@ -6,7 +6,21 @@
 
 <?php
 $E = $entry;
-do { ?>
+$i = 0;
+$omniscient = $thisstaff->getRole()->hasPerm(ThreadEntry::PERM_EDIT);
+do {
+    $i++;
+    if (!$omniscient
+        // The current version is always visible
+        && $i > 1
+        // If you originally posted it, you can see all the edits
+        && $E->staff_id != $thisstaff->getId()
+        // You can see your own edits
+        //  && $E->editor != $thisstaff->getId()
+    ) {
+        // Skip edits made by other agents
+        continue;
+    } ?>
 <dt>
     <a href="#"><i class="icon-copy"></i>
     <strong><?php if ($E->title)
@@ -48,11 +62,13 @@ $(function() {
 
     var allPanels = $('dd', A).hide().removeClass('hidden');
     $('dt > a', A).click(function() {
-      $('dt', A).removeClass('active');
-      allPanels.slideUp();
-      $(this).parent().addClass('active').next().slideDown();
+      if (!$(this).parent().is('.active')) {
+        $('dt', A).removeClass('active');
+        allPanels.slideUp();
+        $(this).parent().addClass('active').next().slideDown();
+      }
       return false;
     });
-    allPanels.last().show();
+    allPanels.last().show().prev().addClass('active');
   }, 100);
 });
diff --git a/include/staff/templates/ticket-preview.tmpl.php b/include/staff/templates/ticket-preview.tmpl.php
index 875c9d701bdcd641540b6f1c5d37e76b674ddc4c..f4091921f15fc4f32455e2fdd7aed9f94008f93d 100644
--- a/include/staff/templates/ticket-preview.tmpl.php
+++ b/include/staff/templates/ticket-preview.tmpl.php
@@ -34,12 +34,12 @@ echo '<ul class="tabs" id="ticket-preview">';
 echo '
         <li class="active"><a id="preview_tab" href="#preview"
             ><i class="icon-list-alt"></i>&nbsp;'.__('Ticket Summary').'</a></li>';
-if ($ticket->getNumCollaborators()) {
+if ($ticket->getThread()->getNumCollaborators()) {
 echo sprintf('
         <li><a id="collab_tab" href="#collab"
             ><i class="icon-fixed-width icon-group
             faded"></i>&nbsp;'.__('Collaborators (%d)').'</a></li>',
-            $ticket->getNumCollaborators());
+            $ticket->getThread()->getNumCollaborators());
 }
 echo '</ul>';
 echo '<div id="ticket-preview_container">';
@@ -121,7 +121,7 @@ echo '</div>'; // ticket preview content.
     <table border="0" cellspacing="" cellpadding="1">
         <colgroup><col style="min-width: 250px;"></col></colgroup>
         <?php
-        if (($collabs=$ticket->getCollaborators())) {?>
+        if (($collabs=$ticket->getThread()->getCollaborators())) {?>
         <?php
             foreach($collabs as $collab) {
                 echo sprintf('<tr><td %s><i class="icon-%s"></i>
@@ -141,7 +141,7 @@ echo '</div>'; // ticket preview content.
     echo sprintf('<span><a class="collaborators"
                             href="#tickets/%d/collaborators">%s</a></span>',
                             $ticket->getId(),
-                            $ticket->getNumCollaborators()
+                            $ticket->getThread()->getNumCollaborators()
                                 ? __('Manage Collaborators') : __('Add Collaborator')
                                 );
     ?>
diff --git a/include/staff/templates/ticket-print.tmpl.php b/include/staff/templates/ticket-print.tmpl.php
index 11323c4a14b60077e7e208cc41f0b1434726882e..97074ed2682031b73672ecd817a5ba0085f30394 100644
--- a/include/staff/templates/ticket-print.tmpl.php
+++ b/include/staff/templates/ticket-print.tmpl.php
@@ -183,13 +183,10 @@ div.hr {
 <?php
 foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) {
     // Skip core fields shown earlier in the ticket view
-    // TODO: Rewrite getAnswers() so that one could write
-    //       ->getAnswers()->filter(not(array('field__name__in'=>
-    //           array('email', ...))));
-    $answers = array_filter($form->getAnswers(), function ($a) {
-        return !in_array($a->getField()->get('name'),
-                array('email','subject','name','priority'));
-        });
+    $answers = $form->getAnswers()->exclude(Q::any(array(
+        'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED,
+        'field__name__in' => array('subject', 'priority')
+    )));
     if (count($answers) == 0)
         continue;
     ?>
diff --git a/include/staff/templates/ticket-status.tmpl.php b/include/staff/templates/ticket-status.tmpl.php
index eae1b3272e99c586e0abdf88e08bdf9995a6c83b..458c6010c5b543ee79dd601af16ae43fa154bfbb 100644
--- a/include/staff/templates/ticket-status.tmpl.php
+++ b/include/staff/templates/ticket-status.tmpl.php
@@ -5,7 +5,7 @@ if (!$info['title'])
     $info['title'] = 'Change Tickets Status';
 
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
diff --git a/include/staff/templates/timezone.tmpl.php b/include/staff/templates/timezone.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..840940b0ce92d9019847096d73334f4aa936a225
--- /dev/null
+++ b/include/staff/templates/timezone.tmpl.php
@@ -0,0 +1,39 @@
+<?php
+$TZ_NAME = @$TZ_NAME ?: 'timezone';
+$TZ_ALLOW_DEFAULT = isset($TZ_ALLOW_DEFAULT) ? $TZ_ALLOW_DEFAULT : true;
+$TZ_PLACEHOLDER = @$TZ_PLACEHOLDER ?: __('System Default');
+$TZ_TIMEZONE = @$TZ_TIMEZONE ?: '';
+?>
+<select name="<?php echo $TZ_NAME; ?>" id="timezone-dropdown"
+        data-placeholder="<?php echo $TZ_PLACEHOLDER; ?>">
+<?php if ($TZ_ALLOW_DEFAULT) { ?>
+        <option value=""></option>
+<?php }
+    foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
+        <option value="<?php echo $zone; ?>" <?php
+        if ($TZ_TIMEZONE == $zone)
+            echo 'selected="selected"';
+        ?>><?php echo str_replace('/',' / ',$zone); ?></option>
+<?php } ?>
+    </select>
+    <button class="action-button" onclick="javascript:
+$('head').append($('<script>').attr('src', '<?php
+    echo ROOT_PATH; ?>js/jstz.min.js'));
+var recheck = setInterval(function() {
+    if (window.jstz !== undefined) {
+        clearInterval(recheck);
+        var zone = jstz.determine();
+        $('#timezone-dropdown').val(zone.name()).trigger('change');
+
+    }
+}, 100);
+return false;" style="vertical-align:middle"><i class="icon-map-marker"></i> <?php echo __('Auto Detect'); ?></button>
+
+<script type="text/javascript">
+$(function() {
+    $('#timezone-dropdown').select2({
+        allowClear: <?php echo $TZ_ALLOW_DEFAULT ? 'true' : 'false'; ?>,
+        width: '300px'
+    });
+});
+</script>
diff --git a/include/staff/templates/user-account.tmpl.php b/include/staff/templates/user-account.tmpl.php
index 6319aeb960daf8b427dc67169770b0e4f91d6100..ce1605f961cd27542a63df8589941f05469a8bd4 100644
--- a/include/staff/templates/user-account.tmpl.php
+++ b/include/staff/templates/user-account.tmpl.php
@@ -5,7 +5,7 @@ $access = (isset($info['_target']) && $info['_target'] == 'access');
 if (!$info['title'])
     $info['title'] = Format::htmlchars($user->getName());
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
@@ -67,16 +67,10 @@ if ($info['error']) {
                     <?php echo __('Time Zone');?>:
                 </td>
                 <td>
-                    <select name="timezone" class="chosen-select" id="timezone-dropdown"
-                        data-placeholder="<?php echo __('System Default'); ?>">
-                        <option value=""></option>
-    <?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                        <option value="<?php echo $zone; ?>" <?php
-                        if ($info['timezone'] == $zone)
-                            echo 'selected="selected"';
-                        ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-    <?php } ?>
-                    </select>
+                    <?php
+                    $TZ_NAME = 'timezone';
+                    $TZ_TIMEZONE = $info['timezone'];
+                    include STAFFINC_DIR.'templates/timezone.tmpl.php'; ?>
                     <div class="error"><?php echo $errors['timezone']; ?></div>
                 </td>
             </tr>
@@ -174,11 +168,4 @@ $(function() {
             $('tbody#password').show();
     });
 });
-!(function() {
-    $('#timezone-dropdown').chosen({
-        header: <?php echo JsonDataEncoder::encode(__('Time Zones')); ?>,
-        allow_single_deselect: true,
-        width: '350px'
-    });
-})();
 </script>
diff --git a/include/staff/templates/user-delete.tmpl.php b/include/staff/templates/user-delete.tmpl.php
index 35bb685be93e07e0ca69efded5f0fe6c3466ff43..3c8ab2a6516cb1a190c19b501a237892d7d3ed0f 100644
--- a/include/staff/templates/user-delete.tmpl.php
+++ b/include/staff/templates/user-delete.tmpl.php
@@ -6,7 +6,7 @@ if (!$info['title'])
 $info['warn'] = __('Deleted users and tickets CANNOT be recovered');
 
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/user-import.tmpl.php b/include/staff/templates/user-import.tmpl.php
index 413ed54e4bcbaeed35f4a2a234e4d78722b4a96d..a1c47340b131e4487dbcae4e21451c381175f84d 100644
--- a/include/staff/templates/user-import.tmpl.php
+++ b/include/staff/templates/user-import.tmpl.php
@@ -1,5 +1,5 @@
 <div id="the-lookup-form">
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
diff --git a/include/staff/templates/user-lookup.tmpl.php b/include/staff/templates/user-lookup.tmpl.php
index 948026e8ff188f4ce6fb7ee5c1319db346226314..4a8e1c505bf782b04fec58c0b8a606958e10a6d2 100644
--- a/include/staff/templates/user-lookup.tmpl.php
+++ b/include/staff/templates/user-lookup.tmpl.php
@@ -1,5 +1,5 @@
 <div id="the-lookup-form">
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr/>
 <?php
@@ -10,9 +10,9 @@ if (!isset($info['lookup']) || $info['lookup'] !== false) { ?>
     : __('Search existing users.');
 ?></p></div>
 <div style="margin-bottom:10px;">
-    <input type="text" class="search-input" style="width:100%;"
+    <input type="search" class="search-input" style="width:100%;"
     placeholder="<?php echo __('Search by email, phone or name'); ?>" id="user-search"
-    autocorrect="off" autocomplete="off"/>
+    autofocus autocorrect="off" autocomplete="off"/>
 </div>
 <?php
 }
diff --git a/include/staff/templates/user-register.tmpl.php b/include/staff/templates/user-register.tmpl.php
index a68d1a23c17be5dcc3255a3d7955c638d275bd2d..1fee0e6f30c21ec81bd4a0c84bf7e4748406fa68 100644
--- a/include/staff/templates/user-register.tmpl.php
+++ b/include/staff/templates/user-register.tmpl.php
@@ -9,7 +9,7 @@ if (!$_POST) {
 }
 
 ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <div class="clear"></div>
 <hr/>
@@ -130,17 +130,11 @@ echo sprintf(__(
             </tr>
                 <td><?php echo __('Time Zone'); ?>:</td>
                 <td>
-                    <select name="timezone" class="chosen-select" id="timezone-dropdown"
-                        data-placeholder="<?php echo __('System Default'); ?>">
-                        <option value=""></option>
-    <?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
-                        <option value="<?php echo $zone; ?>" <?php
-                        if ($info['timezone'] == $zone)
-                            echo 'selected="selected"';
-                        ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-    <?php } ?>
-                    </select>
-                    &nbsp;<span class="error"><?php echo $errors['timezone']; ?></span>
+                    <?php
+                    $TZ_NAME = 'timezone';
+                    $TZ_TIMEZONE = $info['timezone'];
+                    include STAFFINC_DIR.'templates/timezone.tmpl.php'; ?>
+                    <div class="error"><?php echo $errors['timezone']; ?></div>
                 </td>
             </tr>
         </tbody>
@@ -166,9 +160,5 @@ $(function() {
         else
             $('tbody#password').show();
     });
-    $('#timezone-dropdown').chosen({
-        allow_single_deselect: true,
-        width: '350px'
-    });
 });
 </script>
diff --git a/include/staff/templates/user.tmpl.php b/include/staff/templates/user.tmpl.php
index 8c89749991d6bec12ebf2f901dacc57893ee324a..5add6b0824d389ff454ded25c57e9b83ce49717c 100644
--- a/include/staff/templates/user.tmpl.php
+++ b/include/staff/templates/user.tmpl.php
@@ -3,7 +3,7 @@ if (!isset($info['title']))
     $info['title'] = Format::htmlchars($user->getName());
 
 if ($info['title']) { ?>
-<h3><?php echo $info['title']; ?></h3>
+<h3 class="drag-handle"><?php echo $info['title']; ?></h3>
 <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
 <hr>
 <?php
diff --git a/include/staff/templates/users.tmpl.php b/include/staff/templates/users.tmpl.php
index c8a262022a0d036d6127720354c77902ca59861d..a91a586f988889877c41d34331dfe2f9f589e341 100644
--- a/include/staff/templates/users.tmpl.php
+++ b/include/staff/templates/users.tmpl.php
@@ -159,7 +159,7 @@ if ($res && $num) { //Show options..
 } ?>
 
 <div style="display:none;" class="dialog" id="confirm-action">
-    <h3><?php echo __('Please Confirm'); ?></h3>
+    <h3 class="drag-handle"><?php echo __('Please Confirm'); ?></h3>
     <a class="close" href=""><i class="icon-remove-circle"></i></a>
     <hr/>
     <p class="confirm-action" style="display:none;" id="remove-users-confirm">
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 35fb34acacdc3334b36e1ffd7381ad9d82b72bd3..74407ea1952c951da73f9345baa0dc6fe88ddb5a 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -213,10 +213,13 @@ if($ticket->isOverdue())
                             ><?php echo Format::htmlchars($ticket->getName());
                         ?></span></a>
                         <?php
-                        if($user) {
-                            echo sprintf('&nbsp;&nbsp;<a href="tickets.php?a=search&uid=%d" title="%s" data-dropdown="#action-dropdown-stats">(<b>%d</b>)</a>',
-                                    urlencode($user->getId()), __('Related Tickets'), $user->getNumTickets());
-                        ?>
+                        if ($user) { ?>
+                            <a href="tickets.php?<?php echo Http::build_query(array(
+                                'status'=>'open', 'a'=>'search', 'uid'=> $user->getId()
+                            )); ?>" title="<?php echo __('Related Tickets'); ?>"
+                            data-dropdown="#action-dropdown-stats">
+                            (<b><?php echo $user->getNumTickets(); ?></b>)
+                            </a>
                             <div id="action-dropdown-stats" class="action-dropdown anchor-right">
                                 <ul>
                                     <?php
@@ -234,16 +237,48 @@ if($ticket->isOverdue())
                                     <li><a href="users.php?id=<?php echo
                                     $user->getId(); ?>"><i class="icon-user
                                     icon-fixed-width"></i> <?php echo __('Manage User'); ?></a></li>
-<?php       if ($user->getOrgId()) { ?>
+<?php   } ?>
+                                </ul>
+                            </div>
+<?php   if ($user->getOrgId()) { ?>
+                &nbsp; <span style="display:inline-block">
+                    <i class="icon-building"></i>
+                    <?php echo Format::htmlchars($user->getOrganization()->getName()); ?>
+                        <a href="tickets.php?<?php echo Http::build_query(array(
+                            'status'=>'open', 'a'=>'search', 'orgid'=> $user->getOrgId()
+                        )); ?>" title="<?php echo __('Related Tickets'); ?>"
+                        data-dropdown="#action-dropdown-org-stats">
+                        (<b><?php echo $user->getNumOrganizationTickets(); ?></b>)
+                        </a>
+                    </span>
+                            <div id="action-dropdown-org-stats" class="action-dropdown anchor-right">
+                                <ul>
+<?php   if ($open = $user->getNumOpenOrganizationTickets()) { ?>
+                                    <li><a href="tickets.php?<?php echo Http::build_query(array(
+                                        'a' => 'search', 'status' => 'open', 'orgid' => $user->getOrgId()
+                                    )); ?>"><i class="icon-folder-open-alt icon-fixed-width"></i>
+                                    <?php echo sprintf(_N('%d Open Ticket', '%d Open Tickets', $open), $open); ?>
+                                    </a></li>
+<?php   }
+        if ($closed = $user->getNumClosedOrganizationTickets()) { ?>
+                                    <li><a href="tickets.php?<?php echo Http::build_query(array(
+                                        'a' => 'search', 'status' => 'closed', 'orgid' => $user->getOrgId()
+                                    )); ?>"><i class="icon-folder-close-alt icon-fixed-width"></i>
+                                    <?php echo sprintf(_N('%d Closed Ticket', '%d Closed Tickets', $closed), $closed); ?>
+                                    </a></li>
+                                    <li><a href="tickets.php?<?php echo Http::build_query(array(
+                                        'a' => 'search', 'orgid' => $user->getOrgId()
+                                    )); ?>"><i class="icon-double-angle-right icon-fixed-width"></i> <?php echo __('All Tickets'); ?></a></li>
+<?php   }
+        if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) { ?>
                                     <li><a href="orgs.php?id=<?php echo $user->getOrgId(); ?>"><i
                                         class="icon-building icon-fixed-width"></i> <?php
                                         echo __('Manage Organization'); ?></a></li>
-<?php       }
-        } ?>
+<?php   } ?>
                                 </ul>
                             </div>
-                    <?php
-                        }
+<?php   } # end if (user->org)
+                        } # end if ($user)
                     ?>
                     </td>
                 </tr>
@@ -433,7 +468,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
     </ul>
     <?php
     if ($role->hasPerm(TicketModel::PERM_REPLY)) { ?>
-    <form id="reply" class="tab_content" action="tickets.php?id=<?php
+    <form id="reply" class="tab_content spellcheck" action="tickets.php?id=<?php
         echo $ticket->getId(); ?>" name="reply" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
@@ -475,18 +510,19 @@ $tcount = $ticket->getThreadEntries($types)->count();
                 <td>
                     <input type='checkbox' value='1' name="emailcollab" id="emailcollab"
                         <?php echo ((!$info['emailcollab'] && !$errors) || isset($info['emailcollab']))?'checked="checked"':''; ?>
-                        style="display:<?php echo $ticket->getNumCollaborators() ? 'inline-block': 'none'; ?>;"
+                        style="display:<?php echo $ticket->getThread()->getNumCollaborators() ? 'inline-block': 'none'; ?>;"
                         >
                     <?php
                     $recipients = __('Add Recipients');
-                    if ($ticket->getNumCollaborators())
+                    if ($ticket->getThread()->getNumCollaborators())
                         $recipients = sprintf(__('Recipients (%d of %d)'),
-                                $ticket->getNumActiveCollaborators(),
-                                $ticket->getNumCollaborators());
+                                $ticket->getThread()->getNumActiveCollaborators(),
+                                $ticket->getThread()->getNumCollaborators());
 
                     echo sprintf('<span><a class="collaborators preview"
-                            href="#tickets/%d/collaborators"><span id="recipients">%s</span></a></span>',
-                            $ticket->getId(),
+                            href="#thread/%d/collaborators"><span id="t%d-recipients">%s</span></a></span>',
+                            $ticket->getThreadId(),
+                            $ticket->getThreadId(),
                             $recipients);
                    ?>
                 </td>
@@ -622,7 +658,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
     </form>
     <?php
     } ?>
-    <form id="note" class="hidden tab_content" action="tickets.php?id=<?php
+    <form id="note" class="hidden tab_content spellcheck" action="tickets.php?id=<?php
         echo $ticket->getId(); ?>#note" name="note" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
@@ -705,7 +741,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
    </form>
     <?php
     if ($role->hasPerm(TicketModel::PERM_TRANSFER)) { ?>
-    <form id="transfer" class="hidden tab_content" action="tickets.php?id=<?php
+    <form id="transfer" class="hidden tab_content spellcheck" action="tickets.php?id=<?php
         echo $ticket->getId(); ?>#transfer" name="transfer" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="ticket_id" value="<?php echo $ticket->getId(); ?>">
@@ -766,7 +802,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
     } ?>
     <?php
     if ($role->hasPerm(TicketModel::PERM_ASSIGN)) { ?>
-    <form id="assign" class="hidden tab_content" action="tickets.php?id=<?php
+    <form id="assign" class="hidden tab_content spellcheck" action="tickets.php?id=<?php
          echo $ticket->getId(); ?>#assign" name="assign" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
@@ -1010,5 +1046,5 @@ foreach (AttachmentFile::objects()->filter(array(
         'filename' => $file->name,
     );
 } ?>
-$.showImagesInline(<?php echo JsonDataEncoder::encode($urls); ?>);
+$('#ticket_thread').data('imageUrls', <?php echo JsonDataEncoder::encode($urls); ?>);
 </script>
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 612f76f1759a62230fc2fc9a87410b7b9ed17ed7..518d40896878cf171c909ed3dbe64f0917b2a306 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -12,7 +12,7 @@ parse_str($_SERVER['QUERY_STRING'], $args);
 
 // Remove commands from query
 unset($args['id']);
-unset($args['a']);
+if ($args['a'] !== 'search') unset($args['a']);
 
 $refresh_url = $path . '?' . http_build_query($args);
 
@@ -30,7 +30,8 @@ $sort_options = array(
 );
 $use_subquery = true;
 
-$queue_name = strtolower($_GET['status'] ?: $_GET['a']); //Status is overloaded
+$queue_name = strtolower($_GET['a'] ?: $_GET['status']); //Status is overloaded
+
 // Stash current queue view
 $_SESSION['::Q'] = $queue_name;
 
@@ -69,6 +70,9 @@ case 'answered':
     break;
 default:
 case 'search':
+    $queue_sort_options = array('priority,updated', 'priority,created',
+        'priority,due', 'due', 'updated', 'answered',
+        'closed', 'number', 'hot');
     // Consider basic search
     if ($_REQUEST['query']) {
         $results_type=__('Search Results');
@@ -95,9 +99,6 @@ case 'search':
         $view_all_tickets = $thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING);
         $results_type=__('Advanced Search')
             . '<a class="action-button" href="?clear_filter"><i style="top:0" class="icon-ban-circle"></i> <em>' . __('clear') . '</em></a>';
-        $queue_sort_options = array('priority,updated', 'priority,created',
-            'priority,due', 'due', 'updated', 'answered',
-            'closed', 'number', 'hot');
         $has_relevance = false;
         foreach ($tickets->getSortFields() as $sf) {
             if ($sf instanceof SqlCode && $sf->code == '`relevance`') {
@@ -115,6 +116,21 @@ case 'search':
 
         break;
     }
+    // Apply user filter
+    elseif (isset($_GET['uid']) && ($user = User::lookup($_GET['uid']))) {
+        $tickets->filter(array('user__id'=>$_GET['uid']));
+        $results_type = sprintf('%s — %s', __('Search Results'),
+            $user->getName());
+        // Don't apply normal open ticket
+        break;
+    }
+    elseif (isset($_GET['orgid']) && ($org = Organization::lookup($_GET['orgid']))) {
+        $tickets->filter(array('user__org_id'=>$_GET['orgid']));
+        $results_type = sprintf('%s — %s', __('Search Results'),
+            $org->getName());
+        // Don't apply normal open ticket
+        break;
+    }
     // Fall-through and show open tickets
 case 'open':
     $status='open';
@@ -132,13 +148,9 @@ case 'open':
     break;
 }
 
-// Apply user filter
-if (isset($_GET['uid'])) {
-    $tickets->filter(array('user__id'=>$_GET['uid']));
-}
-
-
 // Apply primary ticket status
+if (!isset($status) && isset($_GET['status']))
+    $status = $_GET['status'];
 if ($status)
     $tickets->filter(array('status__state'=>$status));
 
@@ -290,13 +302,18 @@ $_SESSION[':Q:tickets'] = $orig_tickets;
 
 <!-- SEARCH FORM START -->
 <div id='basic_search'>
-    <form action="tickets.php" method="get">
+    <form action="tickets.php" method="get" onsubmit="javascript:
+  $.pjax({
+    url:$(this).attr('action') + '?' + $(this).serialize(),
+    container:'#pjax-container',
+    timeout: 2000
+  });
+return false;">
     <input type="hidden" name="a" value="search">
     <table>
         <tr>
-            <td><input type="text" id="basic-ticket-search" name="query"
-            size=30 value="<?php echo Format::htmlchars($_REQUEST['query'],
-            true); ?>"
+            <td><input type="search" id="basic-ticket-search" name="query"
+                autofocus size="30" value="<?php echo Format::htmlchars($_REQUEST['query'], true); ?>"
                 autocomplete="off" autocorrect="off" autocapitalize="off"></td>
             <td><input type="submit" class="button" value="<?php echo __('Search'); ?>"></td>
             <td>&nbsp;&nbsp;<a href="#" onclick="javascript:
@@ -449,7 +466,8 @@ $_SESSION[':Q:tickets'] = $orig_tickets;
                     href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><span
                     class="truncate"><?php echo $subject; ?></span></a>
 <?php               if ($T['attachment_count'])
-                        echo '<i class="small icon-paperclip icon-flip-horizontal"></i>';
+                        echo '<i class="small icon-paperclip icon-flip-horizontal" data-toggle="tooltip" title="'
+                            .$T['attachment_count'].'"></i>';
                     if ($threadcount > 1) { ?>
                         <span class="pull-right faded-more"><i class="icon-comments-alt"></i>
                             <small><?php echo $threadcount; ?></small>
@@ -458,7 +476,8 @@ $_SESSION[':Q:tickets'] = $orig_tickets;
                 </td>
                 <td nowrap><div><?php
                     if ($T['collab_count'])
-                        echo '<span class="pull-right faded-more"><i class="icon-group"></i></span>';
+                        echo '<span class="pull-right faded-more" data-toggle="tooltip" title="'
+                            .$T['collab_count'].'"><i class="icon-group"></i></span>';
                     ?><span class="truncate" style="max-width:<?php
                         echo $T['collab_count'] ? '150px' : '170px'; ?>"><?php
                     $un = new PersonsName($T['user__name']);
diff --git a/include/staff/user-view.inc.php b/include/staff/user-view.inc.php
index 29c573a608649af3242abe7bee5a972615eac07a..256654d42816ec1d803c589dce7c00aa1dfde781 100644
--- a/include/staff/user-view.inc.php
+++ b/include/staff/user-view.inc.php
@@ -143,7 +143,7 @@ if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
 </table>
 <br>
 <div class="clear"></div>
-<ul class="tabs" id="user-view-tabs">
+<ul class="clean tabs" id="user-view-tabs">
     <li class="active"><a href="#tickets"><i
     class="icon-list-alt"></i>&nbsp;<?php echo __('User Tickets'); ?></a></li>
     <li><a href="#notes"><i
diff --git a/include/staff/users.inc.php b/include/staff/users.inc.php
index 848abf4dc1f35eed7bea90308af83504ab464b34..7e4993ad459d2e9bc63f57060fc11f0714c4ec15 100644
--- a/include/staff/users.inc.php
+++ b/include/staff/users.inc.php
@@ -63,8 +63,9 @@ $users->order_by($order . $order_column);
         <input type="hidden" name="a" value="search">
         <table>
             <tr>
-                <td><input type="text" id="basic-user-search" name="query" size=30 value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"
-                autocomplete="off" autocorrect="off" autocapitalize="off"></td>
+                <td><input type="search" id="basic-user-search" name="query"
+                    autofocus size="30" value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"
+                    autocomplete="off" autocorrect="off" autocapitalize="off"></td>
                 <td><input type="submit" name="basic_search" class="button" value="<?php echo __('Search'); ?>"></td>
                 <!-- <td>&nbsp;&nbsp;<a href="" id="advanced-user-search">[advanced]</a></td> -->
             </tr>
diff --git a/index.php b/index.php
index 97ff2378770c07cf0a2f3a58add652a7bea8c718..6c9558fa930d71173e59645febce619cf38651af 100644
--- a/index.php
+++ b/index.php
@@ -21,39 +21,8 @@ $section = 'home';
 require(CLIENTINC_DIR.'header.inc.php');
 ?>
 <div id="landing_page">
-    <div class="sidebar pull-right">
-        <div class="front-page-button flush-right">
-<p>
-            <a href="open.php" style="display:block" class="blue button"><?php
-                echo __('Open a New Ticket');?></a>
-</p>
-        </div>
-        <div class="content">
-<?php
-    $faqs = FAQ::getFeatured()->select_related('category')->limit(5);
-    if ($faqs->all()) { ?>
-            <section><div class="header"><?php echo __('Featured Questions'); ?></div>
-<?php   foreach ($faqs as $F) { ?>
-            <div><a href="<?php echo ROOT_PATH; ?>/kb/faq.php?id=<?php
-                echo urlencode($F->getId());
-                ?>"><?php echo $F->getLocalQuestion(); ?></a></div>
-<?php   } ?>
-            </section>
-<?php
-    }
-    $resources = Page::getActivePages()->filter(array('type'=>'other'));
-    if ($resources->all()) { ?>
-            <section><div class="header"><?php echo __('Other Resources'); ?></div>
-<?php   foreach ($resources as $page) { ?>
-            <a href="<?php echo ROOT_PATH; ?>pages/<?php echo $page->getNameAsSlug();
-            ?>"><?php echo $page->getLocalName(); ?></a>
-<?php   } ?>
-            </section>
-<?php
-    } ?>
-        </div>
-    </div>
-<div class="welcome">
+<?php include CLIENTINC_DIR.'templates/sidebar.tmpl.php'; ?>
+<div class="main-content">
 <?php
 if ($cfg && $cfg->isKnowledgebaseEnabled()) { ?>
 <div class="search-form">
@@ -63,6 +32,7 @@ if ($cfg && $cfg->isKnowledgebaseEnabled()) { ?>
     <button type="submit" class="green button">Search</button>
     </form>
 </div>
+    <div class="thread-body">
 <?php
 }
     if($cfg && ($page = $cfg->getLandingPage()))
@@ -70,6 +40,7 @@ if ($cfg && $cfg->isKnowledgebaseEnabled()) { ?>
     else
         echo  '<h1>'.__('Welcome to the Support Center').'</h1>';
     ?>
+    </div>
 </div>
 <div class="clear"></div>
 
diff --git a/js/chosen.jquery.min.js b/js/chosen.jquery.min.js
deleted file mode 100644
index 3c564f995a397b8b0315b44dbd3eb3956e1c57df..0000000000000000000000000000000000000000
--- a/js/chosen.jquery.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
-!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.text,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+"</em>"+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+"<em>"+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d instanceof Chosen?d.destroy():d instanceof Chosen||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("touchstart.chosen",function(b){a.container_mousedown(b)}),this.container.bind("touchend.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=a.originalEvent.deltaY||-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
\ No newline at end of file
diff --git a/js/filedrop.field.js b/js/filedrop.field.js
index fc99870bdfd5fbe41d7679666344a1bd19ff3f78..4e82280aeeb894a8249c8723fefd22570635d1c8 100644
--- a/js/filedrop.field.js
+++ b/js/filedrop.field.js
@@ -349,8 +349,8 @@
     this.on('drop', drop).on('dragstart', opts.dragStart).on('dragenter', dragEnter).on('dragover', dragOver).on('dragleave', dragLeave);
     $(document).on('drop', docDrop).on('dragenter', docEnter).on('dragover', docOver).on('dragleave', docLeave);
 
-    (opts.link || this).on('click', function(e){
-      $('#' + opts.fallback_id).trigger(e);
+    (opts.link || this).click(function(e) {
+      $('#' + opts.fallback_id).trigger('click');
       return false;
     });
 
diff --git a/js/osticket.js b/js/osticket.js
index 911cbf4e758ab7b185837dfe8a51855e692d48c4..28fd56fc8fd5df9153eac06242e8116b8cdf5dc0 100644
--- a/js/osticket.js
+++ b/js/osticket.js
@@ -161,7 +161,9 @@ showImagesInline = function(urls, thread_id) {
                     }
                 ).append($('<div class="caption">')
                     .append('<span class="filename">'+info.filename+'</span>')
-                    .append('<a href="'+info.download_url+'" class="action-button pull-right"><i class="icon-download-alt"></i> ' + __('Download') + '</a>')
+                    .append($('<a href="'+info.download_url+'" class="action-button pull-right"><i class="icon-download-alt"></i> ' + __('Download') + '</a>')
+                      .attr('download', info.filename)
+                    )
                 );
             e.data('wrapped', true);
         }
diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js
index 23b1ee76a4aaed7305df84ed4f974294dbe53139..38ca07f2c3e2a5f2dec0b8814415d52177a2f48d 100644
--- a/js/redactor-osticket.js
+++ b/js/redactor-osticket.js
@@ -53,8 +53,8 @@ RedactorPlugins.draft = function() {
         // Add [Delete Draft] button to the toolbar
         if (this.opts.draftDelete) {
             var trash = this.draft.deleteButton =
-                this.button.add('deleteDraft', __('Delete Draft'),
-                    this.draft.deleteDraft);
+                this.button.add('deleteDraft', __('Delete Draft'))
+            this.button.addCallback(trash, this.draft.deleteDraft);
             this.button.setAwesome('deleteDraft', 'icon-trash');
             trash.parent().addClass('pull-right');
             trash.addClass('delete-draft');
@@ -268,6 +268,14 @@ $(function() {
                 'tabFocus': false,
                 'toolbarFixedBox': true,
                 'focusCallback': function() { this.$box.addClass('no-pjax'); },
+                'initCallback': function() {
+                    if (this.$element.data('width'))
+                        this.$editor.width(this.$element.data('width'));
+                    this.$editor.attr('spellcheck', 'true');
+                    var lang = this.$editor.closest('[lang]').attr('lang');
+                    if (lang)
+                        this.$editor.attr('lang', lang);
+                },
                 'linkSize': 100000,
                 'definedLinks': 'ajax.php/config/links'
             }, options||{});
diff --git a/js/redactor-plugins.js b/js/redactor-plugins.js
index 772573bab655b84260ba3b706921f0115a47e254..33edff821410ffa9c3dd136beed65170e145a0b5 100644
--- a/js/redactor-plugins.js
+++ b/js/redactor-plugins.js
@@ -93,7 +93,7 @@ RedactorPlugins.fontcolor = function()
 			{
 				var color = colors[z];
 
-				var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 22px; height: 22px;"></a>');
+				var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 22px; height: 22px; box-sizing: border-box;"></a>');
 				$swatch.css('background-color', color);
 				$swatch.on('click', func);
 
@@ -790,16 +790,35 @@ RedactorPlugins.imagepaste = function() {
           return true;
 
       this.$editor.on('paste.imagepaste', $.proxy(this.imagepaste.buildEventPaste, this));
+
+      // Capture the selection position every so often as Redactor seems to
+      // drop it when attempting an image paste before `paste` browser event
+      // fires
+      var that = this,
+          plugin = this.imagepaste;
+      setInterval(function() {
+        if (plugin.inpaste)
+          return;
+        plugin.offset = that.caret.getOffset() || plugin.offset;
+      }, 300);
     },
+    offset: 0,
+    inpaste: false,
     buildEventPaste: function(e)
     {
       var event = e.originalEvent || e,
           fileUpload = false,
           files = [],
           i, file,
-          cd = event.clipboardData;
+          plugin = this.imagepaste,
+          cd = event.clipboardData,
+          self = this, node,
+          bail = function() {
+            plugin.inpaste = false;
+          };
+      plugin.inpaste = true;
 
-      if (typeof(cd) === 'undefined') return;
+      if (typeof(cd) === 'undefined') return bail();
 
       if (cd.items && cd.items.length)
       {
@@ -824,23 +843,41 @@ RedactorPlugins.imagepaste = function() {
           }
         }
       }
-      var self = this, node;
-      this.opts.imageUploadCallback = function(image, json) {
-        // Redactor just has a bloody hard time inserting for some dumb
-        // reason.
-      };
 
-      if (files.length) {
-        // clipboard upload
-        var I = setInterval(function() {
-          if (!self.focus.isFocused())
-            return;
-          clearInterval(I);
-          self.clean.singleLine = false;
-          for (i = 0, k = files.length; i < k; i++)
-            self.upload.directUpload(files[i], e);
-        }, 5);
-      }
+      if (!files.length)
+        return bail();
+
+      // Clipboard upload
+
+      setTimeout(function() {
+        // We need to allow the paste operation to settle, so we can set
+        // self.clean.singleLine and not have to cleared by some other running
+        // code
+
+        var oldIUC = self.opts.imageUploadCallback;
+        self.opts.imageUploadCallback = function(image, json) {
+          self.$editor.find('.-image-upload-placeholder').remove();
+          self.opts.imageUploadCallback = oldIUC;
+          // Add a zero-width space so that the caret:getOffset will find
+          // locations after pictures if only <br> tags exist otherwise. In
+          // other words, ensure there is at least one character after the
+          // image for text character counting. Additionally, Redactor will
+          // strip the zero-width space when saving
+          $(document.createTextNode("\u200b")).insertAfter($(image));
+          bail();
+        };
+
+        // Place the cursor back in the box!
+        self.caret.setOffset(plugin.offset);
+
+        // Add cool wait cursor
+        self.insert.htmlWithoutClean('<span class="-image-upload-placeholder icon-stack"><i class="icon-circle icon-stack-base"></i><i class="icon-picture icon-light icon-spin"></i></span>');
+
+        // Upload clipboard files
+        self.clean.singleLine = false;
+        for (i = 0, k = files.length; i < k; i++)
+          self.upload.directUpload(files[i], e);
+      }, 1);
     }
   };
 };
@@ -1766,11 +1803,13 @@ RedactorPlugins.contexttypeahead = function() {
       }
     },
 
-    select: function(item) {
+    select: function(item, event) {
       var current = this.selection.getCurrent(),
           sel     = this.selection.get(),
           range   = this.sel.getRangeAt(0),
           cursorAt = range.endOffset,
+          // TODO: Consume immediately following `}` symbols
+          plugin  = this.contexttypeahead,
           search  = new RegExp(/%\{([^}]*)(\}?)$/);
 
       // FIXME: ENTER will end up here, but current will be empty
@@ -1781,7 +1820,9 @@ RedactorPlugins.contexttypeahead = function() {
       // Set cursor at the end of the expanded text
       var left = current.textContent.substring(0, cursorAt),
           right = current.textContent.substring(cursorAt),
-          newLeft = left.replace(search, '%{' + item.variable + '}');
+          autoExpand = event.target.nodeName == 'I',
+          selected = item.variable + (autoExpand ? '.' : '')
+          newLeft = left.replace(search, '%{' + selected + '}');
 
       current.textContent = newLeft
         // Drop the remaining part of a variable block, if any
@@ -1790,7 +1831,12 @@ RedactorPlugins.contexttypeahead = function() {
       this.range.setStart(current, newLeft.length - 1);
       this.range.setEnd(current, newLeft.length - 1);
       this.selection.addRange();
-      return this.contexttypeahead.destroy();
+      if (!autoExpand)
+          return plugin.destroy();
+
+      plugin.typeahead.val(selected);
+      plugin.typeahead.typeahead('lookup');
+      return false;
     }
   };
 };
diff --git a/js/select2.full.min.js b/js/select2.full.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..e311779ea07982aa4cad467adcfc14b072076557
--- /dev/null
+++ b/js/select2.full.min.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.0-rc.2 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){return n.apply(b,v.call(arguments,0).concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice;this.listeners=this.listeners||{},a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),this.$results.append(d)},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")});var f=e.filter("[aria-selected=true]");f.length>0?f.first().trigger("mouseenter"):e.first().trigger("mouseenter")})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";{a(h)}this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b){var c=this,d=b.id+"-results";this.$results.attr("id",d),b.on("results:all",function(a){c.clear(),c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("results:append",function(a){c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("query",function(a){c.showLoading(a)}),b.on("select",function(){b.isOpen()&&c.setClasses()}),b.on("unselect",function(){b.isOpen()&&c.setClasses()}),b.on("open",function(){c.$results.attr("aria-expanded","true"),c.$results.attr("aria-hidden","false"),c.setClasses(),c.ensureHighlightVisible()}),b.on("close",function(){c.$results.attr("aria-expanded","false"),c.$results.attr("aria-hidden","true"),c.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=c.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=c.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?c.trigger("close"):c.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a);if(0!==d){var e=d-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top,h=f.offset().top,i=c.$results.scrollTop()+(h-g);0===e?c.$results.scrollTop(0):0>h-g&&c.$results.scrollTop(i)}}),b.on("results:next",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a),e=d+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top+c.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=c.$results.scrollTop()+h-g;0===e?c.$results.scrollTop(0):h>g&&c.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){c.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=c.$results.scrollTop(),d=c.$results.get(0).scrollHeight-c.$results.scrollTop()+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&d<=c.$results.height();e?(c.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(c.$results.scrollTop(c.$results.get(0).scrollHeight-c.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var d=a(this),e=d.data("data");return"true"===d.attr("aria-selected")?void(c.options.get("multiple")?c.trigger("unselect",{originalEvent:b,data:e}):c.trigger("close")):void c.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var b=a(this).data("data");c.getHighlightedResults().removeClass("select2-results__option--highlighted"),c.trigger("results:focus",{data:b,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a){var b=this,d=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){b.trigger("focus",a)}),this.$selection.on("blur",function(a){b.trigger("blur",a)}),this.$selection.on("keydown",function(a){b.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){b.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){b.update(a.data)}),a.on("open",function(){b.$selection.attr("aria-expanded","true"),b.$selection.attr("aria-owns",d),b._attachCloseHandler(a)}),a.on("close",function(){b.$selection.attr("aria-expanded","false"),b.$selection.removeAttr("aria-activedescendant"),b.$selection.removeAttr("aria-owns"),b.$selection.focus(),b._detachCloseHandler(a)}),a.on("enable",function(){b.$selection.attr("tabindex",b._tabindex)}),a.on("disable",function(){b.$selection.attr("tabindex","-1")})},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},d.prototype.bind=function(a){var b=this;d.__super__.bind.apply(this,arguments);var c=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",c),this.$selection.attr("aria-labelledby",c),this.$selection.on("mousedown",function(a){1===a.which&&b.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),a.on("selection:update",function(a){b.update(a.data)})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){return a("<span></span>")},d.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.display(b),d=this.$selection.find(".select2-selection__rendered");d.empty().append(c),d.prop("title",b.title||b.text)},d}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(){var b=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){b.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(c){var d=a(this),e=d.parent(),f=e.data("data");b.trigger("unselect",{originalEvent:c,data:f})})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.display(e),g=this.selectionContainer();g.append(f),g.prop("title",e.title||e.text),g.data("data",e),b.push(g)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(){function a(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},a.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},a}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle")}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">&times;</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus()}),b.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.focus()}),b.on("enable",function(){e.$search.prop("disabled",!1)}),b.on("disable",function(){e.$search.prop("disabled",!0)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e.trigger("blur",a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}}),this.$selection.on("input",".select2-search--inline",function(){e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input",".select2-search--inline",function(a){e.handleSearch(a)})},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.trigger("open"),this.$search.val(b.text+" ")},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a){var b=this;this.container=a,a.on("select",function(a){b.select(a.data)}),a.on("unselect",function(a){b.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};
+if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=(c.extend(!0,{},l,j),this.option(l));k.replaceWith(m)}else{var n=this.option(j);if(j.children){var o=this.convertToOptions(j.children);b.appendMany(n,o)}h.push(n)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(b,c){this.ajaxOptions=this._applyDefaults(c.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),a.__super__.constructor.call(this,b,c)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return{q:a.term}},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url(a)),"function"==typeof f.data&&(f.data=f.data(a)),this.ajaxOptions.delay&&""!==a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");if(void 0!==f&&(this.createTag=f),b.call(this,c,d),a.isArray(e))for(var g=0;g<e.length;g++){var h=e[g],i=this._normalizeItem(h),j=this.option(i);this.$element.append(j)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(){var b=(this._lastTag,this.$element.find("option[data-select2-tag]"));b.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(a,b,c){function d(a){e.select(a)}var e=this;b.term=b.term||"";var f=this.tokenizer(b,this.options,d);f.term!==b.term&&(this.$search.length&&(this.$search.val(f.term),this.$search.focus()),b.term=f.term),a.call(this,b,c)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);e(m),g=g.substr(h+1)||"",h=0}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.position=function(){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a){function b(){}return b.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},b.prototype.handleSearch=function(){if(!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},b.prototype.showSearch=function(){return!0},b}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="option load-more" role="treeitem"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(a,b,c){this.$dropdownParent=c.get("dropdownParent")||document.body,a.call(this,b,c)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c){var d=this,e="scroll.select2."+c.id,f="resize.select2."+c.id,g="orientationchange.select2."+c.id,h=this.$container.parents().filter(b.hasScroll);h.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),h.on(e,function(){var b=a(this).data("select2-scroll-position");a(this).scrollTop(b.y)}),a(window).on(e+" "+f+" "+g,function(){d._positionDropdown(),d._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c){var d="scroll.select2."+c.id,e="resize.select2."+c.id,f="orientationchange.select2."+c.id,g=this.$container.parents().filter(b.hasScroll);g.off(d),a(window).off(d+" "+e+" "+f)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=(this.$container.position(),this.$container.offset());f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom};c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){this.$dropdownContainer.width(),this.$dropdown.css({width:this.$container.outerWidth(!1)+"px"})},c.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(){d._handleSelectOnClose()})},a.prototype._handleSelectOnClose=function(){var a=this.getHighlightedResults();a.length<1||this.trigger("select",{data:a.data("data")})},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close")},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend({},this.defaults,l),null==l.dataAdapter){if(l.dataAdapter=null!=l.ajax?o:null!=l.data?n:m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.selectionAdapter=l.multiple?e:d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(this.options.dir=a.prop("dir")?a.prop("dir"):a.closest("[dir]").prop("dir")?a.closest("[dir]").prop("dir"):"ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this._sync=c.bind(this._syncAttributes,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._sync);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._sync)}),this._observer.observe(this.$element[0],{attributes:!0,subtree:!1})):this.$element[0].addEventListener&&this.$element[0].addEventListener("DOMAttrModified",b._sync,!1)},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("focus",function(){a.$container.addClass("select2-container--focus")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open"),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ENTER?(a.trigger("results:select"),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle"),b.preventDefault()):c===d.UP?(a.trigger("results:previous"),b.preventDefault()):c===d.DOWN?(a.trigger("results:next"),b.preventDefault()):(c===d.ESC||c===d.TAB)&&(a.close(),b.preventDefault()):(c===d.ENTER||c===d.SPACE||(c===d.DOWN||c===d.UP)&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable")):this.trigger("enable")},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||(this.trigger("query",{}),this.trigger("open"))},e.prototype.close=function(){this.isOpen()&&this.trigger("close")},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._sync),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&this.$element[0].removeEventListener("DOMAttrModified",this._sync,!1),this._sync=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&(f=d(this),null!=f&&g.push(f))})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;return this._isInitialized?void b.call(this,c):void this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f<this._currentData.length;f++){var g=this._currentData[f];e.push.apply(e,d(g,this.$element.val().split(this._valueSeparator)))}c(e)},b.prototype.select=function(b,c){if(this.options.get("multiple")){var d=this.$element.val();d+=this._valueSeparator+c.id,this.$element.val(d),this.$element.trigger("change")}else this.current(function(b){a.map(b,function(a){a.selected=!1})}),this.$element.val(c.id),this.$element.trigger("change")},b.prototype.unselect=function(a,b){var c=this;b.selected=!1,this.current(function(a){for(var d=[],e=0;e<a.length;e++){var f=a[e];b.id!=f.id&&d.push(f.id)}c.$element.val(d.join(c._valueSeparator)),c.$element.trigger("change")
+})},b.prototype.query=function(a,b,c){for(var d=[],e=0;e<this._currentData.length;e++){var f=this._currentData[e],g=this.matches(b,f);null!==g&&d.push(g)}c({results:d})},b.prototype.addOptions=function(b,c){var d=a.map(c,function(b){return a.data(b[0],"data")});this._currentData.push.apply(this._currentData,d)},b}),b.define("select2/compat/matcher",["jquery"],function(a){function b(b){function c(c,d){var e=a.extend(!0,{},d);if(null==c.term||""===a.trim(c.term))return e;if(d.children){for(var f=d.children.length-1;f>=0;f--){var g=d.children[f],h=b(c.term,g.text,g);h||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c;var d=this.options.get("query");d.call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){var d=c.find(".dropdown-wrapper");d.append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("jquery.select2",["jquery","require","./select2/core","./select2/defaults"],function(a,b,c,d){if(b("jquery.mousewheel"),null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){{var d=a.extend({},b,!0);new c(a(this),d)}}),this;if("string"==typeof b){var d=this.data("select2");null==d&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2.");var f=Array.prototype.slice.call(arguments,1),g=d[b](f);return a.inArray(b,e)>-1?this:g}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery.mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
diff --git a/pages/index.php b/pages/index.php
index ab50a1c586d5793301fdcb0246842c31eba95ec2..e9de487346c43d950020397bdc2df70250d8e526 100644
--- a/pages/index.php
+++ b/pages/index.php
@@ -28,27 +28,35 @@ $slug = Format::slugify($ost->get_path_info());
 $first_word = explode('-', $slug);
 $first_word = $first_word[0];
 
-$sql = 'SELECT id, name FROM '.PAGE_TABLE
-    .' WHERE name LIKE '.db_input("$first_word%");
-$page_id = null;
-
-$res = db_query($sql);
-while (list($id, $name) = db_fetch_row($res)) {
-    if (Format::slugify($name) == $slug) {
-        $page_id = $id;
+$pages = Page::objects()->filter(array(
+    'name__like' => "$first_word%"
+));
+
+$selected_page = null;
+foreach ($pages as $P) {
+    if (Format::slugify($P->name) == $slug) {
+        $selected_page = $P;
         break;
     }
 }
 
-if (!$page_id || !($page = Page::lookup($page_id)))
+if (!$selected_page)
     Http::response(404, __('Page Not Found'));
 
-if (!$page->isActive() || $page->getType() != 'other')
+if (!$selected_page->isActive() || $selected_page->getType() != 'other')
     Http::response(404, __('Page Not Found'));
 
 require(CLIENTINC_DIR.'header.inc.php');
 
-print $page->getBodyWithImages();
+$BUTTONS = false;
+include CLIENTINC_DIR.'templates/sidebar.tmpl.php';
+?>
+<div class="main-content">
+<?php
+print $selected_page->getBodyWithImages();
+?>
+</div>
 
+<?php
 require(CLIENTINC_DIR.'footer.inc.php');
 ?>
diff --git a/scp/ajax.php b/scp/ajax.php
index f6e2f36de5eb6a966eca31a4980cae32ea8406d9..54e2770736488081832ac325a9a345e94bb5081d 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -143,12 +143,6 @@ $dispatcher = patterns('',
         url_post('^(?P<tid>\d+)/lock$', 'acquireLock'),
         url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/renew', 'renewLock'),
         url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock'),
-        url_get('^(?P<tid>\d+)/collaborators/preview$', 'previewCollaborators'),
-        url_get('^(?P<tid>\d+)/collaborators$', 'showCollaborators'),
-        url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'),
-        url_get('^(?P<tid>\d+)/add-collaborator/(?P<uid>\d+)$', 'addCollaborator'),
-        url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'),
-        url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'),
         url_get('^(?P<tid>\d+)/forms/manage$', 'manageForms'),
         url_post('^(?P<tid>\d+)/forms/manage$', 'updateForms'),
         url_get('^(?P<tid>\d+)/canned-resp/(?P<cid>\w+).(?P<format>json|txt)', 'cannedResponse'),
@@ -189,9 +183,15 @@ $dispatcher = patterns('',
         url_get('^mass/(?P<action>[\w.]+)', 'massProcess'),
         url_post('^mass/(?P<action>[\w.]+)', 'massProcess')
     )),
-    url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI',
-        url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'),
-        url_post('^(?P<cid>\d+)$', 'updateCollaborator')
+    url('^/thread/', patterns('ajax.thread.php:ThreadAjaxAPI',
+        url_get('^(?P<tid>\d+)/collaborators/preview$', 'previewCollaborators'),
+        url_get('^(?P<tid>\d+)/collaborators$', 'showCollaborators'),
+        url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'),
+        url_get('^(?P<tid>\d+)/add-collaborator/(?P<uid>\d+)$', 'addCollaborator'),
+        url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'),
+        url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'),
+        url_get('^(?P<tid>\d+)/collaborators/(?P<cid>\d+)/view$', 'viewCollaborator'),
+        url_post('^(?P<tid>\d+)/collaborators/(?P<cid>\d+)$', 'updateCollaborator')
     )),
     url('^/draft/', patterns('ajax.draft.php:DraftAjaxAPI',
         url_post('^(?P<id>\d+)$', 'updateDraft'),
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 061e241a1d73d1275a7cee449000d559a186f617..4dd7cef3afd1c4cf0b48512b451375e6146e447f 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -28,10 +28,6 @@ div#header a {
     color:#E65524;
 }
 
-.form_table a:hover {
-    text-decoration: underline;
-}
-
 .centered {
     text-align:center;
 }
@@ -613,6 +609,10 @@ a.print {
     height:25px;
 }
 
+input[type=search] {
+    font-size: 16px;
+}
+.search input[type=search],
 .search input[type=text] {
     height:23px;
     line-height:23px;
@@ -927,6 +927,7 @@ ul.tabs {
     border-bottom:1px solid #aaa;
     background:#eef3f8;
     position: relative;
+    box-shadow: inset 0 -5px 10px -9px rgba(0,0,0,0.3);
 }
 
 #response_options ul.tabs {
@@ -967,7 +968,13 @@ ul.tabs li.active {
     text-align: center;
     border-top:2px solid #81a9d7;
     bottom: 0;
-    box-shadow: 4px -1px 6px -3px rgba(0,0,0,0.3);
+    box-shadow: 4px -1px 6px -3px rgba(0,0,0,0.2);
+}
+ul.tabs li:not(.active) {
+    box-shadow: inset 0 -5px 10px -9px rgba(0,0,0,0.2);
+}
+ul.tabs.clean li.active {
+    background-color: white;
 }
 
 ul.tabs li a {
@@ -978,6 +985,9 @@ ul.tabs li a {
     outline: none;
     padding: 5px 10px;
 }
+ul.tabs li a:hover {
+    text-decoration: none;
+}
 
 ul.tabs li.active a {
     font-weight: bold;
@@ -997,6 +1007,7 @@ ul.tabs.vertical {
     padding-bottom: 40px;
     padding-top: 10px;
     background: transparent;
+    box-shadow: inset -5px 0 10px -9px rgba(0,0,0,0.3);
 }
 ul.tabs.vertical.left {
     float: left;
@@ -1014,6 +1025,9 @@ ul.tabs.vertical li {
     right: 0;
     height: auto;
 }
+ul.tabs.vertical li:not(.active) {
+    box-shadow: inset -5px 0 10px -9px rgba(0,0,0,0.3);
+}
 
 ul.tabs.vertical li + li {
     margin-top: 5px;
@@ -1551,7 +1565,7 @@ time {
     -webkit-box-sizing: content-box;
 }
 
-.dialog.draggable h3:hover {
+.dialog.draggable h3.drag-handle:hover {
     cursor: move;
 }
 
@@ -1776,6 +1790,8 @@ div.selected-signature {
     overflow-y: hidden;
     font-size: 15px;
     line-height: 1.25rem;
+    background-color: white;
+    background-color: rgba(255, 255, 255, 0.9);
 }
 div.selected-signature .inner {
     opacity: 0.5;
@@ -2149,6 +2165,7 @@ td.indented {
 }
 .accordian dt.active a {
   color: #184E81;
+  text-decoration: none;
 }
 .accordian dt:not(.active) a i {
   display: none;
diff --git a/scp/css/tooltip.css b/scp/css/tooltip.css
new file mode 100644
index 0000000000000000000000000000000000000000..ae54e90fc6b05e52e73828a6a4fa8492244023bc
--- /dev/null
+++ b/scp/css/tooltip.css
@@ -0,0 +1,115 @@
+.tooltip {
+  position: absolute;
+  z-index: 1070;
+  display: block;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-style: normal;
+  font-weight: normal;
+  letter-spacing: normal;
+  line-break: auto;
+  line-height: 1.428571429;
+  text-align: left;
+  text-align: start;
+  text-decoration: none;
+  text-shadow: none;
+  text-transform: none;
+  white-space: normal;
+  word-break: normal;
+  word-spacing: normal;
+  word-wrap: normal;
+  font-size: 12px;
+  opacity: 0;
+  filter: alpha(opacity=0);
+}
+.tooltip.in {
+  opacity: 0.9;
+  filter: alpha(opacity=90);
+}
+.tooltip.top {
+  margin-top: -3px;
+  padding: 5px 0;
+}
+.tooltip.right {
+  margin-left: 3px;
+  padding: 0 5px;
+}
+.tooltip.bottom {
+  margin-top: 3px;
+  padding: 5px 0;
+}
+.tooltip.left {
+  margin-left: -3px;
+  padding: 0 5px;
+}
+.tooltip-inner {
+  max-width: 200px;
+  padding: 3px 8px;
+  color: #ffffff;
+  text-align: center;
+  background-color: #000000;
+  border-radius: 4px;
+}
+.tooltip-arrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-color: transparent;
+  border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+  bottom: 0;
+  left: 50%;
+  margin-left: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000000;
+}
+.tooltip.top-left .tooltip-arrow {
+  bottom: 0;
+  right: 5px;
+  margin-bottom: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000000;
+}
+.tooltip.top-right .tooltip-arrow {
+  bottom: 0;
+  left: 5px;
+  margin-bottom: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000000;
+}
+.tooltip.right .tooltip-arrow {
+  top: 50%;
+  left: 0;
+  margin-top: -5px;
+  border-width: 5px 5px 5px 0;
+  border-right-color: #000000;
+}
+.tooltip.left .tooltip-arrow {
+  top: 50%;
+  right: 0;
+  margin-top: -5px;
+  border-width: 5px 0 5px 5px;
+  border-left-color: #000000;
+}
+.tooltip.bottom .tooltip-arrow {
+  top: 0;
+  left: 50%;
+  margin-left: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+  top: 0;
+  right: 5px;
+  margin-top: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+  top: 0;
+  left: 5px;
+  margin-top: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000000;
+}
+
diff --git a/scp/emailtest.php b/scp/emailtest.php
index 9e15baf36b1ccb10d0cd3cc93e87b94edf9d88c3..cd9fbae9d67afcab14e96ed180d5490faab6bae9 100644
--- a/scp/emailtest.php
+++ b/scp/emailtest.php
@@ -99,7 +99,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php echo __('To');?>:
             </td>
             <td>
-                <input type="text" size="60" name="email" value="<?php echo $info['email']; ?>">
+                <input type="text" size="60" name="email" value="<?php echo $info['email']; ?>"
+                    autofocus>
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['email']; ?></span>
             </td>
         </tr>
diff --git a/scp/js/bootstrap-tooltip.js b/scp/js/bootstrap-tooltip.js
new file mode 100644
index 0000000000000000000000000000000000000000..0779f139d6ccd8349f5ac1a2a8610a4a2515047e
--- /dev/null
+++ b/scp/js/bootstrap-tooltip.js
@@ -0,0 +1,514 @@
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.4
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // TOOLTIP PUBLIC CLASS DEFINITION
+  // ===============================
+
+  var Tooltip = function (element, options) {
+    this.type       = null
+    this.options    = null
+    this.enabled    = null
+    this.timeout    = null
+    this.hoverState = null
+    this.$element   = null
+    this.inState    = null
+
+    this.init('tooltip', element, options)
+  }
+
+  Tooltip.VERSION  = '3.3.4'
+
+  Tooltip.TRANSITION_DURATION = 150
+
+  Tooltip.DEFAULTS = {
+    animation: true,
+    placement: 'top',
+    selector: false,
+    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+    trigger: 'hover focus',
+    title: '',
+    delay: 0,
+    html: false,
+    container: false,
+    viewport: {
+      selector: 'body',
+      padding: 0
+    }
+  }
+
+  Tooltip.prototype.init = function (type, element, options) {
+    this.enabled   = true
+    this.type      = type
+    this.$element  = $(element)
+    this.options   = this.getOptions(options)
+    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
+    this.inState   = { click: false, hover: false, focus: false }
+
+    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+    }
+
+    var triggers = this.options.trigger.split(' ')
+
+    for (var i = triggers.length; i--;) {
+      var trigger = triggers[i]
+
+      if (trigger == 'click') {
+        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+      } else if (trigger != 'manual') {
+        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
+        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+      }
+    }
+
+    this.options.selector ?
+      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+      this.fixTitle()
+  }
+
+  Tooltip.prototype.getDefaults = function () {
+    return Tooltip.DEFAULTS
+  }
+
+  Tooltip.prototype.getOptions = function (options) {
+    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+    if (options.delay && typeof options.delay == 'number') {
+      options.delay = {
+        show: options.delay,
+        hide: options.delay
+      }
+    }
+
+    return options
+  }
+
+  Tooltip.prototype.getDelegateOptions = function () {
+    var options  = {}
+    var defaults = this.getDefaults()
+
+    this._options && $.each(this._options, function (key, value) {
+      if (defaults[key] != value) options[key] = value
+    })
+
+    return options
+  }
+
+  Tooltip.prototype.enter = function (obj) {
+    var self = obj instanceof this.constructor ?
+      obj : $(obj.currentTarget).data('bs.' + this.type)
+
+    if (!self) {
+      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+      $(obj.currentTarget).data('bs.' + this.type, self)
+    }
+
+    if (obj instanceof $.Event) {
+      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+    }
+
+    if (self.tip().hasClass('in') || self.hoverState == 'in') {
+      self.hoverState = 'in'
+      return
+    }
+
+    clearTimeout(self.timeout)
+
+    self.hoverState = 'in'
+
+    if (!self.options.delay || !self.options.delay.show) return self.show()
+
+    self.timeout = setTimeout(function () {
+      if (self.hoverState == 'in') self.show()
+    }, self.options.delay.show)
+  }
+
+  Tooltip.prototype.isInStateTrue = function () {
+    for (var key in this.inState) {
+      if (this.inState[key]) return true
+    }
+
+    return false
+  }
+
+  Tooltip.prototype.leave = function (obj) {
+    var self = obj instanceof this.constructor ?
+      obj : $(obj.currentTarget).data('bs.' + this.type)
+
+    if (!self) {
+      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+      $(obj.currentTarget).data('bs.' + this.type, self)
+    }
+
+    if (obj instanceof $.Event) {
+      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+    }
+
+    if (self.isInStateTrue()) return
+
+    clearTimeout(self.timeout)
+
+    self.hoverState = 'out'
+
+    if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+    self.timeout = setTimeout(function () {
+      if (self.hoverState == 'out') self.hide()
+    }, self.options.delay.hide)
+  }
+
+  Tooltip.prototype.show = function () {
+    var e = $.Event('show.bs.' + this.type)
+
+    if (this.hasContent() && this.enabled) {
+      this.$element.trigger(e)
+
+      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+      if (e.isDefaultPrevented() || !inDom) return
+      var that = this
+
+      var $tip = this.tip()
+
+      var tipId = this.getUID(this.type)
+
+      this.setContent()
+      $tip.attr('id', tipId)
+      this.$element.attr('aria-describedby', tipId)
+
+      if (this.options.animation) $tip.addClass('fade')
+
+      var placement = typeof this.options.placement == 'function' ?
+        this.options.placement.call(this, $tip[0], this.$element[0]) :
+        this.options.placement
+
+      var autoToken = /\s?auto?\s?/i
+      var autoPlace = autoToken.test(placement)
+      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+      $tip
+        .detach()
+        .css({ top: 0, left: 0, display: 'block' })
+        .addClass(placement)
+        .data('bs.' + this.type, this)
+
+      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+      this.$element.trigger('inserted.bs.' + this.type)
+
+      var pos          = this.getPosition()
+      var actualWidth  = $tip[0].offsetWidth
+      var actualHeight = $tip[0].offsetHeight
+
+      if (autoPlace) {
+        var orgPlacement = placement
+        var viewportDim = this.getPosition(this.$viewport)
+
+        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
+                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
+                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
+                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
+                    placement
+
+        $tip
+          .removeClass(orgPlacement)
+          .addClass(placement)
+      }
+
+      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+      this.applyPlacement(calculatedOffset, placement)
+
+      var complete = function () {
+        var prevHoverState = that.hoverState
+        that.$element.trigger('shown.bs.' + that.type)
+        that.hoverState = null
+
+        if (prevHoverState == 'out') that.leave(that)
+      }
+
+      $.support.transition && this.$tip.hasClass('fade') ?
+        $tip
+          .one('bsTransitionEnd', complete)
+          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+        complete()
+    }
+  }
+
+  Tooltip.prototype.applyPlacement = function (offset, placement) {
+    var $tip   = this.tip()
+    var width  = $tip[0].offsetWidth
+    var height = $tip[0].offsetHeight
+
+    // manually read margins because getBoundingClientRect includes difference
+    var marginTop = parseInt($tip.css('margin-top'), 10)
+    var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+    // we must check for NaN for ie 8/9
+    if (isNaN(marginTop))  marginTop  = 0
+    if (isNaN(marginLeft)) marginLeft = 0
+
+    offset.top  += marginTop
+    offset.left += marginLeft
+
+    // $.fn.offset doesn't round pixel values
+    // so we use setOffset directly with our own function B-0
+    $.offset.setOffset($tip[0], $.extend({
+      using: function (props) {
+        $tip.css({
+          top: Math.round(props.top),
+          left: Math.round(props.left)
+        })
+      }
+    }, offset), 0)
+
+    $tip.addClass('in')
+
+    // check to see if placing tip in new offset caused the tip to resize itself
+    var actualWidth  = $tip[0].offsetWidth
+    var actualHeight = $tip[0].offsetHeight
+
+    if (placement == 'top' && actualHeight != height) {
+      offset.top = offset.top + height - actualHeight
+    }
+
+    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+
+    if (delta.left) offset.left += delta.left
+    else offset.top += delta.top
+
+    var isVertical          = /top|bottom/.test(placement)
+    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+    $tip.offset(offset)
+    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+  }
+
+  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+    this.arrow()
+      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+      .css(isVertical ? 'top' : 'left', '')
+  }
+
+  Tooltip.prototype.setContent = function () {
+    var $tip  = this.tip()
+    var title = this.getTitle()
+
+    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+    $tip.removeClass('fade in top bottom left right')
+  }
+
+  Tooltip.prototype.hide = function (callback) {
+    var that = this
+    var $tip = $(this.$tip)
+    var e    = $.Event('hide.bs.' + this.type)
+
+    function complete() {
+      if (that.hoverState != 'in') $tip.detach()
+      that.$element
+        .removeAttr('aria-describedby')
+        .trigger('hidden.bs.' + that.type)
+      callback && callback()
+    }
+
+    this.$element.trigger(e)
+
+    if (e.isDefaultPrevented()) return
+
+    $tip.removeClass('in')
+
+    $.support.transition && $tip.hasClass('fade') ?
+      $tip
+        .one('bsTransitionEnd', complete)
+        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+      complete()
+
+    this.hoverState = null
+
+    return this
+  }
+
+  Tooltip.prototype.fixTitle = function () {
+    var $e = this.$element
+    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+    }
+  }
+
+  Tooltip.prototype.hasContent = function () {
+    return this.getTitle()
+  }
+
+  Tooltip.prototype.getPosition = function ($element) {
+    $element   = $element || this.$element
+
+    var el     = $element[0]
+    var isBody = el.tagName == 'BODY'
+
+    var elRect    = el.getBoundingClientRect()
+    if (elRect.width == null) {
+      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+    }
+    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
+    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+    return $.extend({}, elRect, scroll, outerDims, elOffset)
+  }
+
+  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
+           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+
+  }
+
+  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+    var delta = { top: 0, left: 0 }
+    if (!this.$viewport) return delta
+
+    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+    var viewportDimensions = this.getPosition(this.$viewport)
+
+    if (/right|left/.test(placement)) {
+      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
+      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+      if (topEdgeOffset < viewportDimensions.top) { // top overflow
+        delta.top = viewportDimensions.top - topEdgeOffset
+      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+      }
+    } else {
+      var leftEdgeOffset  = pos.left - viewportPadding
+      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+        delta.left = viewportDimensions.left - leftEdgeOffset
+      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+      }
+    }
+
+    return delta
+  }
+
+  Tooltip.prototype.getTitle = function () {
+    var title
+    var $e = this.$element
+    var o  = this.options
+
+    title = $e.attr('data-original-title')
+      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
+
+    return title
+  }
+
+  Tooltip.prototype.getUID = function (prefix) {
+    do prefix += ~~(Math.random() * 1000000)
+    while (document.getElementById(prefix))
+    return prefix
+  }
+
+  Tooltip.prototype.tip = function () {
+    if (!this.$tip) {
+      this.$tip = $(this.options.template)
+      if (this.$tip.length != 1) {
+        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+      }
+    }
+    return this.$tip
+  }
+
+  Tooltip.prototype.arrow = function () {
+    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+  }
+
+  Tooltip.prototype.enable = function () {
+    this.enabled = true
+  }
+
+  Tooltip.prototype.disable = function () {
+    this.enabled = false
+  }
+
+  Tooltip.prototype.toggleEnabled = function () {
+    this.enabled = !this.enabled
+  }
+
+  Tooltip.prototype.toggle = function (e) {
+    var self = this
+    if (e) {
+      self = $(e.currentTarget).data('bs.' + this.type)
+      if (!self) {
+        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+        $(e.currentTarget).data('bs.' + this.type, self)
+      }
+    }
+
+    if (e) {
+      self.inState.click = !self.inState.click
+      if (self.isInStateTrue()) self.enter(self)
+      else self.leave(self)
+    } else {
+      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+    }
+  }
+
+  Tooltip.prototype.destroy = function () {
+    var that = this
+    clearTimeout(this.timeout)
+    this.hide(function () {
+      that.$element.off('.' + that.type).removeData('bs.' + that.type)
+      if (that.$tip) {
+        that.$tip.detach()
+      }
+      that.$tip = null
+      that.$arrow = null
+      that.$viewport = null
+    })
+  }
+
+
+  // TOOLTIP PLUGIN DEFINITION
+  // =========================
+
+  function Plugin(option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.tooltip')
+      var options = typeof option == 'object' && option
+
+      if (!data && /destroy|hide/.test(option)) return
+      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  var old = $.fn.tooltip
+
+  $.fn.tooltip             = Plugin
+  $.fn.tooltip.Constructor = Tooltip
+
+
+  // TOOLTIP NO CONFLICT
+  // ===================
+
+  $.fn.tooltip.noConflict = function () {
+    $.fn.tooltip = old
+    return this
+  }
+
+}(jQuery);
diff --git a/scp/js/bootstrap-typeahead.js b/scp/js/bootstrap-typeahead.js
index 6c8238ad132a24178d565420083d6ccd0cd27cff..7ddc01f61c56312e657d858e286c0b3c5a03401a 100644
--- a/scp/js/bootstrap-typeahead.js
+++ b/scp/js/bootstrap-typeahead.js
@@ -41,7 +41,7 @@
 
     constructor: Typeahead
 
-  , select: function () {
+  , select: function (e) {
       var val = JSON.parse(this.$menu.find('.active').attr('data-value'))
         , text
 
@@ -51,7 +51,8 @@
       this.$element.val(text)
 
       if (typeof this.onselect == "function")
-          this.onselect(val)
+          if (false === this.onselect(val, e))
+              return;
 
       return this.hide()
     }
@@ -252,7 +253,7 @@
         case 9: // tab
         case 13: // enter
           if (!this.shown) return
-          this.select()
+          this.select(e)
           break
 
         case 27: // escape
@@ -298,7 +299,7 @@
   , click: function (e) {
       e.stopPropagation()
       e.preventDefault()
-      this.select()
+      this.select(e)
     }
 
   , mouseenter: function (e) {
diff --git a/scp/js/jquery.translatable.js b/scp/js/jquery.translatable.js
index 08a28ae3c7e030fdf20c79a6882a6dfd55974019..08f754a1a5e85c0d50f9759edb458b1a2e7e8a7e 100644
--- a/scp/js/jquery.translatable.js
+++ b/scp/js/jquery.translatable.js
@@ -60,6 +60,7 @@
         .focus($.proxy(function() { this.addClass('focus'); }, this.$container))
         .blur($.proxy(function() { this.removeClass('focus'); }, this.$container));
       getConfig().then($.proxy(function(c) {
+        this.attr({'spellcheck': 'true', 'lang': c.primary_language})
         $('<span class="flag"></span>')
           .addClass('flag-' + c.primary_lang_flag)
           .insertAfter(this);
@@ -113,6 +114,8 @@
           .text(info.name)
           .prepend($('<span>').addClass('flag flag-'+info.flag))
           .append($('<input type="text" data-lang="'+lang+'">')
+            .attr('lang', lang)
+            .attr('spellcheck', 'true')
             .attr('dir', info.direction || 'ltr')
             .on('change keydown', $.proxy(this.showCommit, this))
             .val(text)
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 7bfaf9a910b2cf4fb89496389b3412b475376a31..d1c73fc8bf47f33a938b5194803683a234a90534 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -37,7 +37,10 @@ function checkbox_checker(formObj, min, max) {
 
 var scp_prep = function() {
 
-    $("input:not(.dp):visible:enabled:first").focus();
+    $("input[autofocus]:visible:enabled:first").each(function() {
+      if ($(this).val())
+        $(this).blur();
+    });
     $('table.list input:checkbox').bind('click, change', function() {
         $(this)
             .parents("tr:first")
@@ -314,14 +317,14 @@ var scp_prep = function() {
             top : (w.innerHeight() / 7),
             left : (w.width() - $this.outerWidth()) / 2
         });
-        $this.hasClass('draggable') && $this.draggable({handle:'h3'});
+        $this.hasClass('draggable') && $this.draggable({handle:'.drag-handle'});
     });
 
 
     $('.dialog').each(function() {
         $this=$(this);
         $this.resize();
-        $this.hasClass('draggable') && $this.draggable({handle:'h3'});
+        $this.hasClass('draggable') && $this.draggable({handle:'.drag-handle'});
     });
 
     $('.dialog').delegate('input.close, a.close', 'click', function(e) {
@@ -447,13 +450,13 @@ var scp_prep = function() {
          stop = $('div.sticky.bar.stop'),
          stopAt,
          visible = false;
-     if (stop.length)
-       stopAt = stop.offset().top - $that.height();
 
      $that.find('.content').width($that.width());
      $(window).scroll(function (event) {
        // what the y position of the scroll is
        var y = $(this).scrollTop();
+       if (stop.length)
+         stopAt = stop.offset().top - $that.height();
 
        // whether that's below the form
        if (y >= top && (!stopAt || stopAt > y)) {
@@ -476,6 +479,8 @@ var scp_prep = function() {
        }
     });
   });
+
+  $('[data-toggle="tooltip"]').tooltip()
 };
 
 $(document).ready(scp_prep);
@@ -563,6 +568,16 @@ $(document).keydown(function(e) {
     }
 });
 
+
+$(document).on('focus', 'form.spellcheck textarea, form.spellcheck input[type=text]', function() {
+  var $this = $(this);
+  if ($this.attr('lang') !== undefined)
+    return;
+  var lang = $(this).closest('[lang]').attr('lang');
+  if (lang)
+    $(this).attr({'spellcheck':'true', 'lang': lang});
+});
+
 $.toggleOverlay = function (show) {
   if (typeof(show) === 'undefined') {
     return $.toggleOverlay(!$('#overlay').is(':visible'));
@@ -663,7 +678,7 @@ $.sysAlert = function (title, msg, cb) {
         $.toggleOverlay(true);
         $('#title', $dialog).html(title);
         $('#body', $dialog).html(msg);
-        $dialog.show();
+        $dialog.resize().show();
         if (cb)
             $dialog.find('input.ok.close').click(cb);
     } else {
@@ -700,7 +715,7 @@ $.confirm = function(message, title) {
                     .click(function() {  hide(); D.resolve(); })
         ))).append($('<div class="clear"></div>'));
     $.toggleOverlay(true);
-    $popup.show();
+    $popup.resize().show();
     return D.promise();
 };
 
@@ -787,6 +802,11 @@ $.changeHash = function(hash, quiet) {
   }
 };
 
+// Forms — submit, stay on same tab
+$(document).on('submit', 'form', function() {
+    $(this).attr('action', $(this).attr('action') + window.location.hash);
+});
+
 //Collaborators
 $(document).on('click', 'a.collaborator, a.collaborators', function(e) {
     e.preventDefault();
@@ -804,21 +824,10 @@ $(document).on('click', 'a.collaborator, a.collaborators', function(e) {
 // NOTE: getConfig should be global
 getConfig = (function() {
     var dfd = $.Deferred(),
-        requested = null;
+        requested = false;
     return function() {
-        if (dfd.state() != 'resolved' && !requested)
-            requested = $.ajax({
-                url: "ajax.php/config/scp",
-                dataType: 'json',
-                success: function (json_config) {
-                    dfd.resolve(json_config);
-                },
-                error: function() {
-                    requested = null;
-                }
-            });
         return dfd;
-    }
+    };
 })();
 
 $(document).on('pjax:click', function(options) {
@@ -834,7 +843,7 @@ $(document).on('pjax:click', function(options) {
         if ($(this).data('timer'))
             clearTimeout($(this).data('timer'));
     });
-    $('.tip_box').remove();
+    $('.tip_box, .typeahead.dropdown-menu').remove();
 });
 
 $(document).on('pjax:start', function() {
@@ -872,6 +881,17 @@ $(document).on('pjax:complete', function() {
     $('#overlay').removeAttr('style');
 });
 
+// Enable PJAX for the staff interface
+if ($.support.pjax) {
+  $(document).on('click', 'a', function(event) {
+    var $this = $(this);
+    if (!$this.hasClass('no-pjax')
+        && !$this.closest('.no-pjax').length
+        && $this.attr('href')[0] != '#')
+      $.pjax.click(event, {container: $this.data('pjaxContainer') || $('#pjax-container'), timeout: 2000});
+  })
+}
+
 // Quick note interface
 $(document).on('click.note', '.quicknote .action.edit-note', function() {
     var note = $(this).closest('.quicknote'),
diff --git a/scp/js/ticket.js b/scp/js/ticket.js
index a105918683214496cb4050d7d238089924dc120b..9e731a756fccbb9bb3e889833901ad456a406659 100644
--- a/scp/js/ticket.js
+++ b/scp/js/ticket.js
@@ -328,7 +328,9 @@ $.showImagesInline = function(urls, thread_id) {
                     }
                 ).append($('<div class="caption">')
                     .append('<span class="filename">'+info.filename+'</span>')
-                    .append('<a href="'+info.download_url+'" class="action-button pull-right no-pjax"><i class="icon-download-alt"></i> '+__('Download')+'</a>')
+                    .append($('<a href="'+info.download_url+'" class="action-button pull-right no-pjax"><i class="icon-download-alt"></i> '+__('Download')+'</a>')
+                      .attr('download', info.filename)
+                    )
                 );
             e.data('wrapped', true);
         }
@@ -341,6 +343,9 @@ $.refreshTicketView = function() {
 }
 
 var ticket_onload = function($) {
+    if (0 === $('#ticket_thread').length)
+        return;
+
     //Start watching the form for activity.
     autoLock.Init();
 
@@ -419,11 +424,12 @@ var ticket_onload = function($) {
         });
     });
 
-    $('.thread-body').each(function() {
-        var urls = $(this).data('urls');
-        if (urls)
-            $.showImagesInline(urls, $(this).data('id'));
-    });
+    $.showImagesInline($('#ticket_thread').data('imageUrls'));
+
+    var last_entry = $('#ticket_thread .thread-entry').last().offset().top - 50;
+    $('html, body').animate({
+        scrollTop: last_entry
+    }, 1000);
 };
 $(ticket_onload);
 $(document).on('pjax:success', function() { ticket_onload(jQuery); });
diff --git a/scp/js/tips.js b/scp/js/tips.js
index 76fabcd7bbc4814f7cc7db6c801daee1ed8a1b68..5801829bd10ec9f257dd47fb9030e8bdcf834393 100644
--- a/scp/js/tips.js
+++ b/scp/js/tips.js
@@ -53,8 +53,9 @@ jQuery(function() {
     },
     getHelpTips = (function() {
         var dfd, cache = {};
-        return function(namespace) {
-            var namespace = namespace
+        return function(elem) {
+            var namespace =
+                   $(elem).closest('[data-tip-namespace]').data('tipNamespace')
                 || $('#content').data('tipNamespace')
                 || $('meta[name=tip-namespace]').attr('content');
             if (!namespace)
@@ -147,7 +148,7 @@ jQuery(function() {
             clearTimeout(tip_timer);
         });
 
-        getHelpTips().then(function(tips) {
+        getHelpTips(elem).then(function(tips) {
             var href = elem.attr('href');
             if (href) {
                 section = tips[elem.attr('href').substr(1)];
diff --git a/setup/js/tips.js b/setup/js/tips.js
index 1e35d976897cfc3cd121f3a8cb0ad195eb55fecf..a3e8b06463a22dfa94e8a00c85d7ef3df2c422a5 100644
--- a/setup/js/tips.js
+++ b/setup/js/tips.js
@@ -18,7 +18,7 @@ jQuery(function($) {
     .each(function(i, e) {
         e.rel = 'tip-' + i;
     })
-    .live('mouseover click', function(e) {
+    .on('mouseover click', function(e) {
         e.preventDefault();
 
         var elem = $(this),
@@ -51,7 +51,7 @@ jQuery(function($) {
                 }
             }, 500);
 
-        elem.live('mouseout', function() {
+        elem.on('mouseout', function() {
             clearTimeout(tip_timer);
         });
 
diff --git a/setup/test/run-tests.php b/setup/test/run-tests.php
index f42c121d7e48b345bf6407b2cde0ea25dc2454c3..30d81e225735c50e21d2634cae790d00b22d1d4f 100644
--- a/setup/test/run-tests.php
+++ b/setup/test/run-tests.php
@@ -8,6 +8,7 @@ $selected_test = (isset($argv[1])) ? $argv[1] : false;
 require_once 'bootstrap.php';
 require_once "tests/class.test.php";
 
+$root = get_osticket_root_path();
 $fails = array();
 
 require_once INCLUDE_DIR . 'class.i18n.php';
diff --git a/setup/test/tests/stubs.php b/setup/test/tests/stubs.php
index 620f763a55090b6bb423e2b36a6b378f44255a8e..24670dbdea13641aa632e59d82231af895c4c611 100644
--- a/setup/test/tests/stubs.php
+++ b/setup/test/tests/stubs.php
@@ -37,6 +37,7 @@ class mysqli_result {
 class ReflectionClass {
     function getMethods() {}
     function getConstants() {}
+    function newInstanceArgs() {}
 }
 
 class DomNode {
diff --git a/tickets.php b/tickets.php
index 10f70676a4713d3c7b696f8304a2c6bf74067a70..0c6dd8947c1925f025552e20971b8f8cc0079c82 100644
--- a/tickets.php
+++ b/tickets.php
@@ -35,7 +35,7 @@ if($_REQUEST['id']) {
 if (!$ticket && $thisclient->isGuest())
     Http::redirect('view.php');
 
-$tform = TicketForm::objects()->one();
+$tform = TicketForm::objects()->one()->getForm();
 $messageField = $tform->getField('message');
 $attachments = $messageField->getWidget()->getAttachments();
 
@@ -130,8 +130,6 @@ if($ticket && $ticket->checkUserAccess($thisclient)) {
 }
 include(CLIENTINC_DIR.'header.inc.php');
 include(CLIENTINC_DIR.$inc);
-if ($tform instanceof DynamicFormEntry)
-    $tform = $tform->getForm();
 print $tform->getMedia();
 include(CLIENTINC_DIR.'footer.inc.php');
 ?>