diff --git a/include/class.config.php b/include/class.config.php
index e6bed4657f69b4c432e617a750042ad3271b3611..d01d1be1bf8306cc974cb1f955f857acec23b4dc 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -17,50 +17,128 @@
 require_once(INCLUDE_DIR.'class.email.php');
 
 class Config {
-
-    var $id = 0;
     var $config = array();
 
-    var $defaultDept;   //Default Department
-    var $defaultSLA;   //Default SLA
-    var $defaultEmail;  //Default Email
-    var $alertEmail;  //Alert Email
-    var $defaultSMTPEmail; //Default  SMTP Email
+    var $section = null;                    # Default namespace ('core')
+    var $table = 'config';                  # Table name (with prefix)
+    var $section_column = 'namespace';      # namespace column name
 
-    function Config($id) {
-        $this->load($id);
-    }
+    var $session = null;                    # Session-backed configuration
 
-    function load($id=0) {
+    function Config($section=null) {
+        if ($section)
+            $this->section = $section;
 
-        if(!$id && !($id=$this->getId()))
+        if ($this->section === null)
             return false;
 
-        $sql='SELECT *, (TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))/3600) as db_tz_offset '
-            .' FROM '.CONFIG_TABLE
-            .' WHERE id='.db_input($id);
+        if (!isset($_SESSION['cfg:'.$this->section]))
+            $_SESSION['cfg:'.$this->section] = array();
+        $this->session = &$_SESSION['cfg:'.$this->section];
 
-        if(!($res=db_query($sql)) || !db_num_rows($res))
-            return false;
+        $sql='SELECT id, `key`, value FROM '.$this->table
+            .' WHERE `'.$this->section_column.'` = '.db_input($this->section);
 
+        if(($res=db_query($sql)) && db_num_rows($res))
+            while ($row = db_fetch_array($res))
+                $this->config[$row['key']] = $row;
+    }
 
-        $this->config = db_fetch_array($res);
-        $this->id = $this->config['id'];
+    function getNamespace() {
+        return $this->section;
+    }
 
-        //Get the default time zone
-        // We can't JOIN timezone table above due to upgrade support.
-        if($this->config['default_timezone_id'])
-            $this->config['tz_offset'] = Timezone::getOffsetById($this->config['default_timezone_id']);
-        else
-            $this->config['tz_offset'] = 0;
+    function get($key, $default=null) {
+        if (isset($this->config[$key]))
+            return $this->config[$key]['value'];
+        elseif (isset($this->session[$key]))
+            return $this->session[$key];
+        elseif ($default !== null)
+            return $this->set($key, $default);
+        return null;
+    }
+
+    function exists($key) {
+        return $this->get($key, null) ? true : false;
+    }
+
+    function set($key, $value) {
+        return ($this->update($key, $value)) ? $value : null;
+    }
 
+    function persist($key, $value) {
+        $this->session[$key] = $value;
         return true;
     }
 
-    function reload() {
-        if(!$this->load($this->getId()))
+    function create($key, $value) {
+        $sql = 'INSERT INTO '.$this->table
+            .' SET `'.$this->section_column.'`='.db_input($this->section)
+            .', `key`='.db_input($key)
+            .', value='.db_input($value);
+        if (!db_query($sql) || !($id=db_insert_id()))
             return false;
 
+        $this->config[$key] = array('key'=>$key, 'value'=>$value, 'id'=>$id);
+        return true;
+    }
+
+    function update($key, $value) {
+        if (!isset($this->config[$key]))
+            return $this->create($key, $value);
+
+        $setting = &$this->config[$key];
+        if ($setting['value'] == $value)
+            return true;
+
+        if (!db_query('UPDATE '.$this->table.' SET updated=NOW(), value='
+                .db_input($value).' WHERE id='.db_input($setting['id'])))
+            return false;
+
+        $setting['value'] = $value;
+        return true;
+    }
+
+    function updateAll($updates) {
+        foreach ($updates as $key=>$value)
+            if (!$this->update($key, $value))
+                return false;
+        return true;
+    }
+}
+
+class OsticketConfig extends Config {
+    var $table = CONFIG_TABLE;
+    var $section = 'core';
+
+    var $defaultDept;   //Default Department
+    var $defaultSLA;   //Default SLA
+    var $defaultEmail;  //Default Email
+    var $alertEmail;  //Alert Email
+    var $defaultSMTPEmail; //Default  SMTP Email
+
+    function OsticketConfig($section=null) {
+        parent::Config($section);
+
+        if (count($this->config) == 0) {
+            // Fallback for osticket < 1.7@852ca89e
+            $sql='SELECT * FROM '.$this->table.' WHERE id = 1';
+            if (($res=db_query($sql)) && db_num_rows($res))
+                foreach (db_fetch_array($res) as $key=>$value)
+                    $this->config[$key] = array('value'=>$value);
+        }
+
+        //Get the default time zone
+        // We can't JOIN timezone table above due to upgrade support.
+        if ($this->get('default_timezone_id')) {
+            if (!$this->exists('tz_offset'))
+                $this->persist('tz_offset',
+                    Timezone::getOffsetById($this->get('default_timezone_id')));
+        } else
+            // Previous osTicket versions saved the offset value instead of
+            // a timezone instance. This is compatibility for the upgrader
+            $this->persist('tz_offset', 0);
+
         return true;
     }
 
@@ -73,75 +151,82 @@ class Config {
     }
 
     function isOnline() {
-        return ($this->config['isonline']);
+        return ($this->get('isonline'));
     }
 
     function isKnowledgebaseEnabled() {
         require_once(INCLUDE_DIR.'class.faq.php');
-        return ($this->config['enable_kb'] && FAQ::countPublishedFAQs());
+        return ($this->get('enable_kb') && FAQ::countPublishedFAQs());
     }
 
     function getVersion() {
         return THIS_VERSION;
     }
 
-    //Used to detect version prior to 1.7 (useful during upgrade)
-    function getDBVersion() {
-        return $this->config['ostversion'];
-    }
+    function getSchemaSignature($section=null) {
 
-    function getSchemaSignature() {
+        if (!$section && ($v=$this->get('schema_signature')))
+            return $v;
 
-        if($this->config['schema_signature'])
-            return $this->config['schema_signature'];
+        // 1.7 after namespaced configuration, other namespace
+        if ($section) {
+            $sql='SELECT value FROM '.$this->table
+                .' WHERE `key` = "schema_signature" and namespace='.db_input($section);
+            if (($res=db_query($sql, false)) && db_num_rows($res))
+                return db_result($res);
+        }
 
-        if($this->config['ostversion']) //old version 1.6 RC[1-5]-ST
-            return md5(strtoupper(trim($this->config['ostversion'])));
+        // 1.7 before namespaced configuration
+        $sql='SELECT `schema_signature` FROM '.$this->table
+            .' WHERE id=1';
+        if (($res=db_query($sql, false)) && db_num_rows($res))
+            return db_result($res);
 
-        return null;
+        // old version 1.6
+        return md5(self::getDBVersion());
     }
 
     function getDBTZoffset() {
-        return $this->config['db_tz_offset'];
+        if (!$this->exists('db_tz_offset')) {
+            $sql='SELECT (TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))/3600) as db_tz_offset';
+            if(($res=db_query($sql)) && db_num_rows($res))
+                $this->persist('db_tz_offset', db_result($res));
+        }
+        return $this->get('db_tz_offset');
     }
 
     /* Date & Time Formats */
     function observeDaylightSaving() {
-        return ($this->config['enable_daylight_saving']);
+        return ($this->get('enable_daylight_saving'));
     }
     function getTimeFormat() {
-        return $this->config['time_format'];
+        return $this->get('time_format');
     }
     function getDateFormat() {
-        return $this->config['date_format'];
+        return $this->get('date_format');
     }
 
     function getDateTimeFormat() {
-        return $this->config['datetime_format'];
+        return $this->get('datetime_format');
     }
 
     function getDayDateTimeFormat() {
-        return $this->config['daydatetime_format'];
-    }
-
-    function getId() {
-        return $this->id;
-    }
-
-    function getConfigId() {
-        return $this->getId();
+        return $this->get('daydatetime_format');
     }
 
     function getConfigInfo() {
-        return $this->config;
+        $info = array();
+        foreach ($this->config as $key=>$setting)
+            $info[$key] = $setting['value'];
+        return $info;
     }
 
     function getTitle() {
-        return $this->config['helpdesk_title'];
+        return $this->get('helpdesk_title');
     }
 
     function getUrl() {
-        return $this->config['helpdesk_url'];
+        return $this->get('helpdesk_url');
     }
 
     function getBaseUrl() { //Same as above with no trailing slash.
@@ -149,27 +234,27 @@ class Config {
     }
 
     function getTZOffset() {
-        return $this->config['tz_offset'];
+        return $this->get('tz_offset');
     }
 
     function getPageSize() {
-        return $this->config['max_page_size'];
+        return $this->get('max_page_size');
     }
 
     function getGracePeriod() {
-        return $this->config['overdue_grace_period'];
+        return $this->get('overdue_grace_period');
     }
 
     function getPasswdResetPeriod() {
-        return $this->config['passwd_reset_period'];
+        return $this->get('passwd_reset_period');
     }
 
     function showRelatedTickets() {
-        return $this->config['show_related_tickets'];
+        return $this->get('show_related_tickets');
     }
 
     function showNotesInline(){
-        return $this->config['show_notes_inline'];
+        return $this->get('show_notes_inline');
     }
 
     function getClientTimeout() {
@@ -177,15 +262,15 @@ class Config {
     }
 
     function getClientSessionTimeout() {
-        return $this->config['client_session_timeout']*60;
+        return $this->get('client_session_timeout')*60;
     }
 
     function getClientLoginTimeout() {
-        return $this->config['client_login_timeout']*60;
+        return $this->get('client_login_timeout')*60;
     }
 
     function getClientMaxLogins() {
-        return $this->config['client_max_logins'];
+        return $this->get('client_max_logins');
     }
 
     function getStaffTimeout() {
@@ -193,23 +278,23 @@ class Config {
     }
 
     function getStaffSessionTimeout() {
-        return $this->config['staff_session_timeout']*60;
+        return $this->get('staff_session_timeout')*60;
     }
 
     function getStaffLoginTimeout() {
-        return $this->config['staff_login_timeout']*60;
+        return $this->get('staff_login_timeout')*60;
     }
 
     function getStaffMaxLogins() {
-        return $this->config['staff_max_logins'];
+        return $this->get('staff_max_logins');
     }
 
     function getLockTime() {
-        return $this->config['autolock_minutes'];
+        return $this->get('autolock_minutes');
     }
 
     function getDefaultDeptId() {
-        return $this->config['default_dept_id'];
+        return $this->get('default_dept_id');
     }
 
     function getDefaultDept() {
@@ -221,7 +306,7 @@ class Config {
     }
 
     function getDefaultEmailId() {
-        return $this->config['default_email_id'];
+        return $this->get('default_email_id');
     }
 
     function getDefaultEmail() {
@@ -238,7 +323,7 @@ class Config {
     }
 
     function getDefaultSLAId() {
-        return $this->config['default_sla_id'];
+        return $this->get('default_sla_id');
     }
 
     function getDefaultSLA() {
@@ -250,33 +335,29 @@ class Config {
     }
 
     function getAlertEmailId() {
-        return $this->config['alert_email_id'];
+        return $this->get('alert_email_id');
     }
 
     function getAlertEmail() {
 
-        if(!$this->alertEmail && $this->config['alert_email_id'])
-            $this->alertEmail= new Email($this->config['alert_email_id']);
+        if(!$this->alertEmail && $this->get('alert_email_id'))
+            $this->alertEmail= new Email($this->get('alert_email_id'));
         return $this->alertEmail;
     }
 
     function getDefaultSMTPEmail() {
 
-        if(!$this->defaultSMTPEmail && $this->config['default_smtp_id'])
-            $this->defaultSMTPEmail= new Email($this->config['default_smtp_id']);
+        if(!$this->defaultSMTPEmail && $this->get('default_smtp_id'))
+            $this->defaultSMTPEmail= new Email($this->get('default_smtp_id'));
         return $this->defaultSMTPEmail;
     }
 
-    function allowSMTPSpoofing() {
-        return $this->config['spoof_default_smtp'];
-    }
-
     function getDefaultPriorityId() {
-        return $this->config['default_priority_id'];
+        return $this->get('default_priority_id');
     }
 
     function getDefaultTemplateId() {
-        return $this->config['default_template_id'];
+        return $this->get('default_template_id');
     }
 
     function getDefaultTemplate() {
@@ -288,73 +369,73 @@ class Config {
     }
 
     function getMaxOpenTickets() {
-         return $this->config['max_open_tickets'];
+         return $this->get('max_open_tickets');
     }
 
     function getMaxFileSize() {
-        return $this->config['max_file_size'];
+        return $this->get('max_file_size');
     }
 
     function getStaffMaxFileUploads() {
-        return $this->config['max_staff_file_uploads'];
+        return $this->get('max_staff_file_uploads');
     }
 
     function getClientMaxFileUploads() {
         //TODO: change max_user_file_uploads to max_client_file_uploads
-        return $this->config['max_user_file_uploads'];
+        return $this->get('max_user_file_uploads');
     }
 
     function getLogLevel() {
-        return $this->config['log_level'];
+        return $this->get('log_level');
     }
 
     function getLogGracePeriod() {
-        return $this->config['log_graceperiod'];
+        return $this->get('log_graceperiod');
     }
 
     function logTicketActivity() {
-        return $this->config['log_ticket_activity'];
+        return $this->get('log_ticket_activity');
     }
 
     function clickableURLS() {
-        return ($this->config['clickable_urls']);
+        return ($this->get('clickable_urls'));
     }
 
     function enableStaffIPBinding() {
-        return ($this->config['staff_ip_binding']);
+        return ($this->get('staff_ip_binding'));
     }
 
     function isCaptchaEnabled() {
-        return (extension_loaded('gd') && function_exists('gd_info') && $this->config['enable_captcha']);
+        return (extension_loaded('gd') && function_exists('gd_info') && $this->get('enable_captcha'));
     }
 
     function isAutoCronEnabled() {
-        return ($this->config['enable_auto_cron']);
+        return ($this->get('enable_auto_cron'));
     }
 
     function isEmailPollingEnabled() {
-        return ($this->config['enable_mail_polling']);
+        return ($this->get('enable_mail_polling'));
     }
 
     function allowPriorityChange() {
-        return ($this->config['allow_priority_change']);
+        return ($this->get('allow_priority_change'));
     }
 
 
     function useEmailPriority() {
-        return ($this->config['use_email_priority']);
+        return ($this->get('use_email_priority'));
     }
 
     function getAdminEmail() {
-         return $this->config['admin_email'];
+         return $this->get('admin_email');
     }
 
     function getReplySeparator() {
-        return $this->config['reply_separator'];
+        return $this->get('reply_separator');
     }
 
     function stripQuotedReply() {
-        return ($this->config['strip_quoted_reply']);
+        return ($this->get('strip_quoted_reply'));
     }
 
     function saveEmailHeaders() {
@@ -362,176 +443,176 @@ class Config {
     }
 
     function useRandomIds() {
-        return ($this->config['random_ticket_ids']);
+        return ($this->get('random_ticket_ids'));
     }
 
     /* autoresponders  & Alerts */
     function autoRespONNewTicket() {
-        return ($this->config['ticket_autoresponder']);
+        return ($this->get('ticket_autoresponder'));
     }
 
     function autoRespONNewMessage() {
-        return ($this->config['message_autoresponder']);
+        return ($this->get('message_autoresponder'));
     }
 
     function notifyONNewStaffTicket() {
-        return ($this->config['ticket_notice_active']);
+        return ($this->get('ticket_notice_active'));
     }
 
     function alertONNewMessage() {
-        return ($this->config['message_alert_active']);
+        return ($this->get('message_alert_active'));
     }
 
     function alertLastRespondentONNewMessage() {
-        return ($this->config['message_alert_laststaff']);
+        return ($this->get('message_alert_laststaff'));
     }
 
     function alertAssignedONNewMessage() {
-        return ($this->config['message_alert_assigned']);
+        return ($this->get('message_alert_assigned'));
     }
 
     function alertDeptManagerONNewMessage() {
-        return ($this->config['message_alert_dept_manager']);
+        return ($this->get('message_alert_dept_manager'));
     }
 
     function alertONNewNote() {
-        return ($this->config['note_alert_active']);
+        return ($this->get('note_alert_active'));
     }
 
     function alertLastRespondentONNewNote() {
-        return ($this->config['note_alert_laststaff']);
+        return ($this->get('note_alert_laststaff'));
     }
 
     function alertAssignedONNewNote() {
-        return ($this->config['note_alert_assigned']);
+        return ($this->get('note_alert_assigned'));
     }
 
     function alertDeptManagerONNewNote() {
-        return ($this->config['note_alert_dept_manager']);
+        return ($this->get('note_alert_dept_manager'));
     }
 
     function alertONNewTicket() {
-        return ($this->config['ticket_alert_active']);
+        return ($this->get('ticket_alert_active'));
     }
 
     function alertAdminONNewTicket() {
-        return ($this->config['ticket_alert_admin']);
+        return ($this->get('ticket_alert_admin'));
     }
 
     function alertDeptManagerONNewTicket() {
-        return ($this->config['ticket_alert_dept_manager']);
+        return ($this->get('ticket_alert_dept_manager'));
     }
 
     function alertDeptMembersONNewTicket() {
-        return ($this->config['ticket_alert_dept_members']);
+        return ($this->get('ticket_alert_dept_members'));
     }
 
     function alertONTransfer() {
-        return ($this->config['transfer_alert_active']);
+        return ($this->get('transfer_alert_active'));
     }
 
     function alertAssignedONTransfer() {
-        return ($this->config['transfer_alert_assigned']);
+        return ($this->get('transfer_alert_assigned'));
     }
 
     function alertDeptManagerONTransfer() {
-        return ($this->config['transfer_alert_dept_manager']);
+        return ($this->get('transfer_alert_dept_manager'));
     }
 
     function alertDeptMembersONTransfer() {
-        return ($this->config['transfer_alert_dept_members']);
+        return ($this->get('transfer_alert_dept_members'));
     }
 
     function alertONAssignment() {
-        return ($this->config['assigned_alert_active']);
+        return ($this->get('assigned_alert_active'));
     }
 
     function alertStaffONAssignment() {
-        return ($this->config['assigned_alert_staff']);
+        return ($this->get('assigned_alert_staff'));
     }
 
     function alertTeamLeadONAssignment() {
-        return ($this->config['assigned_alert_team_lead']);
+        return ($this->get('assigned_alert_team_lead'));
     }
 
     function alertTeamMembersONAssignment() {
-        return ($this->config['assigned_alert_team_members']);
+        return ($this->get('assigned_alert_team_members'));
     }
 
 
     function alertONOverdueTicket() {
-        return ($this->config['overdue_alert_active']);
+        return ($this->get('overdue_alert_active'));
     }
 
     function alertAssignedONOverdueTicket() {
-        return ($this->config['overdue_alert_assigned']);
+        return ($this->get('overdue_alert_assigned'));
     }
 
     function alertDeptManagerONOverdueTicket() {
-        return ($this->config['overdue_alert_dept_manager']);
+        return ($this->get('overdue_alert_dept_manager'));
     }
 
     function alertDeptMembersONOverdueTicket() {
-        return ($this->config['overdue_alert_dept_members']);
+        return ($this->get('overdue_alert_dept_members'));
     }
 
     function autoAssignReopenedTickets() {
-        return ($this->config['auto_assign_reopened_tickets']);
+        return ($this->get('auto_assign_reopened_tickets'));
     }
 
     function showAssignedTickets() {
-        return ($this->config['show_assigned_tickets']);
+        return ($this->get('show_assigned_tickets'));
     }
 
     function showAnsweredTickets() {
-        return ($this->config['show_answered_tickets']);
+        return ($this->get('show_answered_tickets'));
     }
 
     function hideStaffName() {
-        return ($this->config['hide_staff_name']);
+        return ($this->get('hide_staff_name'));
     }
 
     function sendOverLimitNotice() {
-        return ($this->config['overlimit_notice_active']);
+        return ($this->get('overlimit_notice_active'));
     }
 
     /* Error alerts sent to admin email when enabled */
     function alertONSQLError() {
-        return ($this->config['send_sql_errors']);
+        return ($this->get('send_sql_errors'));
     }
     function alertONLoginError() {
-        return ($this->config['send_login_errors']);
+        return ($this->get('send_login_errors'));
     }
 
     function alertONMailParseError() {
-        return ($this->config['send_mailparse_errors']);
+        return ($this->get('send_mailparse_errors'));
     }
 
 
 
     /* Attachments */
     function getAllowedFileTypes() {
-        return trim($this->config['allowed_filetypes']);
+        return trim($this->get('allowed_filetypes'));
     }
 
     function emailAttachments() {
-        return ($this->config['email_attachments']);
+        return ($this->get('email_attachments'));
     }
 
     function allowAttachments() {
-        return ($this->config['allow_attachments']);
+        return ($this->get('allow_attachments'));
     }
 
     function allowOnlineAttachments() {
-        return ($this->allowAttachments() && $this->config['allow_online_attachments']);
+        return ($this->allowAttachments() && $this->get('allow_online_attachments'));
     }
 
     function allowAttachmentsOnlogin() {
-        return ($this->allowOnlineAttachments() && $this->config['allow_online_attachments_onlogin']);
+        return ($this->allowOnlineAttachments() && $this->get('allow_online_attachments_onlogin'));
     }
 
     function allowEmailAttachments() {
-        return ($this->allowAttachments() && $this->config['allow_email_attachments']);
+        return ($this->allowAttachments() && $this->get('allow_email_attachments'));
     }
 
     //TODO: change db field to allow_api_attachments - which will include  email/json/xml attachments
@@ -542,7 +623,7 @@ class Config {
 
     /* Needed by upgrader on 1.6 and older releases upgrade - not not remove */
     function getUploadDir() {
-        return $this->config['upload_dir'];
+        return $this->get('upload_dir');
     }
 
     function updateSettings($vars, &$errors) {
@@ -560,9 +641,6 @@ class Config {
             case 'emails':
                 return $this->updateEmailsSettings($vars, $errors);
                 break;
-           case 'attachments':
-                return $this->updateAttachmentsSetting($vars,$errors);
-                break;
            case 'autoresp':
                 return $this->updateAutoresponderSettings($vars, $errors);
                 break;
@@ -599,32 +677,30 @@ class Config {
         if(!Validator::process($f, $vars, $errors) || $errors)
             return false;
 
-        $sql='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-            .',isonline='.db_input($vars['isonline'])
-            .',helpdesk_title='.db_input($vars['helpdesk_title'])
-            .',helpdesk_url='.db_input($vars['helpdesk_url'])
-            .',default_dept_id='.db_input($vars['default_dept_id'])
-            .',default_template_id='.db_input($vars['default_template_id'])
-            .',max_page_size='.db_input($vars['max_page_size'])
-            .',log_level='.db_input($vars['log_level'])
-            .',log_graceperiod='.db_input($vars['log_graceperiod'])
-            .',passwd_reset_period='.db_input($vars['passwd_reset_period'])
-            .',staff_max_logins='.db_input($vars['staff_max_logins'])
-            .',staff_login_timeout='.db_input($vars['staff_login_timeout'])
-            .',staff_session_timeout='.db_input($vars['staff_session_timeout'])
-            .',staff_ip_binding='.db_input(isset($vars['staff_ip_binding'])?1:0)
-            .',client_max_logins='.db_input($vars['client_max_logins'])
-            .',client_login_timeout='.db_input($vars['client_login_timeout'])
-            .',client_session_timeout='.db_input($vars['client_session_timeout'])
-            .',time_format='.db_input($vars['time_format'])
-            .',date_format='.db_input($vars['date_format'])
-            .',datetime_format='.db_input($vars['datetime_format'])
-            .',daydatetime_format='.db_input($vars['daydatetime_format'])
-            .',default_timezone_id='.db_input($vars['default_timezone_id'])
-            .',enable_daylight_saving='.db_input(isset($vars['enable_daylight_saving'])?1:0)
-            .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
+        return $this->updateAll(array(
+            'isonline'=>$vars['isonline'],
+            'helpdesk_title'=>$vars['helpdesk_title'],
+            'helpdesk_url'=>$vars['helpdesk_url'],
+            'default_dept_id'=>$vars['default_dept_id'],
+            'default_template_id'=>$vars['default_template_id'],
+            'max_page_size'=>$vars['max_page_size'],
+            'log_level'=>$vars['log_level'],
+            'log_graceperiod'=>$vars['log_graceperiod'],
+            'passwd_reset_period'=>$vars['passwd_reset_period'],
+            'staff_max_logins'=>$vars['staff_max_logins'],
+            'staff_login_timeout'=>$vars['staff_login_timeout'],
+            'staff_session_timeout'=>$vars['staff_session_timeout'],
+            'staff_ip_binding'=>isset($vars['staff_ip_binding'])?1:0,
+            'client_max_logins'=>$vars['client_max_logins'],
+            'client_login_timeout'=>$vars['client_login_timeout'],
+            'client_session_timeout'=>$vars['client_session_timeout'],
+            'time_format'=>$vars['time_format'],
+            'date_format'=>$vars['date_format'],
+            'datetime_format'=>$vars['datetime_format'],
+            'daydatetime_format'=>$vars['daydatetime_format'],
+            'default_timezone_id'=>$vars['default_timezone_id'],
+            'enable_daylight_saving'=>isset($vars['enable_daylight_saving'])?1:0,
+        ));
     }
 
     function updateTicketsSettings($vars, &$errors) {
@@ -670,35 +746,33 @@ class Config {
         if(!Validator::process($f, $vars, $errors) || $errors)
             return false;
 
-        $sql='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-            .',random_ticket_ids='.db_input($vars['random_ticket_ids'])
-            .',default_priority_id='.db_input($vars['default_priority_id'])
-            .',default_sla_id='.db_input($vars['default_sla_id'])
-            .',max_open_tickets='.db_input($vars['max_open_tickets'])
-            .',autolock_minutes='.db_input($vars['autolock_minutes'])
-            .',allow_priority_change='.db_input(isset($vars['allow_priority_change'])?1:0)
-            .',use_email_priority='.db_input(isset($vars['use_email_priority'])?1:0)
-            .',enable_captcha='.db_input(isset($vars['enable_captcha'])?1:0)
-            .',log_ticket_activity='.db_input(isset($vars['log_ticket_activity'])?1:0)
-            .',auto_assign_reopened_tickets='.db_input(isset($vars['auto_assign_reopened_tickets'])?1:0)
-            .',show_assigned_tickets='.db_input(isset($vars['show_assigned_tickets'])?1:0)
-            .',show_answered_tickets='.db_input(isset($vars['show_answered_tickets'])?1:0)
-            .',show_related_tickets='.db_input(isset($vars['show_related_tickets'])?1:0)
-            .',show_notes_inline='.db_input(isset($vars['show_notes_inline'])?1:0)
-            .',clickable_urls='.db_input(isset($vars['clickable_urls'])?1:0)
-            .',hide_staff_name='.db_input(isset($vars['hide_staff_name'])?1:0)
-            .',allow_attachments='.db_input(isset($vars['allow_attachments'])?1:0)
-            .',allowed_filetypes='.db_input(strtolower(preg_replace("/\n\r|\r\n|\n|\r/", '',trim($vars['allowed_filetypes']))))
-            .',max_file_size='.db_input($vars['max_file_size'])
-            .',max_user_file_uploads='.db_input($vars['max_user_file_uploads'])
-            .',max_staff_file_uploads='.db_input($vars['max_staff_file_uploads'])
-            .',email_attachments='.db_input(isset($vars['email_attachments'])?1:0)
-            .',allow_email_attachments='.db_input(isset($vars['allow_email_attachments'])?1:0)
-            .',allow_online_attachments='.db_input(isset($vars['allow_online_attachments'])?1:0)
-            .',allow_online_attachments_onlogin='.db_input(isset($vars['allow_online_attachments_onlogin'])?1:0)
-            .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
+        return $this->updateAll(array(
+            'random_ticket_ids'=>$vars['random_ticket_ids'],
+            'default_priority_id'=>$vars['default_priority_id'],
+            'default_sla_id'=>$vars['default_sla_id'],
+            'max_open_tickets'=>$vars['max_open_tickets'],
+            'autolock_minutes'=>$vars['autolock_minutes'],
+            'allow_priority_change'=>isset($vars['allow_priority_change'])?1:0,
+            'use_email_priority'=>isset($vars['use_email_priority'])?1:0,
+            'enable_captcha'=>isset($vars['enable_captcha'])?1:0,
+            'log_ticket_activity'=>isset($vars['log_ticket_activity'])?1:0,
+            'auto_assign_reopened_tickets'=>isset($vars['auto_assign_reopened_tickets'])?1:0,
+            'show_assigned_tickets'=>isset($vars['show_assigned_tickets'])?1:0,
+            'show_answered_tickets'=>isset($vars['show_answered_tickets'])?1:0,
+            'show_related_tickets'=>isset($vars['show_related_tickets'])?1:0,
+            'show_notes_inline'=>isset($vars['show_notes_inline'])?1:0,
+            'clickable_urls'=>isset($vars['clickable_urls'])?1:0,
+            'hide_staff_name'=>isset($vars['hide_staff_name'])?1:0,
+            'allow_attachments'=>isset($vars['allow_attachments'])?1:0,
+            'allowed_filetypes'=>strtolower(preg_replace("/\n\r|\r\n|\n|\r/", '',trim($vars['allowed_filetypes']))),
+            'max_file_size'=>$vars['max_file_size'],
+            'max_user_file_uploads'=>$vars['max_user_file_uploads'],
+            'max_staff_file_uploads'=>$vars['max_staff_file_uploads'],
+            'email_attachments'=>isset($vars['email_attachments'])?1:0,
+            'allow_email_attachments'=>isset($vars['allow_email_attachments'])?1:0,
+            'allow_online_attachments'=>isset($vars['allow_online_attachments'])?1:0,
+            'allow_online_attachments_onlogin'=>isset($vars['allow_online_attachments_onlogin'])?1:0,
+        ));
     }
 
 
@@ -718,75 +792,28 @@ class Config {
         if(!Validator::process($f,$vars,$errors) || $errors)
             return false;
 
-        $sql='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-            .',default_email_id='.db_input($vars['default_email_id'])
-            .',alert_email_id='.db_input($vars['alert_email_id'])
-            .',default_smtp_id='.db_input($vars['default_smtp_id'])
-            .',admin_email='.db_input($vars['admin_email'])
-            .',enable_auto_cron='.db_input(isset($vars['enable_auto_cron'])?1:0)
-            .',enable_mail_polling='.db_input(isset($vars['enable_mail_polling'])?1:0)
-            .',strip_quoted_reply='.db_input(isset($vars['strip_quoted_reply'])?1:0)
-            .',reply_separator='.db_input($vars['reply_separator'])
-            .' WHERE id='.db_input($this->getId());
-
-
-
-        return (db_query($sql));
-    }
-
-    function updateAttachmentsSetting($vars,&$errors) {
-
-
-        if($vars['allow_attachments']) {
-
-            if(!ini_get('file_uploads'))
-                $errors['err']='The \'file_uploads\' directive is disabled in php.ini';
-
-            if(!is_numeric($vars['max_file_size']))
-                $errors['max_file_size']='Maximum file size required';
-
-            if(!$vars['allowed_filetypes'])
-                $errors['allowed_filetypes']='Allowed file extentions required';
-
-            if(!($maxfileuploads=ini_get('max_file_uploads')))
-                $maxfileuploads=DEFAULT_MAX_FILE_UPLOADS;
-
-            if(!$vars['max_user_file_uploads'] || $vars['max_user_file_uploads']>$maxfileuploads)
-                $errors['max_user_file_uploads']='Invalid selection. Must be less than '.$maxfileuploads;
-
-            if(!$vars['max_staff_file_uploads'] || $vars['max_staff_file_uploads']>$maxfileuploads)
-                $errors['max_staff_file_uploads']='Invalid selection. Must be less than '.$maxfileuploads;
-        }
-
-        if($errors) return false;
-
-        $sql= 'UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-             .',allow_attachments='.db_input(isset($vars['allow_attachments'])?1:0)
-             .',allowed_filetypes='.db_input(strtolower(preg_replace("/\n\r|\r\n|\n|\r/", '',trim($vars['allowed_filetypes']))))
-             .',max_file_size='.db_input($vars['max_file_size'])
-             .',max_user_file_uploads='.db_input($vars['max_user_file_uploads'])
-             .',max_staff_file_uploads='.db_input($vars['max_staff_file_uploads'])
-             .',email_attachments='.db_input(isset($vars['email_attachments'])?1:0)
-             .',allow_email_attachments='.db_input(isset($vars['allow_email_attachments'])?1:0)
-             .',allow_online_attachments='.db_input(isset($vars['allow_online_attachments'])?1:0)
-             .',allow_online_attachments_onlogin='.db_input(isset($vars['allow_online_attachments_onlogin'])?1:0)
-             .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
+        return $this->updateAll(array(
+            'default_email_id'=>$vars['default_email_id'],
+            'alert_email_id'=>$vars['alert_email_id'],
+            'default_smtp_id'=>$vars['default_smtp_id'],
+            'admin_email'=>$vars['admin_email'],
+            'enable_auto_cron'=>isset($vars['enable_auto_cron'])?1:0,
+            'enable_mail_polling'=>isset($vars['enable_mail_polling'])?1:0,
+            'strip_quoted_reply'=>isset($vars['strip_quoted_reply'])?1:0,
+            'reply_separator'=>$vars['reply_separator'],
+         ));
     }
 
     function updateAutoresponderSettings($vars, &$errors) {
 
         if($errors) return false;
 
-        $sql ='UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-             .',ticket_autoresponder='.db_input($vars['ticket_autoresponder'])
-             .',message_autoresponder='.db_input($vars['message_autoresponder'])
-             .',ticket_notice_active='.db_input($vars['ticket_notice_active'])
-             .',overlimit_notice_active='.db_input($vars['overlimit_notice_active'])
-             .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
+        return $this->updateAll(array(
+            'ticket_autoresponder'=>$vars['ticket_autoresponder'],
+            'message_autoresponder'=>$vars['message_autoresponder'],
+            'ticket_notice_active'=>$vars['ticket_notice_active'],
+            'overlimit_notice_active'=>$vars['overlimit_notice_active'],
+        ));
     }
 
 
@@ -794,12 +821,10 @@ class Config {
 
         if($errors) return false;
 
-        $sql = 'UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-              .',enable_kb='.db_input(isset($vars['enable_kb'])?1:0)
-              .',enable_premade='.db_input(isset($vars['enable_premade'])?1:0)
-              .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
+        return $this->updateAll(array(
+            'enable_kb'=>isset($vars['enable_kb'])?1:0,
+               'enable_premade'=>isset($vars['enable_premade'])?1:0,
+        ));
     }
 
 
@@ -849,43 +874,42 @@ class Config {
 
         if($errors) return false;
 
-        $sql= 'UPDATE '.CONFIG_TABLE.' SET updated=NOW() '
-             .',ticket_alert_active='.db_input($vars['ticket_alert_active'])
-             .',ticket_alert_admin='.db_input(isset($vars['ticket_alert_admin'])?1:0)
-             .',ticket_alert_dept_manager='.db_input(isset($vars['ticket_alert_dept_manager'])?1:0)
-             .',ticket_alert_dept_members='.db_input(isset($vars['ticket_alert_dept_members'])?1:0)
-             .',message_alert_active='.db_input($vars['message_alert_active'])
-             .',message_alert_laststaff='.db_input(isset($vars['message_alert_laststaff'])?1:0)
-             .',message_alert_assigned='.db_input(isset($vars['message_alert_assigned'])?1:0)
-             .',message_alert_dept_manager='.db_input(isset($vars['message_alert_dept_manager'])?1:0)
-             .',note_alert_active='.db_input($vars['note_alert_active'])
-             .',note_alert_laststaff='.db_input(isset($vars['note_alert_laststaff'])?1:0)
-             .',note_alert_assigned='.db_input(isset($vars['note_alert_assigned'])?1:0)
-             .',note_alert_dept_manager='.db_input(isset($vars['note_alert_dept_manager'])?1:0)
-             .',assigned_alert_active='.db_input($vars['assigned_alert_active'])
-             .',assigned_alert_staff='.db_input(isset($vars['assigned_alert_staff'])?1:0)
-             .',assigned_alert_team_lead='.db_input(isset($vars['assigned_alert_team_lead'])?1:0)
-             .',assigned_alert_team_members='.db_input(isset($vars['assigned_alert_team_members'])?1:0)
-             .',transfer_alert_active='.db_input($vars['transfer_alert_active'])
-             .',transfer_alert_assigned='.db_input(isset($vars['transfer_alert_assigned'])?1:0)
-             .',transfer_alert_dept_manager='.db_input(isset($vars['transfer_alert_dept_manager'])?1:0)
-             .',transfer_alert_dept_members='.db_input(isset($vars['transfer_alert_dept_members'])?1:0)
-             .',overdue_alert_active='.db_input($vars['overdue_alert_active'])
-             .',overdue_alert_assigned='.db_input(isset($vars['overdue_alert_assigned'])?1:0)
-             .',overdue_alert_dept_manager='.db_input(isset($vars['overdue_alert_dept_manager'])?1:0)
-             .',overdue_alert_dept_members='.db_input(isset($vars['overdue_alert_dept_members'])?1:0)
-             .',send_sys_errors='.db_input(isset($vars['send_sys_errors'])?1:0)
-             .',send_sql_errors='.db_input(isset($vars['send_sql_errors'])?1:0)
-             .',send_login_errors='.db_input(isset($vars['send_login_errors'])?1:0)
-             .' WHERE id='.db_input($this->getId());
-
-        return (db_query($sql));
-
-    }
-
-    /** static **/
-    function lookup($id) {
-        return ($id && ($cfg = new Config($id)) && $cfg->getId()==$id)?$cfg:null;
+        return $this->updateAll(array(
+            'ticket_alert_active'=>$vars['ticket_alert_active'],
+            'ticket_alert_admin'=>isset($vars['ticket_alert_admin'])?1:0,
+            'ticket_alert_dept_manager'=>isset($vars['ticket_alert_dept_manager'])?1:0,
+            'ticket_alert_dept_members'=>isset($vars['ticket_alert_dept_members'])?1:0,
+            'message_alert_active'=>$vars['message_alert_active'],
+            'message_alert_laststaff'=>isset($vars['message_alert_laststaff'])?1:0,
+            'message_alert_assigned'=>isset($vars['message_alert_assigned'])?1:0,
+            'message_alert_dept_manager'=>isset($vars['message_alert_dept_manager'])?1:0,
+            'note_alert_active'=>$vars['note_alert_active'],
+            'note_alert_laststaff'=>isset($vars['note_alert_laststaff'])?1:0,
+            'note_alert_assigned'=>isset($vars['note_alert_assigned'])?1:0,
+            'note_alert_dept_manager'=>isset($vars['note_alert_dept_manager'])?1:0,
+            'assigned_alert_active'=>$vars['assigned_alert_active'],
+            'assigned_alert_staff'=>isset($vars['assigned_alert_staff'])?1:0,
+            'assigned_alert_team_lead'=>isset($vars['assigned_alert_team_lead'])?1:0,
+            'assigned_alert_team_members'=>isset($vars['assigned_alert_team_members'])?1:0,
+            'transfer_alert_active'=>$vars['transfer_alert_active'],
+            'transfer_alert_assigned'=>isset($vars['transfer_alert_assigned'])?1:0,
+            'transfer_alert_dept_manager'=>isset($vars['transfer_alert_dept_manager'])?1:0,
+            'transfer_alert_dept_members'=>isset($vars['transfer_alert_dept_members'])?1:0,
+            'overdue_alert_active'=>$vars['overdue_alert_active'],
+            'overdue_alert_assigned'=>isset($vars['overdue_alert_assigned'])?1:0,
+            'overdue_alert_dept_manager'=>isset($vars['overdue_alert_dept_manager'])?1:0,
+            'overdue_alert_dept_members'=>isset($vars['overdue_alert_dept_members'])?1:0,
+            'send_sys_errors'=>isset($vars['send_sys_errors'])?1:0,
+            'send_sql_errors'=>isset($vars['send_sql_errors'])?1:0,
+            'send_login_errors'=>isset($vars['send_login_errors'])?1:0,
+        ));
+    }
+
+    //Used to detect version prior to 1.7 (useful during upgrade)
+    /* static */ function getDBVersion() {
+        $sql='SELECT `ostversion` FROM '.TABLE_PREFIX.'config '
+            .'WHERE id=1';
+        return db_result(db_query($sql));
     }
 }
 ?>
diff --git a/include/class.migrater.php b/include/class.migrater.php
index 93854d797d72c150f71dc13a30831509ee9665c7..ba26d091e31defa230ab4da3f7420d3e044dbaf2 100644
--- a/include/class.migrater.php
+++ b/include/class.migrater.php
@@ -212,7 +212,7 @@ class AttachmentMigrater {
         if(!($res=db_query($sql)))
             return $this->error('Unable to query DB for attached files to migrate!');
 
-        $ost->logDebug('Found '.db_num_rows($res).' attachments to migrate');
+        $ost->logDebug("Attachment migration", 'Found '.db_num_rows($res).' attachments to migrate');
         if(!db_num_rows($res))
             return 0;  //Nothing else to do!!
 
diff --git a/include/class.osticket.php b/include/class.osticket.php
index 9dd1df016f1b9727d388ed57f837a4f92c47f72f..1a1945218d05ba79ba906d41ddaf8eb4ce942b2a 100644
--- a/include/class.osticket.php
+++ b/include/class.osticket.php
@@ -46,15 +46,11 @@ class osTicket {
     var $session;
     var $csrf;
 
-    function osTicket($cfgId) {
+    function osTicket() {
 
-        $this->config = Config::lookup($cfgId);
+        $this->session = osTicketSession::start(SESSION_TTL); // start DB based session
 
-        //DB based session storage was added starting with v1.7
-        if($this->config && !$this->getConfig()->getDBVersion())
-            $this->session = osTicketSession::start(SESSION_TTL); // start DB based session
-        else
-            session_start();
+        $this->config = new OsticketConfig();
 
         $this->csrf = new CSRF('__CSRFToken__');
     }
@@ -64,7 +60,8 @@ class osTicket {
     }
 
     function isUpgradePending() {
-        return (defined('SCHEMA_SIGNATURE') && strcasecmp($this->getDBSignature(), SCHEMA_SIGNATURE));
+        return strcasecmp(SCHEMA_SIGNATURE,
+                $this->getConfig()->getSchemaSignature());
     }
 
     function getSession() {
@@ -75,11 +72,6 @@ class osTicket {
         return $this->config;
     }
 
-    function getConfigId() {
-
-        return $this->getConfig()?$this->getConfig()->getId():0;
-    }
-
     function getDBSignature() {
         return $this->getConfig()->getSchemaSignature();
     }
@@ -237,7 +229,7 @@ class osTicket {
         if($email) {
             $email->sendAlert($to, $subject, $message);
         } else {//no luck - try the system mail.
-            Email::sendmail($to, $subject, $message, sprintf('"osTicket Alerts"<%s>',$to));
+            Mailer::sendmail($to, $subject, $message, sprintf('"osTicket Alerts"<%s>',$to));
         }
 
         //log the alert? Watch out for loops here.
@@ -364,9 +356,9 @@ class osTicket {
     }
 
     /**** static functions ****/
-    function start($configId) {
+    function start() {
 
-        if(!$configId || !($ost = new osTicket($configId)) || $ost->getConfigId()!=$configId)
+        if(!($ost = new osTicket()))
             return null;
 
         //Set default time zone... user/staff settting will overwrite it (on login).
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index bb35fe23043e7106259b50d1186dadeb2674b0ec..f2be6b18b5ea2ffe9c94beda2cfd896e699e91f4 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -17,6 +17,8 @@
 class osTicketSession {
 
     var $ttl = SESSION_TTL;
+    var $data = '';
+    var $id = '';
 
     function osTicketSession($ttl=0){
 
@@ -24,50 +26,55 @@ class osTicketSession {
         if(!$this->ttl)
             $this->ttl=SESSION_TTL;
 
-        //Set handlers.
-        session_set_save_handler(
-            array(&$this, 'open'),
-            array(&$this, 'close'),
-            array(&$this, 'read'),
-            array(&$this, 'write'),
-            array(&$this, 'destroy'),
-            array(&$this, 'gc')
-        );
-        //Forced cleanup.
-        register_shutdown_function('session_write_close');
+        if (!OsticketConfig::getDBVersion()) {
+            //Set handlers.
+            session_set_save_handler(
+                array(&$this, 'open'),
+                array(&$this, 'close'),
+                array(&$this, 'read'),
+                array(&$this, 'write'),
+                array(&$this, 'destroy'),
+                array(&$this, 'gc')
+            );
+            //Forced cleanup.
+            register_shutdown_function('session_write_close');
+        }
         //Start the session.
         session_start();
     }
- 
+
     function regenerate_id(){
         $oldId = session_id();
         session_regenerate_id();
         $this->destroy($oldId);
     }
- 
+
     function open($save_path, $session_name){
         return (true);
     }
- 
+
     function close(){
         return (true);
     }
- 
+
     function read($id){
-        $data="";
-        $sql='SELECT session_data FROM '.SESSION_TABLE
-            .' WHERE session_id='.db_input($id)
-            .'  AND session_expire>NOW()';
-        if(($res=db_query($sql)) && db_num_rows($res))
-            list($data)=db_fetch_row($res);
-
-        return $data;
+        if (!$this->data || $this->id != $id) {
+            $sql='SELECT session_data FROM '.SESSION_TABLE
+                .' WHERE session_id='.db_input($id)
+                .'  AND session_expire>NOW()';
+            if(!($res=db_query($sql)))
+                return false;
+            elseif (db_num_rows($res))
+                list($this->data)=db_fetch_row($res);
+            $this->id = $id;
+        }
+        return $this->data;
     }
 
     function write($id, $data){
         global $thisstaff;
 
-        $ttl = ($this && get_class($this) == 'osTicketSession') 
+        $ttl = ($this && get_class($this) == 'osTicketSession')
             ? $this->getTTL() : SESSION_TTL;
 
         $sql='REPLACE INTO '.SESSION_TABLE.' SET session_updated=NOW() '.
@@ -78,6 +85,7 @@ class osTicketSession {
              ',user_ip='.db_input($_SERVER['REMOTE_ADDR']).
              ',user_agent='.db_input($_SERVER['HTTP_USER_AGENT']);
 
+        $this->data = '';
         return (db_query($sql) && db_affected_rows());
     }
 
@@ -85,7 +93,7 @@ class osTicketSession {
         $sql='DELETE FROM '.SESSION_TABLE.' WHERE session_id='.db_input($id);
         return (db_query($sql) && db_affected_rows());
     }
-    
+
     function gc($maxlife){
         $sql='DELETE FROM '.SESSION_TABLE.' WHERE session_expire<NOW()';
         db_query($sql);
diff --git a/include/class.template.php b/include/class.template.php
index 629f76f2991243f7dea20224e83bdc00cae369cb..0ed98ca6473f4167a25bba4f5e64cbd07c5d39f7 100644
--- a/include/class.template.php
+++ b/include/class.template.php
@@ -374,7 +374,6 @@ class Template {
 
             $sql='INSERT INTO '.EMAIL_TEMPLATE_TABLE.' SET '.$sql
                 .' ,created=NOW() '
-                .' ,cfg_id='.db_input($ost->getConfigId())
                 .' ,ticket_autoresp_subj='.db_input($info['ticket_autoresp_subj'])
                 .' ,ticket_autoresp_body='.db_input($info['ticket_autoresp_body'])
                 .' ,ticket_autoreply_subj='.db_input($info['ticket_autoreply_subj'])
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 60d26d7eb31ba73f5b176a47168314d4bf166f6f..327560c551579d232ada7f16a1a833d2d0f9cc64 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1741,7 +1741,7 @@ class Ticket {
         global $cfg;
 
         /* Unknown or invalid staff */
-        if(!$staff || (!is_object($staff) && !($staff=Staff::lookup($staff))) || !$staff->isStaff() || $cfg->getDBVersion())
+        if(!$staff || (!is_object($staff) && !($staff=Staff::lookup($staff))) || !$staff->isStaff())
             return null;
 
         $sql='SELECT count(open.ticket_id) as open, count(answered.ticket_id) as answered '
diff --git a/include/class.upgrader.php b/include/class.upgrader.php
index 8b86b9e5724f07ea3fbb4bf3132a554e79ca7586..8f6fea22342aacb2c2a23da4547f7c9d935a7e47 100644
--- a/include/class.upgrader.php
+++ b/include/class.upgrader.php
@@ -148,10 +148,11 @@ class Upgrader extends SetupWizard {
 
     function readPatchInfo($patch) {
         $info = array();
-        if (preg_match('/\*(.*)\*/', file_get_contents($patch), $matches)) {
-            if (preg_match('/@([\w\d_-]+)\s+(.*)$/', $matches[0], $matches2))
+        if (preg_match(':/\*\*(.*)\*/:s', file_get_contents($patch), $matches)) {
+            if (preg_match_all('/@([\w\d_-]+)\s+(.*)$/m', $matches[0],
+                        $matches2, PREG_SET_ORDER))
                 foreach ($matches2 as $match)
-                    $info[$match[0]] = $match[1];
+                    $info[$match[1]] = $match[2];
         }
         if (!isset($info['version']))
             $info['version'] = substr(basename($patch), 9, 8);
@@ -249,7 +250,8 @@ class Upgrader extends SetupWizard {
         if(!($max_time = ini_get('max_execution_time')))
             $max_time = 300; //Apache/IIS defaults.
 
-        foreach ($patches as $patch) {
+        // Apply up to five patches at a time
+        foreach (array_slice($patches, 0, 5) as $patch) {
             //TODO: check time used vs. max execution - break if need be
             if (!$this->load_sql_file($patch, $this->getTablePrefix()))
                 return false;
diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php
index 3fba7f15977390d6882f00894523b90d92d4aced..1576ca1f9ab0f51f4ef60b120a1d7ec046f879dc 100644
--- a/include/staff/settings-system.inc.php
+++ b/include/staff/settings-system.inc.php
@@ -11,7 +11,7 @@ $gmtime = Misc::gmtime();
     <thead>
         <tr>
             <th colspan="2">
-                <h4>System Settings & Preferences</h4>
+                <h4>System Settings &amp; Preferences</h4>
                 <em><b>General Settings</b>: Offline mode will disable client interface and only allow admins to login to Staff Control Panel</em>
             </th>
         </tr>
@@ -60,7 +60,7 @@ $gmtime = Misc::gmtime();
                 <select name="default_template_id">
                     <option value="">&mdash; Select Default Template &mdash;</option>
                     <?php
-                    $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' WHERE isactive=1 AND cfg_id='.db_input($cfg->getId()).' ORDER BY name';
+                    $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' WHERE isactive=1 ORDER BY name';
                     if(($res=db_query($sql)) && db_num_rows($res)){
                         while (list($id, $name) = db_fetch_row($res)){
                             $selected = ($config['default_template_id']==$id)?'selected="selected"':''; ?>
diff --git a/include/upgrader/sql/32de1766-852ca89e.patch.sql b/include/upgrader/sql/32de1766-852ca89e.patch.sql
new file mode 100644
index 0000000000000000000000000000000000000000..ba1768fa33fa041703b22cd3257be91eb886fc45
--- /dev/null
+++ b/include/upgrader/sql/32de1766-852ca89e.patch.sql
@@ -0,0 +1,123 @@
+/**
+ * @version v1.7.1
+ * @signature 852ca89e1440e736d763b3b87f039bd7
+ *
+ *  - Changes config table to be key/value based and allows for
+ *    configuration key clobbering by defining a namespace for the keys. The
+ *    current configuration settings are stored in the 'core' namespace
+ */
+
+DROP TABLE IF EXISTS `%TABLE_PREFIX%_config`;
+CREATE TABLE `%TABLE_PREFIX%_config` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `namespace` varchar(64) NOT NULL,
+  `key` varchar(64) NOT NULL,
+  `value` text NOT NULL,
+  `updated` timestamp NOT NULL default CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY (`namespace`, `key`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO `%TABLE_PREFIX%_config` (`key`, `value`, `namespace`) VALUES
+  ('isonline', (SELECT `isonline` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_daylight_saving', (SELECT `enable_daylight_saving` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('staff_ip_binding', (SELECT `staff_ip_binding` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('staff_max_logins', (SELECT `staff_max_logins` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('staff_login_timeout', (SELECT `staff_login_timeout` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('staff_session_timeout', (SELECT `staff_session_timeout` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('passwd_reset_period', (SELECT `passwd_reset_period` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('client_max_logins', (SELECT `client_max_logins` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('client_login_timeout', (SELECT `client_login_timeout` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('client_session_timeout', (SELECT `client_session_timeout` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('max_page_size', (SELECT `max_page_size` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('max_open_tickets', (SELECT `max_open_tickets` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('max_file_size', (SELECT `max_file_size` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('max_user_file_uploads', (SELECT `max_user_file_uploads` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('max_staff_file_uploads', (SELECT `max_staff_file_uploads` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('autolock_minutes', (SELECT `autolock_minutes` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overdue_grace_period', (SELECT `overdue_grace_period` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('alert_email_id', (SELECT `alert_email_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_email_id', (SELECT `default_email_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_dept_id', (SELECT `default_dept_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_sla_id', (SELECT `default_sla_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_priority_id', (SELECT `default_priority_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_template_id', (SELECT `default_template_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_timezone_id', (SELECT `default_timezone_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('default_smtp_id', (SELECT `default_smtp_id` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_email_spoofing', (SELECT `allow_email_spoofing` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('clickable_urls', (SELECT `clickable_urls` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_priority_change', (SELECT `allow_priority_change` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('use_email_priority', (SELECT `use_email_priority` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_kb', (SELECT `enable_kb` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_premade', (SELECT `enable_premade` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_captcha', (SELECT `enable_captcha` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_auto_cron', (SELECT `enable_auto_cron` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('enable_mail_polling', (SELECT `enable_mail_polling` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('send_sys_errors', (SELECT `send_sys_errors` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('send_sql_errors', (SELECT `send_sql_errors` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('send_mailparse_errors', (SELECT `send_mailparse_errors` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('send_login_errors', (SELECT `send_login_errors` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('save_email_headers', (SELECT `save_email_headers` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('strip_quoted_reply', (SELECT `strip_quoted_reply` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('log_ticket_activity', (SELECT `log_ticket_activity` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_autoresponder', (SELECT `ticket_autoresponder` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('message_autoresponder', (SELECT `message_autoresponder` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_notice_active', (SELECT `ticket_notice_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_alert_active', (SELECT `ticket_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_alert_admin', (SELECT `ticket_alert_admin` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_alert_dept_manager', (SELECT `ticket_alert_dept_manager` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('ticket_alert_dept_members', (SELECT `ticket_alert_dept_members` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('message_alert_active', (SELECT `message_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('message_alert_laststaff', (SELECT `message_alert_laststaff` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('message_alert_assigned', (SELECT `message_alert_assigned` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('message_alert_dept_manager', (SELECT `message_alert_dept_manager` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('note_alert_active', (SELECT `note_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('note_alert_laststaff', (SELECT `note_alert_laststaff` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('note_alert_assigned', (SELECT `note_alert_assigned` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('note_alert_dept_manager', (SELECT `note_alert_dept_manager` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('transfer_alert_active', (SELECT `transfer_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('transfer_alert_assigned', (SELECT `transfer_alert_assigned` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('transfer_alert_dept_manager', (SELECT `transfer_alert_dept_manager` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('transfer_alert_dept_members', (SELECT `transfer_alert_dept_members` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overdue_alert_active', (SELECT `overdue_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overdue_alert_assigned', (SELECT `overdue_alert_assigned` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overdue_alert_dept_manager', (SELECT `overdue_alert_dept_manager` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overdue_alert_dept_members', (SELECT `overdue_alert_dept_members` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('assigned_alert_active', (SELECT `assigned_alert_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('assigned_alert_staff', (SELECT `assigned_alert_staff` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('assigned_alert_team_lead', (SELECT `assigned_alert_team_lead` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('assigned_alert_team_members', (SELECT `assigned_alert_team_members` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('auto_assign_reopened_tickets', (SELECT `auto_assign_reopened_tickets` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('show_related_tickets', (SELECT `show_related_tickets` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('show_assigned_tickets', (SELECT `show_assigned_tickets` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('show_answered_tickets', (SELECT `show_answered_tickets` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('show_notes_inline', (SELECT `show_notes_inline` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('hide_staff_name', (SELECT `hide_staff_name` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('overlimit_notice_active', (SELECT `overlimit_notice_active` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('email_attachments', (SELECT `email_attachments` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_attachments', (SELECT `allow_attachments` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_email_attachments', (SELECT `allow_email_attachments` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_online_attachments', (SELECT `allow_online_attachments` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allow_online_attachments_onlogin', (SELECT `allow_online_attachments_onlogin` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('random_ticket_ids', (SELECT `random_ticket_ids` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('log_level', (SELECT `log_level` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('log_graceperiod', (SELECT `log_graceperiod` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('upload_dir', (SELECT `upload_dir` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('allowed_filetypes', (SELECT `allowed_filetypes` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('time_format', (SELECT `time_format` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('date_format', (SELECT `date_format` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('datetime_format', (SELECT `datetime_format` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('daydatetime_format', (SELECT `daydatetime_format` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('reply_separator', (SELECT `reply_separator` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('admin_email', (SELECT `admin_email` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('helpdesk_title', (SELECT `helpdesk_title` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('helpdesk_url', (SELECT `helpdesk_url` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core')
+, ('schema_signature', (SELECT `schema_signature` FROM `%TABLE_PREFIX%config` WHERE `id` = 1), 'core');
+
+DROP TABLE `%TABLE_PREFIX%config`;
+ALTER TABLE `%TABLE_PREFIX%_config` RENAME TO `%TABLE_PREFIX%config`;
+
+-- Finished with patch
+UPDATE `%TABLE_PREFIX%config`
+    SET `value` = '852ca89e1440e736d763b3b87f039bd7'
+	WHERE `key` = 'schema_signature' AND `namespace` = 'core';
diff --git a/main.inc.php b/main.inc.php
index f45b074d89c226a6521e461558f1ff2fd009cbbc..69ec71bde3045b4f22d0c7ffef5d93f01621f742 100644
--- a/main.inc.php
+++ b/main.inc.php
@@ -76,7 +76,7 @@
 
     #Current version && schema signature (Changes from version to version)
     define('THIS_VERSION','1.7.0+'); //Shown on admin panel
-    define('SCHEMA_SIGNATURE', '32de1766d56e43215041fa982dcb465e'); //MD5 signature of the db schema. (used to trigger upgrades)
+    define('SCHEMA_SIGNATURE', '852ca89e1440e736d763b3b87f039bd7'); //MD5 signature of the db schema. (used to trigger upgrades)
     #load config info
     $configfile='';
     if(file_exists(ROOT_DIR.'ostconfig.php')) //Old installs prior to v 1.6 RC5
@@ -205,7 +205,7 @@
         $ferror='Unable to connect to the database -'.db_connect_error();
     }elseif(!db_select_database(DBNAME)) {
         $ferror='Unknown or invalid database '.DBNAME;
-    } elseif(!($ost=osTicket::start(1)) || !($cfg = $ost->getConfig())) {
+    } elseif(!($ost=osTicket::start()) || !($cfg = $ost->getConfig())) {
         $ferror='Unable to load config info from DB. Get tech support.';
     }
 
diff --git a/scp/settings.php b/scp/settings.php
index 845659408fba46dbc6c4319da7fe6098d8940311..2b30ced16a154a9a6976206045a801f2ae5efe68 100644
--- a/scp/settings.php
+++ b/scp/settings.php
@@ -3,7 +3,7 @@
     settings.php
 
     Handles all admin settings.
-    
+
     Peter Rotich <peter@osticket.com>
     Copyright (c)  2006-2013 osTicket
     http://www.osticket.com
@@ -26,7 +26,6 @@ $settingOptions=array(
 if($_POST && !$errors) {
     if($cfg && $cfg->updateSettings($_POST,$errors)) {
         $msg=Format::htmlchars($settingOptions[$_POST['t']]).' Updated Successfully';
-        $cfg->reload();
     } elseif(!$errors['err']) {
         $errors['err']='Unable to update settings - correct errors below and try again';
     }
diff --git a/setup/inc/class.installer.php b/setup/inc/class.installer.php
index 79591febcb28cce57da3ec7f95102ba6c89fe04a..8bc22a311e84b4d7f4f6c40accc97acd8c726cc0 100644
--- a/setup/inc/class.installer.php
+++ b/setup/inc/class.installer.php
@@ -169,17 +169,19 @@ class Installer extends SetupWizard {
 
             //Create config settings---default settings!
             //XXX: rename ostversion  helpdesk_* ??
-            $sql='INSERT INTO '.PREFIX.'config SET updated=NOW(), isonline=0 '
-                .", default_email_id=$support_email_id, alert_email_id=$alert_email_id"
-                .", default_dept_id=$dept_id_1"
-                .", default_sla_id=$sla_id_1, default_timezone_id=$eastern_timezone"
-                .", default_template_id=$template_id_1 "
-                .', admin_email='.db_input($vars['admin_email'])
-                .', schema_signature='.db_input($signature)
-                .', helpdesk_url='.db_input(URL)
-                .', helpdesk_title='.db_input($vars['name']);
-            if(!db_query($sql, false) || !($cid=db_insert_id()))
-                $this->errors['err']='Unable to create config settings (#7)';
+			$defaults = array('isonline'=>'0', 'default_email_id'=>$support_email_id,
+				'alert_email_id'=>$alert_email_id, 'default_dept_id'=>$dept_id_1, 'default_sla_id'=>$sla_id_1,
+				'default_timezone_id'=>$eastern_timezone, 'default_template_id'=>$template_id_1,
+				'admin_email'=>db_input($vars['admin_email']),
+				'schema_signature'=>db_input($signature),
+				'helpdesk_url'=>db_input(URL),
+				'helpdesk_title'=>db_input($vars['name']));
+			foreach ($defaults as $key=>$value) {
+				$sql='UPDATE '.PREFIX.'config SET updated=NOW(), value='.$value
+					.' WHERE namespace="core" AND `key`='.db_input($key);
+	            if(!db_query($sql, false))
+	                $this->errors['err']='Unable to create config settings (#7)';
+			}
         }
 
         if($this->errors) return false; //Abort on internal errors.
diff --git a/setup/inc/sql/osTicket-mysql.sql b/setup/inc/sql/osTicket-mysql.sql
index d65bf4f8570e6813b7cef16653984cf02b9ad6be..6ad1a1810f2248ac2c840a10c50e313c541e896b 100644
--- a/setup/inc/sql/osTicket-mysql.sql
+++ b/setup/inc/sql/osTicket-mysql.sql
@@ -59,111 +59,6 @@ CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%faq_topic` (
   PRIMARY KEY  (`faq_id`,`topic_id`)
 ) DEFAULT CHARSET=utf8;
 
-DROP TABLE IF EXISTS `%TABLE_PREFIX%config`;
-CREATE TABLE `%TABLE_PREFIX%config` (
-  `id` tinyint(1) unsigned NOT NULL auto_increment,
-  `isonline` tinyint(1) unsigned NOT NULL default '0',
-  `timezone_offset` float(3,1) NOT NULL default '0.0',
-  `enable_daylight_saving` tinyint(1) unsigned NOT NULL default '0',
-  `staff_ip_binding` tinyint(1) unsigned NOT NULL default '1',
-  `staff_max_logins` tinyint(3) unsigned NOT NULL default '4',
-  `staff_login_timeout` int(10) unsigned NOT NULL default '2',
-  `staff_session_timeout` int(10) unsigned NOT NULL default '30',
-  `passwd_reset_period` int(10) unsigned NOT NULL default '0',
-  `client_max_logins` tinyint(3) unsigned NOT NULL default '4',
-  `client_login_timeout` int(10) unsigned NOT NULL default '2',
-  `client_session_timeout` int(10) unsigned NOT NULL default '30',
-  `max_page_size` tinyint(3) unsigned NOT NULL default '25',
-  `max_open_tickets` tinyint(3) unsigned NOT NULL default '0',
-  `max_file_size` int(11) unsigned NOT NULL default '1048576',
-  `max_user_file_uploads` tinyint(3) unsigned NOT NULL,
-  `max_staff_file_uploads` tinyint(3) unsigned NOT NULL,
-  `autolock_minutes` tinyint(3) unsigned NOT NULL default '3',
-  `overdue_grace_period` int(10) unsigned NOT NULL default '0',
-  `alert_email_id` tinyint(4) unsigned NOT NULL default '0',
-  `default_email_id` tinyint(4) unsigned NOT NULL default '0',
-  `default_dept_id` tinyint(3) unsigned NOT NULL default '0',
-  `default_sla_id` int(10) unsigned NOT NULL default '0',
-  `default_priority_id` tinyint(2) unsigned NOT NULL default '2',
-  `default_template_id` tinyint(4) unsigned NOT NULL default '1',
-  `default_timezone_id` int(10) unsigned NOT NULL default '0',
-  `default_smtp_id` tinyint(4) unsigned NOT NULL default '0',
-  `allow_email_spoofing` tinyint(1) unsigned NOT NULL default '0',
-  `clickable_urls` tinyint(1) unsigned NOT NULL default '1',
-  `allow_priority_change` tinyint(1) unsigned NOT NULL default '0',
-  `use_email_priority` tinyint(1) unsigned NOT NULL default '0',
-  `enable_kb` tinyint(1) unsigned NOT NULL default '0',
-  `enable_premade` tinyint(1) unsigned NOT NULL default '1',
-  `enable_captcha` tinyint(1) unsigned NOT NULL default '0',
-  `enable_auto_cron` tinyint(1) unsigned NOT NULL default '0',
-  `enable_mail_polling` tinyint(1) unsigned NOT NULL default '0',
-  `send_sys_errors` tinyint(1) unsigned NOT NULL default '1',
-  `send_sql_errors` tinyint(1) unsigned NOT NULL default '1',
-  `send_mailparse_errors` tinyint(1) unsigned NOT NULL default '1',
-  `send_login_errors` tinyint(1) unsigned NOT NULL default '1',
-  `save_email_headers` tinyint(1) unsigned NOT NULL default '1',
-  `strip_quoted_reply` tinyint(1) unsigned NOT NULL default '1',
-  `log_ticket_activity` tinyint(1) unsigned NOT NULL default '1',
-  `ticket_autoresponder` tinyint(1) unsigned NOT NULL default '0',
-  `message_autoresponder` tinyint(1) unsigned NOT NULL default '0',
-  `ticket_notice_active` tinyint(1) unsigned NOT NULL default '0',
-  `ticket_alert_active` tinyint(1) unsigned NOT NULL default '0',
-  `ticket_alert_admin` tinyint(1) unsigned NOT NULL default '1',
-  `ticket_alert_dept_manager` tinyint(1) unsigned NOT NULL default '1',
-  `ticket_alert_dept_members` tinyint(1) unsigned NOT NULL default '0',
-  `message_alert_active` tinyint(1) unsigned NOT NULL default '0',
-  `message_alert_laststaff` tinyint(1) unsigned NOT NULL default '1',
-  `message_alert_assigned` tinyint(1) unsigned NOT NULL default '1',
-  `message_alert_dept_manager` tinyint(1) unsigned NOT NULL default '0',
-  `note_alert_active` tinyint(1) unsigned NOT NULL default '0',
-  `note_alert_laststaff` tinyint(1) unsigned NOT NULL default '1',
-  `note_alert_assigned` tinyint(1) unsigned NOT NULL default '1',
-  `note_alert_dept_manager` tinyint(1) unsigned NOT NULL default '0',
-  `transfer_alert_active` tinyint(1) unsigned NOT NULL default '0',
-  `transfer_alert_assigned` tinyint(1) unsigned NOT NULL default '0',
-  `transfer_alert_dept_manager` tinyint(1) unsigned NOT NULL default '1',
-  `transfer_alert_dept_members` tinyint(1) unsigned NOT NULL default '0',
-  `overdue_alert_active` tinyint(1) unsigned NOT NULL default '0',
-  `overdue_alert_assigned` tinyint(1) unsigned NOT NULL default '1',
-  `overdue_alert_dept_manager` tinyint(1) unsigned NOT NULL default '1',
-  `overdue_alert_dept_members` tinyint(1) unsigned NOT NULL default '0',
-  `assigned_alert_active` tinyint(1) unsigned NOT NULL default '1',
-  `assigned_alert_staff` tinyint(1) unsigned NOT NULL default '1',
-  `assigned_alert_team_lead` tinyint(1) unsigned NOT NULL default '0',
-  `assigned_alert_team_members` tinyint(1) unsigned NOT NULL default '0',
-  `auto_assign_reopened_tickets` tinyint(1) unsigned NOT NULL default '1',
-  `show_related_tickets` tinyint(1) unsigned NOT NULL default '1',
-  `show_assigned_tickets` tinyint(1) unsigned NOT NULL default '1',
-  `show_answered_tickets` tinyint(1) unsigned NOT NULL default '0',
-  `show_notes_inline` tinyint(1) unsigned NOT NULL default '1',
-  `hide_staff_name` tinyint(1) unsigned NOT NULL default '0',
-  `overlimit_notice_active` tinyint(1) unsigned NOT NULL default '0',
-  `email_attachments` tinyint(1) unsigned NOT NULL default '1',
-  `allow_attachments` tinyint(1) unsigned NOT NULL default '0',
-  `allow_email_attachments` tinyint(1) unsigned NOT NULL default '0',
-  `allow_online_attachments` tinyint(1) unsigned NOT NULL default '0',
-  `allow_online_attachments_onlogin` tinyint(1) unsigned NOT NULL default
-  '0',
-  `random_ticket_ids` tinyint(1) unsigned NOT NULL default '1',
-  `log_level` tinyint(1) unsigned NOT NULL default '2',
-  `log_graceperiod` int(10) unsigned NOT NULL default '12',
-  `upload_dir` varchar(255) NOT NULL default '',
-  `allowed_filetypes` varchar(255) NOT NULL default '.doc, .pdf',
-  `time_format` varchar(32) NOT NULL default ' h:i A',
-  `date_format` varchar(32) NOT NULL default 'm/d/Y',
-  `datetime_format` varchar(60) NOT NULL default 'm/d/Y g:i a',
-  `daydatetime_format` varchar(60) NOT NULL default 'D, M j Y g:ia',
-  `reply_separator` varchar(60) NOT NULL default '-- do not edit --',
-  `admin_email` varchar(125) NOT NULL default '',
-  `helpdesk_title` varchar(255) NOT NULL default
-  'osTicket Support Ticket System',
-  `helpdesk_url` varchar(255) NOT NULL default '',
-  `schema_signature` char(32) NOT NULL default '',
-  `updated` timestamp NOT NULL default CURRENT_TIMESTAMP,
-  PRIMARY KEY  (`id`),
-  KEY `isoffline` (`isonline`)
-) DEFAULT CHARSET=utf8;
-
 DROP TABLE IF EXISTS `%TABLE_PREFIX%sla`;
 CREATE TABLE `%TABLE_PREFIX%sla` (
   `id` int(11) unsigned NOT NULL auto_increment,
@@ -183,6 +78,113 @@ INSERT INTO `%TABLE_PREFIX%sla` (`isactive`, `enable_priority_escalation`,
   `disable_overdue_alerts`, `grace_period`, `name`, `notes`, `created`, `updated`)
   VALUES (1, 1, 0, 48, 'Default SLA', NULL, NOW(), NOW());
 
+DROP TABLE IF EXISTS `%TABLE_PREFIX%config`;
+CREATE TABLE `%TABLE_PREFIX%config` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `namespace` varchar(64) NOT NULL,
+  `key` varchar(64) NOT NULL,
+  `value` text NOT NULL,
+  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY (`namespace`, `key`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+INSERT INTO `%TABLE_PREFIX%config` (`namespace`, `key`, `value`) VALUES
+  ('core', 'isonline', '0'),
+  ('core', 'enable_daylight_saving', '0'),
+  ('core', 'staff_ip_binding', '1'),
+  ('core', 'staff_max_logins', '4'),
+  ('core', 'staff_login_timeout', '2'),
+  ('core', 'staff_session_timeout', '30'),
+  ('core', 'passwd_reset_period', '0'),
+  ('core', 'client_max_logins', '4'),
+  ('core', 'client_login_timeout', '2'),
+  ('core', 'client_session_timeout', '30'),
+  ('core', 'max_page_size', '25'),
+  ('core', 'max_open_tickets', '0'),
+  ('core', 'max_file_size', '1048576'),
+  ('core', 'max_user_file_uploads', ''),
+  ('core', 'max_staff_file_uploads', ''),
+  ('core', 'autolock_minutes', '3'),
+  ('core', 'overdue_grace_period', '0'),
+  ('core', 'alert_email_id', '0'),
+  ('core', 'default_email_id', '0'),
+  ('core', 'default_dept_id', '0'),
+  ('core', 'default_sla_id', '0'),
+  ('core', 'default_priority_id', '2'),
+  ('core', 'default_template_id', '1'),
+  ('core', 'default_timezone_id', '0'),
+  ('core', 'default_smtp_id', '0'),
+  ('core', 'allow_email_spoofing', '0'),
+  ('core', 'clickable_urls', '1'),
+  ('core', 'allow_priority_change', '0'),
+  ('core', 'use_email_priority', '0'),
+  ('core', 'enable_kb', '0'),
+  ('core', 'enable_premade', '1'),
+  ('core', 'enable_captcha', '0'),
+  ('core', 'enable_auto_cron', '0'),
+  ('core', 'enable_mail_polling', '0'),
+  ('core', 'send_sys_errors', '1'),
+  ('core', 'send_sql_errors', '1'),
+  ('core', 'send_mailparse_errors', '1'),
+  ('core', 'send_login_errors', '1'),
+  ('core', 'save_email_headers', '1'),
+  ('core', 'strip_quoted_reply', '1'),
+  ('core', 'log_ticket_activity', '1'),
+  ('core', 'ticket_autoresponder', '0'),
+  ('core', 'message_autoresponder', '0'),
+  ('core', 'ticket_notice_active', '0'),
+  ('core', 'ticket_alert_active', '0'),
+  ('core', 'ticket_alert_admin', '1'),
+  ('core', 'ticket_alert_dept_manager', '1'),
+  ('core', 'ticket_alert_dept_members', '0'),
+  ('core', 'message_alert_active', '0'),
+  ('core', 'message_alert_laststaff', '1'),
+  ('core', 'message_alert_assigned', '1'),
+  ('core', 'message_alert_dept_manager', '0'),
+  ('core', 'note_alert_active', '0'),
+  ('core', 'note_alert_laststaff', '1'),
+  ('core', 'note_alert_assigned', '1'),
+  ('core', 'note_alert_dept_manager', '0'),
+  ('core', 'transfer_alert_active', '0'),
+  ('core', 'transfer_alert_assigned', '0'),
+  ('core', 'transfer_alert_dept_manager', '1'),
+  ('core', 'transfer_alert_dept_members', '0'),
+  ('core', 'overdue_alert_active', '0'),
+  ('core', 'overdue_alert_assigned', '1'),
+  ('core', 'overdue_alert_dept_manager', '1'),
+  ('core', 'overdue_alert_dept_members', '0'),
+  ('core', 'assigned_alert_active', '1'),
+  ('core', 'assigned_alert_staff', '1'),
+  ('core', 'assigned_alert_team_lead', '0'),
+  ('core', 'assigned_alert_team_members', '0'),
+  ('core', 'auto_assign_reopened_tickets', '1'),
+  ('core', 'show_related_tickets', '1'),
+  ('core', 'show_assigned_tickets', '1'),
+  ('core', 'show_answered_tickets', '0'),
+  ('core', 'show_notes_inline', '1'),
+  ('core', 'hide_staff_name', '0'),
+  ('core', 'overlimit_notice_active', '0'),
+  ('core', 'email_attachments', '1'),
+  ('core', 'allow_attachments', '0'),
+  ('core', 'allow_email_attachments', '0'),
+  ('core', 'allow_online_attachments', '0'),
+  ('core', 'allow_online_attachments_onlogin', '0'),
+  ('core', 'random_ticket_ids', '1'),
+  ('core', 'log_level', '2'),
+  ('core', 'log_graceperiod', '12'),
+  ('core', 'upload_dir', ''),
+  ('core', 'allowed_filetypes', '.doc, .pdf'),
+  ('core', 'time_format', ' h:i A'),
+  ('core', 'date_format', 'm/d/Y'),
+  ('core', 'datetime_format', 'm/d/Y g:i a'),
+  ('core', 'daydatetime_format', 'D, M j Y g:ia'),
+  ('core', 'reply_separator', '-- do not edit --'),
+  ('core', 'admin_email', ''),
+  ('core', 'helpdesk_title', 'osTicket Support Ticket System'),
+  ('core', 'helpdesk_url', ''),
+  ('core', 'schema_signature', '');
+
 DROP TABLE IF EXISTS `%TABLE_PREFIX%department`;
 CREATE TABLE `%TABLE_PREFIX%department` (
   `dept_id` int(11) unsigned NOT NULL auto_increment,
diff --git a/setup/inc/sql/osTicket-mysql.sql.md5 b/setup/inc/sql/osTicket-mysql.sql.md5
index a5c1ef08aecc8d20fd13ac1fb2f4123b0682f7a9..d55c64b4a73863e0de3bb0b52805535251c07dfe 100644
--- a/setup/inc/sql/osTicket-mysql.sql.md5
+++ b/setup/inc/sql/osTicket-mysql.sql.md5
@@ -1 +1 @@
-32de1766d56e43215041fa982dcb465e
+852ca89e1440e736d763b3b87f039bd7