Index: /bmo-2.22/post_bug.cgi
===================================================================
--- /bmo-2.22/post_bug.cgi	2006-01-08 12:56:03.000000000 -0700
+++ /bmo-2.22-testopia/post_bug.cgi	2006-09-29 13:55:02.000000000 -0600
@@ -32,6 +32,8 @@
 use Bugzilla::Util;
 use Bugzilla::Bug;
 use Bugzilla::User;
+use Bugzilla::Testopia::TestCaseRun;
+use Bugzilla::Testopia::Util;
 use Bugzilla::Field;
 
 # Shut up misguided -w warnings about "used only once". For some reason,
@@ -494,6 +496,18 @@
 }
 $vars->{'bug_list'} = \@bug_list;
 
+if ($cgi->param('caserun_id')) {
+    my $tcid = $cgi->param('caserun_id');
+    detaint_natural($tcid);
+    validate_test_id($tcid, 'case_run');
+    my $caserun = Bugzilla::Testopia::TestCaseRun->new($tcid);
+
+    $caserun->attach_bug($id);
+
+    $vars->{'caserun'} = $caserun;
+}
+
+
 print $cgi->header();
 $template->process("bug/create/created.html.tmpl", $vars)
   || ThrowTemplateError($template->error());
Index: /bmo-2.22/enter_bug.cgi
===================================================================
--- /bmo-2.22/enter_bug.cgi	2006-01-05 07:54:52.000000000 -0700
+++ /bmo-2.22-testopia/enter_bug.cgi	2006-09-29 13:55:02.000000000 -0600
@@ -590,6 +590,8 @@
 
 $vars->{'default'} = \%default;
 
+$vars->{'caserun_id'} = $cgi->param('caserun_id');
+
 my $format = $template->get_format("bug/create/create",
                                    scalar $cgi->param('format'), 
                                    scalar $cgi->param('ctype'));
Index: /bmo-2.22/checksetup.pl
===================================================================
--- /bmo-2.22/checksetup.pl	2006-01-12 00:03:46.000000000 -0700
+++ /bmo-2.22-testopia/checksetup.pl	2006-10-04 16:06:13.000000000 -0600
@@ -313,7 +313,7 @@
     },
     { 
         name => 'Template', 
-        version => '2.08' 
+        version => '2.12' 
     }, 
     { 
         name => 'Text::Wrap',
@@ -376,6 +376,10 @@
     }
 }
 
+print "\nThe following Perl modules are Required for Testopia:\n" unless $silent;
+$missing{'Text::Diff'} = '0.35' unless have_vers("Text::Diff","0.35");
+$missing{'JSON'} = '1.07' unless have_vers("JSON","1.07");
+
 print "\nThe following Perl modules are optional:\n" unless $silent;
 my $gd          = have_vers("GD","1.20");
 my $chartbase   = have_vers("Chart::Base","1.0");
@@ -1305,7 +1309,7 @@
 # These are the files which need to be marked executable
 my @executable_files = ('whineatnews.pl', 'collectstats.pl',
    'checksetup.pl', 'importxml.pl', 'runtests.pl', 'testserver.pl',
-   'whine.pl');
+   'whine.pl', 'build_bugmail.pl', 'tr_install.pl', 'tr_importxml.pl');
 
 # tell me if a file is executable.  All CGI files and those in @executable_files
 # are executable
Index: /bmo-2.22/Bugzilla.pm
===================================================================
--- /bmo-2.22/Bugzilla.pm	2006-02-07 15:46:28.000000000 -0700
+++ /bmo-2.22-testopia/Bugzilla.pm	2006-10-04 16:24:33.000000000 -0600
@@ -46,6 +46,7 @@
 use constant SHUTDOWNHTML_EXEMPT => [
     'editparams.cgi',
     'checksetup.pl',
+    'tr_install.pl',
 ];
 
 # Non-cgi scripts that should silently exit.
Index: /bmo-2.22/Bugzilla/DB/Schema.pm
===================================================================
--- /bmo-2.22/Bugzilla/DB/Schema.pm	2006-01-06 07:38:42.000000000 -0700
+++ /bmo-2.22-testopia/Bugzilla/DB/Schema.pm	2006-10-04 16:28:11.000000000 -0600
@@ -1039,6 +1039,492 @@
             version     => {TYPE => 'decimal(3,2)', NOTNULL => 1},
         ],
     },
+    
+    # TESTOPIA TABLES
+    # ---------------
+    test_attachments => {
+        FIELDS => [
+            attachment_id => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            plan_id       => {TYPE => 'INT4', UNSIGNED => 1},
+            case_id       => {TYPE => 'INT4', UNSIGNED => 1},
+            submitter_id  => {TYPE => 'INT3', NOTNULL => 1},
+            description   => {TYPE => 'MEDIUMTEXT'},
+            filename      => {TYPE => 'MEDIUMTEXT'},
+            creation_ts   => {TYPE => 'DATETIME', NOTNULL => 1},
+            mime_type     => {TYPE => 'varchar(100)', NOTNULL => 1},
+        ],
+        INDEXES => [
+            attachment_plan_idx => ['plan_id'],
+            attachment_case_idx => ['case_id'],
+        ],
+    },
+
+    test_case_categories => {
+        FIELDS => [
+            category_id => {TYPE => 'SMALLSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            product_id  => {TYPE => 'INT2', NOTNULL => 1},
+            name        => {TYPE => 'varchar(240)', NOTNULL => 1},
+            description => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            category_name_idx => ['name'],
+            category_product_id_name_idx => {FIELDS => [qw(product_id name)],
+                                             TYPE => 'UNIQUE'},
+        ],
+    },
+   
+    test_cases => {
+        FIELDS => [
+            case_id        => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            case_status_id => {TYPE => 'INT1', NOTNULL => 1},
+            category_id    => {TYPE => 'INT2', NOTNULL => 1, UNSIGNED =>1},
+            priority_id    => {TYPE => 'INT2'},
+            author_id      => {TYPE => 'INT3', NOTNULL => 1},
+            default_tester_id => {TYPE => 'INT3'},
+            creation_date  => {TYPE => 'DATETIME', NOTNULL => 1},
+            isautomated    => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '0'},
+            sortkey        => {TYPE => 'INT4'},
+            script         => {TYPE => 'MEDIUMTEXT'},
+            arguments      => {TYPE => 'MEDIUMTEXT'},
+            summary        => {TYPE => 'varchar(255)'},
+            requirement    => {TYPE => 'varchar(255)'},
+            alias          => {TYPE => 'varchar(255)'},
+        ],
+        INDEXES => [
+            test_case_category_idx      => ['category_id'],
+            test_case_author_idx        => ['author_id'],
+            test_case_creation_date_idx => ['creation_date'],
+            test_case_sortkey_idx       => ['sortkey'],
+            test_case_requirement_idx   => ['requirement'],
+            test_case_shortname_idx     => ['alias'],
+        ],     
+    },
+   
+    test_case_bugs => {
+        FIELDS => [
+            bug_id      => {TYPE => 'INT3', NOTNULL => 1},
+            case_run_id => {TYPE => 'INT4', UNSIGNED => 1},
+            case_id     => {TYPE => 'INT4', UNSIGNED => 1},
+        ],    
+        INDEXES => [
+            case_run_id_idx     => [qw(case_run_id bug_id)],
+            case_run_bug_id_idx => ['bug_id'],
+        ],
+    },        
+    
+    test_case_runs => {
+        FIELDS => [ 
+            case_run_id         => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            run_id              => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            case_id             => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            assignee            => {TYPE => 'INT3'},
+            testedby            => {TYPE => 'INT3'},
+            case_run_status_id  => {TYPE => 'INT1', NOTNULL => 1, UNSIGNED => 1},
+            case_text_version   => {TYPE => 'INT3', NOTNULL => 1},
+            build_id            => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            close_date          => {TYPE => 'DATETIME'},
+            notes               => {TYPE => 'TEXT'},
+            iscurrent           => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '0'},
+            sortkey             => {TYPE => 'INT4'},
+            environment_id      => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                           
+        ],
+        INDEXES => [
+            case_run_run_id_idx     => ['run_id'],
+            case_run_case_id_idx    => ['case_id'],
+            case_run_assignee_idx   => ['assignee'],
+            case_run_testedby_idx   => ['testedby'],
+            case_run_close_date_idx => ['close_date'],
+            case_run_shortkey_idx   => ['sortkey'],
+            case_run_build_idx      => [qw(case_run_id build_id)],
+            case_run_env_idx        => [qw(case_run_id environment_id)],
+            case_run_build_env_idx  => {FIELDS => [qw(run_id case_id build_id environment_id)],
+                                        TYPE => 'UNIQUE'},
+        ],
+    },
+    
+    test_case_texts => {
+        FIELDS => [
+            case_id           => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL =>1},        
+            case_text_version => {TYPE => 'INT3', NOTNULL => 1},        
+            who               => {TYPE => 'INT3', NOTNULL => 1},        
+            creation_ts       => {TYPE => 'DATETIME', NOTNULL => 1},        
+            action            => {TYPE => 'MEDIUMTEXT'},        
+            effect            => {TYPE => 'MEDIUMTEXT'},
+            setup             => {TYPE => 'MEDIUMTEXT'},
+            breakdown         => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            case_versions_idx             => {FIELDS => [qw(case_id case_text_version)],
+                                              TYPE => 'UNIQUE'},
+            case_versions_who_idx         => ['who'],                      
+            case_versions_creation_ts_idx => ['creation_ts'],
+        ],
+    },
+    
+    test_case_tags => {
+        FIELDS => [
+            tag_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            case_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            userid  => {TYPE => 'INT3', NOTNULL => 1},
+        ],
+        INDEXES => [
+            case_tags_case_id_idx => {FIELDS => [qw(tag_id case_id)], TYPE => 'UNIQUE'},
+            case_tags_tag_id_idx  => [qw(tag_id case_id)],
+            case_tags_user_idx    => [qw(tag_id userid)],
+        ],
+    },
+    
+    test_tags => {
+        FIELDS => [
+            tag_id   => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            tag_name => {TYPE => 'varchar(255)', NOTNULL => 1},
+        ],
+        INDEXES => [
+            test_tag_name_indx    => {FIELDS => ['tag_name'], TYPE => 'UNIQUE'},
+        ],
+    },
+    
+    test_plans => {
+        FIELDS => [
+            plan_id                 => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            product_id              => {TYPE => 'INT2', NOTNULL => 1},
+            author_id               => {TYPE => 'INT3', NOTNULL => 1},
+            type_id                 => {TYPE => 'INT1', NOTNULL => 1, UNSIGNED => 1},
+            default_product_version => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
+            name                    => {TYPE => 'varchar(255)', NOTNULL => 1},
+            creation_date           => {TYPE => 'DATETIME', NOTNULL => 1},
+            isactive                => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'},
+        ],
+        INDEXES => [
+            plan_product_plan_id_idx => [qw(product_id plan_id)],
+            plan_author_idx          => ['author_id'],        
+            plan_type_idx            => ['type_id'],        
+            plan_isactive_idx        => ['isactive'],
+            plan_name_idx            => ['name'],
+        ],
+    },
+
+    test_plan_texts => {
+        FIELDS => [
+            plan_id           => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            plan_text_version => {TYPE => 'INT4', NOTNULL => 1},
+            who               => {TYPE => 'INT3', NOTNULL => 1},
+            creation_ts       => {TYPE => 'DATETIME', NOTNULL => 1},
+            plan_text         => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            test_plan_text_version_idx => [qw(plan_id plan_text_version)],
+            test_plan_text_who_idx     => ['who'],
+        ],
+    },
+    
+    test_plan_types => {
+        FIELDS => [
+            type_id => {TYPE => 'TINYSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            name    => {TYPE => 'varchar(64)', NOTNULL => 1},
+        ],
+        INDEXES => [
+            plan_type_name_idx => ['name'],
+        ],
+    },
+    
+    test_runs => {
+        FIELDS => [
+            run_id            => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            plan_id           => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                           
+            environment_id    => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                           
+            product_version   => {TYPE => 'MEDIUMTEXT'},                           
+            build_id          => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                           
+            plan_text_version => {TYPE => 'INT4', NOTNULL => 1},                           
+            manager_id        => {TYPE => 'INT3', NOTNULL => 1},                           
+            default_tester_id => {TYPE => 'INT3'},                           
+            start_date        => {TYPE => 'DATETIME', NOTNULL => 1},                           
+            stop_date         => {TYPE => 'DATETIME'},                           
+            summary           => {TYPE => 'TINYTEXT', NOTNULL => 1},                           
+            notes             => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            test_run_plan_id_run_id_idx => [qw(plan_id run_id)],
+            test_run_manager_idx        => ['manager_id'],
+            test_run_start_date_idx     => ['start_date'],
+            test_run_stop_date_idx      => ['stop_date'],
+            test_runs_summary_idx       => {FIELDS => ['summary'],
+                                            TYPE => 'FULLTEXT'},
+        ],
+    },
+    
+    test_case_plans => {
+        FIELDS => [
+            plan_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                           
+            case_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+        ],
+        INDEXES => [
+            case_plans_plan_id_idx => [qw(plan_id case_id)],
+            case_plans_case_id_idx => [qw(case_id plan_id)],
+        ],
+    },
+
+    test_case_activity => {
+        FIELDS => [
+            case_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            fieldid  => {TYPE => 'INT2', UNSIGNED => 1, NOTNULL => 1},
+            who      => {TYPE => 'INT3', NOTNULL => 1},
+            changed  => {TYPE => 'DATETIME', NOTNULL => 1},
+            oldvalue => {TYPE => 'MEDIUMTEXT'},
+            newvalue => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            case_activity_case_id_idx => ['case_id'],    
+            case_activity_who_idx     => ['who'],    
+            case_activity_when_idx    => ['changed'],    
+            case_activity_field_idx   => ['fieldid'],
+        ],
+    },
+
+    test_fielddefs => {
+        FIELDS => [
+            fieldid     => {TYPE => 'SMALLSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            name        => {TYPE => 'varchar(100)', NOTNULL => 1},
+            description => {TYPE => 'MEDIUMTEXT'},
+            table_name  => {TYPE => 'varchar(100)', NOTNULL => 1},
+        ],
+        INDEXES => [
+            test_fielddefs_name_idx => ['name'],
+        ],
+    },
+    
+    test_plan_activity => {
+        FIELDS => [
+            plan_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},             
+            fieldid  => {TYPE => 'INT2', UNSIGNED => 1, NOTNULL => 1},             
+            who      => {TYPE => 'INT3', NOTNULL => 1},             
+            changed  => {TYPE => 'DATETIME', NOTNULL => 1},             
+            oldvalue => {TYPE => 'MEDIUMTEXT'},             
+            newvalue => {TYPE => 'MEDIUMTEXT'},             
+        ],
+        INDEXES => [
+            plan_activity_who_idx => ['who'],
+        ],
+    },
+    
+    test_case_components => {
+        FIELDS => [
+            case_id      => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            component_id => {TYPE => 'INT2', NOTNULL => 1},
+        ],
+        INDEXES => [
+            case_components_case_id_idx       => ['case_id'],    
+            case_commponents_component_id_idx => ['component_id'],
+        ],
+    },
+    
+    test_run_activity => {
+        FIELDS => [
+            run_id   => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            fieldid  => {TYPE => 'INT2', UNSIGNED => 1, NOTNULL => 1},
+            who      => {TYPE => 'INT3', NOTNULL => 1},
+            changed  => {TYPE => 'DATETIME', NOTNULL => 1},
+            oldvalue => {TYPE => 'MEDIUMTEXT'},
+            newvalue => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            run_activity_run_id_idx => ['run_id'],    
+            run_activity_who_idx    => ['who'],    
+            run_activity_when_idx   => ['changed'],
+        ],
+    },
+    
+    test_run_cc => {
+        FIELDS => [
+            run_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                     
+            who    => {TYPE => 'INT3', NOTNULL => 1},
+        ],
+        INDEXES => [
+            run_cc_run_id_who_idx => [qw(run_id who)],
+        ],
+    },
+    
+    test_email_settings => {
+        FIELDS => [
+            userid          => {TYPE => 'INT3', NOTNULL => 1},                                   
+            eventid         => {TYPE => 'INT1', UNSIGNED => 1, NOTNULL => 1},                                   
+            relationship_id => {TYPE => 'INT1', UNSIGNED => 1, NOTNULL => 1},
+        ],
+        INDEXES => [
+            test_event_user_event_idx        => [qw(userid eventid)],    
+            test_event_user_relationship_idx => [qw(userid relationship_id)],    
+        ],
+    },
+    
+    test_events => {
+        FIELDS => [
+            eventid => {TYPE => 'INT1', UNSIGNED => 1, PRIMARYKEY => 1, NOTNULL => 1},        
+            name    => {TYPE => 'varchar(50)'},
+        ],
+        INDEXES => [
+            test_event_name_idx => ['name'],
+        ],
+    },
+    
+    test_relationships => {
+        FIELDS => [
+            relationship_id => {TYPE => 'INT1', UNSIGNED => 1, PRIMARYKEY => 1, NOTNULL => 1},            
+            name            => {TYPE => 'varchar(50)'},
+        ],
+    },
+    
+    test_case_run_status => {
+        FIELDS => [
+            case_run_status_id => {TYPE => 'TINYSERIAL', PRIMARYKEY => 1, NOTNULL => 1},                    
+            name               => {TYPE => 'varchar(20)'},                    
+            sortkey            => {TYPE => 'INT4'},
+        ],
+        INDEXES => [
+            case_run_status_name_idx => ['name'],    
+            case_run_status_sortkey_idx => ['sortkey'],    
+        ],
+    },
+    
+    test_case_status => {
+        FIELDS => [
+            case_status_id => {TYPE => 'TINYSERIAL', PRIMARYKEY => 1, NOTNULL => 1},                    
+            name           => {TYPE => 'varchar(255)', NOTNULL => 1},                    
+        ],
+        INDEXES => [
+            test_case_status_name_idx => ['name'],    
+        ],
+    },    
+    
+    test_case_dependencies => {
+        FIELDS => [
+            dependson => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                    
+            blocked   => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},                    
+        ],
+    },
+
+    test_plan_group_map => {
+        FIELDS => [
+            group_id => {TYPE => 'INT3'},
+            plan_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL =>1},
+        ],
+    },    
+        
+    test_environments => {
+        FIELDS => [
+            environment_id  => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            product_id      => {TYPE => 'INT2', NOTNULL => 1},        
+            name            => {TYPE => 'varchar(255)'},
+            isactive        => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'},        
+        ],    
+        INDEXES => [
+            environment_name_idx     => ['name'],
+        ],    
+    },
+
+    test_run_tags => {    
+        FIELDS => [
+            tag_id =>  {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            run_id =>  {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            userid  => {TYPE => 'INT3', NOTNULL => 1},
+        ],
+        INDEXES => [
+            run_tags_idx       => {FIELDS => [qw(tag_id run_id)], TYPE => 'UNIQUE'},
+            run_tags_user_idx  => [qw(tag_id userid)],
+            
+        ],    
+    },
+    
+    test_plan_tags => {
+        FIELDS => [
+            tag_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            plan_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            userid  => {TYPE => 'INT3', NOTNULL => 1},        
+        ],
+        INDEXES => [
+            plan_tags_idx       => {FIELDS => [qw(tag_id plan_id)], TYPE => 'UNIQUE'},
+            plan_tags_user_idx  => [qw(tag_id userid)],
+        ],    
+    },
+    
+    test_builds => {
+        FIELDS => [
+            build_id    => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            product_id  => {TYPE => 'INT2', NOTNULL => 1},
+            milestone   => {TYPE => 'varchar(20)'},
+            name        => {TYPE => 'varchar(255)'},
+            description => {TYPE => 'TEXT'},        
+        ],
+        INDEXES => [
+            build_name_idx => ['name'],
+            build_product_id_name_idx => {FIELDS => [qw(product_id name)],
+                                          TYPE => 'UNIQUE'},
+        ],      
+    },
+    
+    test_attachment_data => {
+        FIELDS => [
+            attachment_id => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            contents      => {TYPE => 'LONGBLOB'},
+        ],          
+    },    
+
+    test_named_queries => {
+        FIELDS => [
+            userid    => {TYPE => 'INT3', NOTNULL => 1},
+            name      => {TYPE => 'varchar(64)', NOTNULL => 1},
+            isvisible => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 1},
+            query     => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
+        ],
+        INDEXES => [
+            test_namedquery_name_idx => ['name'],
+        ],    
+    },
+    
+    test_environment_map => {
+        FIELDS => [
+            environment_id   => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            property_id      => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            element_id       => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            value_selected   => {TYPE => 'TINYTEXT'},
+        ],
+        INDEXES => [
+            env_map_env_element_idx  => [qw(environment_id element_id)],
+            env_map_property_idx     => [qw(environment_id property_id)],
+        ],
+    },
+    test_environment_element => {
+        FIELDS => [
+            element_id       => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            env_category_id  => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            name             => {TYPE => 'varchar(255)'},
+            parent_id        => {TYPE => 'INT4', UNSIGNED => 1},
+            isprivate        => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0},
+        ],
+        INDEXES => [
+            env_element_category_idx => [qw(env_category_id name)],
+        ],
+    },
+    test_environment_category => {
+        FIELDS => [
+            env_category_id  => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            product_id       => {TYPE => 'INT2', NOTNULL => 1},
+            name             => {TYPE => 'varchar(255)'},
+        ],
+        INDEXES => [
+            env_category_idx => [qw(name product_id)],
+        ],
+    },
+    test_environment_property => {
+        FIELDS => [
+            property_id   => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
+            element_id    => {TYPE => 'INT4', UNSIGNED => 1, NOTNULL => 1},
+            name          => {TYPE => 'varchar(255)'},
+            validexp      => {TYPE => 'TEXT'},
+        ],
+        INDEXES => [
+            env_element_property_idx => [qw(element_id name)],
+        ],
+    },
 
 };
 #--------------------------------------------------------------------------
Index: /bmo-2.22/Bugzilla/Template.pm
===================================================================
--- /bmo-2.22/Bugzilla/Template.pm	22 Jan 2006 21:37:37 -0000	1.41
+++ /bmo-2.22-testopia/Bugzilla/Template.pm	8 Dec 2006 18:20:56 -0000
@@ -498,6 +498,14 @@
                 }
                 return $var;
             },
+                        
+            # Prevent XSS attacks in WYSIWYG fields. 
+            xss => sub{
+                my ($var) = @_;
+                $var =~ s/(&lt;|<)script/_script/ig;
+                $var =~ s/(&lt;|<)\/script(>|&gt;)/script_/gi;
+                return $var;
+            },
             
             # iCalendar contentline filter
             ics => [ sub {
Index: /bmo-2.22/Bugzilla/DB/Schema/Mysql.pm
===================================================================
--- /bmo-2.22/Bugzilla/DB/Schema/Mysql.pm	2005-12-18 11:53:00.000000000 -0700
+++ /bmo-2.22-testopia/Bugzilla/DB/Schema/Mysql.pm	2006-09-29 14:08:38.000000000 -0600
@@ -103,9 +103,10 @@
         INT3 =>         'mediumint',
         INT4 =>         'integer',
 
-        SMALLSERIAL =>  'smallint auto_increment',
-        MEDIUMSERIAL => 'mediumint auto_increment',
-        INTSERIAL =>    'integer auto_increment',
+        TINYSERIAL =>    'tinyint unsigned auto_increment',
+        SMALLSERIAL =>   'smallint unsigned auto_increment',
+        MEDIUMSERIAL =>  'mediumint unsigned auto_increment',
+        INTSERIAL =>     'integer unsigned auto_increment',
 
         TINYTEXT =>     'tinytext',
         MEDIUMTEXT =>   'mediumtext',
Index: /bmo-2.22/Bugzilla/DB/Schema/Pg.pm
===================================================================
--- /bmo-2.22/Bugzilla/DB/Schema/Pg.pm	2005-06-14 21:54:59.000000000 -0600
+++ /bmo-2.22-testopia/Bugzilla/DB/Schema/Pg.pm	2006-09-21 15:10:19.000000000 -0600
@@ -69,6 +69,7 @@
         INT3 =>         'integer',
         INT4 =>         'integer',
 
+        TINYSERIAL =>   'serial unique',
         SMALLSERIAL =>  'serial unique',
         MEDIUMSERIAL => 'serial unique',
         INTSERIAL =>    'serial unique',
