[Bast-commits] r3502 - in trunk/DBIx-Class: . lib/DBIx lib/DBIx/Class lib/DBIx/Class/InflateColumn lib/DBIx/Class/Manual lib/DBIx/Class/Relationship lib/DBIx/Class/ResultClass lib/DBIx/Class/ResultSource lib/DBIx/Class/ResultSourceProxy lib/DBIx/Class/Schema lib/DBIx/Class/Storage lib/DBIx/Class/Storage/DBI lib/DBIx/Class/Storage/DBI/ODBC lib/DBIx/Class/Storage/DBI/Oracle lib/SQL/Translator/Parser/DBIx t t/cdbi-sweet-t t/lib t/lib/DBICNSTest t/lib/DBICNSTest/OtherRslt t/lib/DBICNSTest/RSet t/lib/DBICNSTest/Result t/lib/DBICNSTest/ResultSet t/lib/DBICNSTest/Rslt t/lib/DBICTest t/lib/DBICTest/Schema

matthewt at dev.catalyst.perl.org matthewt at dev.catalyst.perl.org
Sun Jun 17 20:27:09 GMT 2007


Author: matthewt
Date: 2007-06-17 20:27:08 +0100 (Sun, 17 Jun 2007)
New Revision: 3502

Added:
   trunk/DBIx-Class/lib/DBIx/Class/Exception.pm
   trunk/DBIx-Class/lib/DBIx/Class/InflateColumn/File.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultClass/
   trunk/DBIx-Class/lib/DBIx/Class/ResultClass/HashRefInflator.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSourceHandle.pm
   trunk/DBIx-Class/lib/DBIx/Class/Schema/
   trunk/DBIx-Class/lib/DBIx/Class/Schema/Versioned.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/WhereJoins.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Replication.pm
   trunk/DBIx-Class/t/100populate.t
   trunk/DBIx-Class/t/101populate_rs.t
   trunk/DBIx-Class/t/33storage_reconnect.t
   trunk/DBIx-Class/t/34exception_action.t
   trunk/DBIx-Class/t/35disable_sth_caching.t
   trunk/DBIx-Class/t/39load_namespaces_1.t
   trunk/DBIx-Class/t/39load_namespaces_2.t
   trunk/DBIx-Class/t/39load_namespaces_3.t
   trunk/DBIx-Class/t/39load_namespaces_4.t
   trunk/DBIx-Class/t/55storage_stress.t
   trunk/DBIx-Class/t/61findnot.t
   trunk/DBIx-Class/t/63register_class.t
   trunk/DBIx-Class/t/68inflate_resultclass_hashrefinflator.t
   trunk/DBIx-Class/t/93nobindvars.t
   trunk/DBIx-Class/t/94versioning.t
   trunk/DBIx-Class/t/96file_column.t
   trunk/DBIx-Class/t/96multi_create.t
   trunk/DBIx-Class/t/97result_class.t
   trunk/DBIx-Class/t/bindtype_columns.t
   trunk/DBIx-Class/t/lib/DBICNSTest/
   trunk/DBIx-Class/t/lib/DBICNSTest/OtherRslt/
   trunk/DBIx-Class/t/lib/DBICNSTest/OtherRslt/D.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/RSBase.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/RSet/
   trunk/DBIx-Class/t/lib/DBICNSTest/RSet/A.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/RSet/C.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/Result/
   trunk/DBIx-Class/t/lib/DBICNSTest/Result/A.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/Result/B.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/
   trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/A.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/C.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/
   trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/A.pm
   trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/B.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/FileColumn.pm
   trunk/DBIx-Class/t/lib/DBICVersionNew.pm
   trunk/DBIx-Class/t/lib/DBICVersionOrig.pm
   trunk/DBIx-Class/t/resultset_class.t
Modified:
   trunk/DBIx-Class/Build.PL
   trunk/DBIx-Class/Changes
   trunk/DBIx-Class/MANIFEST.SKIP
   trunk/DBIx-Class/Makefile.PL
   trunk/DBIx-Class/lib/DBIx/Class.pm
   trunk/DBIx-Class/lib/DBIx/Class/Componentised.pm
   trunk/DBIx-Class/lib/DBIx/Class/Core.pm
   trunk/DBIx-Class/lib/DBIx/Class/DB.pm
   trunk/DBIx-Class/lib/DBIx/Class/InflateColumn.pm
   trunk/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod
   trunk/DBIx-Class/lib/DBIx/Class/Manual/DocMap.pod
   trunk/DBIx-Class/lib/DBIx/Class/Manual/FAQ.pod
   trunk/DBIx-Class/lib/DBIx/Class/Ordered.pm
   trunk/DBIx-Class/lib/DBIx/Class/Relationship/Accessor.pm
   trunk/DBIx-Class/lib/DBIx/Class/Relationship/Base.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSet.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSetColumn.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSource.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSource/Table.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy.pm
   trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy/Table.pm
   trunk/DBIx-Class/lib/DBIx/Class/Row.pm
   trunk/DBIx-Class/lib/DBIx/Class/Schema.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Cursor.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/DB2.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/MSSQL.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Pg.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/SQLite.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/mysql.pm
   trunk/DBIx-Class/lib/DBIx/Class/Storage/Statistics.pm
   trunk/DBIx-Class/lib/SQL/Translator/Parser/DBIx/Class.pm
   trunk/DBIx-Class/t/03podcoverage.t
   trunk/DBIx-Class/t/19quotes.t
   trunk/DBIx-Class/t/19quotes_newstyle.t
   trunk/DBIx-Class/t/30dbicplain.t
   trunk/DBIx-Class/t/31stats.t
   trunk/DBIx-Class/t/40resultsetmanager.t
   trunk/DBIx-Class/t/41orrible.t
   trunk/DBIx-Class/t/60core.t
   trunk/DBIx-Class/t/65multipk.t
   trunk/DBIx-Class/t/67pager.t
   trunk/DBIx-Class/t/68inflate.t
   trunk/DBIx-Class/t/71mysql.t
   trunk/DBIx-Class/t/72pg.t
   trunk/DBIx-Class/t/73oracle.t
   trunk/DBIx-Class/t/745db2.t
   trunk/DBIx-Class/t/746db2_400.t
   trunk/DBIx-Class/t/74mssql.t
   trunk/DBIx-Class/t/76joins.t
   trunk/DBIx-Class/t/81transactions.t
   trunk/DBIx-Class/t/83cache.t
   trunk/DBIx-Class/t/86sqlt.t
   trunk/DBIx-Class/t/87ordered.t
   trunk/DBIx-Class/t/89dbicadmin.t
   trunk/DBIx-Class/t/90join_torture.t
   trunk/DBIx-Class/t/92storage.t
   trunk/DBIx-Class/t/95sql_maker_quote.t
   trunk/DBIx-Class/t/cdbi-sweet-t/08pager.t
   trunk/DBIx-Class/t/lib/DBICTest.pm
   trunk/DBIx-Class/t/lib/DBICTest/Plain.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/Artist.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/ArtistSourceName.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/Employee.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/FourKeys.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/LinerNotes.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/NoPrimaryKey.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/OneKey.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/Serialized.pm
   trunk/DBIx-Class/t/lib/DBICTest/Schema/Track.pm
   trunk/DBIx-Class/t/lib/sqlite.sql
Log:
0.08000 release commit

Modified: trunk/DBIx-Class/Build.PL
===================================================================
--- trunk/DBIx-Class/Build.PL	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/Build.PL	2007-06-17 19:27:08 UTC (rev 3502)
@@ -1,32 +1,3 @@
-use strict;
-use Module::Build;
-
-my %arguments = (
-    create_makefile_pl => 'passthrough',
-    license            => 'perl',
-    module_name        => 'DBIx::Class',
-    requires           => {
-        'Cwd'                       => 3.19,
-        'Data::Page'                => 2.00,
-        'Scalar::Util'              => 0,
-        'SQL::Abstract'             => 1.20,
-        'SQL::Abstract::Limit'      => 0.101,
-        'Class::C3'                 => 0.13,
-        'Storable'                  => 0,
-        'Class::Data::Accessor'     => 0.01,
-     	'Carp::Clan'		    => 0,
-        'DBI'                       => 1.40,
-        'Module::Find'              => 0,
-        'Class::Inspector'          => 0,
-    },
-    build_requires      => {
-        'DBD::SQLite'               => 1.11,
-    },
-    create_makefile_pl => 'passthrough',
-    create_readme      => 1,
-    test_files         => [ glob('t/*.t'), glob('t/*/*.t') ],
-    script_files       => [ glob('script/*') ],
-);
-
-Module::Build->new(%arguments)->create_build_script;
-
+# Dear Distribution Packager. This use of require is intentional.
+# Module::Install detects Build.PL usage and acts accordingly.
+require 'Makefile.PL';

Modified: trunk/DBIx-Class/Changes
===================================================================
--- trunk/DBIx-Class/Changes	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/Changes	2007-06-17 19:27:08 UTC (rev 3502)
@@ -1,6 +1,58 @@
 Revision history for DBIx::Class
 
+0.08000 2007-06-17 18:06:12
+        - Fixed DBIC_TRACE debug filehandles to set ->autoflush(1)
+        - Fixed circular dbh<->storage in HandleError with weakref
+
+0.07999_06 2007-06-13 04:45:00
+        - tweaked Row.pm to make last_insert_id take multiple column names
+        - Fixed DBIC::Storage::DBI::Cursor::DESTROY bug that was
+          messing up exception handling
+        - added exception objects to eliminate stacktrace/Carp::Clan
+          output redundancy
+        - setting $ENV{DBIC_TRACE} defaults stacktrace on.
+        - added stacktrace option to Schema, makes throw_exception
+          use "confess"
+        - make database handles use throw_exception by default
+        - make database handles supplied by a coderef use our
+          standard HandleError/RaiseError/PrintError
+        - add "unsafe" connect_info option to suppress our setting
+          of HandleError/RaiseError/PrintError
+        - removed several redundant evals whose sole purpose was to
+          provide extra debugging info
+        - fixed page-within-page bug (reported by nilsonsfj)
+        - fixed rare bug when database is disconnected inbetween
+          "$dbh->prepare_cached" and "$sth->execute"
+
+0.07999_05 2007-06-07 23:00:00
+        - Made source_name rw in ResultSource
+        - Fixed up SQL::Translator test/runtime dependencies
+        - Fixed t/60core.t in the absence of DateTime::Format::MySQL
         - Test cleanup and doc note (ribasushi)
+
+0.07999_04 2007-06-01 14:04:00
+        - pulled in Replication storage from branch and marked EXPERIMENTAL
+        - fixup to ensure join always LEFT after first LEFT join depthwise
+        - converted the vendor tests to use schema objects intead of schema
+          classes, made cleaned more reliable with END blocks
+        - versioning support via DBIx::Class::Schema::Versioned
+        - find/next now return undef rather than () on fail from Bernhard Graf
+        - rewritten collapse_result to fix prefetch
+        - moved populate to resultset
+        - added support for creation of related rows via insert and populate
+        - transaction support more robust now in the face of varying AutoCommit
+          and manual txn_begin usage
+        - unbreak back-compat for Row/ResultSet->new_result
+        - Added Oracle/WhereJoins.pm for Oracle >= 8 to support
+          Oracle <= 9i, and provide Oracle with a better join method for
+          later versions.  (I use the term better loosely.)
+        - The SQL::T parser class now respects a relationship attribute of
+          is_foreign_key_constrain to allow explicit control over wether or
+          not a foreign constraint is needed
+        - resultset_class/result_class now (again) auto loads the specified
+          class; requires Class::Accessor::Grouped 0.05002+
+        - added get_inflated_columns to Row
+        - %colinfo accessor and inflate_column now work together
         - More documentation updates
         - Error messages from ->deploy made more informative
         - connect_info will now always return the arguments it was
@@ -16,6 +68,15 @@
         - CDBI compat infers has_many from has_a (Schwern)
         - Fix ddl_filename transformation (Carl Vincent)
 
+0.07999_02 2007-01-25 20:11:00
+        - add support for binding BYTEA and similar parameters (w/Pg impl)
+        - add support to Ordered for multiple ordering columns
+        - mark DB.pm and compose_connection as deprecated
+        - switch tests to compose_namespace
+        - ResultClass::HashRefInflator added
+        - Changed row and rs objects to not have direct handle to a source,
+          instead a (schema,source_name) tuple of type ResultSourceHandle
+
 0.07005 2007-01-10 18:36:00
         - fixup changes file
         - remove erroneous .orig files - oops
@@ -34,11 +95,33 @@
         - Don't blow up if columns_info_for returns useless results
         - Documentation updates
 
+0.07999_01 2006-10-05 21:00:00
+        - add connect_info option "disable_statement_caching"
+        - create insert_bulk using execute_array, populate uses it
+        - added DBIx::Class::Schema::load_namespaces, alternative to
+          load_classes
+        - added source_info method for source-level metadata (kinda like
+          column_info)
+        - Some of ::Storage::DBI's code/docs moved to ::Storage
+        - DBIx::Class::Schema::txn_do code moved to ::Storage
+        - Storage::DBI now uses exceptions instead of ->ping/->{Active} checks
+        - Storage exceptions are thrown via the schema class's throw_exception
+        - DBIx::Class::Schema::throw_exception's behavior can be modified via
+          ->exception_action
+        - columns_info_for is deprecated, and no longer runs automatically.
+          You can make it work like before via
+          __PACKAGE__->column_info_from_storage(1) for now
+        - Replaced DBIx::Class::AccessorGroup and Class::Data::Accessor with
+          Class::Accessor::Grouped. Only user noticible change is to
+          table_class on ResultSourceProxy::Table (i.e. table objects in
+          schemas) and, resultset_class and result_class in ResultSource.
+          These accessors no longer automatically require the classes when
+          set.
+
 0.07002 2006-09-14 21:17:32
         - fix quote tests for recent versions of SQLite
         - added reference implementation of Manual::Example
         - backported column_info_from_storage accessor from -current, but
-          defaults true instead of false in 0.07xxx
         - fixed inflate_datetime.t tests/stringify under older Test::More
         - minor fixes for many-to-many relationship helpers
         - cleared up Relationship docs, and fixed some typos
@@ -105,7 +188,7 @@
         - fixes to pass test suite on Windows
         - rewrote and cleaned up SQL::Translator tests
         - changed relationship helpers to only call ensure_class_loaded when the
-          join condition is inferred 
+          join condition is inferred
         - rewrote many_to_many implementation, now provides helpers for adding
           and deleting objects without dealing with the link table
         - reworked InflateColumn implementation to lazily deflate where
@@ -113,12 +196,12 @@
         - changed join merging to not create a rel_2 alias when adding a join
           that already exists in a parent resultset
         - Storage::DBI::deployment_statements now calls ensure_connected
-          if it isn't passed a type 
+          if it isn't passed a type
         - fixed Componentized::ensure_class_loaded
         - InflateColumn::DateTime supports date as well as datetime
         - split Storage::DBI::MSSQL into MSSQL and Sybase::MSSQL
-        - fixed wrong debugging hook call in Storage::DBI 
-        - set connect_info properly before setting any ->sql_maker things 
+        - fixed wrong debugging hook call in Storage::DBI
+        - set connect_info properly before setting any ->sql_maker things
 
 0.06999_02 2006-06-09 23:58:33
         - Fixed up POD::Coverage tests, filled in some POD holes
@@ -276,7 +359,8 @@
 
 0.05002 2006-02-06 12:12:03
         - Added recommends for Class::Inspector
-        - Added skip_all to t/40resultsetmanager.t if no Class::Inspector available
+        - Added skip_all to t/40resultsetmanager.t if no Class::Inspector
+        available
 
 0.05001 2006-02-05 15:28:10
         - debug output now prints NULL for undef params
@@ -316,8 +400,10 @@
 
 0.04999_04 2006-01-24 21:48:21
         - more documentation improvements
-        - add columns_info_for for vendor-specific column info (Zbigniew Lukasiak)
-        - add SQL::Translator::Producer for DBIx::Class table classes (Jess Robinson)
+        - add columns_info_for for vendor-specific column info (Zbigniew
+        Lukasiak)
+        - add SQL::Translator::Producer for DBIx::Class table classes (Jess
+        Robinson)
         - add unique constraint declaration (Daniel Westermann-Clark)
         - add new update_or_create method (Daniel Westermann-Clark)
         - rename ResultSetInstance class to ResultSetProxy, ResultSourceInstance
@@ -327,11 +413,13 @@
 
 0.04999_03 2006-01-20 06:05:27
         - imported Jess Robinson's SQL::Translator::Parser::DBIx::Class
-        - lots of internals cleanup to eliminate result_source_instance requirement
+        - lots of internals cleanup to eliminate result_source_instance
+        requirement
         - added register_column and register_relationship class APIs
         - made Storage::DBI use prepare_cached safely (thanks to Tim Bunce)
         - many documentation improvements (thanks guys!)
-        - added ->connection, ->connect, ->register_source and ->clone schema methods
+        - added ->connection, ->connect, ->register_source and ->clone schema
+        methods
         - Use croak instead of die for user errors.
 
 0.04999_02 2006-01-14 07:17:35
@@ -404,3 +492,4 @@
 
 0.01    2005-08-08 17:10:00
         - initial release
+

Modified: trunk/DBIx-Class/MANIFEST.SKIP
===================================================================
--- trunk/DBIx-Class/MANIFEST.SKIP	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/MANIFEST.SKIP	2007-06-17 19:27:08 UTC (rev 3502)
@@ -25,6 +25,7 @@
 \.tmp$
 \.old$
 \.bak$
+\..*?\.sw[po]$
 \#$
 \b\.#
 
@@ -42,3 +43,6 @@
 
 # Avoid copies to .orig
 \.orig$
+
+# Dont use Module::Build anymore
+# Build.PL

Modified: trunk/DBIx-Class/Makefile.PL
===================================================================
--- trunk/DBIx-Class/Makefile.PL	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/Makefile.PL	2007-06-17 19:27:08 UTC (rev 3502)
@@ -1,31 +1,39 @@
-# Note: this file was auto-generated by Module::Build::Compat version 0.03
-    
-    unless (eval "use Module::Build::Compat 0.02; 1" ) {
-      print "This module requires Module::Build to install itself.\n";
-      
-      require ExtUtils::MakeMaker;
-      my $yn = ExtUtils::MakeMaker::prompt
-	('  Install Module::Build now from CPAN?', 'y');
-      
-      unless ($yn =~ /^y/i) {
-	die " *** Cannot install without Module::Build.  Exiting ...\n";
-      }
-      
-      require Cwd;
-      require File::Spec;
-      require CPAN;
-      
-      # Save this 'cause CPAN will chdir all over the place.
-      my $cwd = Cwd::cwd();
-      
-      CPAN::Shell->install('Module::Build::Compat');
-      CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
-	or die "Couldn't install Module::Build, giving up.\n";
-      
-      chdir $cwd or die "Cannot chdir() back to $cwd: $!";
-    }
-    eval "use Module::Build::Compat 0.02; 1" or die $@;
-    
-    Module::Build::Compat->run_build_pl(args => \@ARGV);
-    require Module::Build;
-    Module::Build::Compat->write_makefile(build_class => 'Module::Build');
+use inc::Module::Install 0.67;
+
+name     'DBIx-Class';
+all_from 'lib/DBIx/Class.pm';
+perl_version '5.006001';
+
+requires 'Cwd'                       => 3.19; 
+requires 'Data::Page'                => 2.00;
+requires 'Scalar::Util'              => 0;
+requires 'SQL::Abstract'             => 1.20;
+requires 'SQL::Abstract::Limit'      => 0.101;
+requires 'Class::C3'                 => 0.13;
+requires 'Storable'                  => 0;
+requires 'Carp::Clan'                => 0;
+requires 'DBI'                       => 1.40;
+requires 'Module::Find'              => 0;
+requires 'Class::Inspector'          => 0;
+requires 'Class::Accessor::Grouped'  => 0.05002;
+requires 'JSON'                      => 1.00; 
+
+# Perl 5.8.0 doesn't have utf8::is_utf8()
+requires 'Encode'                    => 0 if ($] <= 5.008000);  
+
+build_requires 'DBD::SQLite'         => 1.11;
+
+install_script 'script/dbicadmin';
+
+tests "t/*.t t/*/*.t";
+
+# re-build README if we're in an svk checkout
+if( -e 'MANIFEST.SKIP' ) {
+    system('pod2text lib/DBIx/Class.pm > README');
+}
+
+auto_provides;
+
+auto_install;
+
+WriteAll;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Componentised.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Componentised.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Componentised.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -6,7 +6,7 @@
 
 use Class::C3;
 use Class::Inspector;
-use Carp::Clan qw/DBIx::Class/;
+use Carp::Clan qw/^DBIx::Class/;
 
 sub inject_base {
   my ($class, $target, @to_inject) = @_;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Core.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Core.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Core.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,14 +7,12 @@
 use base qw/DBIx::Class/;
 
 __PACKAGE__->load_components(qw/
-  Serialize::Storable
   Relationship
   InflateColumn
   PK::Auto
   PK
   Row
-  ResultSourceProxy::Table
-  AccessorGroup/);
+  ResultSourceProxy::Table/);
 
 1;
 
@@ -50,8 +48,6 @@
 
 =item L<DBIx::Class::ResultSourceProxy::Table>
 
-=item L<DBIx::Class::AccessorGroup>
-
 =back
 
 =head1 AUTHORS

Modified: trunk/DBIx-Class/lib/DBIx/Class/DB.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/DB.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/DB.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -8,7 +8,12 @@
 use DBIx::Class::Storage::DBI;
 use DBIx::Class::ClassResolver::PassThrough;
 use DBI;
+use Scalar::Util;
 
+unless ($INC{"DBIx/Class/CDBICompat.pm"}) {
+  warn "IMPORTANT: DBIx::Class::DB is DEPRECATED AND *WILL* BE REMOVED. DO NOT USE.\n";
+}
+
 __PACKAGE__->load_components(qw/ResultSetProxy/);
 
 {
@@ -23,30 +28,16 @@
 
 DBIx::Class::DB - (DEPRECATED) classdata schema component
 
-=head1 SYNOPSIS
-
-  package MyDB;
-
-  use base qw/DBIx::Class/;
-  __PACKAGE__->load_components('DB');
-
-  __PACKAGE__->connection('dbi:...', 'user', 'pass', \%attrs);
-
-  package MyDB::MyTable;
-
-  use base qw/MyDB/;
-  __PACKAGE__->load_components('Core'); # just load this in MyDB if it will
-                                        # always be there
-
-  ...
-
 =head1 DESCRIPTION
 
 This class is designed to support the Class::DBI connection-as-classdata style
 for DBIx::Class. You are *strongly* recommended to use a DBIx::Class::Schema
 instead; DBIx::Class::DB will not undergo new development and will be moved
-to being a CDBICompat-only component before 1.0.
+to being a CDBICompat-only component before 1.0. In order to discourage further
+use, documentation has been removed as of 0.08000
 
+=begin HIDE_BECAUSE_THIS_CLASS_IS_DEPRECATED
+
 =head1 METHODS
 
 =head2 storage
@@ -150,13 +141,49 @@
 =cut
 
 sub resultset_instance {
-  my $class = ref $_[0] || $_[0];
-  my $source = $class->result_source_instance;
+  $_[0]->result_source_instance->resultset
+}
+
+=head2 result_source_instance
+
+Returns an instance of the result source for this class
+
+=cut
+
+sub result_source_instance {
+  my $class = shift;
+  $class = ref $class || $class;
+ 
+  __PACKAGE__->mk_classdata(qw/_result_source_instance/)
+    unless __PACKAGE__->can('_result_source_instance');
+
+  
+  return $class->_result_source_instance(@_) if @_;
+
+  my $source = $class->_result_source_instance;
+  return {} unless Scalar::Util::blessed($source);
+
   if ($source->result_class ne $class) {
-    $source = $source->new($source);
-    $source->result_class($class);
+    # Remove old source instance so we dont get deep recursion
+    #$DB::single = 1;
+    # Need to set it to a non-undef value so that it doesn't just fallback to
+    # a parent class's _result_source_instance
+    #$class->_result_source_instance({});
+    #$class->table($class);
+    #$source = $class->_result_source_instance;
+
+    $DB::single = 1;
+    $source = $source->new({ 
+        %$source, 
+        source_name  => $class,
+        result_class => $class
+    } );
+    $class->_result_source_instance($source);
+    if (my $coderef = $class->can('schema_instance')) {
+        $coderef->($class)->register_class($class, $class);
+    }
   }
-  return $source->resultset;
+  return $source;
 }
 
 =head2 resolve_class
@@ -177,6 +204,8 @@
 
 Alias for L<txn_rollback>
 
+=end HIDE_BECAUSE_THIS_CLASS_IS_DEPRECATED
+
 =head1 AUTHORS
 
 Matt S. Trout <mst at shadowcatsystems.co.uk>

Added: trunk/DBIx-Class/lib/DBIx/Class/Exception.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Exception.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/Exception.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,81 @@
+package DBIx::Class::Exception;
+
+use strict;
+use warnings;
+
+use Carp::Clan qw/^DBIx::Class/;
+use Scalar::Util qw/blessed/;
+
+use overload
+    '""' => sub { shift->{msg} },
+    fallback => 1;
+
+=head1 NAME
+
+DBIx::Class::Exception - Exception objects for DBIx::Class
+
+=head1 DESCRIPTION
+
+Exception objects of this class are used in internally by
+he default error handling of L<DBIx::Class::Schema/throw_exception>
+to prevent confusing and/or redundant re-application of L<Carp>'s
+stack trace information.
+
+These objects stringify to the contained error message, and use
+overload fallback to give natural boolean/numeric values.
+
+=head1 METHODS
+
+=head2 throw
+
+=over 4
+
+=item Arguments: $exception_scalar, $stacktrace
+
+=back
+
+This is meant for internal use by L<DBIx::Class>'s C<throw_exception>
+code, and shouldn't be used directly elsewhere.
+
+Expects a scalar exception message.  The optional argument
+C<$stacktrace> tells it to use L<Carp/longmess> instead of
+L<Carp::Clan/croak>.
+
+  DBIx::Class::Exception->throw('Foo');
+  eval { ... }; DBIx::Class::Exception->throw($@) if $@;
+
+=cut
+
+sub throw {
+    my ($class, $msg, $stacktrace) = @_;
+
+    # Don't re-encapsulate multiple times
+    die $msg if blessed($msg) && $msg->isa('DBIx::Class::Exception');
+
+    # use Carp::Clan's croak if we're not stack tracing
+    if(!$stacktrace) {
+        local $@;
+        eval { croak $msg };
+        $msg = $@
+    }
+    else {
+        $msg = Carp::longmess($msg);
+    }
+    
+    my $self = { msg => $msg };
+    bless $self => $class;
+
+    die $self;
+}
+
+=head1 AUTHORS
+
+Brandon L. Black <blblack at gmail.com>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
+
+1;

Added: trunk/DBIx-Class/lib/DBIx/Class/InflateColumn/File.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/InflateColumn/File.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/InflateColumn/File.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,204 @@
+package DBIx::Class::InflateColumn::File;
+
+use strict;
+use warnings;
+use base 'DBIx::Class';
+use File::Path;
+use File::Copy;
+use IO::File;
+
+__PACKAGE__->load_components(qw/InflateColumn/);
+
+
+sub register_column {
+  my ($self, $column, $info, @rest) = @_;
+  $self->next::method($column, $info, @rest);
+  return unless defined($info->{is_file_column});
+    $self->inflate_column(
+      $column =>
+        {
+          inflate => sub { 
+            my ($value, $obj) = @_;
+            #$self->_inflate_file_column;
+          },
+          deflate => sub {
+            my ($value, $obj) = @_;
+            #my ( $file, @column_names ) = $self->_load_file_column_information;
+            #$self->_save_file_column( $file, $self, @column_names );
+          },
+        }
+    );
+}
+
+
+sub delete {
+    my ( $self, @rest ) = @_;
+
+    my @column_names = $self->columns;
+    for (@column_names) {
+        if ( $self->column_info($_)->{is_file_column} ) {
+            my $path =
+              File::Spec->catdir( $self->column_info($_)->{file_column_path},
+                $self->id );
+            rmtree( [$path], 0, 0 );
+        }
+    }
+
+    my $ret = $self->next::method(@rest);
+
+    return $ret;
+}
+
+sub _inflate_file_column {
+    my $self = shift;
+
+    my @column_names = $self->columns;
+    for(@column_names) {
+        if ( $self->column_info($_)->{is_file_column} ) {
+            # make sure everything checks out
+            unless (defined $self->$_) {
+                # if something is wrong set it to undef
+                $self->$_(undef);
+                next;
+            }
+            my $fs_file =
+              File::Spec->catfile( $self->column_info($_)->{file_column_path}, 
+                $self->id, $self->$_ );
+            $self->$_({handle => new IO::File($fs_file, "r"), filename => $self->$_});
+        }
+    }
+}
+
+sub _load_file_column_information {
+    my $self = shift;
+
+    my $file;
+    my @column_names;
+
+    @column_names = $self->columns;
+    for (@column_names) {
+        if ( $self->column_info($_)->{is_file_column} ) {
+            # make sure everything checks out
+            unless ((defined $self->$_) ||
+             (defined $self->$_->{filename} && defined $self->$_->{handle})) {
+                # if something is wrong set it to undef
+                $self->$_(undef);
+                next;
+            }
+            $file->{$_} = $self->$_;
+            $self->$_( $self->$_->{filename} );
+        }
+    }
+
+    return ( $file, @column_names );
+}
+
+sub _save_file_column {
+    my ( $self, $file, $ret, @column_names ) = @_;
+
+    for (@column_names) {
+        if ( $ret->column_info($_)->{is_file_column} ) {
+            next unless (defined $ret->$_);
+            my $file_path =
+              File::Spec->catdir( $ret->column_info($_)->{file_column_path},
+                $ret->id );
+            mkpath [$file_path];
+            
+            my $outfile =
+              File::Spec->catfile( $file_path, $file->{$_}->{filename} );
+            File::Copy::copy( $file->{$_}->{handle}, $outfile );
+        
+            $self->_file_column_callback($file->{$_},$ret,$_);
+        }
+    }
+}
+
+=head1 NAME
+
+DBIx::Class::InflateColumn::File -  map files from the Database to the filesystem.
+
+=head1 SYNOPSIS
+
+In your L<DBIx::Class> table class:
+
+    __PACKAGE__->load_components( "PK::Auto", "InflateColumn::File", "Core" );
+    
+    # define your columns
+    __PACKAGE__->add_columns(
+        "id",
+        {
+            data_type         => "integer",
+            is_auto_increment => 1,
+            is_nullable       => 0,
+            size              => 4,
+        },
+        "filename",
+        {
+            data_type           => "varchar",
+            is_file_column      => 1,
+            file_column_path    =>'/tmp/uploaded_files',
+            # or for a Catalyst application 
+            # file_column_path  => MyApp->path_to('root','static','files'),
+            default_value       => undef,
+            is_nullable         => 1,
+            size                => 255,
+        },
+    );
+    
+
+In your L<Catalyst::Controller> class:
+
+FileColumn requires a hash that contains L<IO::File> as handle and the file's
+name as name.
+
+    my $entry = $c->model('MyAppDB::Articles')->create({ 
+        subject => 'blah',
+        filename => { 
+            handle => $c->req->upload('myupload')->fh, 
+            filename => $c->req->upload('myupload')->basename 
+        },
+        body => '....'
+    });
+    $c->stash->{entry}=$entry;
+    
+
+And Place the following in your TT template
+    
+    Article Subject: [% entry.subject %]
+    Uploaded File: 
+    <a href="/static/files/[% entry.id %]/[% entry.filename.filename %]">File</a>
+    Body: [% entry.body %]
+    
+The file will be stored on the filesystem for later retrieval.  Calling delete
+on your resultset will delete the file from the filesystem.  Retrevial of the
+record automatically inflates the column back to the set hash with the
+IO::File handle and filename.
+
+=head1 DESCRIPTION
+
+InflateColumn::File
+
+=head1 METHODS
+
+=head2 _file_column_callback ($file,$ret,$target)
+
+method made to be overridden for callback purposes.
+
+=cut
+
+sub _file_column_callback {
+    my ($self,$file,$ret,$target) = @_;
+}
+
+=head1 AUTHOR
+
+Victor Igumnov
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/InflateColumn.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/InflateColumn.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/InflateColumn.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -73,7 +73,7 @@
   $self->throw_exception("inflate_column needs attr hashref")
     unless ref $attrs eq 'HASH';
   $self->column_info($col)->{_inflate_info} = $attrs;
-  $self->mk_group_accessors('inflated_column' => $col);
+  $self->mk_group_accessors('inflated_column' => [$self->column_info($col)->{accessor} || $col, $col]);
   return 1;
 }
 
@@ -164,93 +164,6 @@
   return $self->{_inflated_column}{$col} = $inflated;
 }
 
-=head2 get_column
-
-Gets a column value in the same way as L<DBIx::Class::Row/get_column>. If there
-is an inflated value stored that has not yet been deflated, it is deflated
-when the method is invoked.
-
-=cut
-
-sub get_column {
-  my ($self, $col) = @_;
-  if (exists $self->{_inflated_column}{$col}
-        && !exists $self->{_column_data}{$col}) {
-    $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col})); 
-  }
-  return $self->next::method($col);
-}
-
-=head2 get_columns 
-
-Returns the get_column info for all columns as a hash,
-just like L<DBIx::Class::Row/get_columns>.  Handles inflation just
-like L</get_column>.
-
-=cut
-
-sub get_columns {
-  my $self = shift;
-  if (exists $self->{_inflated_column}) {
-    foreach my $col (keys %{$self->{_inflated_column}}) {
-      $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
-       unless exists $self->{_column_data}{$col};
-    }
-  }
-  return $self->next::method;
-}
-
-=head2 has_column_loaded
-
-Like L<DBIx::Class::Row/has_column_loaded>, but also returns true if there
-is an inflated value stored.
-
-=cut
-
-sub has_column_loaded {
-  my ($self, $col) = @_;
-  return 1 if exists $self->{_inflated_column}{$col};
-  return $self->next::method($col);
-}
-
-=head2 update
-
-Updates a row in the same way as L<DBIx::Class::Row/update>, handling
-inflation and deflation of columns appropriately.
-
-=cut
-
-sub update {
-  my ($class, $attrs, @rest) = @_;
-  foreach my $key (keys %{$attrs||{}}) {
-    if (ref $attrs->{$key} && $class->has_column($key)
-          && exists $class->column_info($key)->{_inflate_info}) {
-      $class->set_inflated_column($key, delete $attrs->{$key});
-    }
-  }
-  return $class->next::method($attrs, @rest);
-}
-
-=head2 new
-
-Creates a row in the same way as L<DBIx::Class::Row/new>, handling
-inflation and deflation of columns appropriately.
-
-=cut
-
-sub new {
-  my ($class, $attrs, @rest) = @_;
-  my $inflated;
-  foreach my $key (keys %{$attrs||{}}) {
-    $inflated->{$key} = delete $attrs->{$key} 
-      if ref $attrs->{$key} && $class->has_column($key)
-         && exists $class->column_info($key)->{_inflate_info};
-  }
-  my $obj = $class->next::method($attrs, @rest);
-  $obj->{_inflated_column} = $inflated if $inflated;
-  return $obj;
-}
-
 =head1 SEE ALSO
 
 =over 4

Modified: trunk/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod	2007-06-17 19:27:08 UTC (rev 3502)
@@ -544,7 +544,7 @@
 =head2 Transactions
 
 As of version 0.04001, there is improved transaction support in
-L<DBIx::Class::Storage::DBI> and L<DBIx::Class::Schema>.  Here is an
+L<DBIx::Class::Storage> and L<DBIx::Class::Schema>.  Here is an
 example of the recommended way to use it:
 
   my $genus = $schema->resultset('Genus')->find(12);
@@ -964,7 +964,7 @@
 
 =head2 Profiling
 
-When you enable L<DBIx::Class::Storage::DBI>'s debugging it prints the SQL
+When you enable L<DBIx::Class::Storage>'s debugging it prints the SQL
 executed as well as notifications of query completion and transaction
 begin/commit.  If you'd like to profile the SQL you can subclass the
 L<DBIx::Class::Storage::Statistics> class and write your own profiling
@@ -1159,60 +1159,18 @@
 
 DBIx::Class is not built for speed, it's built for convenience and
 ease of use, but sometimes you just need to get the data, and skip the
-fancy objects. Luckily this is also fairly easy using
-C<inflate_result>:
-
-  # Define a class which just returns the results as a hashref:
-  package My::HashRefInflator;
-
-  ## $me is the hashref of cols/data from the immediate resultsource
-  ## $prefetch is a deep hashref of all the data from the prefetched
-  ##   related sources.
-
-  sub mk_hash {
-     my ($me, $rest) = @_;
-
-     # to avoid emtpy has_many rels contain one empty hashref
-     return if (not keys %$me);
-
-     my $def;
-
-     foreach (values %$me) {
-         if (defined $_) {
-             $def = 1;
-             last;
-         }
-     }
-     return unless $def;
-
-     return { %$me,
-         map {
-           ( $_ =>
-              ref($rest->{$_}[0]) eq 'ARRAY' ? [ map { mk_hash(@$_) } @{$rest->{$_}} ]
-                                             : mk_hash( @{$rest->{$_}} )
-           )
-         } keys %$rest
-     };
-  }
-
-  sub inflate_result {
-     my ($self, $source, $me, $prefetch) = @_;
-     return mk_hash($me, $prefetch); 
-  }
-
-  # Change the object inflation to a hashref for just this resultset:
-  $rs->result_class('My::HashRefInflator');
-
-  my $datahashref = $rs->next;
-  foreach my $col (keys %$datahashref) {
-     if(!ref($datahashref->{$col})) {
-        # It's a plain value
-     }
-     elsif(ref($datahashref->{$col} eq 'HASH')) {
-        # It's a related value in a hashref
-     }
-  }
-
+fancy objects.
+  
+To do this simply use L<DBIx::Class::ResultClass::HashRefInflator>.
+  
+ my $rs = $schema->resultset('CD');
+ 
+ $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+ 
+ my $hash_ref = $rs->find(1);
+  
+Wasn't that easy?
+  
 =head2 Get raw data for blindingly fast results
 
 If the C<inflate_result> solution above is not fast enough for you, you

Modified: trunk/DBIx-Class/lib/DBIx/Class/Manual/DocMap.pod
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Manual/DocMap.pod	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Manual/DocMap.pod	2007-06-17 19:27:08 UTC (rev 3502)
@@ -64,6 +64,8 @@
 
 =item L<DBIx::Class::Row> - Dealing with actual data.
 
+=item L<DBIx::Class::Storage> - Basic Storage stuff.
+
 =item L<DBIx::Class::Storage::DBI> - Storage using L<DBI> and L<SQL::Abstract>.
 
 =back

Modified: trunk/DBIx-Class/lib/DBIx/Class/Manual/FAQ.pod
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Manual/FAQ.pod	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Manual/FAQ.pod	2007-06-17 19:27:08 UTC (rev 3502)
@@ -376,7 +376,7 @@
 
 =item See the SQL statements my code is producing?
 
-Turn on debugging! See L<DBIx::Class::Storage::DBI> for details of how
+Turn on debugging! See L<DBIx::Class::Storage> for details of how
 to turn on debugging in the environment, pass your own filehandle to
 save debug to, or create your own callback.
 

Modified: trunk/DBIx-Class/lib/DBIx/Class/Ordered.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Ordered.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Ordered.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -17,8 +17,27 @@
     name TEXT NOT NULL,
     position INTEGER NOT NULL
   );
-  # Optional: group_id INTEGER NOT NULL
 
+Optionally, add one or more columns to specify groupings, allowing you 
+to maintain independent ordered lists within one table:
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL
+  );
+
+Or even
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL,
+    other_group_id INTEGER NOT NULL
+  );
+
 In your Schema or DB class add "Ordered" to the top 
 of the component list.
 
@@ -29,8 +48,15 @@
 
   package My::Item;
   __PACKAGE__->position_column('position');
-  __PACKAGE__->grouping_column('group_id'); # optional
 
+If you are using one grouping column, specify it as follows:
+
+  __PACKAGE__->grouping_column('group_id');
+
+Or if you have multiple grouping columns:
+
+  __PACKAGE__->grouping_column(['group_id', 'other_group_id']);
+
 That's it, now you can change the position of your objects.
 
   #!/use/bin/perl
@@ -54,6 +80,10 @@
   $item->move_first();
   $item->move_last();
   $item->move_to( $position );
+  $item->move_to_group( 'groupname' );
+  $item->move_to_group( 'groupname', $position );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'} );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'}, $position );
 
 =head1 DESCRIPTION
 
@@ -127,6 +157,7 @@
 sub first_sibling {
     my( $self ) = @_;
     return 0 if ($self->get_column($self->position_column())==1);
+
     return ($self->result_source->resultset->search(
         {
             $self->position_column => 1,
@@ -290,11 +321,72 @@
         $self->_grouping_clause(),
     });
     my $op = ($from_position>$to_position) ? '+' : '-';
-    $rs->update({ $position_column => \"$position_column $op 1" });
+    $rs->update({ $position_column => \"$position_column $op 1" });  #" Sorry, GEdit bug
+    $self->{_ORDERED_INTERNAL_UPDATE} = 1;
     $self->update({ $position_column => $to_position });
     return 1;
 }
 
+
+
+=head2 move_to_group
+
+  $item->move_to_group( $group, $position );
+
+Moves the object to the specified position of the specified
+group, or to the end of the group if $position is undef.
+1 is returned on success, and 0 is returned if the object is
+already at the specified position of the specified group.
+
+$group may be specified as a single scalar if only one 
+grouping column is in use, or as a hashref of column => value pairs
+if multiple grouping columns are in use.
+
+=cut
+
+sub move_to_group {
+    my( $self, $to_group, $to_position ) = @_;
+
+    # if we're given a string, turn it into a hashref
+    unless (ref $to_group eq 'HASH') {
+        $to_group = {($self->_grouping_columns)[0] => $to_group};
+    }
+
+    my $position_column = $self->position_column;
+    #my @grouping_columns = $self->_grouping_columns;
+
+    return 0 if ( ! defined($to_group) );
+    return 0 if ( defined($to_position) and $to_position < 1 );
+    return 0 if ( $self->_is_in_group($to_group) 
+                    and ((not defined($to_position)) 
+                            or (defined($to_position) and $self->$position_column==$to_position)
+                        )
+                    );
+
+    # Move to end of current group and adjust siblings
+    $self->move_last;
+
+    $self->set_columns($to_group);
+    my $new_group_count = $self->result_source->resultset->search({$self->_grouping_clause()})->count();
+    if (!defined($to_position) or $to_position > $new_group_count) {
+        $self->{_ORDERED_INTERNAL_UPDATE} = 1;
+        $self->update({ $position_column => $new_group_count + 1 });
+    }
+    else {
+        my @between = ($to_position, $new_group_count);
+
+        my $rs = $self->result_source->resultset->search({
+            $position_column => { -between => [ @between ] },
+            $self->_grouping_clause(),
+        });
+        $rs->update({ $position_column => \"$position_column + 1" }); #"
+        $self->{_ORDERED_INTERNAL_UPDATE} = 1;
+        $self->update({ $position_column => $to_position });
+    }
+
+    return 1;
+}
+
 =head2 insert
 
 Overrides the DBIC insert() method by providing a default 
@@ -311,6 +403,53 @@
     return $self->next::method( @_ );
 }
 
+=head2 update
+
+Overrides the DBIC update() method by checking for a change
+to the position and/or group columns.  Movement within a
+group or to another group is handled by repositioning
+the appropriate siblings.  Position defaults to the end
+of a new group if it has been changed to undef.
+
+=cut
+
+sub update {
+    my $self = shift;
+
+    if ($self->{_ORDERED_INTERNAL_UPDATE}) {
+        delete $self->{_ORDERED_INTERNAL_UPDATE};
+        return $self->next::method( @_ );
+    }
+
+    $self->set_columns($_[0]) if @_ > 0;
+    my %changes = $self->get_dirty_columns;
+    $self->discard_changes;
+
+    my $pos_col = $self->position_column;
+
+    # if any of our grouping columns have been changed
+    if (grep {$_} map {exists $changes{$_}} $self->_grouping_columns ) {
+
+        # create new_group by taking the current group and inserting changes
+        my $new_group = {$self->_grouping_clause};
+        foreach my $col (keys %$new_group) {
+            if (exists $changes{$col}) {
+                $new_group->{$col} = $changes{$col};
+                delete $changes{$col}; # don't want to pass this on to next::method
+            }
+        }
+
+        $self->move_to_group(
+            $new_group,
+            exists($changes{$pos_col}) ? delete($changes{$pos_col}) : $self->$pos_col
+        );
+    }
+    elsif (exists $changes{$pos_col}) {
+        $self->move_to(delete $changes{$pos_col});
+    }
+    return $self->next::method( \%changes );
+}
+
 =head2 delete
 
 Overrides the DBIC delete() method by first moving the object 
@@ -332,21 +471,57 @@
 
 =head2 _grouping_clause
 
-This method returns a name=>value pair for limiting a search 
-by the collection column.  If the collection column is not 
+This method returns one or more name=>value pairs for limiting a search 
+by the grouping column(s).  If the grouping column is not 
 defined then this will return an empty list.
 
 =cut
-
 sub _grouping_clause {
     my( $self ) = @_;
+    return map {  $_ => $self->get_column($_)  } $self->_grouping_columns();
+}
+
+
+
+=head2 _get_grouping_columns
+
+Returns a list of the column names used for grouping, regardless of whether
+they were specified as an arrayref or a single string, and returns ()
+if there is no grouping.
+
+=cut
+sub _grouping_columns {
+    my( $self ) = @_;
     my $col = $self->grouping_column();
-    if ($col) {
-        return ( $col => $self->get_column($col) );
+    if (ref $col eq 'ARRAY') {
+        return @$col;
+    } elsif ($col) {
+        return ( $col );
+    } else {
+        return ();
     }
-    return ();
 }
 
+
+
+=head2 _is_in_group($other)
+
+    $item->_is_in_group( {user => 'fred', list => 'work'} )
+
+Returns true if the object is in the group represented by hashref $other
+=cut
+sub _is_in_group {
+    my ($self, $other) = @_;
+    my $current = {$self->_grouping_clause};
+    return 0 unless (ref $other eq 'HASH') and (keys %$current == keys %$other);
+    for my $key (keys %$current) {
+        return 0 unless exists $other->{$key};
+        return 0 if $current->{$key} ne $other->{$key};
+    }
+    return 1;
+}
+
+
 1;
 __END__
 

Modified: trunk/DBIx-Class/lib/DBIx/Class/Relationship/Accessor.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Relationship/Accessor.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Relationship/Accessor.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -62,39 +62,4 @@
   }
 }
 
-sub new {
-  my ($class, $attrs, @rest) = @_;
-  my ($related, $info);
-  foreach my $key (keys %{$attrs||{}}) {
-    next unless $info = $class->relationship_info($key);
-    $related->{$key} = delete $attrs->{$key}
-      if ref $attrs->{$key}
-         && $info->{attrs}{accessor}
-         && $info->{attrs}{accessor} eq 'single';
-  }
-  my $obj = $class->next::method($attrs, @rest);
-  if ($related) {
-    $obj->{_relationship_data} = $related;
-    foreach my $rel (keys %$related) {
-      $obj->set_from_related($rel, $related->{$rel});
-    }
-  }
-  return $obj;
-}
-
-sub update {
-  my ($obj, $attrs, @rest) = @_;
-  my $info;
-  foreach my $key (keys %{$attrs||{}}) {
-    next unless $info = $obj->relationship_info($key);
-    if (ref $attrs->{$key} && $info->{attrs}{accessor}
-        && $info->{attrs}{accessor} eq 'single') {
-      my $rel = delete $attrs->{$key};
-      $obj->set_from_related($key => $rel);
-      $obj->{_relationship_data}{$key} = $rel;
-    }
-  }
-  return $obj->next::method($attrs, @rest);
-}
-
 1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Relationship/Base.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Relationship/Base.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Relationship/Base.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -102,6 +102,13 @@
 a column accessor). For C<multi> accessors, an add_to_* method is also
 created, which calls C<create_related> for the relationship.
 
+=item is_foreign_key_constraint
+
+If you are using L<SQL::Translator> to create SQL for you and you find that it
+is creating constraints where it shouldn't, or not creating them where it 
+should, set this attribute to a true or false value to override the detection
+of when to create constraints.
+
 =back
 
 =head2 register_relationship
@@ -317,12 +324,16 @@
 =head2 set_from_related
 
   $book->set_from_related('author', $author_obj);
+  $book->author($author_obj);                      ## same thing
 
 Set column values on the current object, using related values from the given
 related object. This is used to associate previously separate objects, for
 example, to set the correct author for a book, find the Author object, then
 call set_from_related on the book.
 
+This is called internally when you pass existing objects as values to
+L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to acessor.
+
 The columns are only set in the local copy of the object, call L</update> to
 set them in the storage.
 

Added: trunk/DBIx-Class/lib/DBIx/Class/ResultClass/HashRefInflator.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultClass/HashRefInflator.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultClass/HashRefInflator.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,86 @@
+package DBIx::Class::ResultClass::HashRefInflator;
+
+=head1 NAME
+
+DBIx::Class::ResultClass::HashRefInflator
+
+=head1 SYNOPSIS
+
+ my $rs = $schema->resultset('CD');
+
+ $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+=head1 DESCRIPTION
+
+DBIx::Class is not built for speed: it's built for convenience and
+ease of use. But sometimes you just need to get the data, and skip the
+fancy objects. That is what this class provides.
+
+There are two ways of using this class.
+
+=over
+
+=item *
+
+Specify C<< $rs->result_class >> on a specific resultset to affect only that
+resultser (and any chained off of it); or
+
+=item *
+
+Specify C<< __PACKAGE__->result_class >> on your source object to force all
+uses of that result source to be inflated to hash-refs - this approach is not
+recomended
+
+=back
+
+=head1 METHODS
+
+=head2 inflate_result
+
+Inflates the result and prefetched data into a hash-ref using L<mk_hash>.
+
+=cut
+
+sub inflate_result {
+    my ($self, $source, $me, $prefetch) = @_;
+
+    return mk_hash($me, $prefetch);
+}
+
+=head2 mk_hash
+
+This does all the work of inflating the (pre)fetched data.
+
+=cut
+
+sub mk_hash {
+    my ($me, $rest) = @_;
+
+    # $me is the hashref of cols/data from the immediate resultsource
+    # $rest is a deep hashref of all the data from the prefetched
+    # related sources.
+
+    # to avoid emtpy has_many rels contain one empty hashref
+    return if (not keys %$me);
+
+    my $def;
+
+    foreach (values %$me) {
+        if (defined $_) {
+            $def = 1;
+            last;
+        }
+    }
+    return unless $def;
+
+    return { %$me,
+        map {
+          ( $_ =>
+             ref($rest->{$_}[0]) eq 'ARRAY' ? [ map { mk_hash(@$_) } @{$rest->{$_}} ]
+                                            : mk_hash( @{$rest->{$_}} )
+          )
+        } keys %$rest
+    };
+}
+
+1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSet.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSet.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSet.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -10,10 +10,10 @@
 use Data::Page;
 use Storable;
 use DBIx::Class::ResultSetColumn;
+use DBIx::Class::ResultSourceHandle;
 use base qw/DBIx::Class/;
 
-__PACKAGE__->load_components(qw/AccessorGroup/);
-__PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
+__PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/);
 
 =head1 NAME
 
@@ -85,20 +85,19 @@
   return $class->new_result(@_) if ref $class;
 
   my ($source, $attrs) = @_;
-  #weaken $source;
+  $source = $source->handle 
+    unless $source->isa('DBIx::Class::ResultSourceHandle');
   $attrs = { %{$attrs||{}} };
 
   if ($attrs->{page}) {
     $attrs->{rows} ||= 10;
-    $attrs->{offset} ||= 0;
-    $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
   }
 
   $attrs->{alias} ||= 'me';
 
   my $self = {
-    result_source => $source,
-    result_class => $attrs->{result_class} || $source->result_class,
+    _source_handle => $source,
+    result_class => $attrs->{result_class} || $source->resolve->result_class,
     cond => $attrs->{where},
     count => undef,
     pager => undef,
@@ -349,11 +348,13 @@
 
   my (%related, $info);
 
-  foreach my $key (keys %$input_query) {
+  KEY: foreach my $key (keys %$input_query) {
     if (ref($input_query->{$key})
         && ($info = $self->result_source->relationship_info($key))) {
+      my $val = delete $input_query->{$key};
+      next KEY if (ref($val) eq 'ARRAY'); # has_many for multi_create
       my $rel_q = $self->result_source->resolve_condition(
-                    $info->{cond}, delete $input_query->{$key}, $key
+                    $info->{cond}, $val, $key
                   );
       die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY';
       @related{keys %$rel_q} = values %$rel_q;
@@ -542,7 +543,7 @@
     $attrs->{where}, $attrs
   );
 
-  return (@data ? ($self->_construct_object(@data))[0] : ());
+  return (@data ? ($self->_construct_object(@data))[0] : undef);
 }
 
 # _is_unique_query
@@ -737,7 +738,7 @@
       ? @{delete $self->{stashed_row}}
       : $self->cursor->next
   );
-  return unless (@row);
+  return undef unless (@row);
   my ($row, @more) = $self->_construct_object(@row);
   $self->{stashed_objects} = \@more if @more;
   return $row;
@@ -753,78 +754,125 @@
 }
 
 sub _collapse_result {
-  my ($self, $as, $row, $prefix) = @_;
+  my ($self, $as_proto, $row) = @_;
 
-  my %const;
   my @copy = @$row;
-  
-  foreach my $this_as (@$as) {
-    my $val = shift @copy;
-    if (defined $prefix) {
-      if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
-        my $remain = $1;
-        $remain =~ /^(?:(.*)\.)?([^.]+)$/;
-        $const{$1||''}{$2} = $val;
+
+  # 'foo'         => [ undef, 'foo' ]
+  # 'foo.bar'     => [ 'foo', 'bar' ]
+  # 'foo.bar.baz' => [ 'foo.bar', 'baz' ]
+
+  my @construct_as = map { [ (/^(?:(.*)\.)?([^.]+)$/) ] } @$as_proto;
+
+  my %collapse = %{$self->{_attrs}{collapse}||{}};
+
+  my @pri_index;
+
+  # if we're doing collapsing (has_many prefetch) we need to grab records
+  # until the PK changes, so fill @pri_index. if not, we leave it empty so
+  # we know we don't have to bother.
+
+  # the reason for not using the collapse stuff directly is because if you
+  # had for e.g. two artists in a row with no cds, the collapse info for
+  # both would be NULL (undef) so you'd lose the second artist
+
+  # store just the index so we can check the array positions from the row
+  # without having to contruct the full hash
+
+  if (keys %collapse) {
+    my %pri = map { ($_ => 1) } $self->result_source->primary_columns;
+    foreach my $i (0 .. $#construct_as) {
+      next if defined($construct_as[$i][0]); # only self table
+      if (delete $pri{$construct_as[$i][1]}) {
+        push(@pri_index, $i);
       }
-    } else {
-      $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
-      $const{$1||''}{$2} = $val;
+      last unless keys %pri; # short circuit (Johnny Five Is Alive!)
     }
   }
 
-  my $alias = $self->{attrs}{alias};
-  my $info = [ {}, {} ];
-  foreach my $key (keys %const) {
-    if (length $key && $key ne $alias) {
-      my $target = $info;
-      my @parts = split(/\./, $key);
-      foreach my $p (@parts) {
-        $target = $target->[1]->{$p} ||= [];
-      }
-      $target->[0] = $const{$key};
-    } else {
-      $info->[0] = $const{$key};
-    }
-  }
+  # no need to do an if, it'll be empty if @pri_index is empty anyway
+
+  my %pri_vals = map { ($_ => $copy[$_]) } @pri_index;
+
+  my @const_rows;
+
+  do { # no need to check anything at the front, we always want the first row
+
+    my %const;
   
-  my @collapse;
-  if (defined $prefix) {
-    @collapse = map {
-        m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
-    } keys %{$self->{_attrs}{collapse}}
-  } else {
-    @collapse = keys %{$self->{_attrs}{collapse}};
-  };
-
-  if (@collapse) {
-    my ($c) = sort { length $a <=> length $b } @collapse;
-    my $target = $info;
-    foreach my $p (split(/\./, $c)) {
-      $target = $target->[1]->{$p} ||= [];
+    foreach my $this_as (@construct_as) {
+      $const{$this_as->[0]||''}{$this_as->[1]} = shift(@copy);
     }
-    my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
-    my @co_key = @{$self->{_attrs}{collapse}{$c_prefix}};
-    my $tree = $self->_collapse_result($as, $row, $c_prefix);
-    my %co_check = map { ($_, $tree->[0]->{$_}); } @co_key;
-    my (@final, @raw);
 
-    while (
-      !(
+    push(@const_rows, \%const);
+
+  } until ( # no pri_index => no collapse => drop straight out
+      !@pri_index
+    or
+      do { # get another row, stash it, drop out if different PK
+
+        @copy = $self->cursor->next;
+        $self->{stashed_row} = \@copy;
+
+        # last thing in do block, counts as true if anything doesn't match
+
+        # check xor defined first for NULL vs. NOT NULL then if one is
+        # defined the other must be so check string equality
+
         grep {
-          !defined($tree->[0]->{$_}) || $co_check{$_} ne $tree->[0]->{$_}
-        } @co_key
-        )
-    ) {
-      push(@final, $tree);
-      last unless (@raw = $self->cursor->next);
-      $row = $self->{stashed_row} = \@raw;
-      $tree = $self->_collapse_result($as, $row, $c_prefix);
+          (defined $pri_vals{$_} ^ defined $copy[$_])
+          || (defined $pri_vals{$_} && ($pri_vals{$_} ne $copy[$_]))
+        } @pri_index;
+      }
+  );
+
+  my $alias = $self->{attrs}{alias};
+  my $info = [];
+
+  my %collapse_pos;
+
+  my @const_keys;
+
+  use Data::Dumper;
+
+  foreach my $const (@const_rows) {
+    scalar @const_keys or do {
+      @const_keys = sort { length($a) <=> length($b) } keys %$const;
+    };
+    foreach my $key (@const_keys) {
+      if (length $key) {
+        my $target = $info;
+        my @parts = split(/\./, $key);
+        my $cur = '';
+        my $data = $const->{$key};
+        foreach my $p (@parts) {
+          $target = $target->[1]->{$p} ||= [];
+          $cur .= ".${p}";
+          if ($cur eq ".${key}" && (my @ckey = @{$collapse{$cur}||[]})) { 
+            # collapsing at this point and on final part
+            my $pos = $collapse_pos{$cur};
+            CK: foreach my $ck (@ckey) {
+              if (!defined $pos->{$ck} || $pos->{$ck} ne $data->{$ck}) {
+                $collapse_pos{$cur} = $data;
+                delete @collapse_pos{ # clear all positioning for sub-entries
+                  grep { m/^\Q${cur}.\E/ } keys %collapse_pos
+                };
+                push(@$target, []);
+                last CK;
+              }
+            }
+          }
+          if (exists $collapse{$cur}) {
+            $target = $target->[-1];
+          }
+        }
+        $target->[0] = $data;
+      } else {
+        $info->[0] = $const->{$key};
+      }
     }
-    @$target = (@final ? @final : [ {}, {} ]);
-      # single empty result to indicate an empty prefetched has_many
   }
 
-  #print "final info: " . Dumper($info);
   return $info;
 }
 
@@ -887,7 +935,9 @@
   my $count = $self->_count;
   return 0 unless $count;
 
-  $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
+  # need to take offset from resolved attrs
+
+  $count -= $self->{_attrs}{offset} if $self->{_attrs}{offset};
   $count = $self->{attrs}{rows} if
     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
   return $count;
@@ -922,7 +972,7 @@
   # offset, order by and page are not needed to count. record_filter is cdbi
   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
 
-  my $tmp_rs = (ref $self)->new($self->result_source, $attrs);
+  my $tmp_rs = (ref $self)->new($self->_source_handle, $attrs);
   my ($count) = $tmp_rs->cursor->next;
   return $count;
 }
@@ -1113,9 +1163,9 @@
     unless ref $values eq 'HASH';
 
   my $cond = $self->_cond_for_update_delete;
-
+   
   return $self->result_source->storage->update(
-    $self->result_source->from, $values, $cond
+    $self->result_source, $values, $cond
   );
 }
 
@@ -1165,7 +1215,7 @@
 
   my $cond = $self->_cond_for_update_delete;
 
-  $self->result_source->storage->delete($self->result_source->from, $cond);
+  $self->result_source->storage->delete($self->result_source, $cond);
   return 1;
 }
 
@@ -1190,6 +1240,137 @@
   return 1;
 }
 
+=head2 populate
+
+=over 4
+
+=item Arguments: \@data;
+
+=back
+
+Pass an arrayref of hashrefs. Each hashref should be a structure suitable for
+submitting to a $resultset->create(...) method.
+
+In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
+to insert the data, as this is a faster method.
+
+Otherwise, each set of data is inserted into the database using
+L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
+objects is returned.
+
+Example:  Assuming an Artist Class that has many CDs Classes relating:
+
+  my $Artist_rs = $schema->resultset("Artist");
+  
+  ## Void Context Example 
+  $Artist_rs->populate([
+     { artistid => 4, name => 'Manufactured Crap', cds => [ 
+        { title => 'My First CD', year => 2006 },
+        { title => 'Yet More Tweeny-Pop crap', year => 2007 },
+      ],
+     },
+     { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
+        { title => 'My parents sold me to a record company' ,year => 2005 },
+        { title => 'Why Am I So Ugly?', year => 2006 },
+        { title => 'I Got Surgery and am now Popular', year => 2007 }
+      ],
+     },
+  ]);
+  
+  ## Array Context Example
+  my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
+    { name => "Artist One"},
+    { name => "Artist Two"},
+    { name => "Artist Three", cds=> [
+    { title => "First CD", year => 2007},
+    { title => "Second CD", year => 2008},
+  ]}
+  ]);
+  
+  print $ArtistOne->name; ## response is 'Artist One'
+  print $ArtistThree->cds->count ## reponse is '2'
+
+=cut
+
+sub populate {
+  my ($self, $data) = @_;
+  
+  if(defined wantarray) {
+    my @created;
+    foreach my $item (@$data) {
+      push(@created, $self->create($item));
+    }
+    return @created;
+  } else {
+    my ($first, @rest) = @$data;
+
+    my @names = grep {!ref $first->{$_}} keys %$first;
+    my @rels = grep { $self->result_source->has_relationship($_) } keys %$first;
+    my @pks = $self->result_source->primary_columns;  
+
+    ## do the belongs_to relationships  
+    foreach my $index (0..$#$data) {
+      if( grep { !defined $data->[$index]->{$_} } @pks ) {
+        my @ret = $self->populate($data);
+        return;
+      }
+    
+      foreach my $rel (@rels) {
+        next unless $data->[$index]->{$rel} && ref $data->[$index]->{$rel} eq "HASH";
+        my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
+        my ($reverse) = keys %{$self->result_source->reverse_relationship_info($rel)};
+        my $related = $result->result_source->resolve_condition(
+          $result->result_source->relationship_info($reverse)->{cond},
+          $self,        
+          $result,        
+        );
+
+        delete $data->[$index]->{$rel};
+        $data->[$index] = {%{$data->[$index]}, %$related};
+      
+        push @names, keys %$related if $index == 0;
+      }
+    }
+
+    ## do bulk insert on current row
+    my @values = map {
+      [ map {
+         defined $_ ? $_ : $self->throw_exception("Undefined value for column!")
+      } @$_{@names} ]
+    } @$data;
+
+    $self->result_source->storage->insert_bulk(
+      $self->result_source, 
+      \@names, 
+      \@values,
+    );
+
+    ## do the has_many relationships
+    foreach my $item (@$data) {
+
+      foreach my $rel (@rels) {
+        next unless $item->{$rel} && ref $item->{$rel} eq "ARRAY";
+
+        my $parent = $self->find(map {{$_=>$item->{$_}} } @pks) 
+     || $self->throw_exception('Cannot find the relating object.');
+     
+        my $child = $parent->$rel;
+    
+        my $related = $child->result_source->resolve_condition(
+          $parent->result_source->relationship_info($rel)->{cond},
+          $child,
+          $parent,
+        );
+
+        my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
+        my @populate = map { {%$_, %$related} } @rows_to_add;
+
+        $child->populate( \@populate );
+      }
+    }
+  }
+}
+
 =head2 pager
 
 =over 4
@@ -1233,7 +1414,7 @@
 
 sub page {
   my ($self, $page) = @_;
-  return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
+  return (ref $self)->new($self->_source_handle, { %{$self->{attrs}}, page => $page });
 }
 
 =head2 new_result
@@ -1263,11 +1444,11 @@
   my %new = (
     %{ $self->_remove_alias($values, $alias) },
     %{ $self->_remove_alias($collapsed_cond, $alias) },
-    -result_source => $self->result_source,
+    -source_handle => $self->_source_handle,
+    -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
   );
 
-  my $obj = $self->result_class->new(\%new);
-  return $obj;
+  return $self->result_class->new(\%new);
 }
 
 # _collapse_cond
@@ -1561,7 +1742,7 @@
     my $rel_obj = $self->result_source->relationship_info($rel);
 
     $self->throw_exception(
-      "search_related: result source '" . $self->result_source->name .
+      "search_related: result source '" . $self->_source_handle->source_moniker .
         "' has no such relationship $rel")
       unless $rel_obj;
     
@@ -1570,18 +1751,36 @@
     my $join_count = $seen->{$rel};
     my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
 
-    $self->result_source->schema->resultset($rel_obj->{class})->search_rs(
-      undef, {
-        %{$self->{attrs}||{}},
-        join => undef,
-        prefetch => undef,
-        select => undef,
-        as => undef,
-        alias => $alias,
-        where => $self->{cond},
-        seen_join => $seen,
-        from => $from,
-    });
+    #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
+    my %attrs = %{$self->{attrs}||{}};
+    delete $attrs{result_class};
+
+    my $new_cache;
+
+    if (my $cache = $self->get_cache) {
+      if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
+        $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
+                        @$cache ];
+      }
+    }
+
+    my $new = $self->_source_handle
+                   ->schema
+                   ->resultset($rel_obj->{class})
+                   ->search_rs(
+                       undef, {
+                         %attrs,
+                         join => undef,
+                         prefetch => undef,
+                         select => undef,
+                         as => undef,
+                         alias => $alias,
+                         where => $self->{cond},
+                         seen_join => $seen,
+                         from => $from,
+                     });
+    $new->set_cache($new_cache) if $new_cache;
+    $new;
   };
 }
 
@@ -1611,7 +1810,7 @@
   return $self->{_attrs} if $self->{_attrs};
 
   my $attrs = { %{$self->{attrs}||{}} };
-  my $source = $self->{result_source};
+  my $source = $self->result_source;
   my $alias = $attrs->{alias};
 
   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
@@ -1696,6 +1895,11 @@
   }
   $attrs->{collapse} = $collapse;
 
+  if ($attrs->{page}) {
+    $attrs->{offset} ||= 0;
+    $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
+  }
+
   return $self->{_attrs} = $attrs;
 }
 
@@ -1743,6 +1947,16 @@
   }
 }
 
+sub result_source {
+    my $self = shift;
+
+    if (@_) {
+        $self->_source_handle($_[0]->handle);
+    } else {
+        $self->_source_handle->resolve;
+    }
+}
+
 =head2 throw_exception
 
 See L<DBIx::Class::Schema/throw_exception> for details.
@@ -1751,7 +1965,7 @@
 
 sub throw_exception {
   my $self=shift;
-  $self->result_source->schema->throw_exception(@_);
+  $self->_source_handle->schema->throw_exception(@_);
 }
 
 # XXX: FIXME: Attributes docs need clearing up
@@ -1773,8 +1987,8 @@
 through directly to SQL, so you can give e.g. C<year DESC> for a
 descending order on the column `year'.
 
-Please note that if you have quoting enabled (see
-L<DBIx::Class::Storage/quote_char>) you will need to do C<\'year DESC' > to
+Please note that if you have C<quote_char> enabled (see
+L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
 so you will need to manually quote things as appropriate.)
 

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSetColumn.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSetColumn.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -35,12 +35,8 @@
 sub new {
   my ($class, $rs, $column) = @_;
   $class = ref $class if ref $class;
-
-  my $object_ref = { _column => $column,
-		     _parent_resultset => $rs };
-  
-  my $new = bless $object_ref, $class;
-  $new->throw_exception("column must be supplied") unless ($column);
+  my $new = bless { _column => $column, _parent_resultset => $rs }, $class;
+  $new->throw_exception("column must be supplied") unless $column;
   return $new;
 }
 
@@ -64,7 +60,6 @@
 
 sub next {
   my $self = shift;
-    
   $self->{_resultset} = $self->{_parent_resultset}->search(undef, {select => [$self->{_column}], as => [$self->{_column}]}) unless ($self->{_resultset});
   my ($row) = $self->{_resultset}->cursor->next;
   return $row;
@@ -111,8 +106,7 @@
 =cut
 
 sub min {
-  my $self = shift;
-  return $self->func('MIN');
+  return shift->func('MIN');
 }
 
 =head2 max
@@ -133,8 +127,7 @@
 =cut
 
 sub max {
-  my $self = shift;
-  return $self->func('MAX');
+  return shift->func('MAX');
 }
 
 =head2 sum
@@ -155,8 +148,7 @@
 =cut
 
 sub sum {
-  my $self = shift;
-  return $self->func('SUM');
+  return shift->func('SUM');
 }
 
 =head2 func
@@ -180,9 +172,7 @@
 =cut
 
 sub func {
-  my $self = shift;
-  my $function = shift;
-
+  my ($self,$function) = @_;
   my ($row) = $self->{_parent_resultset}->search(undef, {select => {$function => $self->{_column}}, as => [$self->{_column}]})->cursor->next;
   return $row;
 }

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSource/Table.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSource/Table.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSource/Table.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,8 +5,6 @@
 
 use DBIx::Class::ResultSet;
 
-use Carp qw/croak/;
-
 use base qw/DBIx::Class/;
 __PACKAGE__->load_components(qw/ResultSource/);
 

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSource.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSource.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSource.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -4,15 +4,16 @@
 use warnings;
 
 use DBIx::Class::ResultSet;
+use DBIx::Class::ResultSourceHandle;
 use Carp::Clan qw/^DBIx::Class/;
 use Storable;
 
 use base qw/DBIx::Class/;
-__PACKAGE__->load_components(qw/AccessorGroup/);
 
 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
   _columns _primaries _unique_constraints name resultset_attributes
-  schema from _relationships column_info_from_storage source_name/);
+  schema from _relationships column_info_from_storage source_info
+  source_name/);
 
 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
   result_class/);
@@ -46,9 +47,7 @@
   my ($class, $attrs) = @_;
   $class = ref $class if ref $class;
 
-  my $new = { %{$attrs || {}}, _resultset => undef };
-  bless $new, $class;
-
+  my $new = bless { %{$attrs || {}} }, $class;
   $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
   $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
   $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
@@ -56,14 +55,22 @@
   $new->{_relationships} = { %{$new->{_relationships}||{}} };
   $new->{name} ||= "!!NAME NOT SET!!";
   $new->{_columns_info_loaded} ||= 0;
-  if(!defined $new->column_info_from_storage) {
-      $new->{column_info_from_storage} = 1
-  }
   return $new;
 }
 
 =pod
 
+=head2 source_info
+
+Stores a hashref of per-source metadata.  No specific key names
+have yet been standardized, the examples below are purely hypothetical
+and don't actually accomplish anything on their own:
+
+  __PACKAGE__->source_info({
+    "_tablespace" => 'fast_disk_array_3',
+    "_engine" => 'InnoDB',
+  });
+
 =head2 add_columns
 
   $table->add_columns(qw/col1 col2 col3/);
@@ -167,7 +174,7 @@
   return $self;
 }
 
-*add_column = \&add_columns;
+sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
 
 =head2 has_column
 
@@ -223,13 +230,10 @@
 
 =head2 column_info_from_storage
 
-Enables or disables the on-demand automatic loading of the above
-column metadata from storage as neccesary.  Defaults to true in the
-current release, but will default to false in future releases starting
-with 0.08000.  This is *deprecated*, and should not be used.  It will
-be removed before 1.0.
+Enables the on-demand automatic loading of the above column
+metadata from storage as neccesary.  This is *deprecated*, and
+should not be used.  It will be removed before 1.0.
 
-  __PACKAGE__->column_info_from_storage(0);
   __PACKAGE__->column_info_from_storage(1);
 
 =head2 columns
@@ -281,7 +285,7 @@
   $self->_ordered_columns(\@remaining);
 }
 
-*remove_column = \&remove_columns;
+sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
 
 =head2 set_primary_key
 
@@ -708,16 +712,22 @@
 =cut
 
 sub resolve_join {
-  my ($self, $join, $alias, $seen) = @_;
+  my ($self, $join, $alias, $seen, $force_left) = @_;
   $seen ||= {};
+  $force_left ||= { force => 0 };
   if (ref $join eq 'ARRAY') {
     return map { $self->resolve_join($_, $alias, $seen) } @$join;
   } elsif (ref $join eq 'HASH') {
     return
       map {
         my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
-        ($self->resolve_join($_, $alias, $seen),
-          $self->related_source($_)->resolve_join($join->{$_}, $as, $seen));
+        local $force_left->{force};
+        (
+          $self->resolve_join($_, $alias, $seen, $force_left),
+          $self->related_source($_)->resolve_join(
+            $join->{$_}, $as, $seen, $force_left
+          )
+        );
       } keys %$join;
   } elsif (ref $join) {
     $self->throw_exception("No idea how to resolve join reftype ".ref $join);
@@ -727,7 +737,13 @@
     my $as = ($count > 1 ? "${join}_${count}" : $join);
     my $rel_info = $self->relationship_info($join);
     $self->throw_exception("No such relationship ${join}") unless $rel_info;
-    my $type = $rel_info->{attrs}{join_type} || '';
+    my $type;
+    if ($force_left->{force}) {
+      $type = 'left';
+    } else {
+      $type = $rel_info->{attrs}{join_type} || '';
+      $force_left->{force} = 1 if lc($type) eq 'left';
+    }
     return [ { $as => $self->related_source($join)->from,
                -join_type => $type },
              $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
@@ -766,6 +782,8 @@
         #warn %ret;
       } elsif (!defined $for) { # undef, i.e. "no object"
         $ret{$k} = undef;
+      } elsif (ref $as eq 'HASH') { # reverse hashref
+        $ret{$v} = $as->{$k};
       } elsif (ref $as) { # reverse object
         $ret{$v} = $as->get_column($k);
       } elsif (!defined $as) { # undef, i.e. "no reverse object"
@@ -869,9 +887,13 @@
       $self->throw_exception(
         "Can't prefetch has_many ${pre} (join cond too complex)")
         unless ref($rel_info->{cond}) eq 'HASH';
+      #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
+      #              values %{$rel_info->{cond}};
+      $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
+        # action at a distance. prepending the '.' allows simpler code
+        # in ResultSet->_collapse_result
       my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
                     keys %{$rel_info->{cond}};
-      $collapse->{"${as_prefix}${pre}"} = \@key;
       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
                    ? @{$rel_info->{attrs}{order_by}}
                    : (defined $rel_info->{attrs}{order_by}
@@ -965,12 +987,6 @@
     'call it on the schema instead.'
   ) if scalar @_;
 
-  # disabled until we can figure out a way to do it without consistency issues
-  #
-  #return $self->{_resultset}
-  #  if ref $self->{_resultset} eq $self->resultset_class;
-  #return $self->{_resultset} =
-
   return $self->resultset_class->new(
     $self, $self->{resultset_attributes}
   );
@@ -996,6 +1012,20 @@
   # from your schema...
   $schema->resultset('Books')->find(1);
 
+=head2 handle
+
+Obtain a new handle to this source. Returns an instance of a 
+L<DBIx::Class::ResultSourceHandle>.
+
+=cut
+
+sub handle {
+    return new DBIx::Class::ResultSourceHandle({
+        schema         => $_[0]->schema,
+        source_moniker => $_[0]->source_name
+    });
+}
+
 =head2 throw_exception
 
 See L<DBIx::Class::Schema/"throw_exception">.
@@ -1021,3 +1051,4 @@
 
 =cut
 
+1;

Added: trunk/DBIx-Class/lib/DBIx/Class/ResultSourceHandle.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSourceHandle.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSourceHandle.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,88 @@
+package DBIx::Class::ResultSourceHandle;
+
+use strict;
+use warnings;
+use Storable;
+
+use base qw/DBIx::Class/;
+
+use overload
+    q/""/ => sub { __PACKAGE__ . ":" . shift->source_moniker; },
+    fallback => 1;
+
+__PACKAGE__->mk_group_accessors('simple' => qw/schema source_moniker/);
+
+=head1 NAME
+
+DBIx::Class::ResultSourceHandle
+
+=head1 DESCRIPTION
+
+This module removes fixed link between Rows/ResultSets and the actual source
+objects, which gets round the following problems
+
+=over 4
+
+=item *
+
+Needing to keep C<$schema> in scope, since any objects/result_sets
+will have a C<$schema> object through their source handle
+
+=item *
+
+Large output when using Data::Dump(er) since this class can be set to
+stringify to almost nothing
+
+=item *
+
+Closer to being able to do a Serialize::Storable that doesn't require class-based connections
+
+=back
+
+=head1 METHODS
+
+=head2 new
+
+=cut
+
+sub new {
+    my ($class, $data) = @_;
+
+    $class = ref $class if ref $class;
+
+    bless $data, $class;
+}
+
+=head2 resolve
+
+Resolve the moniker into the actual ResultSource object
+
+=cut
+
+sub resolve { return $_[0]->schema->source($_[0]->source_moniker) }
+
+=head2 STORABLE_freeze
+
+Freezes a handle.
+
+=cut
+
+sub STORABLE_freeze {
+    my ($self, $cloning) = @_;
+    my $to_serialize = { %$self };
+    delete $to_serialize->{schema};
+    return (Storable::freeze($to_serialize));
+}
+
+=head2 STORABLE_thaw
+
+Thaws frozen handle.
+
+=cut
+
+sub STORABLE_thaw {
+    my ($self, $cloning,$ice) = @_;
+    %$self = %{ Storable::thaw($ice) };
+}
+
+1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy/Table.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy/Table.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy/Table.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -4,11 +4,11 @@
 use warnings;
 
 use base qw/DBIx::Class::ResultSourceProxy/;
-__PACKAGE__->load_components(qw/AccessorGroup/);
 
-__PACKAGE__->mk_group_accessors('component_class' => 'table_class');
-__PACKAGE__->table_class('DBIx::Class::ResultSource::Table');
+use DBIx::Class::ResultSource::Table;
 
+__PACKAGE__->mk_classdata(table_class => 'DBIx::Class::ResultSource::Table');
+
 __PACKAGE__->mk_classdata('table_alias'); # FIXME: Doesn't actually do
                                           # anything yet!
 
@@ -53,7 +53,12 @@
         source_name => undef,
     });
   }
-  $class->mk_classdata('result_source_instance' => $table);
+
+  $class->mk_classdata('result_source_instance')
+    unless $class->can('result_source_instance');
+
+  $class->result_source_instance($table);
+
   if ($class->can('schema_instance')) {
     $class =~ m/([^:]+)$/;
     $class->schema_instance->register_class($class, $class);

Modified: trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/ResultSourceProxy.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,12 +5,29 @@
 use warnings;
 
 use base qw/DBIx::Class/;
+use Scalar::Util qw/blessed/;
+use Carp::Clan qw/^DBIx::Class/;
 
 sub iterator_class  { shift->result_source_instance->resultset_class(@_) }
 sub resultset_class { shift->result_source_instance->resultset_class(@_) }
 sub result_class { shift->result_source_instance->result_class(@_) }
-sub source_name { shift->result_source_instance->source_name(@_) }
+sub source_info { shift->result_source_instance->source_info(@_) }
 
+sub set_inherited_ro_instance {
+    my $self = shift;
+
+    croak "Cannot set @{[shift]} on an instance" if blessed $self;
+
+    return $self->set_inherited(@_);
+}
+
+sub get_inherited_ro_instance {
+    return shift->get_inherited(@_);
+}
+
+__PACKAGE__->mk_group_accessors('inherited_ro_instance' => 'source_name');
+
+
 sub resultset_attributes {
   shift->result_source_instance->resultset_attributes(@_);
 }

Modified: trunk/DBIx-Class/lib/DBIx/Class/Row.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Row.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Row.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,11 +5,10 @@
 
 use base qw/DBIx::Class/;
 use Carp::Clan qw/^DBIx::Class/;
+use Scalar::Util ();
 
-__PACKAGE__->load_components(qw/AccessorGroup/);
+__PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/);
 
-__PACKAGE__->mk_group_accessors('simple' => 'result_source');
-
 =head1 NAME
 
 DBIx::Class::Row - Basic row methods
@@ -29,8 +28,21 @@
 
 Creates a new row object from column => value mappings passed as a hash ref
 
+Passing an object, or an arrayref of objects as a value will call
+L<DBIx::Class::Relationship::Base/set_from_related> for you. When
+passed a hashref or an arrayref of hashrefs as the value, these will
+be turned into objects via new_related, and treated as if you had
+passed objects.
+
 =cut
 
+## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
+## This only works because DBIC doesnt yet care to check whether the new_related objects have been passed all their mandatory columns
+## When doing the later insert, we need to make sure the PKs are set.
+## using _relationship_data in new and funky ways..
+## check Relationship::CascadeActions and Relationship::Accessor for compat
+## tests!
+
 sub new {
   my ($class, $attrs) = @_;
   $class = ref $class if ref $class;
@@ -38,17 +50,73 @@
   my $new = { _column_data => {} };
   bless $new, $class;
 
+  if (my $handle = delete $attrs->{-source_handle}) {
+    $new->_source_handle($handle);
+  }
+  if (my $source = delete $attrs->{-result_source}) {
+    $new->result_source($source);
+  }
+
   if ($attrs) {
     $new->throw_exception("attrs must be a hashref")
       unless ref($attrs) eq 'HASH';
-    if (my $source = delete $attrs->{-result_source}) {
-      $new->result_source($source);
+    
+    my ($related,$inflated);
+    ## Pretend all the rels are actual objects, unset below if not, for insert() to fix
+    $new->{_rel_in_storage} = 1;
+
+    foreach my $key (keys %$attrs) {
+      if (ref $attrs->{$key}) {
+        ## Can we extract this lot to use with update(_or .. ) ?
+        my $info = $class->relationship_info($key);
+        if ($info && $info->{attrs}{accessor}
+          && $info->{attrs}{accessor} eq 'single')
+        {
+          my $rel_obj = delete $attrs->{$key};
+          if(!Scalar::Util::blessed($rel_obj)) {
+            $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+          }
+          $new->set_from_related($key, $rel_obj);        
+          $related->{$key} = $rel_obj;
+          next;
+        } elsif ($info && $info->{attrs}{accessor}
+            && $info->{attrs}{accessor} eq 'multi'
+            && ref $attrs->{$key} eq 'ARRAY') {
+          my $others = delete $attrs->{$key};
+          foreach my $rel_obj (@$others) {
+            if(!Scalar::Util::blessed($rel_obj)) {
+              $rel_obj = $new->new_related($key, $rel_obj);
+              $new->{_rel_in_storage} = 0;
+            }
+          }
+          $related->{$key} = $others;
+          next;
+        } elsif ($info && $info->{attrs}{accessor}
+          && $info->{attrs}{accessor} eq 'filter')
+        {
+          ## 'filter' should disappear and get merged in with 'single' above!
+          my $rel_obj = delete $attrs->{$key};
+          if(!Scalar::Util::blessed($rel_obj)) {
+            $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+          }
+          $inflated->{$key} = $rel_obj;
+          next;
+        } elsif ($class->has_column($key)
+            && $class->column_info($key)->{_inflate_info}) {
+          $inflated->{$key} = $attrs->{$key};
+          next;
+        }
+      }
+      use Data::Dumper;
+      $new->throw_exception("No such column $key on $class")
+        unless $class->has_column($key);
+      $new->store_column($key => $attrs->{$key});          
     }
-    foreach my $k (keys %$attrs) {
-      $new->throw_exception("No such column $k on $class")
-        unless $class->has_column($k);
-      $new->store_column($k => $attrs->{$k});
-    }
+
+    $new->{_relationship_data} = $related if $related;
+    $new->{_inflated_column} = $inflated if $inflated;
   }
 
   return $new;
@@ -69,13 +137,70 @@
 sub insert {
   my ($self) = @_;
   return $self if $self->in_storage;
-  $self->{result_source} ||= $self->result_source_instance
+  my $source = $self->result_source;
+  $source ||=  $self->result_source($self->result_source_instance)
     if $self->can('result_source_instance');
-  my $source = $self->{result_source};
   $self->throw_exception("No result_source set on this object; can't insert")
     unless $source;
-  #use Data::Dumper; warn Dumper($self);
-  $source->storage->insert($source->from, { $self->get_columns });
+
+  # Check if we stored uninserted relobjs here in new()
+  my %related_stuff = (%{$self->{_relationship_data} || {}}, 
+                       %{$self->{_inflated_column} || {}});
+  if(!$self->{_rel_in_storage})
+  {
+    $source->storage->txn_begin;
+
+    ## Should all be in relationship_data, but we need to get rid of the
+    ## 'filter' reltype..
+    ## These are the FK rels, need their IDs for the insert.
+    foreach my $relname (keys %related_stuff) {
+      my $rel_obj = $related_stuff{$relname};
+      if(Scalar::Util::blessed($rel_obj) && $rel_obj->isa('DBIx::Class::Row')) {
+        $rel_obj->insert();
+        $self->set_from_related($relname, $rel_obj);
+      }
+    }
+  }
+
+  $source->storage->insert($source, { $self->get_columns });
+
+  ## PK::Auto
+  my @auto_pri = grep {
+                   !defined $self->get_column($_) || 
+                   ref($self->get_column($_)) eq 'SCALAR'
+                 } $self->primary_columns;
+
+  if (@auto_pri) {
+    #$self->throw_exception( "More than one possible key found for auto-inc on ".ref $self )
+    #  if defined $too_many;
+
+    my $storage = $self->result_source->storage;
+    $self->throw_exception( "Missing primary key but Storage doesn't support last_insert_id" )
+      unless $storage->can('last_insert_id');
+    my @ids = $storage->last_insert_id($self->result_source, at auto_pri);
+    $self->throw_exception( "Can't get last insert id" )
+      unless (@ids == @auto_pri);
+    $self->store_column($auto_pri[$_] => $ids[$_]) for 0 .. $#ids;
+  }
+
+  if(!$self->{_rel_in_storage})
+  {
+    ## Now do the has_many rels, that need $selfs ID.
+    foreach my $relname (keys %related_stuff) {
+      my $relobj = $related_stuff{$relname};
+      if(ref $relobj eq 'ARRAY') {
+        foreach my $obj (@$relobj) {
+          my $info = $self->relationship_info($relname);
+          ## What about multi-col FKs ?
+          my $key = $1 if($info && (keys %{$info->{cond}})[0] =~ /^foreign\.(\w+)/);
+          $obj->set_from_related($key, $self);
+          $obj->insert() if(!$obj->in_storage);
+        }
+      }
+    }
+    $source->storage->txn_commit;
+  }
+
   $self->in_storage(1);
   $self->{_dirty_columns} = {};
   $self->{related_resultsets} = {};
@@ -119,11 +244,45 @@
   my $ident_cond = $self->ident_condition;
   $self->throw_exception("Cannot safely update a row in a PK-less table")
     if ! keys %$ident_cond;
-  $self->set_columns($upd) if $upd;
+
+  if ($upd) {
+    foreach my $key (keys %$upd) {
+      if (ref $upd->{$key}) {
+        my $info = $self->relationship_info($key);
+        if ($info && $info->{attrs}{accessor}
+          && $info->{attrs}{accessor} eq 'single')
+        {
+          my $rel = delete $upd->{$key};
+          $self->set_from_related($key => $rel);
+          $self->{_relationship_data}{$key} = $rel;          
+        } elsif ($info && $info->{attrs}{accessor}
+            && $info->{attrs}{accessor} eq 'multi'
+            && ref $upd->{$key} eq 'ARRAY') {
+            my $others = delete $upd->{$key};
+            foreach my $rel_obj (@$others) {
+              if(!Scalar::Util::blessed($rel_obj)) {
+                $rel_obj = $self->create_related($key, $rel_obj);
+              }
+            }
+            $self->{_relationship_data}{$key} = $others; 
+#            $related->{$key} = $others;
+            next;
+        }
+        elsif ($self->has_column($key)
+          && exists $self->column_info($key)->{_inflate_info})
+        {
+          $self->set_inflated_column($key, delete $upd->{$key});          
+        }
+      }
+    }
+    $self->set_columns($upd);    
+  }
   my %to_update = $self->get_dirty_columns;
   return $self unless keys %to_update;
   my $rows = $self->result_source->storage->update(
-               $self->result_source->from, \%to_update, $self->{_orig_ident} || $ident_cond);
+               $self->result_source, \%to_update,
+               $self->{_orig_ident} || $ident_cond
+             );
   if ($rows == 0) {
     $self->throw_exception( "Can't update ${self}: row not found" );
   } elsif ($rows > 1) {
@@ -140,8 +299,8 @@
   $obj->delete
 
 Deletes the object from the database. The object is still perfectly
-usable, but C<-E<gt>in_storage()> will now return 0 and the object must
-reinserted using C<-E<gt>insert()> before C<-E(<gt>update()> can be used
+usable, but C<< ->in_storage() >> will now return 0 and the object must
+reinserted using C<< ->insert() >> before C<< ->update() >> can be used
 on it. If you delete an object in a class with a C<has_many>
 relationship, all the related objects will be deleted as well. To turn
 this behavior off, pass C<cascade_delete => 0> in the C<$attr>
@@ -162,7 +321,7 @@
               unless exists $self->{_column_data}{$column};
     }
     $self->result_source->storage->delete(
-      $self->result_source->from, $ident_cond);
+      $self->result_source, $ident_cond);
     $self->in_storage(undef);
   } else {
     $self->throw_exception("Can't do class delete without a ResultSource instance")
@@ -178,9 +337,10 @@
 
   my $val = $obj->get_column($col);
 
-Gets a column value from a row object. Currently, does not do
-any queries; the column must have already been fetched from
-the database and stored in the object.
+Gets a column value from a row object. Does not do any queries; the column 
+must have already been fetched from the database and stored in the object. If 
+there is an inflated value stored that has not yet been deflated, it is deflated
+when the method is invoked.
 
 =cut
 
@@ -188,6 +348,10 @@
   my ($self, $column) = @_;
   $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
   return $self->{_column_data}{$column} if exists $self->{_column_data}{$column};
+  if (exists $self->{_inflated_column}{$column}) {
+    return $self->store_column($column,
+      $self->_deflated_column($column, $self->{_inflated_column}{$column}));   
+  }
   $self->throw_exception( "No such column '${column}'" ) unless $self->has_column($column);
   return undef;
 }
@@ -206,6 +370,7 @@
 sub has_column_loaded {
   my ($self, $column) = @_;
   $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
+  return 1 if exists $self->{_inflated_column}{$column};
   return exists $self->{_column_data}{$column};
 }
 
@@ -219,6 +384,12 @@
 
 sub get_columns {
   my $self = shift;
+  if (exists $self->{_inflated_column}) {
+    foreach my $col (keys %{$self->{_inflated_column}}) {
+      $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
+        unless exists $self->{_column_data}{$col};
+    }
+  }
   return %{$self->{_column_data}};
 }
 
@@ -236,6 +407,22 @@
            keys %{$self->{_dirty_columns}};
 }
 
+=head2 get_inflated_columns
+
+  my $inflated_data = $obj->get_inflated_columns;
+
+Similar to get_columns but objects are returned for inflated columns instead of their raw non-inflated values.
+
+=cut
+
+sub get_inflated_columns {
+  my $self = shift;
+  return map {
+    my $accessor = $self->column_info($_)->{'accessor'} || $_;
+    ($_ => $self->$accessor);
+  } $self->columns;
+}
+
 =head2 set_column
 
   $obj->set_column($col => $val);
@@ -335,9 +522,17 @@
 
 sub inflate_result {
   my ($class, $source, $me, $prefetch) = @_;
-  #use Data::Dumper; print Dumper(@_);
+
+  my ($source_handle) = $source;
+
+  if ($source->isa('DBIx::Class::ResultSourceHandle')) {
+      $source = $source_handle->resolve
+  } else {
+      $source_handle = $source->handle
+  }
+
   my $new = {
-    result_source => $source,
+    _source_handle => $source_handle,
     _column_data => $me,
     _in_storage => 1
   };
@@ -368,6 +563,7 @@
         $fetched = $pre_source->result_class->inflate_result(
                       $pre_source, @{$pre_val});
       }
+      $new->related_resultset($pre)->set_cache([ $fetched ]);
       my $accessor = $source->relationship_info($pre)->{attrs}{accessor};
       $class->throw_exception("No accessor for prefetched $pre")
        unless defined $accessor;
@@ -437,6 +633,18 @@
 
 Accessor to the ResultSource this object was created from
 
+=cut
+
+sub result_source {
+    my $self = shift;
+
+    if (@_) {
+        $self->_source_handle($_[0]->handle);
+    } else {
+        $self->_source_handle->resolve;
+    }
+}
+
 =head2 register_column
 
   $column_info = { .... };
@@ -470,7 +678,7 @@
 
 sub throw_exception {
   my $self=shift;
-  if (ref $self && ref $self->result_source) {
+  if (ref $self && ref $self->result_source && $self->result_source->schema) {
     $self->result_source->schema->throw_exception(@_);
   } else {
     croak(@_);

Added: trunk/DBIx-Class/lib/DBIx/Class/Schema/Versioned.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Schema/Versioned.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/Schema/Versioned.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,321 @@
+package DBIx::Class::Version::Table;
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('SchemaVersions');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'name' => 'Version',
+        'is_nullable' => 0,
+        'size' => '10'
+        },
+      'Installed' => {
+          'data_type' => 'VARCHAR',
+          'is_auto_increment' => 0,
+          'default_value' => undef,
+          'is_foreign_key' => 0,
+          'name' => 'Installed',
+          'is_nullable' => 0,
+          'size' => '20'
+          },
+      );
+__PACKAGE__->set_primary_key('Version');
+
+package DBIx::Class::Version;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+__PACKAGE__->register_class('Table', 'DBIx::Class::Version::Table');
+
+
+# ---------------------------------------------------------------------------
+package DBIx::Class::Schema::Versioned;
+
+use strict;
+use warnings;
+use base 'DBIx::Class';
+use POSIX 'strftime';
+use Data::Dumper;
+
+__PACKAGE__->mk_classdata('_filedata');
+__PACKAGE__->mk_classdata('upgrade_directory');
+__PACKAGE__->mk_classdata('backup_directory');
+
+sub schema_version {
+  my ($self) = @_;
+  my $class = ref($self)||$self;
+  my $version;
+  {
+    no strict 'refs';
+    $version = ${"${class}::VERSION"};
+  }
+  return $version;
+}
+
+sub _on_connect
+{
+    my ($self) = @_;
+    my $vschema = DBIx::Class::Version->connect(@{$self->storage->connect_info()});
+    my $vtable = $vschema->resultset('Table');
+    my $pversion;
+
+    if(!$self->exists($vtable))
+    {
+#        $vschema->storage->debug(1);
+        $vschema->storage->ensure_connected();
+        $vschema->deploy();
+        $pversion = 0;
+    }
+    else
+    {
+        my $psearch = $vtable->search(undef, 
+                                      { select => [
+                                                   { 'max' => 'Installed' },
+                                                   ],
+                                            as => ['maxinstall'],
+                                        })->first;
+        $pversion = $vtable->search({ Installed => $psearch->get_column('maxinstall'),
+                                  })->first;
+        $pversion = $pversion->Version if($pversion);
+    }
+#    warn("Previous version: $pversion\n");
+    if($pversion eq $self->schema_version)
+    {
+        warn "This version is already installed\n";
+        return 1;
+    }
+
+## use IC::DT?    
+
+    if(!$pversion)
+    {
+        $vtable->create({ Version => $self->schema_version,
+                          Installed => strftime("%Y-%m-%d %H:%M:%S", gmtime())
+                          });
+        ## If we let the user do this, where does the Version table get updated?
+        warn "No previous version found, calling deploy to install this version.\n";
+        $self->deploy();
+        return 1;
+    }
+
+    my $file = $self->ddl_filename(
+                                   $self->storage->sqlt_type,
+                                   $self->upgrade_directory,
+                                   $self->schema_version
+                                   );
+    if(!$file)
+    {
+        # No upgrade path between these two versions
+        return 1;
+    }
+
+     $file = $self->ddl_filename(
+                                 $self->storage->sqlt_type,
+                                 $self->upgrade_directory,
+                                 $self->schema_version,
+                                 $pversion,
+                                 );
+#    $file =~ s/@{[ $self->schema_version ]}/"${pversion}-" . $self->schema_version/e;
+    if(!-f $file)
+    {
+        warn "Upgrade not possible, no upgrade file found ($file)\n";
+        return;
+    }
+
+    my $fh;
+    open $fh, "<$file" or warn("Can't open upgrade file, $file ($!)");
+    my @data = split(/;\n/, join('', <$fh>));
+    close($fh);
+    @data = grep { $_ && $_ !~ /^-- / } @data;
+    @data = grep { $_ !~ /^(BEGIN TRANACTION|COMMIT)/m } @data;
+
+    $self->_filedata(\@data);
+
+    ## Don't do this yet, do only on command?
+    ## If we do this later, where does the Version table get updated??
+    warn "Versions out of sync. This is " . $self->schema_version . 
+        ", your database contains version $pversion, please call upgrade on your Schema.\n";
+#    $self->upgrade($pversion, $self->schema_version);
+}
+
+sub exists
+{
+    my ($self, $rs) = @_;
+
+    my $c = eval {
+        $rs->search({ 1, 0 })->count;
+    };
+    return 0 if $@ || !defined $c;
+
+    return 1;
+}
+
+sub backup
+{
+    my ($self) = @_;
+    ## Make each ::DBI::Foo do this
+    $self->storage->backup($self->backup_directory());
+}
+
+sub upgrade
+{
+    my ($self) = @_;
+
+    ## overridable sub, per default just run all the commands.
+
+    $self->backup();
+
+    $self->run_upgrade(qr/create/i);
+    $self->run_upgrade(qr/alter table .*? add/i);
+    $self->run_upgrade(qr/alter table .*? (?!drop)/i);
+    $self->run_upgrade(qr/alter table .*? drop/i);
+    $self->run_upgrade(qr/drop/i);
+#    $self->run_upgrade(qr//i);
+
+    my $vschema = DBIx::Class::Version->connect(@{$self->storage->connect_info()});
+    my $vtable = $vschema->resultset('Table');
+    $vtable->create({ Version => $self->schema_version,
+                      Installed => strftime("%Y-%m-%d %H:%M:%S", gmtime())
+                      });
+}
+
+
+sub run_upgrade
+{
+    my ($self, $stm) = @_;
+#    print "Reg: $stm\n";
+    my @statements = grep { $_ =~ $stm } @{$self->_filedata};
+#    print "Statements: ", join("\n", @statements), "\n";
+    $self->_filedata([ grep { $_ !~ /$stm/i } @{$self->_filedata} ]);
+
+    for (@statements)
+    {
+        $self->storage->debugfh->print("$_\n") if $self->storage->debug;
+#        print "Running \n>>$_<<\n";
+        $self->storage->dbh->do($_) or warn "SQL was:\n $_";
+    }
+
+    return 1;
+}
+
+1;
+
+=head1 NAME
+
+DBIx::Class::Versioning - DBIx::Class::Schema plugin for Schema upgrades
+
+=head1 SYNOPSIS
+
+  package Library::Schema;
+  use base qw/DBIx::Class::Schema/;   
+  # load Library::Schema::CD, Library::Schema::Book, Library::Schema::DVD
+  __PACKAGE__->load_classes(qw/CD Book DVD/);
+
+  __PACKAGE__->load_components(qw/+DBIx::Class::Schema::Versioned/);
+  __PACKAGE__->upgrade_directory('/path/to/upgrades/');
+  __PACKAGE__->backup_directory('/path/to/backups/');
+
+  sub backup
+  {
+    my ($self) = @_;
+    # my special backup process
+  }
+
+  sub upgrade
+  {
+    my ($self) = @_;
+
+    ## overridable sub, per default just runs all the commands.
+
+    $self->run_upgrade(qr/create/i);
+    $self->run_upgrade(qr/alter table .*? add/i);
+    $self->run_upgrade(qr/alter table .*? (?!drop)/i);
+    $self->run_upgrade(qr/alter table .*? drop/i);
+    $self->run_upgrade(qr/drop/i);
+    $self->run_upgrade(qr//i);   
+  }
+
+=head1 DESCRIPTION
+
+This module is a component designed to extend L<DBIx::Class::Schema>
+classes, to enable them to upgrade to newer schema layouts. To use this
+module, you need to have called C<create_ddl_dir> on your Schema to
+create your upgrade files to include with your delivery.
+
+A table called I<SchemaVersions> is created and maintained by the
+module. This contains two fields, 'Version' and 'Installed', which
+contain each VERSION of your Schema, and the date+time it was installed.
+
+If you would like to influence which levels of version change need
+upgrades in your Schema, you can override the method C<ddl_filename>
+in L<DBIx::Class::Schema>. Return a false value if there is no upgrade
+path between the two versions supplied. By default, every change in
+your VERSION is regarded as needing an upgrade.
+
+The actual upgrade is called manually by calling C<upgrade> on your
+schema object. Code is run at connect time to determine whether an
+upgrade is needed, if so, a warning "Versions out of sync" is
+produced.
+
+NB: At the moment, SQLite upgrading is rather spotty, as SQL::Translator::Diff
+returns SQL statements that SQLite does not support.
+
+
+=head1 METHODS
+
+=head2 backup
+
+This is an overwritable method which is called just before the upgrade, to
+allow you to make a backup of the database. Per default this method attempts
+to call C<< $self->storage->backup >>, to run the standard backup on each
+database type. 
+
+This method should return the name of the backup file, if appropriate.
+
+C<backup> is called from C<upgrade>, make sure you call it, if you write your
+own <upgrade> method.
+
+=head2 upgrade
+
+This is an overwritable method used to run your upgrade. The freeform method
+allows you to run your upgrade any way you please, you can call C<run_upgrade>
+any number of times to run the actual SQL commands, and in between you can
+sandwich your data upgrading. For example, first run all the B<CREATE>
+commands, then migrate your data from old to new tables/formats, then 
+issue the DROP commands when you are finished.
+
+=head2 run_upgrade
+
+ $self->run_upgrade(qr/create/i);
+
+Runs a set of SQL statements matching a passed in regular expression. The
+idea is that this method can be called any number of times from your
+C<upgrade> method, running whichever commands you specify via the
+regex in the parameter.
+
+=head2 upgrade_directory
+
+Use this to set the directory your upgrade files are stored in.
+
+=head2 backup_directory
+
+Use this to set the directory you want your backups stored in.
+
+=head2 schema_version
+
+Returns the current schema class' $VERSION; does -not- use $schema->VERSION
+since that varies in results depending on if version.pm is installed, and if
+so the perl or XS versions. If you want this to change, bug the version.pm
+author to make vpp and vxs behave the same.
+
+=head1 AUTHOR
+
+Jess Robinson <castaway at desert-island.demon.co.uk>

Modified: trunk/DBIx-Class/lib/DBIx/Class/Schema.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Schema.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Schema.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,8 +3,11 @@
 use strict;
 use warnings;
 
+use DBIx::Class::Exception;
 use Carp::Clan qw/^DBIx::Class/;
 use Scalar::Util qw/weaken/;
+use File::Spec;
+require Module::Find;
 
 use base qw/DBIx::Class/;
 
@@ -12,6 +15,8 @@
 __PACKAGE__->mk_classdata('source_registrations' => {});
 __PACKAGE__->mk_classdata('storage_type' => '::DBI');
 __PACKAGE__->mk_classdata('storage');
+__PACKAGE__->mk_classdata('exception_action');
+__PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
 
 =head1 NAME
 
@@ -91,10 +96,15 @@
 
 sub register_source {
   my ($self, $moniker, $source) = @_;
+
+  %$source = %{ $source->new( { %$source, source_name => $moniker }) };
+
   my %reg = %{$self->source_registrations};
   $reg{$moniker} = $source;
   $self->source_registrations(\%reg);
+
   $source->schema($self);
+
   weaken($source->{schema}) if ref($self);
   if ($source->result_class) {
     my %map = %{$self->class_mappings};
@@ -103,6 +113,19 @@
   }
 }
 
+sub _unregister_source {
+    my ($self, $moniker) = @_;
+    my %reg = %{$self->source_registrations}; 
+
+    my $source = delete $reg{$moniker};
+    $self->source_registrations(\%reg);
+    if ($source->result_class) {
+        my %map = %{$self->class_mappings};
+        delete $map{$source->result_class};
+        $self->class_mappings(\%map);
+    }
+}
+
 =head2 class
 
 =over 4
@@ -253,10 +276,6 @@
       }
     }
   } else {
-    eval "require Module::Find;";
-    $class->throw_exception(
-      "No arguments to load_classes and couldn't load Module::Find ($@)"
-    ) if $@;
     my @comp = map { substr $_, length "${class}::"  }
                  Module::Find::findallmod($class);
     $comps_for{$class} = \@comp;
@@ -277,9 +296,10 @@
           }
         }
         $class->ensure_class_loaded($comp_class);
-        $comp_class->source_name($comp) unless $comp_class->source_name;
 
-        push(@to_register, [ $comp_class->source_name, $comp_class ]);
+        $comp = $comp_class->source_name || $comp;
+#  $DB::single = 1;
+        push(@to_register, [ $comp, $comp_class ]);
       }
     }
   }
@@ -291,16 +311,180 @@
   }
 }
 
-=head2 compose_connection
+=head2 load_namespaces
 
 =over 4
 
+=item Arguments: %options?
+
+=back
+
+This is an alternative to L</load_classes> above which assumes an alternative
+layout for automatic class loading.  It assumes that all result
+classes are underneath a sub-namespace of the schema called C<Result>, any
+corresponding ResultSet classes are underneath a sub-namespace of the schema
+called C<ResultSet>.
+
+Both of the sub-namespaces are configurable if you don't like the defaults,
+via the options C<result_namespace> and C<resultset_namespace>.
+
+If (and only if) you specify the option C<default_resultset_class>, any found
+Result classes for which we do not find a corresponding
+ResultSet class will have their C<resultset_class> set to
+C<default_resultset_class>.
+
+C<load_namespaces> takes care of calling C<resultset_class> for you where
+neccessary if you didn't do it for yourself.
+
+All of the namespace and classname options to this method are relative to
+the schema classname by default.  To specify a fully-qualified name, prefix
+it with a literal C<+>.
+
+Examples:
+
+  # load My::Schema::Result::CD, My::Schema::Result::Artist,
+  #    My::Schema::ResultSet::CD, etc...
+  My::Schema->load_namespaces;
+
+  # Override everything to use ugly names.
+  # In this example, if there is a My::Schema::Res::Foo, but no matching
+  #   My::Schema::RSets::Foo, then Foo will have its
+  #   resultset_class set to My::Schema::RSetBase
+  My::Schema->load_namespaces(
+    result_namespace => 'Res',
+    resultset_namespace => 'RSets',
+    default_resultset_class => 'RSetBase',
+  );
+
+  # Put things in other namespaces
+  My::Schema->load_namespaces(
+    result_namespace => '+Some::Place::Results',
+    resultset_namespace => '+Another::Place::RSets',
+  );
+
+If you'd like to use multiple namespaces of each type, simply use an arrayref
+of namespaces for that option.  In the case that the same result
+(or resultset) class exists in multiple namespaces, the latter entries in
+your list of namespaces will override earlier ones.
+
+  My::Schema->load_namespaces(
+    # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
+    result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
+    resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
+  );
+
+=cut
+
+# Pre-pends our classname to the given relative classname or
+#   class namespace, unless there is a '+' prefix, which will
+#   be stripped.
+sub _expand_relative_name {
+  my ($class, $name) = @_;
+  return if !$name;
+  $name = $class . '::' . $name if ! ($name =~ s/^\+//);
+  return $name;
+}
+
+# returns a hash of $shortname => $fullname for every package
+#  found in the given namespaces ($shortname is with the $fullname's
+#  namespace stripped off)
+sub _map_namespaces {
+  my ($class, @namespaces) = @_;
+
+  my @results_hash;
+  foreach my $namespace (@namespaces) {
+    push(
+      @results_hash,
+      map { (substr($_, length "${namespace}::"), $_) }
+      Module::Find::findallmod($namespace)
+    );
+  }
+
+  @results_hash;
+}
+
+sub load_namespaces {
+  my ($class, %args) = @_;
+
+  my $result_namespace = delete $args{result_namespace} || 'Result';
+  my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
+  my $default_resultset_class = delete $args{default_resultset_class};
+
+  $class->throw_exception('load_namespaces: unknown option(s): '
+    . join(q{,}, map { qq{'$_'} } keys %args))
+      if scalar keys %args;
+
+  $default_resultset_class
+    = $class->_expand_relative_name($default_resultset_class);
+
+  for my $arg ($result_namespace, $resultset_namespace) {
+    $arg = [ $arg ] if !ref($arg) && $arg;
+
+    $class->throw_exception('load_namespaces: namespace arguments must be '
+      . 'a simple string or an arrayref')
+        if ref($arg) ne 'ARRAY';
+
+    $_ = $class->_expand_relative_name($_) for (@$arg);
+  }
+
+  my %results = $class->_map_namespaces(@$result_namespace);
+  my %resultsets = $class->_map_namespaces(@$resultset_namespace);
+
+  my @to_register;
+  {
+    no warnings 'redefine';
+    local *Class::C3::reinitialize = sub { };
+    use warnings 'redefine';
+
+    foreach my $result (keys %results) {
+      my $result_class = $results{$result};
+      $class->ensure_class_loaded($result_class);
+      $result_class->source_name($result) unless $result_class->source_name;
+
+      my $rs_class = delete $resultsets{$result};
+      my $rs_set = $result_class->resultset_class;
+      if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
+        if($rs_class && $rs_class ne $rs_set) {
+          warn "We found ResultSet class '$rs_class' for '$result', but it seems "
+             . "that you had already set '$result' to use '$rs_set' instead";
+        }
+      }
+      elsif($rs_class ||= $default_resultset_class) {
+        $class->ensure_class_loaded($rs_class);
+        $result_class->resultset_class($rs_class);
+      }
+
+      push(@to_register, [ $result_class->source_name, $result_class ]);
+    }
+  }
+
+  foreach (sort keys %resultsets) {
+    warn "load_namespaces found ResultSet class $_ with no "
+      . 'corresponding Result class';
+  }
+
+  Class::C3->reinitialize;
+  $class->register_class(@$_) for (@to_register);
+
+  return;
+}
+
+=head2 compose_connection (DEPRECATED)
+
+=over 4
+
 =item Arguments: $target_namespace, @db_info
 
 =item Return Value: $new_schema
 
 =back
 
+DEPRECATED. You probably wanted compose_namespace.
+
+Actually, you probably just wanted to call connect.
+
+=for hidden due to deprecation
+
 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
 then injects the L<DBix::Class::ResultSetProxy> component and a
@@ -315,43 +499,51 @@
 
 =cut
 
-sub compose_connection {
-  my ($self, $target, @info) = @_;
-  my $base = 'DBIx::Class::ResultSetProxy';
-  eval "require ${base};";
-  $self->throw_exception
-    ("No arguments to load_classes and couldn't load ${base} ($@)")
-      if $@;
+{
+  my $warn;
 
-  if ($self eq $target) {
-    # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
-    foreach my $moniker ($self->sources) {
-      my $source = $self->source($moniker);
+  sub compose_connection {
+    my ($self, $target, @info) = @_;
+
+    warn "compose_connection deprecated as of 0.08000"
+      unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
+
+    my $base = 'DBIx::Class::ResultSetProxy';
+    eval "require ${base};";
+    $self->throw_exception
+      ("No arguments to load_classes and couldn't load ${base} ($@)")
+        if $@;
+  
+    if ($self eq $target) {
+      # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
+      foreach my $moniker ($self->sources) {
+        my $source = $self->source($moniker);
+        my $class = $source->result_class;
+        $self->inject_base($class, $base);
+        $class->mk_classdata(resultset_instance => $source->resultset);
+        $class->mk_classdata(class_resolver => $self);
+      }
+      $self->connection(@info);
+      return $self;
+    }
+  
+    my $schema = $self->compose_namespace($target, $base);
+    {
+      no strict 'refs';
+      *{"${target}::schema"} = sub { $schema };
+    }
+  
+    $schema->connection(@info);
+    foreach my $moniker ($schema->sources) {
+      my $source = $schema->source($moniker);
       my $class = $source->result_class;
-      $self->inject_base($class, $base);
+      #warn "$moniker $class $source ".$source->storage;
+      $class->mk_classdata(result_source_instance => $source);
       $class->mk_classdata(resultset_instance => $source->resultset);
-      $class->mk_classdata(class_resolver => $self);
+      $class->mk_classdata(class_resolver => $schema);
     }
-    $self->connection(@info);
-    return $self;
+    return $schema;
   }
-
-  my $schema = $self->compose_namespace($target, $base);
-  {
-    no strict 'refs';
-    *{"${target}::schema"} = sub { $schema };
-  }
-
-  $schema->connection(@info);
-  foreach my $moniker ($schema->sources) {
-    my $source = $schema->source($moniker);
-    my $class = $source->result_class;
-    #warn "$moniker $class $source ".$source->storage;
-    $class->mk_classdata(result_source_instance => $source);
-    $class->mk_classdata(resultset_instance => $source->resultset);
-    $class->mk_classdata(class_resolver => $schema);
-  }
-  return $schema;
 }
 
 =head2 compose_namespace
@@ -467,9 +659,11 @@
 
 Instantiates a new Storage object of type
 L<DBIx::Class::Schema/"storage_type"> and passes the arguments to
-$storage->connect_info. Sets the connection in-place on the schema. See
-L<DBIx::Class::Storage::DBI/"connect_info"> for more information.
+$storage->connect_info. Sets the connection in-place on the schema.
 
+See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific syntax,
+or L<DBIx::Class::Storage> in general.
+
 =cut
 
 sub connection {
@@ -482,7 +676,7 @@
   $self->throw_exception(
     "No arguments to load_classes and couldn't load ${storage_class} ($@)"
   ) if $@;
-  my $storage = $storage_class->new;
+  my $storage = $storage_class->new($self);
   $storage->connect_info(\@info);
   $self->storage($storage);
   return $self;
@@ -506,36 +700,6 @@
 
 sub connect { shift->clone->connection(@_) }
 
-=head2 txn_begin
-
-Begins a transaction (does nothing if AutoCommit is off). Equivalent to
-calling $schema->storage->txn_begin. See
-L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
-
-=cut
-
-sub txn_begin { shift->storage->txn_begin }
-
-=head2 txn_commit
-
-Commits the current transaction. Equivalent to calling
-$schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
-for more information.
-
-=cut
-
-sub txn_commit { shift->storage->txn_commit }
-
-=head2 txn_rollback
-
-Rolls back the current transaction. Equivalent to calling
-$schema->storage->txn_rollback. See
-L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
-
-=cut
-
-sub txn_rollback { shift->storage->txn_rollback }
-
 =head2 txn_do
 
 =over 4
@@ -547,97 +711,72 @@
 =back
 
 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
-returning its result (if any). If an exception is caught, a rollback is issued
-and the exception is rethrown. If the rollback fails, (i.e. throws an
-exception) an exception is thrown that includes a "Rollback failed" message.
+returning its result (if any). Equivalent to calling $schema->storage->txn_do.
+See L<DBIx::Class::Storage/"txn_do"> for more information.
 
-For example,
+This interface is preferred over using the individual methods L</txn_begin>,
+L</txn_commit>, and L</txn_rollback> below.
 
-  my $author_rs = $schema->resultset('Author')->find(1);
-  my @titles = qw/Night Day It/;
+=cut
 
-  my $coderef = sub {
-    # If any one of these fails, the entire transaction fails
-    $author_rs->create_related('books', {
-      title => $_
-    }) foreach (@titles);
+sub txn_do {
+  my $self = shift;
 
-    return $author->books;
-  };
+  $self->storage or $self->throw_exception
+    ('txn_do called on $schema without storage');
 
-  my $rs;
-  eval {
-    $rs = $schema->txn_do($coderef);
-  };
+  $self->storage->txn_do(@_);
+}
 
-  if ($@) {                                  # Transaction failed
-    die "something terrible has happened!"   #
-      if ($@ =~ /Rollback failed/);          # Rollback failed
+=head2 txn_begin
 
-    deal_with_failed_transaction();
-  }
+Begins a transaction (does nothing if AutoCommit is off). Equivalent to
+calling $schema->storage->txn_begin. See
+L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
 
-In a nested transaction (calling txn_do() from within a txn_do() coderef) only
-the outermost transaction will issue a L<DBIx::Class::Schema/"txn_commit"> on
-the Schema's storage, and txn_do() can be called in void, scalar and list
-context and it will behave as expected.
-
 =cut
 
-sub txn_do {
-  my ($self, $coderef, @args) = @_;
+sub txn_begin {
+  my $self = shift;
 
   $self->storage or $self->throw_exception
-    ('txn_do called on $schema without storage');
-  ref $coderef eq 'CODE' or $self->throw_exception
-    ('$coderef must be a CODE reference');
+    ('txn_begin called on $schema without storage');
 
-  my (@return_values, $return_value);
+  $self->storage->txn_begin;
+}
 
-  $self->txn_begin; # If this throws an exception, no rollback is needed
+=head2 txn_commit
 
-  my $wantarray = wantarray; # Need to save this since the context
-                             # inside the eval{} block is independent
-                             # of the context that called txn_do()
-  eval {
+Commits the current transaction. Equivalent to calling
+$schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
+for more information.
 
-    # Need to differentiate between scalar/list context to allow for
-    # returning a list in scalar context to get the size of the list
-    if ($wantarray) {
-      # list context
-      @return_values = $coderef->(@args);
-    } elsif (defined $wantarray) {
-      # scalar context
-      $return_value = $coderef->(@args);
-    } else {
-      # void context
-      $coderef->(@args);
-    }
-    $self->txn_commit;
-  };
+=cut
 
-  if ($@) {
-    my $error = $@;
+sub txn_commit {
+  my $self = shift;
 
-    eval {
-      $self->txn_rollback;
-    };
+  $self->storage or $self->throw_exception
+    ('txn_commit called on $schema without storage');
 
-    if ($@) {
-      my $rollback_error = $@;
-      my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
-      $self->throw_exception($error)  # propagate nested rollback
-        if $rollback_error =~ /$exception_class/;
+  $self->storage->txn_commit;
+}
 
-      $self->throw_exception(
-        "Transaction aborted: $error. Rollback failed: ${rollback_error}"
-      );
-    } else {
-      $self->throw_exception($error); # txn failed but rollback succeeded
-    }
-  }
+=head2 txn_rollback
 
-  return $wantarray ? @return_values : $return_value;
+Rolls back the current transaction. Equivalent to calling
+$schema->storage->txn_rollback. See
+L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
+
+=cut
+
+sub txn_rollback {
+  my $self = shift;
+
+  $self->storage or $self->throw_exception
+    ('txn_rollback called on $schema without storage');
+
+  $self->storage->txn_rollback;
 }
 
 =head2 clone
@@ -663,6 +802,7 @@
     my $new = $source->new($source);
     $clone->register_source($moniker => $new);
   }
+  $clone->storage->set_schema($clone) if $clone->storage;
   return $clone;
 }
 
@@ -678,7 +818,12 @@
 arrayrefs. The arrayrefs should contain a list of column names,
 followed by one or many sets of matching data for the given columns. 
 
-Each set of data is inserted into the database using
+In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
+to insert the data, as this is a fast method. However, insert_bulk currently
+assumes that your datasets all contain the same type of values, using scalar
+references in a column in one row, and not in another will probably not work.
+
+Otherwise, each set of data is inserted into the database using
 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
 objects is returned.
 
@@ -697,15 +842,62 @@
   my ($self, $name, $data) = @_;
   my $rs = $self->resultset($name);
   my @names = @{shift(@$data)};
-  my @created;
-  foreach my $item (@$data) {
-    my %create;
-    @create{@names} = @$item;
-    push(@created, $rs->create(\%create));
+  if(defined wantarray) {
+    my @created;
+    foreach my $item (@$data) {
+      my %create;
+      @create{@names} = @$item;
+      push(@created, $rs->create(\%create));
+    }
+    return @created;
   }
-  return @created;
+  $self->storage->insert_bulk($self->source($name), \@names, $data);
 }
 
+=head2 exception_action
+
+=over 4
+
+=item Arguments: $code_reference
+
+=back
+
+If C<exception_action> is set for this class/object, L</throw_exception>
+will prefer to call this code reference with the exception as an argument,
+rather than its normal C<croak> or C<confess> action.
+
+Your subroutine should probably just wrap the error in the exception
+object/class of your choosing and rethrow.  If, against all sage advice,
+you'd like your C<exception_action> to suppress a particular exception
+completely, simply have it return true.
+
+Example:
+
+   package My::Schema;
+   use base qw/DBIx::Class::Schema/;
+   use My::ExceptionClass;
+   __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
+   __PACKAGE__->load_classes;
+
+   # or:
+   my $schema_obj = My::Schema->connect( .... );
+   $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
+
+   # suppress all exceptions, like a moron:
+   $schema_obj->exception_action(sub { 1 });
+
+=head2 stacktrace
+
+=over 4
+
+=item Arguments: boolean
+
+=back
+
+Whether L</throw_exception> should include stack trace information.
+Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
+is true.
+
 =head2 throw_exception
 
 =over 4
@@ -715,13 +907,17 @@
 =back
 
 Throws an exception. Defaults to using L<Carp::Clan> to report errors from
-user's perspective.
+user's perspective.  See L</exception_action> for details on overriding
+this method's behavior.  If L</stacktrace> is turned on, C<throw_exception>'s
+default behavior will provide a detailed stack trace.
 
 =cut
 
 sub throw_exception {
-  my ($self) = shift;
-  croak @_;
+  my $self = shift;
+
+  DBIx::Class::Exception->throw($_[0], $self->stacktrace)
+    if !$self->exception_action || !$self->exception_action->(@_);
 }
 
 =head2 deploy (EXPERIMENTAL)
@@ -735,12 +931,17 @@
 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
 
 Note that this feature is currently EXPERIMENTAL and may not work correctly
-across all databases, or fully handle complex relationships.
+across all databases, or fully handle complex relationships. Saying that, it
+has been used successfully by many people, including the core dev team.
 
 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
 common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
 produced include a DROP TABLE statement for each table created.
 
+Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash 
+ref or an array ref, containing a list of source to deploy. If present, then 
+only the sources listed will get deployed.
+
 =cut
 
 sub deploy {
@@ -753,16 +954,41 @@
 
 =over 4
 
-=item Arguments: \@databases, $version, $directory, $sqlt_args
+=item Arguments: \@databases, $version, $directory, $preversion, $sqlt_args
 
 =back
 
 Creates an SQL file based on the Schema, for each of the specified
-database types, in the given directory.
+database types, in the given directory. Given a previous version number,
+this will also create a file containing the ALTER TABLE statements to
+transform the previous schema into the current one. Note that these
+statements may contain DROP TABLE or DROP COLUMN statements that can
+potentially destroy data.
 
+The file names are created using the C<ddl_filename> method below, please
+override this method in your schema if you would like a different file
+name format. For the ALTER file, the same format is used, replacing
+$version in the name with "$preversion-$version".
+
+If no arguments are passed, then the following default values are used:
+
+=over 4
+
+=item databases  - ['MySQL', 'SQLite', 'PostgreSQL']
+
+=item version    - $schema->VERSION
+
+=item directory  - './'
+
+=item preversion - <none>
+
+=back
+
 Note that this feature is currently EXPERIMENTAL and may not work correctly
 across all databases, or fully handle complex relationships.
 
+WARNING: Please check all SQL files created, before applying them.
+
 =cut
 
 sub create_ddl_dir {
@@ -774,19 +1000,30 @@
 
 =head2 ddl_filename (EXPERIMENTAL)
 
-  my $filename = $table->ddl_filename($type, $dir, $version)
+=over 4
 
-Creates a filename for a SQL file based on the table class name.  Not
-intended for direct end user use.
+=item Arguments: $directory, $database-type, $version, $preversion
 
+=back
+
+  my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
+
+This method is called by C<create_ddl_dir> to compose a file name out of
+the supplied directory, database type and version number. The default file
+name format is: C<$dir$schema-$version-$type.sql>.
+
+You may override this method in your schema if you wish to use a different
+format.
+
 =cut
 
 sub ddl_filename {
-    my ($self, $type, $dir, $version) = @_;
+    my ($self, $type, $dir, $version, $pversion) = @_;
 
     my $filename = ref($self);
     $filename =~ s/::/-/g;
-    $filename = "$dir$filename-$version-$type.sql";
+    $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
+    $filename =~ s/$version/$pversion-$version/ if($pversion);
 
     return $filename;
 }

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Cursor.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Cursor.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Cursor.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -43,11 +43,9 @@
     args => $args,
     pos => 0,
     attrs => $attrs,
-    pid => $$,
+    _dbh_gen => $storage->{_dbh_gen},
   };
 
-  $new->{tid} = threads->tid if $INC{'threads.pm'};
-  
   return bless ($new, $class);
 }
 
@@ -66,10 +64,10 @@
 
 =cut
 
-sub next {
-  my ($self) = @_;
+sub _dbh_next {
+  my ($storage, $dbh, $self) = @_;
 
-  $self->_check_forks_threads;
+  $self->_check_dbh_gen;
   if ($self->{attrs}{rows} && $self->{pos} >= $self->{attrs}{rows}) {
     $self->{sth}->finish if $self->{sth}->{Active};
     delete $self->{sth};
@@ -77,7 +75,7 @@
   }
   return if $self->{done};
   unless ($self->{sth}) {
-    $self->{sth} = ($self->{storage}->_select(@{$self->{args}}))[1];
+    $self->{sth} = ($storage->_select(@{$self->{args}}))[1];
     if ($self->{attrs}{software_limit}) {
       if (my $offset = $self->{attrs}{offset}) {
         $self->{sth}->fetch for 1 .. $offset;
@@ -94,6 +92,11 @@
   return @row;
 }
 
+sub next {
+  my ($self) = @_;
+  $self->{storage}->dbh_do($self->can('_dbh_next'), $self);
+}
+
 =head2 all
 
 =over 4
@@ -109,17 +112,22 @@
 
 =cut
 
-sub all {
-  my ($self) = @_;
+sub _dbh_all {
+  my ($storage, $dbh, $self) = @_;
 
-  $self->_check_forks_threads;
-  return $self->SUPER::all if $self->{attrs}{rows};
+  $self->_check_dbh_gen;
   $self->{sth}->finish if $self->{sth}->{Active};
   delete $self->{sth};
-  my ($rv, $sth) = $self->{storage}->_select(@{$self->{args}});
+  my ($rv, $sth) = $storage->_select(@{$self->{args}});
   return @{$sth->fetchall_arrayref};
 }
 
+sub all {
+  my ($self) = @_;
+  return $self->SUPER::all if $self->{attrs}{rows};
+  $self->{storage}->dbh_do($self->can('_dbh_all'), $self);
+}
+
 =head2 reset
 
 Resets the cursor to the beginning of the L<DBIx::Class::ResultSet>.
@@ -129,8 +137,8 @@
 sub reset {
   my ($self) = @_;
 
-  $self->_check_forks_threads;
-  $self->{sth}->finish if $self->{sth}->{Active};
+  # No need to care about failures here
+  eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
   $self->_soft_reset;
 }
 
@@ -138,30 +146,26 @@
   my ($self) = @_;
 
   delete $self->{sth};
+  delete $self->{done};
   $self->{pos} = 0;
-  delete $self->{done};
   return $self;
 }
 
-sub _check_forks_threads {
+sub _check_dbh_gen {
   my ($self) = @_;
 
-  if($INC{'threads.pm'} && $self->{tid} != threads->tid) {
-      $self->_soft_reset;
-      $self->{tid} = threads->tid;
+  if($self->{_dbh_gen} != $self->{storage}->{_dbh_gen}) {
+    $self->{_dbh_gen} = $self->{storage}->{_dbh_gen};
+    $self->_soft_reset;
   }
-
-  if($self->{pid} != $$) {
-      $self->_soft_reset;
-      $self->{pid} = $$;
-  }
 }
 
 sub DESTROY {
   my ($self) = @_;
 
-  $self->_check_forks_threads;
-  $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active};
+  # None of the reasons this would die matter if we're in DESTROY anyways
+  local $@;
+  eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
 }
 
 1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/DB2.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/DB2.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/DB2.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,18 +7,15 @@
 
 # __PACKAGE__->load_components(qw/PK::Auto/);
 
-sub last_insert_id
-{
-    my ($self) = @_;
+sub _dbh_last_insert_id {
+    my ($self, $dbh, $source, $col) = @_;
 
-    my $dbh = $self->_dbh;
-    my $sth = $dbh->prepare_cached("VALUES(IDENTITY_VAL_LOCAL())", {}, 3);
+    my $sth = $dbh->prepare_cached('VALUES(IDENTITY_VAL_LOCAL())', {}, 3);
     $sth->execute();
 
     my @res = $sth->fetchrow_array();
 
     return @res ? $res[0] : undef;
-                         
 }
 
 sub datetime_parser_type { "DateTime::Format::DB2"; }

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/MSSQL.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/MSSQL.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/MSSQL.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,8 +5,9 @@
 
 use base qw/DBIx::Class::Storage::DBI/;
 
-sub last_insert_id {
-  my( $id ) = $_[0]->_dbh->selectrow_array('SELECT @@IDENTITY' );
+sub _dbh_last_insert_id {
+  my ($self, $dbh, $source, $col) = @_;
+  my ($id) = $dbh->selectrow_array('SELECT @@IDENTITY');
   return $id;
 }
 

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -17,58 +17,42 @@
 
 =head1 METHODS
 
-=head2 sth
+=head2 connect_info
 
-Uses C<prepare> instead of the usual C<prepare_cached>, seeing as we can't cache very effectively without bind variables.
+We can't cache very effectively without bind variables, so force the C<disable_sth_caching> setting to be turned on when the connect info is set.
 
 =cut
 
-sub sth {
-  my ($self, $sql) = @_;
-  return $self->dbh->prepare($sql);
+sub connect_info {
+    my $self = shift;
+    my $retval = $self->next::method(@_);
+    $self->disable_sth_caching(1);
+    $retval;
 }
 
-=head2 _execute
+=head2 _prep_for_execute
 
-Manually subs in the values for the usual C<?> placeholders before calling L</sth> on the generated SQL.
+Manually subs in the values for the usual C<?> placeholders.
 
 =cut
 
-sub _execute {
-  my ($self, $op, $extra_bind, $ident, @args) = @_;
-  my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
-  unshift(@bind, @$extra_bind) if $extra_bind;
-  if ($self->debug) {
-    my @debug_bind = map { defined $_ ? qq{'$_'} : q{'NULL'} } @bind;
-    $self->debugobj->query_start($sql, @debug_bind);
-  }
+sub _prep_for_execute {
+  my $self = shift;
+  my ($sql, $bind) = $self->next::method(@_);
 
-  $sql =~ s/\?/$self->_dbh->quote(shift(@bind))/eg;
+  # stringify args, quote via $dbh, and manually insert
 
-  my $sth = eval { $self->sth($sql,$op) };
-
-  if (!$sth || $@) {
-    $self->throw_exception(
-      'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
-    );
-  }
-
-  my $rv;
-  if ($sth) {
-    my $time = time();
-    $rv = eval { $sth->execute };
-
-    if ($@ || !$rv) {
-      $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr));
+  foreach my $bound (@$bind) {
+    shift @$bound;
+    foreach my $data (@$bound) {
+        if(ref $data) {
+            $data = ''.$data;
+        }
+        $sql =~ s/\?/$self->_dbh->quote($data)/e;
     }
-  } else {
-    $self->throw_exception("'$sql' did not generate a statement.");
   }
-  if ($self->debug) {
-    my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
-    $self->debugobj->query_end($sql, @debug_bind);
-  }
-  return (wantarray ? ($rv, $sth, @bind) : $rv);
+
+  return ($sql);
 }
 
 =head1 AUTHORS

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -4,12 +4,9 @@
 
 use base qw/DBIx::Class::Storage::DBI::ODBC/;
 
-sub last_insert_id
-{
-    my ($self) = @_;
+sub _dbh_last_insert_id {
+    my ($self, $dbh, $source, $col) = @_;
 
-    my $dbh = $self->_dbh;
-
     # get the schema/table separator:
     #    '.' when SQL naming is active
     #    '/' when system naming is active
@@ -26,10 +23,14 @@
 sub _sql_maker_opts {
     my ($self) = @_;
     
-    return {
-        limit_dialect => 'FetchFirst',
-        name_sep => $self->_dbh->get_info(41)
-    };
+    $self->dbh_do(sub {
+        my ($self, $dbh) = @_;
+
+        return {
+            limit_dialect => 'FetchFirst',
+            name_sep => $dbh->get_info(41)
+        };
+    });
 }
 
 1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/ODBC.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,7 +7,7 @@
 sub _rebless {
     my ($self) = @_;
 
-    my $dbh = $self->_dbh;
+    my $dbh = $self->dbh;
     my $dbtype = eval { $dbh->get_info(17) };
     unless ( $@ ) {
         # Translate the backend name into a perl identifier

Added: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,99 @@
+package DBIx::Class::Storage::DBI::Oracle::Generic;
+# -*- mode: cperl; cperl-indent-level: 2 -*-
+
+use strict;
+use warnings;
+
+=head1 NAME
+
+DBIx::Class::Storage::DBI::Oracle - Automatic primary key class for Oracle
+
+=head1 SYNOPSIS
+
+  # In your table classes
+  __PACKAGE__->load_components(qw/PK::Auto Core/);
+  __PACKAGE__->set_primary_key('id');
+  __PACKAGE__->sequence('mysequence');
+
+=head1 DESCRIPTION
+
+This class implements autoincrements for Oracle.
+
+=head1 METHODS
+
+=cut
+
+use Carp::Clan qw/^DBIx::Class/;
+
+use base qw/DBIx::Class::Storage::DBI::MultiDistinctEmulation/;
+
+# __PACKAGE__->load_components(qw/PK::Auto/);
+
+sub _dbh_last_insert_id {
+  my ($self, $dbh, $source, $col) = @_;
+  my $seq = ($source->column_info($col)->{sequence} ||= $self->get_autoinc_seq($source,$col));
+  my $sql = 'SELECT ' . $seq . '.currval FROM DUAL';
+  my ($id) = $dbh->selectrow_array($sql);
+  return $id;
+}
+
+sub _dbh_get_autoinc_seq {
+  my ($self, $dbh, $source, $col) = @_;
+
+  # look up the correct sequence automatically
+  my $sql = q{
+    SELECT trigger_body FROM ALL_TRIGGERS t
+    WHERE t.table_name = ?
+    AND t.triggering_event = 'INSERT'
+    AND t.status = 'ENABLED'
+  };
+
+  # trigger_body is a LONG
+  $dbh->{LongReadLen} = 64 * 1024 if ($dbh->{LongReadLen} < 64 * 1024);
+
+  my $sth = $dbh->prepare($sql);
+  $sth->execute( uc($source->name) );
+  while (my ($insert_trigger) = $sth->fetchrow_array) {
+    return uc($1) if $insert_trigger =~ m!(\w+)\.nextval!i; # col name goes here???
+  }
+  $self->throw_exception("Unable to find a sequence INSERT trigger on table '" . $source->name . "'.");
+}
+
+=head2 get_autoinc_seq
+
+Returns the sequence name for an autoincrement column
+
+=cut
+
+sub get_autoinc_seq {
+  my ($self, $source, $col) = @_;
+    
+  $self->dbh_do($self->can('_dbh_get_autoinc_seq'), $source, $col);
+}
+
+=head2 columns_info_for
+
+This wraps the superclass version of this method to force table
+names to uppercase
+
+=cut
+
+sub columns_info_for {
+  my ($self, $table) = @_;
+
+  $self->next::method(uc($table));
+}
+
+=head1 AUTHORS
+
+Andy Grundman <andy at hybridized.org>
+
+Scott Connelly <scottsweep at yahoo.com>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
+
+1;

Added: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/WhereJoins.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/WhereJoins.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle/WhereJoins.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,204 @@
+package DBIx::Class::Storage::DBI::Oracle::WhereJoins;
+
+use base qw( DBIx::Class::Storage::DBI::Oracle::Generic );
+
+use strict;
+use warnings;
+
+BEGIN {
+  package DBIC::SQL::Abstract::Oracle;
+
+  use base qw( DBIC::SQL::Abstract );
+
+  sub select {
+    my ($self, $table, $fields, $where, $order, @rest) = @_;
+
+    if (ref($table) eq 'ARRAY') {
+      $where = $self->_oracle_joins($where, @{ $table });
+    }
+
+    return $self->SUPER::select($table, $fields, $where, $order, @rest);
+  }
+
+  sub _recurse_from {
+    my ($self, $from, @join) = @_;
+
+    my @sqlf = $self->_make_as($from);
+
+    foreach my $j (@join) {
+      my ($to, $on) = @{ $j };
+
+      if (ref $to eq 'ARRAY') {
+        push (@sqlf, $self->_recurse_from(@{ $to }));
+      }
+      else {
+        push (@sqlf, $self->_make_as($to));
+      }
+    }
+
+    return join q{, }, @sqlf;
+  }
+
+  sub _oracle_joins {
+    my ($self, $where, $from, @join) = @_;
+    my $join_where = {};
+    $self->_recurse_oracle_joins($join_where, $from, @join);
+    if (keys %$join_where) {
+      if (!defined($where)) {
+        $where = $join_where;
+      } else {
+        if (ref($where) eq 'ARRAY') {
+          $where = { -or => $where };
+        }
+        $where = { -and => [ $join_where, $where ] };
+      }
+    }
+    return $where;
+  }
+
+  sub _recurse_oracle_joins {
+    my ($self, $where, $from, @join) = @_;
+
+    foreach my $j (@join) {
+      my ($to, $on) = @{ $j };
+
+      if (ref $to eq 'ARRAY') {
+        $self->_recurse_oracle_joins($where, @{ $to });
+      }
+
+      my $to_jt      = ref $to eq 'ARRAY' ? $to->[0] : $to;
+      my $left_join  = q{};
+      my $right_join = q{};
+
+      if (ref $to_jt eq 'HASH' and exists $to_jt->{-join_type}) {
+        #TODO: Support full outer joins -- this would happen much earlier in
+        #the sequence since oracle 8's full outer join syntax is best
+        #described as INSANE.
+        die "Can't handle full outer joins in Oracle 8 yet!\n"
+          if $to_jt->{-join_type} =~ /full/i;
+
+        $left_join  = q{(+)} if $to_jt->{-join_type} =~ /left/i
+                             && $to_jt->{-join_type} !~ /inner/i;
+
+        $right_join = q{(+)} if $to_jt->{-join_type} =~ /right/i
+                             && $to_jt->{-join_type} !~ /inner/i;
+      }
+
+      foreach my $lhs (keys %{ $on }) {
+        $where->{$lhs . $left_join} = \"= $on->{ $lhs }$right_join";
+      }
+    }
+  }
+}
+
+sub sql_maker {
+  my ($self) = @_;
+
+  unless ($self->_sql_maker) {
+    $self->_sql_maker(
+      new DBIC::SQL::Abstract::Oracle( $self->_sql_maker_args )
+    );
+  }
+
+  return $self->_sql_maker;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+DBIx::Class::Storage::DBI::Oracle::WhereJoins - Oracle joins in WHERE syntax
+support (instead of ANSI).
+
+=head1 PURPOSE
+
+This module was originally written to support Oracle < 9i where ANSI joins
+weren't supported at all, but became the module for Oracle >= 8 because
+Oracle's optimising of ANSI joins is horrible.  (See:
+http://scsys.co.uk:8001/7495)
+
+=head1 SYNOPSIS
+
+DBIx::Class should automagically detect Oracle and use this module with no
+work from you.
+
+=head1 DESCRIPTION
+
+This class implements Oracle's WhereJoin support.  Instead of:
+
+    SELECT x FROM y JOIN z ON y.id = z.id
+
+It will write:
+
+    SELECT x FROM y, z WHERE y.id = z.id
+
+It should properly support left joins, and right joins.  Full outer joins are
+not possible due to the fact that Oracle requires the entire query be written
+to union the results of a left and right join, and by the time this module is
+called to create the where query and table definition part of the sql query,
+it's already too late.
+
+=head1 METHODS
+
+This module replaces a subroutine contained in DBIC::SQL::Abstract:
+
+=over
+
+=item sql_maker
+
+=back
+
+It also creates a new module in its BEGIN { } block called
+DBIC::SQL::Abstract::Oracle which has the following methods:
+
+=over
+
+=item select ($\@$;$$@)
+
+Replaces DBIC::SQL::Abstract's select() method, which calls _oracle_joins()
+to modify the column and table list before calling SUPER::select().
+
+=item _recurse_from ($$\@)
+
+Recursive subroutine that builds the table list.
+
+=item _oracle_joins ($$$@)
+
+Creates the left/right relationship in the where query.
+
+=back
+
+=head1 BUGS
+
+Does not support full outer joins.
+Probably lots more.
+
+=head1 SEE ALSO
+
+=over
+
+=item L<DBIC::SQL::Abstract>
+
+=item L<DBIx::Class::Storage::DBI::Oracle::Generic>
+
+=item L<DBIx::Class>
+
+=back
+
+=head1 AUTHOR
+
+Justin Wheeler C<< <jwheeler at datademons.com> >>
+
+=head1 CONTRIBUTORS
+
+David Jack Olrik C<< <djo at cpan.org> >>
+
+=head1 LICENSE
+
+This module is licensed under the same terms as Perl itself.
+
+=cut

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Oracle.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,45 +3,26 @@
 use strict;
 use warnings;
 
-use Carp qw/croak/;
+use base qw/DBIx::Class::Storage::DBI/;
 
-use base qw/DBIx::Class::Storage::DBI::MultiDistinctEmulation/;
+sub _rebless {
+    my ($self) = @_;
 
-# __PACKAGE__->load_components(qw/PK::Auto/);
+    my $version = eval { $self->_dbh->get_info(18); };
 
-sub last_insert_id {
-  my ($self,$source,$col) = @_;
-  my $seq = ($source->column_info($col)->{sequence} ||= $self->get_autoinc_seq($source,$col));
-  my $sql = "SELECT " . $seq . ".currval FROM DUAL";
-  my ($id) = $self->_dbh->selectrow_array($sql);
-  return $id;
-}
+    if ( !$@ ) {
+        my ($major, $minor, $patchlevel) = split(/\./, $version);
 
-sub get_autoinc_seq {
-  my ($self,$source,$col) = @_;
-    
-  # look up the correct sequence automatically
-  my $dbh = $self->_dbh;
-  my $sql = q{
-    SELECT trigger_body FROM ALL_TRIGGERS t
-    WHERE t.table_name = ?
-    AND t.triggering_event = 'INSERT'
-    AND t.status = 'ENABLED'
-  };
-  # trigger_body is a LONG
-  $dbh->{LongReadLen} = 64 * 1024 if ($dbh->{LongReadLen} < 64 * 1024);
-  my $sth = $dbh->prepare($sql);
-  $sth->execute( uc($source->name) );
-  while (my ($insert_trigger) = $sth->fetchrow_array) {
-    return uc($1) if $insert_trigger =~ m!(\w+)\.nextval!i; # col name goes here???
-  }
-  croak "Unable to find a sequence INSERT trigger on table '" . $source->name . "'.";
-}
+        # Default driver
+        my $class = $major <= 8
+          ? 'DBIx::Class::Storage::DBI::Oracle::WhereJoins'
+          : 'DBIx::Class::Storage::DBI::Oracle::Generic';
 
-sub columns_info_for {
-  my ($self, $table) = @_;
+        # Load and rebless
+        eval "require $class";
 
-  $self->next::method(uc($table));
+        bless $self, $class unless $@;
+    }
 }
 
 
@@ -49,25 +30,31 @@
 
 =head1 NAME
 
-DBIx::Class::Storage::DBI::Oracle - Automatic primary key class for Oracle
+DBIx::Class::Storage::DBI::Oracle - Base class for Oracle driver
 
 =head1 SYNOPSIS
 
   # In your table classes
-  __PACKAGE__->load_components(qw/PK::Auto Core/);
-  __PACKAGE__->set_primary_key('id');
-  __PACKAGE__->sequence('mysequence');
+  __PACKAGE__->load_components(qw/Core/);
 
 =head1 DESCRIPTION
 
-This class implements autoincrements for Oracle.
+This class simply provides a mechanism for discovering and loading a sub-class
+for a specific version Oracle backend. It should be transparent to the user.
 
-=head1 AUTHORS
+For Oracle major versions <= 8 it loads the ::Oracle::WhereJoins subclass,
+which unrolls the ANSI join style DBIC normally generates into entries in
+the WHERE clause for compatibility purposes. To force usage of this version
+no matter the database version, add
 
-Andy Grundman <andy at hybridized.org>
+  __PACKAGE__->storage_type('::DBI::Oracle::WhereJoins');
 
-Scott Connelly <scottsweep at yahoo.com>
+to your Schema class.
 
+=head1 AUTHORS
+
+David Jack Olrik C<< <djo at cpan.org> >>
+
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself.

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Pg.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Pg.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Pg.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use DBD::Pg;
+use DBD::Pg qw(:pg_types);
 
 use base qw/DBIx::Class::Storage::DBI/;
 
@@ -13,31 +13,43 @@
 warn "DBD::Pg 1.49 is strongly recommended"
   if ($DBD::Pg::VERSION < 1.49);
 
+sub _dbh_last_insert_id {
+  my ($self, $dbh, $seq) = @_;
+  $dbh->last_insert_id(undef, undef, undef, undef, {sequence => $seq});
+}
+
 sub last_insert_id {
   my ($self,$source,$col) = @_;
   my $seq = ($source->column_info($col)->{sequence} ||= $self->get_autoinc_seq($source,$col));
   $self->throw_exception("could not fetch primary key for " . $source->name . ", could not "
     . "get autoinc sequence for $col (check that table and column specifications are correct "
     . "and in the correct case)") unless defined $seq;
-  $self->_dbh->last_insert_id(undef,undef,undef,undef, {sequence => $seq});
+  $self->dbh_do($self->can('_dbh_last_insert_id'), $seq);
 }
 
+sub _dbh_get_autoinc_seq {
+  my ($self, $dbh, $schema, $table, @pri) = @_;
+
+  while (my $col = shift @pri) {
+    my $info = $dbh->column_info(undef,$schema,$table,$col)->fetchrow_hashref;
+    if(defined $info->{COLUMN_DEF} and
+       $info->{COLUMN_DEF} =~ /^nextval\(+'([^']+)'::(?:text|regclass)\)/) {
+      my $seq = $1;
+      # may need to strip quotes -- see if this works
+      return $seq =~ /\./ ? $seq : $info->{TABLE_SCHEM} . "." . $seq;
+    }
+  }
+  return;
+}
+
 sub get_autoinc_seq {
   my ($self,$source,$col) = @_;
     
   my @pri = $source->primary_columns;
-  my $dbh = $self->_dbh;
   my ($schema,$table) = $source->name =~ /^(.+)\.(.+)$/ ? ($1,$2)
     : (undef,$source->name);
-  while (my $col = shift @pri) {
-    my $info = $dbh->column_info(undef,$schema,$table,$col)->fetchrow_hashref;
-    if (defined $info->{COLUMN_DEF} and $info->{COLUMN_DEF} =~
-      /^nextval\(+'([^']+)'::(?:text|regclass)\)/)
-    {
-	my $seq = $1;
-      return $seq =~ /\./ ? $seq : $info->{TABLE_SCHEM} . "." . $seq; # may need to strip quotes -- see if this works
-    }
-  }
+
+  $self->dbh_do($self->can('_dbh_get_autoinc_seq'), $schema, $table, @pri);
 }
 
 sub sqlt_type {
@@ -46,6 +58,21 @@
 
 sub datetime_parser_type { return "DateTime::Format::Pg"; }
 
+sub bind_attribute_by_data_type {
+  my ($self,$data_type) = @_;
+
+  my $bind_attributes = {
+    bytea => { pg_type => DBD::Pg::PG_BYTEA },
+  };
+ 
+  if( defined $bind_attributes->{$data_type} ) {
+    return $bind_attributes->{$data_type};
+  }
+  else {
+    return;
+  }
+}
+
 1;
 
 =head1 NAME

Added: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Replication.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Replication.pm	                        (rev 0)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/Replication.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,235 @@
+package DBIx::Class::Storage::DBI::Replication;
+
+use strict;
+use warnings;
+
+use DBIx::Class::Storage::DBI;
+use DBD::Multi;
+use base qw/Class::Accessor::Fast/;
+
+__PACKAGE__->mk_accessors( qw/read_source write_source/ );
+
+=head1 NAME
+
+DBIx::Class::Storage::DBI::Replication - EXPERIMENTAL Replicated database support
+
+=head1 SYNOPSIS
+
+  # change storage_type in your schema class
+    $schema->storage_type( '::DBI::Replication' );
+    $schema->connect_info( [
+		     [ "dbi:mysql:database=test;hostname=master", "username", "password", { AutoCommit => 1 } ], # master
+		     [ "dbi:mysql:database=test;hostname=slave1", "username", "password", { priority => 10 } ],  # slave1
+		     [ "dbi:mysql:database=test;hostname=slave2", "username", "password", { priority => 10 } ],  # slave2
+		     <...>,
+		     { limit_dialect => 'LimitXY' } # If needed, see below
+		    ] );
+
+=head1 DESCRIPTION
+
+Warning: This class is marked EXPERIMENTAL. It works for the authors but does
+not currently have automated tests so your mileage may vary.
+
+This class implements replicated data store for DBI. Currently you can define
+one master and numerous slave database connections. All write-type queries
+(INSERT, UPDATE, DELETE and even LAST_INSERT_ID) are routed to master
+database, all read-type queries (SELECTs) go to the slave database.
+
+For every slave database you can define a priority value, which controls data
+source usage pattern. It uses L<DBD::Multi>, so first the lower priority data
+sources used (if they have the same priority, the are used randomized), than
+if all low priority data sources fail, higher ones tried in order.
+
+=head1 CONFIGURATION
+
+=head2 Limit dialect
+
+If you use LIMIT in your queries (effectively, if you use
+SQL::Abstract::Limit), do not forget to set up limit_dialect (perldoc
+SQL::Abstract::Limit) by passing it as an option in the (optional) hash
+reference to connect_info.  DBIC can not set it up automatically, since it can
+not guess DBD::Multi connection types.
+
+=cut
+
+sub new {
+    my $proto = shift;
+    my $class = ref( $proto ) || $proto;
+    my $self = {};
+
+    bless( $self, $class );
+
+    $self->write_source( DBIx::Class::Storage::DBI->new );
+    $self->read_source( DBIx::Class::Storage::DBI->new );
+
+    return $self;
+}
+
+sub all_sources {
+    my $self = shift;
+
+    my @sources = ($self->read_source, $self->write_source);
+
+    return wantarray ? @sources : \@sources;
+}
+
+sub connect_info {
+    my( $self, $source_info ) = @_;
+
+    my( $info, $global_options, $options, @dsns );
+
+    $info = [ @$source_info ];
+
+    $global_options = ref $info->[-1] eq 'HASH' ? pop( @$info ) : {};
+    if( ref( $options = $info->[0]->[-1] ) eq 'HASH' ) {
+	# Local options present in dsn, merge them with global options
+	map { $global_options->{$_} = $options->{$_} } keys %$options;
+	pop @{$info->[0]};
+    }
+
+    # We need to copy-pass $global_options, since connect_info clears it while
+    # processing options
+    $self->write_source->connect_info( [ @{$info->[0]}, { %$global_options } ] );
+
+    @dsns = map { ($_->[3]->{priority} || 10) => $_ } @{$info}[1..@$info-1];
+    $global_options->{dsns} = \@dsns;
+
+    $self->read_source->connect_info( [ 'dbi:Multi:', undef, undef, { %$global_options } ] );
+}
+
+sub select {
+    shift->read_source->select( @_ );
+}
+sub select_single {
+    shift->read_source->select_single( @_ );
+}
+sub throw_exception {
+    shift->read_source->throw_exception( @_ );
+}
+sub sql_maker {
+    shift->read_source->sql_maker( @_ );
+}
+sub columns_info_for {
+    shift->read_source->columns_info_for( @_ );
+}
+sub sqlt_type {
+    shift->read_source->sqlt_type( @_ );
+}
+sub create_ddl_dir {
+    shift->read_source->create_ddl_dir( @_ );
+}
+sub deployment_statements {
+    shift->read_source->deployment_statements( @_ );
+}
+sub datetime_parser {
+    shift->read_source->datetime_parser( @_ );
+}
+sub datetime_parser_type {
+    shift->read_source->datetime_parser_type( @_ );
+}
+sub build_datetime_parser {
+    shift->read_source->build_datetime_parser( @_ );
+}
+
+sub limit_dialect {
+    my $self = shift;
+    $self->$_->limit_dialect( @_ ) for( $self->all_sources );
+}
+sub quote_char {
+    my $self = shift;
+    $self->$_->quote_char( @_ ) for( $self->all_sources );
+}
+sub name_sep {
+    my $self = shift;
+    $self->$_->quote_char( @_ ) for( $self->all_sources );
+}
+sub disconnect {
+    my $self = shift;
+    $self->$_->disconnect( @_ ) for( $self->all_sources );
+}
+sub DESTROY {
+    my $self = shift;
+
+    undef $self->{write_source};
+    undef $self->{read_sources};
+}
+
+sub last_insert_id {
+    shift->write_source->last_insert_id( @_ );
+}
+sub insert {
+    shift->write_source->insert( @_ );
+}
+sub update {
+    shift->write_source->update( @_ );
+}
+sub update_all {
+    shift->write_source->update_all( @_ );
+}
+sub delete {
+    shift->write_source->delete( @_ );
+}
+sub delete_all {
+    shift->write_source->delete_all( @_ );
+}
+sub create {
+    shift->write_source->create( @_ );
+}
+sub find_or_create {
+    shift->write_source->find_or_create( @_ );
+}
+sub update_or_create {
+    shift->write_source->update_or_create( @_ );
+}
+sub connected {
+    shift->write_source->connected( @_ );
+}
+sub ensure_connected {
+    shift->write_source->ensure_connected( @_ );
+}
+sub dbh {
+    shift->write_source->dbh( @_ );
+}
+sub txn_begin {
+    shift->write_source->txn_begin( @_ );
+}
+sub txn_commit {
+    shift->write_source->txn_commit( @_ );
+}
+sub txn_rollback {
+    shift->write_source->txn_rollback( @_ );
+}
+sub sth {
+    shift->write_source->sth( @_ );
+}
+sub deploy {
+    shift->write_source->deploy( @_ );
+}
+
+
+sub debugfh { shift->_not_supported( 'debugfh' ) };
+sub debugcb { shift->_not_supported( 'debugcb' ) };
+
+sub _not_supported {
+    my( $self, $method ) = @_;
+
+    die "This Storage does not support $method method.";
+}
+
+=head1 SEE ALSO
+
+L<DBI::Class::Storage::DBI>, L<DBD::Multi>, L<DBI>
+
+=head1 AUTHOR
+
+Norbert Csongrádi <bert at cpan.org>
+
+Peter Siklósi <einon at einon.hu>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
+
+1;

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/SQLite.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/SQLite.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/SQLite.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -2,13 +2,50 @@
 
 use strict;
 use warnings;
+use POSIX 'strftime';
+use File::Copy;
+use File::Spec;
 
 use base qw/DBIx::Class::Storage::DBI::MultiDistinctEmulation/;
 
-sub last_insert_id {
-  return $_[0]->dbh->func('last_insert_rowid');
+sub _dbh_last_insert_id {
+  my ($self, $dbh, $source, $col) = @_;
+  $dbh->func('last_insert_rowid');
 }
 
+sub backup
+{
+  my ($self, $dir) = @_;
+  $dir ||= './';
+
+  ## Where is the db file?
+  my $dsn = $self->connect_info()->[0];
+
+  my $dbname = $1 if($dsn =~ /dbname=([^;]+)/);
+  if(!$dbname)
+  {
+    $dbname = $1 if($dsn =~ /^dbi:SQLite:(.+)$/i);
+  }
+  $self->throw_exception("Cannot determine name of SQLite db file") 
+    if(!$dbname || !-f $dbname);
+
+#  print "Found database: $dbname\n";
+#  my $dbfile = file($dbname);
+  my ($vol, $dbdir, $file) = File::Spec->splitpath($dbname);
+#  my $file = $dbfile->basename();
+  $file = strftime("%y%m%d%h%M%s", localtime()) . $file; 
+  $file = "B$file" while(-f $file);
+
+  mkdir($dir) unless -f $dir;
+  my $backupfile = File::Spec->catfile($dir, $file);
+
+  my $res = copy($dbname, $backupfile);
+  $self->throw_exception("Backup failed! ($!)") if(!$res);
+
+  return $backupfile;
+}
+
+
 1;
 
 =head1 NAME

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/mysql.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/mysql.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI/mysql.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,8 +7,9 @@
 
 # __PACKAGE__->load_components(qw/PK::Auto/);
 
-sub last_insert_id {
-  return $_[0]->_dbh->{mysql_insertid};
+sub _dbh_last_insert_id {
+  my ($self, $dbh, $source, $col) = @_;
+  $dbh->{mysql_insertid};
 }
 
 sub sqlt_type {

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/DBI.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,14 +3,20 @@
 
 use base 'DBIx::Class::Storage';
 
-use strict;
+use strict;    
 use warnings;
 use DBI;
 use SQL::Abstract::Limit;
 use DBIx::Class::Storage::DBI::Cursor;
 use DBIx::Class::Storage::Statistics;
-use IO::File;
-use Carp::Clan qw/DBIx::Class/;
+use Scalar::Util qw/blessed weaken/;
+
+__PACKAGE__->mk_group_accessors('simple' =>
+    qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts
+       _conn_pid _conn_tid disable_sth_caching cursor on_connect_do
+       transaction_depth unsafe/
+);
+
 BEGIN {
 
 package DBIC::SQL::Abstract; # Would merge upstream, but nate doesn't reply :(
@@ -56,7 +62,6 @@
 sub _find_syntax {
   my ($self, $syntax) = @_;
   my $dbhname = blessed($syntax) ?  $syntax->{Driver}{Name} : $syntax;
-#  print STDERR "Found DBH $syntax >$dbhname< ", $syntax->{Driver}->{Name}, "\n";
   if(ref($self) && $dbhname && $dbhname eq 'DB2') {
     return 'RowNumberOver';
   }
@@ -287,15 +292,6 @@
 
 } # End of BEGIN block
 
-use base qw/DBIx::Class/;
-
-__PACKAGE__->load_components(qw/AccessorGroup/);
-
-__PACKAGE__->mk_group_accessors('simple' =>
-  qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts
-     _conn_pid _conn_tid debug debugobj cursor on_connect_do
-     transaction_depth/);
-
 =head1 NAME
 
 DBIx::Class::Storage::DBI - DBI storage handler
@@ -304,49 +300,24 @@
 
 =head1 DESCRIPTION
 
-This class represents the connection to the database
+This class represents the connection to an RDBMS via L<DBI>.  See
+L<DBIx::Class::Storage> for general information.  This pod only
+documents DBI-specific methods and behaviors.
 
 =head1 METHODS
 
-=head2 new
-
 =cut
 
 sub new {
-  my $new = {};
-  bless $new, (ref $_[0] || $_[0]);
+  my $new = shift->next::method(@_);
 
   $new->cursor("DBIx::Class::Storage::DBI::Cursor");
   $new->transaction_depth(0);
-
-  $new->debugobj(new DBIx::Class::Storage::Statistics());
-
-  my $fh;
-
-  my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
-                  || $ENV{DBIC_TRACE};
-
-  if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
-    $fh = IO::File->new($1, 'w')
-      or $new->throw_exception("Cannot open trace file $1");
-  } else {
-    $fh = IO::File->new('>&STDERR');
-  }
-  $new->debugfh($fh);
-  $new->debug(1) if $debug_env;
   $new->_sql_maker_opts({});
-  return $new;
-}
+  $new->{_in_dbh_do} = 0;
+  $new->{_dbh_gen} = 0;
 
-=head2 throw_exception
-
-Throws an exception - croaks.
-
-=cut
-
-sub throw_exception {
-  my ($self, $msg) = @_;
-  croak($msg);
+  $new;
 }
 
 =head2 connect_info
@@ -359,7 +330,13 @@
 
 The arrayref can either contain the same set of arguments one would
 normally pass to L<DBI/connect>, or a lone code reference which returns
-a connected database handle.
+a connected database handle.  Please note that the L<DBI> docs
+recommend that you always explicitly set C<AutoCommit> to either
+C<0> or C<1>.   L<DBIx::Class> further recommends that it be set
+to C<1>, and that you perform transactions via our L</txn_do>
+method.  L<DBIx::Class> will set it to C<1> if you do not do explicitly
+set it to zero.  This is the default for most DBDs.  See below for more
+details.
 
 In either case, if the final argument in your connect_info happens
 to be a hashref, C<connect_info> will look there for several
@@ -373,6 +350,11 @@
 be executed immediately after making the connection to the database
 every time we [re-]connect.
 
+=item disable_sth_caching
+
+If set to a true value, this option will disable the caching of
+statement handles via L<DBI/prepare_cached>.
+
 =item limit_dialect 
 
 Sets the limit dialect. This is useful for JDBC-bridge among others
@@ -397,6 +379,23 @@
 specify the charecter that seperates elements (schemas, tables, columns) from 
 each other. In most cases this is simply a C<.>.
 
+=item unsafe
+
+This Storage driver normally installs its own C<HandleError>, sets
+C<RaiseError> on, and sets C<PrintError> off on all database handles,
+including those supplied by a coderef.  It does this so that it can
+have consistent and useful error behavior.
+
+If you set this option to a true value, Storage will not do its usual
+modifications to the database handle's C<RaiseError>, C<PrintError>, and
+C<HandleError> attributes, and instead relies on the settings in your
+connect_info DBI options (or the values you set in your connection
+coderef, in the case that you are connecting via coderef).
+
+Note that your custom settings can cause Storage to malfunction,
+especially if you set a C<HandleError> handler that suppresses exceptions
+and/or disable C<RaiseError>.
+
 =back
 
 These options can be mixed in with your other L<DBI> connection attributes,
@@ -407,6 +406,21 @@
 these options will be cleared before setting the new ones, regardless of
 whether any options are specified in the new C<connect_info>.
 
+Another Important Note:
+
+DBIC can do some wonderful magic with handling exceptions,
+disconnections, and transactions when you use C<AutoCommit =&gt; 1>
+combined with C<txn_do> for transaction support.
+
+If you set C<AutoCommit =&gt; 0> in your connect info, then you are always
+in an assumed transaction between commits, and you're telling us you'd
+like to manage that manually.  A lot of DBIC's magic protections
+go away.  We can't protect you from exceptions due to database
+disconnects because we don't know anything about how to restart your
+transactions.  You're on your own for handling all sorts of exceptional
+cases if you choose the C<AutoCommit =&gt 0> path, just as you would
+be with raw DBI.
+
 Examples:
 
   # Simple SQLite connection
@@ -421,7 +435,7 @@
       'dbi:Pg:dbname=foo',
       'postgres',
       'my_pg_password',
-      { AutoCommit => 0 },
+      { AutoCommit => 1 },
       { quote_char => q{"}, name_sep => q{.} },
     ]
   );
@@ -432,7 +446,7 @@
       'dbi:Pg:dbname=foo',
       'postgres',
       'my_pg_password',
-      { AutoCommit => 0, quote_char => q{"}, name_sep => q{.} },
+      { AutoCommit => 1, quote_char => q{"}, name_sep => q{.} },
     ]
   );
 
@@ -444,67 +458,183 @@
           quote_char => q{`},
           name_sep => q{@},
           on_connect_do => ['SET search_path TO myschema,otherschema,public'],
+          disable_sth_caching => 1,
       },
     ]
   );
 
+=cut
+
+sub connect_info {
+  my ($self, $info_arg) = @_;
+
+  return $self->_connect_info if !$info_arg;
+
+  # Kill sql_maker/_sql_maker_opts, so we get a fresh one with only
+  #  the new set of options
+  $self->_sql_maker(undef);
+  $self->_sql_maker_opts({});
+  $self->_connect_info([@$info_arg]); # copy for _connect_info
+
+  my $dbi_info = [@$info_arg]; # copy for _dbi_connect_info
+
+  my $last_info = $dbi_info->[-1];
+  if(ref $last_info eq 'HASH') {
+    for my $storage_opt (qw/on_connect_do disable_sth_caching unsafe/) {
+      if(my $value = delete $last_info->{$storage_opt}) {
+        $self->$storage_opt($value);
+      }
+    }
+    for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
+      if(my $opt_val = delete $last_info->{$sql_maker_opt}) {
+        $self->_sql_maker_opts->{$sql_maker_opt} = $opt_val;
+      }
+    }
+
+    # Get rid of any trailing empty hashref
+    pop(@$dbi_info) if !keys %$last_info;
+  }
+  $self->_dbi_connect_info($dbi_info);
+
+  $self->_connect_info;
+}
+
 =head2 on_connect_do
 
 This method is deprecated in favor of setting via L</connect_info>.
 
-=head2 debug
+=head2 dbh_do
 
-Causes SQL trace information to be emitted on the C<debugobj> object.
-(or C<STDERR> if C<debugobj> has not specifically been set).
+Arguments: $subref, @extra_coderef_args?
 
-This is the equivalent to setting L</DBIC_TRACE> in your
-shell environment.
+Execute the given subref using the new exception-based connection management.
 
-=head2 debugfh
+The first two arguments will be the storage object that C<dbh_do> was called
+on and a database handle to use.  Any additional arguments will be passed
+verbatim to the called subref as arguments 2 and onwards.
 
-Set or retrieve the filehandle used for trace/debug output.  This should be
-an IO::Handle compatible ojbect (only the C<print> method is used.  Initially
-set to be STDERR - although see information on the
-L<DBIC_TRACE> environment variable.
+Using this (instead of $self->_dbh or $self->dbh) ensures correct
+exception handling and reconnection (or failover in future subclasses).
 
+Your subref should have no side-effects outside of the database, as
+there is the potential for your subref to be partially double-executed
+if the database connection was stale/dysfunctional.
+
+Example:
+
+  my @stuff = $schema->storage->dbh_do(
+    sub {
+      my ($storage, $dbh, @cols) = @_;
+      my $cols = join(q{, }, @cols);
+      $dbh->selectrow_array("SELECT $cols FROM foo");
+    },
+    @column_list
+  );
+
 =cut
 
-sub debugfh {
-    my $self = shift;
+sub dbh_do {
+  my $self = shift;
+  my $coderef = shift;
 
-    if ($self->debugobj->can('debugfh')) {
-        return $self->debugobj->debugfh(@_);
+  ref $coderef eq 'CODE' or $self->throw_exception
+    ('$coderef must be a CODE reference');
+
+  return $coderef->($self, $self->_dbh, @_) if $self->{_in_dbh_do}
+      || $self->{transaction_depth};
+
+  local $self->{_in_dbh_do} = 1;
+
+  my @result;
+  my $want_array = wantarray;
+
+  eval {
+    $self->_verify_pid if $self->_dbh;
+    $self->_populate_dbh if !$self->_dbh;
+    if($want_array) {
+        @result = $coderef->($self, $self->_dbh, @_);
     }
+    elsif(defined $want_array) {
+        $result[0] = $coderef->($self, $self->_dbh, @_);
+    }
+    else {
+        $coderef->($self, $self->_dbh, @_);
+    }
+  };
+
+  my $exception = $@;
+  if(!$exception) { return $want_array ? @result : $result[0] }
+
+  $self->throw_exception($exception) if $self->connected;
+
+  # We were not connected - reconnect and retry, but let any
+  #  exception fall right through this time
+  $self->_populate_dbh;
+  $coderef->($self, $self->_dbh, @_);
 }
 
-=head2 debugobj
+# This is basically a blend of dbh_do above and DBIx::Class::Storage::txn_do.
+# It also informs dbh_do to bypass itself while under the direction of txn_do,
+#  via $self->{_in_dbh_do} (this saves some redundant eval and errorcheck, etc)
+sub txn_do {
+  my $self = shift;
+  my $coderef = shift;
 
-Sets or retrieves the object used for metric collection. Defaults to an instance
-of L<DBIx::Class::Storage::Statistics> that is campatible with the original
-method of using a coderef as a callback.  See the aforementioned Statistics
-class for more information.
+  ref $coderef eq 'CODE' or $self->throw_exception
+    ('$coderef must be a CODE reference');
 
-=head2 debugcb
+  local $self->{_in_dbh_do} = 1;
 
-Sets a callback to be executed each time a statement is run; takes a sub
-reference.  Callback is executed as $sub->($op, $info) where $op is
-SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
+  my @result;
+  my $want_array = wantarray;
 
-See L<debugobj> for a better way.
+  my $tried = 0;
+  while(1) {
+    eval {
+      $self->_verify_pid if $self->_dbh;
+      $self->_populate_dbh if !$self->_dbh;
 
-=cut
+      $self->txn_begin;
+      if($want_array) {
+          @result = $coderef->(@_);
+      }
+      elsif(defined $want_array) {
+          $result[0] = $coderef->(@_);
+      }
+      else {
+          $coderef->(@_);
+      }
+      $self->txn_commit;
+    };
 
-sub debugcb {
-    my $self = shift;
+    my $exception = $@;
+    if(!$exception) { return $want_array ? @result : $result[0] }
 
-    if ($self->debugobj->can('callback')) {
-        return $self->debugobj->callback(@_);
+    if($tried++ > 0 || $self->connected) {
+      eval { $self->txn_rollback };
+      my $rollback_exception = $@;
+      if($rollback_exception) {
+        my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
+        $self->throw_exception($exception)  # propagate nested rollback
+          if $rollback_exception =~ /$exception_class/;
+
+        $self->throw_exception(
+          "Transaction aborted: ${exception}. "
+          . "Rollback failed: ${rollback_exception}"
+        );
+      }
+      $self->throw_exception($exception)
     }
+
+    # We were not connected, and was first try - reconnect and retry
+    # via the while loop
+    $self->_populate_dbh;
+  }
 }
 
 =head2 disconnect
 
-Disconnect the L<DBI> handle, performing a rollback first if the
+Our C<disconnect> method also performs a rollback first if the
 database is not in C<AutoCommit> mode.
 
 =cut
@@ -516,25 +646,21 @@
     $self->_dbh->rollback unless $self->_dbh->{AutoCommit};
     $self->_dbh->disconnect;
     $self->_dbh(undef);
+    $self->{_dbh_gen}++;
   }
 }
 
-=head2 connected
+sub connected {
+  my ($self) = @_;
 
-Check if the L<DBI> handle is connected.  Returns true if the handle
-is connected.
-
-=cut
-
-sub connected { my ($self) = @_;
-
   if(my $dbh = $self->_dbh) {
       if(defined $self->_conn_tid && $self->_conn_tid != threads->tid) {
-          return $self->_dbh(undef);
+          $self->_dbh(undef);
+          $self->{_dbh_gen}++;
+          return;
       }
-      elsif($self->_conn_pid != $$) {
-          $self->_dbh->{InactiveDestroy} = 1;
-          return $self->_dbh(undef);
+      else {
+          $self->_verify_pid;
       }
       return ($dbh->FETCH('Active') && $dbh->ping);
   }
@@ -542,13 +668,20 @@
   return 0;
 }
 
-=head2 ensure_connected
+# handle pid changes correctly
+#  NOTE: assumes $self->_dbh is a valid $dbh
+sub _verify_pid {
+  my ($self) = @_;
 
-Check whether the database handle is connected - if not then make a
-connection.
+  return if $self->_conn_pid == $$;
 
-=cut
+  $self->_dbh->{InactiveDestroy} = 1;
+  $self->_dbh(undef);
+  $self->{_dbh_gen}++;
 
+  return;
+}
+
 sub ensure_connected {
   my ($self) = @_;
 
@@ -573,16 +706,9 @@
 sub _sql_maker_args {
     my ($self) = @_;
     
-    return ( limit_dialect => $self->dbh, %{$self->_sql_maker_opts} );
+    return ( bindtype=>'columns', limit_dialect => $self->dbh, %{$self->_sql_maker_opts} );
 }
 
-=head2 sql_maker
-
-Returns a C<sql_maker> object - normally an object of class
-C<DBIC::SQL::Abstract>.
-
-=cut
-
 sub sql_maker {
   my ($self) = @_;
   unless ($self->_sql_maker) {
@@ -591,43 +717,15 @@
   return $self->_sql_maker;
 }
 
-sub connect_info {
-  my ($self, $info_arg) = @_;
-
-  if($info_arg) {
-    # Kill sql_maker/_sql_maker_opts, so we get a fresh one with only
-    #  the new set of options
-    $self->_sql_maker(undef);
-    $self->_sql_maker_opts({});
-    $self->_connect_info($info_arg);
-
-    my $dbi_info = [@$info_arg]; # copy for DBI
-    my $last_info = $dbi_info->[-1];
-    if(ref $last_info eq 'HASH') {
-      if(my $on_connect_do = delete $last_info->{on_connect_do}) {
-        $self->on_connect_do($on_connect_do);
-      }
-      for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
-        if(my $opt_val = delete $last_info->{$sql_maker_opt}) {
-          $self->_sql_maker_opts->{$sql_maker_opt} = $opt_val;
-        }
-      }
-
-      # Get rid of any trailing empty hashref
-      pop(@$dbi_info) if !keys %$last_info;
-    }
-
-    $self->_dbi_connect_info($dbi_info);
-  }
-
-  $self->_connect_info;
-}
-
 sub _populate_dbh {
   my ($self) = @_;
   my @info = @{$self->_dbi_connect_info || []};
   $self->_dbh($self->_connect(@info));
 
+  # Always set the transaction depth on connect, since
+  #  there is no transaction in progress by definition
+  $self->{transaction_depth} = $self->_dbh->{AutoCommit} ? 0 : 1;
+
   if(ref $self eq 'DBIx::Class::Storage::DBI') {
     my $driver = $self->_dbh->{Driver}->{Name};
     if ($self->load_optional_class("DBIx::Class::Storage::DBI::${driver}")) {
@@ -651,167 +749,254 @@
   my ($self, @info) = @_;
 
   $self->throw_exception("You failed to provide any connection info")
-      if !@info;
+    if !@info;
 
   my ($old_connect_via, $dbh);
 
   if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) {
-      $old_connect_via = $DBI::connect_via;
-      $DBI::connect_via = 'connect';
+    $old_connect_via = $DBI::connect_via;
+    $DBI::connect_via = 'connect';
   }
 
   eval {
-    $dbh = ref $info[0] eq 'CODE'
-         ? &{$info[0]}
-         : DBI->connect(@info);
+    if(ref $info[0] eq 'CODE') {
+       $dbh = &{$info[0]}
+    }
+    else {
+       $dbh = DBI->connect(@info);
+    }
+
+    if(!$self->unsafe) {
+      my $weak_self = $self;
+      weaken($weak_self);
+      $dbh->{HandleError} = sub {
+          $weak_self->throw_exception("DBI Exception: $_[0]")
+      };
+      $dbh->{RaiseError} = 1;
+      $dbh->{PrintError} = 0;
+    }
   };
 
   $DBI::connect_via = $old_connect_via if $old_connect_via;
 
-  if (!$dbh || $@) {
-    $self->throw_exception("DBI Connection failed: " . ($@ || $DBI::errstr));
-  }
+  $self->throw_exception("DBI Connection failed: " . ($@||$DBI::errstr))
+    if !$dbh || $@;
 
   $dbh;
 }
 
-=head2 txn_begin
 
-Calls begin_work on the current dbh.
-
-See L<DBIx::Class::Schema> for the txn_do() method, which allows for
-an entire code block to be executed transactionally.
-
-=cut
-
 sub txn_begin {
   my $self = shift;
-  if ($self->{transaction_depth}++ == 0) {
-    my $dbh = $self->dbh;
-    if ($dbh->{AutoCommit}) {
-      $self->debugobj->txn_begin()
-        if ($self->debug);
-      $dbh->begin_work;
-    }
+  if($self->{transaction_depth}++ == 0) {
+    $self->debugobj->txn_begin()
+      if $self->debug;
+    # this isn't ->_dbh-> because
+    #  we should reconnect on begin_work
+    #  for AutoCommit users
+    $self->dbh->begin_work;
   }
 }
 
-=head2 txn_commit
-
-Issues a commit against the current dbh.
-
-=cut
-
 sub txn_commit {
   my $self = shift;
-  my $dbh = $self->dbh;
-  if ($self->{transaction_depth} == 0) {
-    unless ($dbh->{AutoCommit}) {
-      $self->debugobj->txn_commit()
-        if ($self->debug);
-      $dbh->commit;
-    }
+  if ($self->{transaction_depth} == 1) {
+    my $dbh = $self->_dbh;
+    $self->debugobj->txn_commit()
+      if ($self->debug);
+    $dbh->commit;
+    $self->{transaction_depth} = 0
+      if $dbh->{AutoCommit};
   }
-  else {
-    if (--$self->{transaction_depth} == 0) {
-      $self->debugobj->txn_commit()
-        if ($self->debug);
-      $dbh->commit;
-    }
+  elsif($self->{transaction_depth} > 1) {
+    $self->{transaction_depth}--
   }
 }
 
-=head2 txn_rollback
-
-Issues a rollback against the current dbh. A nested rollback will
-throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
-which allows the rollback to propagate to the outermost transaction.
-
-=cut
-
 sub txn_rollback {
   my $self = shift;
-
+  my $dbh = $self->_dbh;
+  my $autocommit;
   eval {
-    my $dbh = $self->dbh;
-    if ($self->{transaction_depth} == 0) {
-      unless ($dbh->{AutoCommit}) {
-        $self->debugobj->txn_rollback()
-          if ($self->debug);
-        $dbh->rollback;
-      }
+    $autocommit = $dbh->{AutoCommit};
+    if ($self->{transaction_depth} == 1) {
+      $self->debugobj->txn_rollback()
+        if ($self->debug);
+      $dbh->rollback;
+      $self->{transaction_depth} = 0
+        if $autocommit;
     }
+    elsif($self->{transaction_depth} > 1) {
+      $self->{transaction_depth}--;
+    }
     else {
-      if (--$self->{transaction_depth} == 0) {
-        $self->debugobj->txn_rollback()
-          if ($self->debug);
-        $dbh->rollback;
-      }
-      else {
-        die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
-      }
+      die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
     }
   };
-
   if ($@) {
     my $error = $@;
     my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
     $error =~ /$exception_class/ and $self->throw_exception($error);
-    $self->{transaction_depth} = 0;          # ensure that a failed rollback
-    $self->throw_exception($error);          # resets the transaction depth
+    # ensure that a failed rollback resets the transaction depth
+    $self->{transaction_depth} = $autocommit ? 0 : 1;
+    $self->throw_exception($error);
   }
 }
 
-sub _execute {
-  my ($self, $op, $extra_bind, $ident, @args) = @_;
-  my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
-  unshift(@bind, @$extra_bind) if $extra_bind;
+# This used to be the top-half of _execute.  It was split out to make it
+#  easier to override in NoBindVars without duping the rest.  It takes up
+#  all of _execute's args, and emits $sql, @bind.
+sub _prep_for_execute {
+  my ($self, $op, $extra_bind, $ident, $args) = @_;
+
+  my ($sql, @bind) = $self->sql_maker->$op($ident, @$args);
+  unshift(@bind,
+    map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
+      if $extra_bind;
+
+  return ($sql, \@bind);
+}
+
+sub _dbh_execute {
+  my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
+  
+  if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
+    $ident = $ident->from();
+  }
+
+  my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
+
   if ($self->debug) {
-      my @debug_bind = map { defined $_ ? qq{'$_'} : q{'NULL'} } @bind;
+      my @debug_bind =
+        map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @$bind;
       $self->debugobj->query_start($sql, @debug_bind);
   }
-  my $sth = eval { $self->sth($sql,$op) };
 
-  if (!$sth || $@) {
-    $self->throw_exception(
-      'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
-    );
-  }
-  @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
-  my $rv;
-  if ($sth) {
-    my $time = time();
-    $rv = eval { $sth->execute(@bind) };
+  my $sth = $self->sth($sql,$op);
 
-    if ($@ || !$rv) {
-      $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr));
+  my $placeholder_index = 1; 
+
+  foreach my $bound (@$bind) {
+    my $attributes = {};
+    my($column_name, @data) = @$bound;
+
+    if ($bind_attributes) {
+      $attributes = $bind_attributes->{$column_name}
+      if defined $bind_attributes->{$column_name};
     }
-  } else {
-    $self->throw_exception("'$sql' did not generate a statement.");
+
+    foreach my $data (@data) {
+      $data = ref $data ? ''.$data : $data; # stringify args
+
+      $sth->bind_param($placeholder_index, $data, $attributes);
+      $placeholder_index++;
+    }
   }
+
+  # Can this fail without throwing an exception anyways???
+  my $rv = $sth->execute();
+  $self->throw_exception($sth->errstr) if !$rv;
+
   if ($self->debug) {
-      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind; 
-      $self->debugobj->query_end($sql, @debug_bind);
+     my @debug_bind =
+       map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @$bind; 
+     $self->debugobj->query_end($sql, @debug_bind);
   }
-  return (wantarray ? ($rv, $sth, @bind) : $rv);
+
+  return (wantarray ? ($rv, $sth, @$bind) : $rv);
 }
 
+sub _execute {
+    my $self = shift;
+    $self->dbh_do($self->can('_dbh_execute'), @_)
+}
+
 sub insert {
-  my ($self, $ident, $to_insert) = @_;
-  $self->throw_exception(
-    "Couldn't insert ".join(', ',
-      map "$_ => $to_insert->{$_}", keys %$to_insert
-    )." into ${ident}"
-  ) unless ($self->_execute('insert' => [], $ident, $to_insert));
+  my ($self, $source, $to_insert) = @_;
+  
+  my $ident = $source->from; 
+  my $bind_attributes = $self->source_bind_attributes($source);
+
+  $self->_execute('insert' => [], $source, $bind_attributes, $to_insert);
+
   return $to_insert;
 }
 
+## Still not quite perfect, and EXPERIMENTAL
+## Currently it is assumed that all values passed will be "normal", i.e. not 
+## scalar refs, or at least, all the same type as the first set, the statement is
+## only prepped once.
+sub insert_bulk {
+  my ($self, $source, $cols, $data) = @_;
+  my %colvalues;
+  my $table = $source->from;
+  @colvalues{@$cols} = (0..$#$cols);
+  my ($sql, @bind) = $self->sql_maker->insert($table, \%colvalues);
+  
+  if ($self->debug) {
+      my @debug_bind = map { defined $_->[1] ? qq{$_->[1]} : q{'NULL'} } @bind;
+      $self->debugobj->query_start($sql, @debug_bind);
+  }
+  my $sth = $self->sth($sql);
+
+#  @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
+
+  ## This must be an arrayref, else nothing works!
+  
+  my $tuple_status = [];
+  
+  ##use Data::Dumper;
+  ##print STDERR Dumper( $data, $sql, [@bind] );
+
+  my $time = time();
+
+  ## Get the bind_attributes, if any exist
+  my $bind_attributes = $self->source_bind_attributes($source);
+
+  ## Bind the values and execute
+  my $placeholder_index = 1; 
+
+  foreach my $bound (@bind) {
+
+    my $attributes = {};
+    my ($column_name, $data_index) = @$bound;
+
+    if( $bind_attributes ) {
+      $attributes = $bind_attributes->{$column_name}
+      if defined $bind_attributes->{$column_name};
+    }
+
+    my @data = map { $_->[$data_index] } @$data;
+
+    $sth->bind_param_array( $placeholder_index, [@data], $attributes );
+    $placeholder_index++;
+  }
+  my $rv = $sth->execute_array({ArrayTupleStatus => $tuple_status});
+  $self->throw_exception($sth->errstr) if !$rv;
+
+  if ($self->debug) {
+      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
+      $self->debugobj->query_end($sql, @debug_bind);
+  }
+  return (wantarray ? ($rv, $sth, @bind) : $rv);
+}
+
 sub update {
-  return shift->_execute('update' => [], @_);
+  my $self = shift @_;
+  my $source = shift @_;
+  my $bind_attributes = $self->source_bind_attributes($source);
+  
+  return $self->_execute('update' => [], $source, $bind_attributes, @_);
 }
 
+
 sub delete {
-  return shift->_execute('delete' => [], @_);
+  my $self = shift @_;
+  my $source = shift @_;
+  
+  my $bind_attrs = {}; ## If ever it's needed...
+  
+  return $self->_execute('delete' => [], $source, $bind_attrs, @_);
 }
 
 sub _select {
@@ -827,7 +1012,8 @@
       ($order ? (order_by => $order) : ())
     };
   }
-  my @args = ('select', $attrs->{bind}, $ident, $select, $condition, $order);
+  my $bind_attrs = {}; ## Future support
+  my @args = ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $condition, $order);
   if ($attrs->{software_limit} ||
       $self->sql_maker->_default_limit_syntax eq "GenericSubQ") {
         $attrs->{software_limit} = 1;
@@ -839,6 +1025,20 @@
   return $self->_execute(@args);
 }
 
+sub source_bind_attributes {
+  my ($self, $source) = @_;
+  
+  my $bind_attributes;
+  foreach my $column ($source->columns) {
+  
+    my $data_type = $source->column_info($column)->{data_type} || '';
+    $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
+     if $data_type;
+  }
+
+  return $bind_attributes;
+}
+
 =head2 select
 
 =over 4
@@ -857,19 +1057,11 @@
   return $self->cursor->new($self, \@_, $attrs);
 }
 
-=head2 select_single
-
-Performs a select, fetch and return of data - handles a single row
-only.
-
-=cut
-
-# Need to call finish() to work round broken DBDs
-
 sub select_single {
   my $self = shift;
   my ($rv, $sth, @bind) = $self->_select(@_);
   my @row = $sth->fetchrow_array;
+  # Need to call finish() to work round broken DBDs
   $sth->finish();
   return @row;
 }
@@ -886,32 +1078,35 @@
 
 =cut
 
-sub sth {
-  my ($self, $sql) = @_;
+sub _dbh_sth {
+  my ($self, $dbh, $sql) = @_;
+
   # 3 is the if_active parameter which avoids active sth re-use
-  return $self->dbh->prepare_cached($sql, {}, 3);
-}
+  my $sth = $self->disable_sth_caching
+    ? $dbh->prepare($sql)
+    : $dbh->prepare_cached($sql, {}, 3);
 
-=head2 columns_info_for
+  # XXX You would think RaiseError would make this impossible,
+  #  but apparently that's not true :(
+  $self->throw_exception($dbh->errstr) if !$sth;
 
-Returns database type info for a given table column.
+  $sth;
+}
 
-=cut
+sub sth {
+  my ($self, $sql) = @_;
+  $self->dbh_do($self->can('_dbh_sth'), $sql);
+}
 
-sub columns_info_for {
-  my ($self, $table) = @_;
+sub _dbh_columns_info_for {
+  my ($self, $dbh, $table) = @_;
 
-  my $dbh = $self->dbh;
-
   if ($dbh->can('column_info')) {
     my %result;
-    local $dbh->{RaiseError} = 1;
-    local $dbh->{PrintError} = 0;
     eval {
       my ($schema,$tab) = $table =~ /^(.+?)\.(.+)$/ ? ($1,$2) : (undef,$table);
       my $sth = $dbh->column_info( undef,$schema, $tab, '%' );
       $sth->execute();
-
       while ( my $info = $sth->fetchrow_hashref() ){
         my %column_info;
         $column_info{data_type}   = $info->{TYPE_NAME};
@@ -960,17 +1155,26 @@
   return \%result;
 }
 
+sub columns_info_for {
+  my ($self, $table) = @_;
+  $self->dbh_do($self->can('_dbh_columns_info_for'), $table);
+}
+
 =head2 last_insert_id
 
 Return the row id of the last insert.
 
 =cut
 
+sub _dbh_last_insert_id {
+    my ($self, $dbh, $source, $col) = @_;
+    # XXX This is a SQLite-ism as a default... is there a DBI-generic way?
+    $dbh->func('last_insert_rowid');
+}
+
 sub last_insert_id {
-  my ($self, $row) = @_;
-    
-  return $self->dbh->func('last_insert_rowid');
-
+  my $self = shift;
+  $self->dbh_do($self->can('_dbh_last_insert_id'), @_);
 }
 
 =head2 sqlt_type
@@ -981,11 +1185,25 @@
 
 sub sqlt_type { shift->dbh->{Driver}->{Name} }
 
+=head2 bind_attribute_by_data_type
+
+Given a datatype from column info, returns a database specific bind attribute for
+$dbh->bind_param($val,$attribute) or nothing if we will let the database planner
+just handle it.
+
+Generally only needed for special case column types, like bytea in postgres.
+
+=cut
+
+sub bind_attribute_by_data_type {
+    return;
+}
+
 =head2 create_ddl_dir (EXPERIMENTAL)
 
 =over 4
 
-=item Arguments: $schema \@databases, $version, $directory, $sqlt_args
+=item Arguments: $schema \@databases, $version, $directory, $preversion, $sqlt_args
 
 =back
 
@@ -999,7 +1217,7 @@
 
 sub create_ddl_dir
 {
-  my ($self, $schema, $databases, $version, $dir, $sqltargs) = @_;
+  my ($self, $schema, $databases, $version, $dir, $preversion, $sqltargs) = @_;
 
   if(!$dir || !-d $dir)
   {
@@ -1011,15 +1229,20 @@
   $version ||= $schema->VERSION || '1.x';
   $sqltargs = { ( add_drop_table => 1 ), %{$sqltargs || {}} };
 
-  eval "use SQL::Translator";
-  $self->throw_exception("Can't deploy without SQL::Translator: $@") if $@;
+  $self->throw_exception(q{Can't create a ddl file without SQL::Translator 0.08: '}
+      . $self->_check_sqlt_message . q{'})
+          if !$self->_check_sqlt_version;
 
-  my $sqlt = SQL::Translator->new($sqltargs);
+  my $sqlt = SQL::Translator->new({
+#      debug => 1,
+      add_drop_table => 1,
+  });
   foreach my $db (@$databases)
   {
     $sqlt->reset();
     $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
 #    $sqlt->parser_args({'DBIx::Class' => $schema);
+    $sqlt = $self->configure_sqlt($sqlt, $db);
     $sqlt->data($schema);
     $sqlt->producer($db);
 
@@ -1027,24 +1250,92 @@
     my $filename = $schema->ddl_filename($db, $dir, $version);
     if(-e $filename)
     {
-      $self->throw_exception("$filename already exists, skipping $db");
+      warn("$filename already exists, skipping $db");
       next;
     }
-    open($file, ">$filename") 
-      or $self->throw_exception("Can't open $filename for writing ($!)");
+
     my $output = $sqlt->translate;
-#use Data::Dumper;
-#    print join(":", keys %{$schema->source_registrations});
-#    print Dumper($sqlt->schema);
     if(!$output)
     {
-      $self->throw_exception("Failed to translate to $db. (" . $sqlt->error . ")");
+      warn("Failed to translate to $db, skipping. (" . $sqlt->error . ")");
       next;
     }
+    if(!open($file, ">$filename"))
+    {
+        $self->throw_exception("Can't open $filename for writing ($!)");
+        next;
+    }
     print $file $output;
     close($file);
+
+    if($preversion)
+    {
+      require SQL::Translator::Diff;
+
+      my $prefilename = $schema->ddl_filename($db, $dir, $preversion);
+#      print "Previous version $prefilename\n";
+      if(!-e $prefilename)
+      {
+        warn("No previous schema file found ($prefilename)");
+        next;
+      }
+      #### We need to reparse the SQLite file we just wrote, so that 
+      ##   Diff doesnt get all confoosed, and Diff is *very* confused.
+      ##   FIXME: rip Diff to pieces!
+#      my $target_schema = $sqlt->schema;
+#      unless ( $target_schema->name ) {
+#        $target_schema->name( $filename );
+#      }
+      my @input;
+      push @input, {file => $prefilename, parser => $db};
+      push @input, {file => $filename, parser => $db};
+      my ( $source_schema, $source_db, $target_schema, $target_db ) = map {
+        my $file   = $_->{'file'};
+        my $parser = $_->{'parser'};
+
+        my $t = SQL::Translator->new;
+        $t->debug( 0 );
+        $t->trace( 0 );
+        $t->parser( $parser )            or die $t->error;
+        my $out = $t->translate( $file ) or die $t->error;
+        my $schema = $t->schema;
+        unless ( $schema->name ) {
+          $schema->name( $file );
+        }
+        ($schema, $parser);
+      } @input;
+
+      my $diff = SQL::Translator::Diff::schema_diff($source_schema, $db,
+                                                    $target_schema, $db,
+                                                    {}
+                                                   );
+      my $difffile = $schema->ddl_filename($db, $dir, $version, $preversion);
+      print STDERR "Diff: $difffile: $db, $dir, $version, $preversion \n";
+      if(-e $difffile)
+      {
+        warn("$difffile already exists, skipping");
+        next;
+      }
+      if(!open $file, ">$difffile")
+      { 
+        $self->throw_exception("Can't write to $difffile ($!)");
+        next;
+      }
+      print $file $diff;
+      close($file);
+    }
   }
+}
 
+sub configure_sqlt() {
+  my $self = shift;
+  my $tr = shift;
+  my $db = shift || $self->sqlt_type;
+  if ($db eq 'PostgreSQL') {
+    $tr->quote_table_names(0);
+    $tr->quote_field_names(0);
+  }
+  return $tr;
 }
 
 =head2 deployment_statements
@@ -1077,43 +1368,38 @@
   $type ||= $self->sqlt_type;
   $version ||= $schema->VERSION || '1.x';
   $dir ||= './';
-  eval "use SQL::Translator";
-  if(!$@)
-  {
-    eval "use SQL::Translator::Parser::DBIx::Class;";
-    $self->throw_exception($@) if $@;
-    eval "use SQL::Translator::Producer::${type};";
-    $self->throw_exception($@) if $@;
-    my $tr = SQL::Translator->new(%$sqltargs);
-    SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
-    return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
-  }
-
   my $filename = $schema->ddl_filename($type, $dir, $version);
-  if(!-f $filename)
+  if(-f $filename)
   {
-#      $schema->create_ddl_dir([ $type ], $version, $dir, $sqltargs);
-      $self->throw_exception("No SQL::Translator, and no Schema file found, aborting deploy");
-      return;
+      my $file;
+      open($file, "<$filename") 
+        or $self->throw_exception("Can't open $filename ($!)");
+      my @rows = <$file>;
+      close($file);
+      return join('', @rows);
   }
-  my $file;
-  open($file, "<$filename") 
-      or $self->throw_exception("Can't open $filename ($!)");
-  my @rows = <$file>;
-  close($file);
 
-  return join('', @rows);
-  
-}
+  $self->throw_exception(q{Can't deploy without SQL::Translator 0.08: '}
+      . $self->_check_sqlt_message . q{'})
+          if !$self->_check_sqlt_version;
 
-=head2 deploy
+  require SQL::Translator::Parser::DBIx::Class;
+  eval qq{use SQL::Translator::Producer::${type}};
+  $self->throw_exception($@) if $@;
 
-Sends the appropriate statements to create or modify tables to the
-db. This would normally be called through
-L<DBIx::Class::Schema/deploy>.
+  # sources needs to be a parser arg, but for simplicty allow at top level 
+  # coming in
+  $sqltargs->{parser_args}{sources} = delete $sqltargs->{sources}
+      if exists $sqltargs->{sources};
 
-=cut
+  my $tr = SQL::Translator->new(%$sqltargs);
+  SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
+  return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
 
+  return;
+
+}
+
 sub deploy {
   my ($self, $schema, $type, $sqltargs, $dir) = @_;
   foreach my $statement ( $self->deployment_statements($schema, $type, undef, $dir, { no_comments => 1, %{ $sqltargs || {} } } ) ) {
@@ -1125,7 +1411,7 @@
       next if($_ =~ /^COMMIT/m);
       next if $_ =~ /^\s+$/; # skip whitespace only
       $self->debugobj->query_start($_) if $self->debug;
-      $self->dbh->do($_) or warn $self->dbh->errstr, "\nSQL was:\n $_";
+      $self->dbh->do($_); # shouldn't be using ->dbh ?
       $self->debugobj->query_end($_) if $self->debug;
     }
   }
@@ -1165,15 +1451,26 @@
   return $type;
 }
 
+{
+    my $_check_sqlt_version; # private
+    my $_check_sqlt_message; # private
+    sub _check_sqlt_version {
+        return $_check_sqlt_version if defined $_check_sqlt_version;
+        eval 'use SQL::Translator 0.08';
+        $_check_sqlt_message = $@ ? $@ : '';
+        $_check_sqlt_version = $@ ? 0 : 1;
+    }
+
+    sub _check_sqlt_message {
+        _check_sqlt_version if !defined $_check_sqlt_message;
+        $_check_sqlt_message;
+    }
+}
+
 sub DESTROY {
-  # NOTE: if there's a merge conflict here when -current is pushed
-  #  back to trunk, take -current's version and ignore this trunk one :)
   my $self = shift;
-
-  if($self->_dbh && $self->_conn_pid != $$) {
-    $self->_dbh->{InactiveDestroy} = 1;
-  }
-
+  return if !$self->_dbh;
+  $self->_verify_pid;
   $self->_dbh(undef);
 }
 
@@ -1214,25 +1511,6 @@
 
 =back
 
-=head1 ENVIRONMENT VARIABLES
-
-=head2 DBIC_TRACE
-
-If C<DBIC_TRACE> is set then SQL trace information
-is produced (as when the L<debug> method is set).
-
-If the value is of the form C<1=/path/name> then the trace output is
-written to the file C</path/name>.
-
-This environment variable is checked when the storage object is first
-created (when you call connect on your schema).  So, run-time changes 
-to this environment variable will not take effect unless you also 
-re-connect on your schema.
-
-=head2 DBIX_CLASS_STORAGE_DBI_DEBUG
-
-Old name for DBIC_TRACE
-
 =head1 AUTHORS
 
 Matt S. Trout <mst at shadowcatsystems.co.uk>

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage/Statistics.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage/Statistics.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage/Statistics.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -1,7 +1,9 @@
 package DBIx::Class::Storage::Statistics;
 use strict;
+use warnings;
 
-use base qw/DBIx::Class::AccessorGroup Class::Data::Accessor/;
+use base qw/Class::Accessor::Grouped/;
+
 __PACKAGE__->mk_group_accessors(simple => qw/callback debugfh/);
 
 =head1 NAME

Modified: trunk/DBIx-Class/lib/DBIx/Class/Storage.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class/Storage.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class/Storage.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -1,42 +1,440 @@
-package # hide from PAUSE
-    DBIx::Class::Storage;
+package DBIx::Class::Storage;
 
 use strict;
 use warnings;
 
-sub new { die "Virtual method!" }
-sub debug { die "Virtual method!" }
-sub debugcb { die "Virtual method!" }
-sub debugfh { die "Virtual method!" }
-sub debugobj { die "Virtual method!" }
-sub cursor { die "Virtual method!" }
+use base qw/DBIx::Class/;
+
+use Scalar::Util qw/weaken/;
+use Carp::Clan qw/^DBIx::Class/;
+use IO::File;
+
+__PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
+
+package # Hide from PAUSE
+    DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
+
+use overload '"' => sub {
+  'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
+};
+
+sub new {
+  my $class = shift;
+  my $self = {};
+  return bless $self, $class;
+}
+
+package DBIx::Class::Storage;
+
+=head1 NAME
+
+DBIx::Class::Storage - Generic Storage Handler
+
+=head1 DESCRIPTION
+
+A base implementation of common Storage methods.  For specific
+information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
+
+=head1 METHODS
+
+=head2 new
+
+Arguments: $schema
+
+Instantiates the Storage object.
+
+=cut
+
+sub new {
+  my ($self, $schema) = @_;
+
+  $self = ref $self if ref $self;
+
+  my $new = {};
+  bless $new, $self;
+
+  $new->set_schema($schema);
+  $new->debugobj(new DBIx::Class::Storage::Statistics());
+
+  my $fh;
+
+  my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
+                  || $ENV{DBIC_TRACE};
+
+  if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
+    $fh = IO::File->new($1, 'w')
+      or $new->throw_exception("Cannot open trace file $1");
+  } else {
+    $fh = IO::File->new('>&STDERR');
+  }
+
+  $fh->autoflush(1);
+  $new->debugfh($fh);
+  $new->debug(1) if $debug_env;
+
+  $new;
+}
+
+=head2 set_schema
+
+Used to reset the schema class or object which owns this
+storage object, such as during L<DBIx::Class::Schema/clone>.
+
+=cut
+
+sub set_schema {
+  my ($self, $schema) = @_;
+  $self->schema($schema);
+  weaken($self->{schema}) if ref $self->{schema};
+}
+
+=head2 connected
+
+Returns true if we have an open storage connection, false
+if it is not (yet) open.
+
+=cut
+
+sub connected { die "Virtual method!" }
+
+=head2 disconnect
+
+Closes any open storage connection unconditionally.
+
+=cut
+
 sub disconnect { die "Virtual method!" }
-sub connected { die "Virtual method!" }
+
+=head2 ensure_connected
+
+Initiate a connection to the storage if one isn't already open.
+
+=cut
+
 sub ensure_connected { die "Virtual method!" }
-sub on_connect_do { die "Virtual method!" }
-sub connect_info { die "Virtual method!" }
-sub sql_maker { die "Virtual method!" }
+
+=head2 throw_exception
+
+Throws an exception - croaks.
+
+=cut
+
+sub throw_exception {
+  my $self = shift;
+
+  $self->schema->throw_exception(@_) if $self->schema;
+  croak @_;
+}
+
+=head2 txn_do
+
+=over 4
+
+=item Arguments: C<$coderef>, @coderef_args?
+
+=item Return Value: The return value of $coderef
+
+=back
+
+Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
+returning its result (if any). If an exception is caught, a rollback is issued
+and the exception is rethrown. If the rollback fails, (i.e. throws an
+exception) an exception is thrown that includes a "Rollback failed" message.
+
+For example,
+
+  my $author_rs = $schema->resultset('Author')->find(1);
+  my @titles = qw/Night Day It/;
+
+  my $coderef = sub {
+    # If any one of these fails, the entire transaction fails
+    $author_rs->create_related('books', {
+      title => $_
+    }) foreach (@titles);
+
+    return $author->books;
+  };
+
+  my $rs;
+  eval {
+    $rs = $schema->txn_do($coderef);
+  };
+
+  if ($@) {                                  # Transaction failed
+    die "something terrible has happened!"   #
+      if ($@ =~ /Rollback failed/);          # Rollback failed
+
+    deal_with_failed_transaction();
+  }
+
+In a nested transaction (calling txn_do() from within a txn_do() coderef) only
+the outermost transaction will issue a L</txn_commit>, and txn_do() can be
+called in void, scalar and list context and it will behave as expected.
+
+Please note that all of the code in your coderef, including non-DBIx::Class
+code, is part of a transaction.  This transaction may fail out halfway, or
+it may get partially double-executed (in the case that our DB connection
+failed halfway through the transaction, in which case we reconnect and
+restart the txn).  Therefore it is best that any side-effects in your coderef
+are idempotent (that is, can be re-executed multiple times and get the
+same result), and that you check up on your side-effects in the case of
+transaction failure.
+
+=cut
+
+sub txn_do {
+  my ($self, $coderef, @args) = @_;
+
+  ref $coderef eq 'CODE' or $self->throw_exception
+    ('$coderef must be a CODE reference');
+
+  my (@return_values, $return_value);
+
+  $self->txn_begin; # If this throws an exception, no rollback is needed
+
+  my $wantarray = wantarray; # Need to save this since the context
+                             # inside the eval{} block is independent
+                             # of the context that called txn_do()
+  eval {
+
+    # Need to differentiate between scalar/list context to allow for
+    # returning a list in scalar context to get the size of the list
+    if ($wantarray) {
+      # list context
+      @return_values = $coderef->(@args);
+    } elsif (defined $wantarray) {
+      # scalar context
+      $return_value = $coderef->(@args);
+    } else {
+      # void context
+      $coderef->(@args);
+    }
+    $self->txn_commit;
+  };
+
+  if ($@) {
+    my $error = $@;
+
+    eval {
+      $self->txn_rollback;
+    };
+
+    if ($@) {
+      my $rollback_error = $@;
+      my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
+      $self->throw_exception($error)  # propagate nested rollback
+        if $rollback_error =~ /$exception_class/;
+
+      $self->throw_exception(
+        "Transaction aborted: $error. Rollback failed: ${rollback_error}"
+      );
+    } else {
+      $self->throw_exception($error); # txn failed but rollback succeeded
+    }
+  }
+
+  return $wantarray ? @return_values : $return_value;
+}
+
+=head2 txn_begin
+
+Starts a transaction.
+
+See the preferred L</txn_do> method, which allows for
+an entire code block to be executed transactionally.
+
+=cut
+
 sub txn_begin { die "Virtual method!" }
+
+=head2 txn_commit
+
+Issues a commit of the current transaction.
+
+=cut
+
 sub txn_commit { die "Virtual method!" }
+
+=head2 txn_rollback
+
+Issues a rollback of the current transaction. A nested rollback will
+throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
+which allows the rollback to propagate to the outermost transaction.
+
+=cut
+
 sub txn_rollback { die "Virtual method!" }
+
+=head2 sql_maker
+
+Returns a C<sql_maker> object - normally an object of class
+C<DBIC::SQL::Abstract>.
+
+=cut
+
+sub sql_maker { die "Virtual method!" }
+
+=head2 debug
+
+Causes trace information to be emitted on the C<debugobj> object.
+(or C<STDERR> if C<debugobj> has not specifically been set).
+
+This is the equivalent to setting L</DBIC_TRACE> in your
+shell environment.
+
+=head2 debugfh
+
+Set or retrieve the filehandle used for trace/debug output.  This should be
+an IO::Handle compatible ojbect (only the C<print> method is used.  Initially
+set to be STDERR - although see information on the
+L<DBIC_TRACE> environment variable.
+
+=cut
+
+sub debugfh {
+    my $self = shift;
+
+    if ($self->debugobj->can('debugfh')) {
+        return $self->debugobj->debugfh(@_);
+    }
+}
+
+=head2 debugobj
+
+Sets or retrieves the object used for metric collection. Defaults to an instance
+of L<DBIx::Class::Storage::Statistics> that is compatible with the original
+method of using a coderef as a callback.  See the aforementioned Statistics
+class for more information.
+
+=head2 debugcb
+
+Sets a callback to be executed each time a statement is run; takes a sub
+reference.  Callback is executed as $sub->($op, $info) where $op is
+SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
+
+See L<debugobj> for a better way.
+
+=cut
+
+sub debugcb {
+    my $self = shift;
+
+    if ($self->debugobj->can('callback')) {
+        return $self->debugobj->callback(@_);
+    }
+}
+
+=head2 cursor
+
+The cursor class for this Storage object.
+
+=cut
+
+sub cursor { die "Virtual method!" }
+
+=head2 deploy
+
+Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
+Storage class). This would normally be called through
+L<DBIx::Class::Schema/deploy>.
+
+=cut
+
+sub deploy { die "Virtual method!" }
+
+=head2 connect_info
+
+The arguments of C<connect_info> are always a single array reference,
+and are Storage-handler specific.
+
+This is normally accessed via L<DBIx::Class::Schema/connection>, which
+encapsulates its argument list in an arrayref before calling
+C<connect_info> here.
+
+=cut
+
+sub connect_info { die "Virtual method!" }
+
+=head2 select
+
+Handle a select statement.
+
+=cut
+
+sub select { die "Virtual method!" }
+
+=head2 insert
+
+Handle an insert statement.
+
+=cut
+
 sub insert { die "Virtual method!" }
+
+=head2 update
+
+Handle an update statement.
+
+=cut
+
 sub update { die "Virtual method!" }
+
+=head2 delete
+
+Handle a delete statement.
+
+=cut
+
 sub delete { die "Virtual method!" }
-sub select { die "Virtual method!" }
+
+=head2 select_single
+
+Performs a select, fetch and return of data - handles a single row
+only.
+
+=cut
+
 sub select_single { die "Virtual method!" }
+
+=head2 columns_info_for
+
+Returns metadata for the given source's columns.  This
+is *deprecated*, and will be removed before 1.0.  You should
+be specifying the metadata yourself if you need it.
+
+=cut
+
 sub columns_info_for { die "Virtual method!" }
 
+=head1 ENVIRONMENT VARIABLES
 
-package DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
+=head2 DBIC_TRACE
 
-use overload '"' => sub {
-  'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
-};
+If C<DBIC_TRACE> is set then trace information
+is produced (as when the L<debug> method is set).
 
-sub new {
-  my $class = shift;
-  my $self = {};
-  return bless $self, $class;
-}
+If the value is of the form C<1=/path/name> then the trace output is
+written to the file C</path/name>.
 
+This environment variable is checked when the storage object is first
+created (when you call connect on your schema).  So, run-time changes 
+to this environment variable will not take effect unless you also 
+re-connect on your schema.
+
+=head2 DBIX_CLASS_STORAGE_DBI_DEBUG
+
+Old name for DBIC_TRACE
+
+=head1 AUTHORS
+
+Matt S. Trout <mst at shadowcatsystems.co.uk>
+
+Andy Grundman <andy at hybridized.org>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
+
 1;

Modified: trunk/DBIx-Class/lib/DBIx/Class.pm
===================================================================
--- trunk/DBIx-Class/lib/DBIx/Class.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/DBIx/Class.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -4,16 +4,21 @@
 use warnings;
 
 use vars qw($VERSION);
-use base qw/DBIx::Class::Componentised Class::Data::Accessor/;
+use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
 
-sub mk_classdata { shift->mk_classaccessor(@_); }
+sub mk_classdata { 
+    my $self = shift;
+    $self->mk_group_accessors('inherited', $_[0]); 
+    $self->set_inherited(@_) if @_ > 1;
+}
+
 sub component_base_class { 'DBIx::Class' }
 
 # Always remember to do all digits for the version even if they're 0
 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
 # brain damage and presumably various other packaging systems too
 
-$VERSION = '0.07006';
+$VERSION = '0.08000';
 
 sub MODIFY_CODE_ATTRIBUTES {
   my ($class,$code, at attrs) = @_;
@@ -180,6 +185,8 @@
 
 ank: Andres Kievsky
 
+ash: Ash Berlin <ash at cpan.org>
+
 blblack: Brandon L. Black <blblack at gmail.com>
 
 bluefeet: Aran Deltac <bluefeet at cpan.org>
@@ -192,8 +199,12 @@
 
 clkao: CL Kao
 
+da5id: David Jack Olrik <djo at cpan.org>
+
 dkubb: Dan Kubb <dan.kubb-cpan at onautopilot.com>
 
+dnm: Justin Wheeler <jwheeler at datademons.com>
+
 draven: Marcus Ramberg <mramberg at cpan.org>
 
 dwc: Daniel Westermann-Clark <danieltwc at cpan.org>
@@ -212,6 +223,8 @@
 
 LTJake: Brian Cassidy <bricas at cpan.org>
 
+ned: Neil de Carteret
+
 nigel: Nigel Metheringham <nigelm at cpan.org>
 
 ningu: David Kamholz <dkamholz at cpan.org>
@@ -236,6 +249,8 @@
 
 typester: Daisuke Murase <typester at cpan.org>
 
+victori: Victor Igumnov <victori at cpan.org>
+
 wdh: Will Hawes
 
 willert: Sebastian Willert <willert at cpan.org>

Modified: trunk/DBIx-Class/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- trunk/DBIx-Class/lib/SQL/Translator/Parser/DBIx/Class.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/lib/SQL/Translator/Parser/DBIx/Class.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -26,10 +26,11 @@
 # We're working with DBIx::Class Schemas, not data streams.
 # -------------------------------------------------------------------
 sub parse {
-    my ($tr, $data) = @_;
-    my $args        = $tr->parser_args;
-    my $dbixschema  = $args->{'DBIx::Schema'} || $data;
-    $dbixschema   ||= $args->{'package'};
+    my ($tr, $data)   = @_;
+    my $args          = $tr->parser_args;
+    my $dbixschema    = $args->{'DBIx::Schema'} || $data;
+    $dbixschema     ||= $args->{'package'};
+    my $limit_sources = $args->{'sources'};
     
     die 'No DBIx::Schema' unless ($dbixschema);
     if (!ref $dbixschema) {
@@ -46,7 +47,23 @@
 
     my %seen_tables;
 
-    foreach my $moniker ($dbixschema->sources)
+    my @monikers = $dbixschema->sources;
+    if ($limit_sources) {
+        my $ref = ref $limit_sources || '';
+        die "'sources' parameter must be an array or hash ref" unless $ref eq 'ARRAY' || ref eq 'HASH';
+
+        # limit monikers to those specified in 
+        my $sources;
+        if ($ref eq 'ARRAY') {
+            $sources->{$_} = 1 for (@$limit_sources);
+        } else {
+            $sources = $limit_sources;
+        }
+        @monikers = grep { $sources->{$_} } @monikers;
+    }
+
+
+    foreach my $moniker (@monikers)
     {
         #eval "use $tableclass";
         #print("Can't load $tableclass"), next if($@);
@@ -91,6 +108,9 @@
         }
 
         my @rels = $source->relationships();
+
+        my %created_FK_rels;
+
         foreach my $rel (@rels)
         {
             my $rel_info = $source->relationship_info($rel);
@@ -120,12 +140,24 @@
                     $on_update = $otherrelationship->{'attrs'}->{cascade_copy} ? 'CASCADE' : '';
                 }
 
+                # Make sure we dont create the same foreign key constraint twice
+                my $key_test = join("\x00", @keys);
+
                 #Decide if this is a foreign key based on whether the self
                 #items are our primary columns.
+                $DB::single = 1 if $moniker eq 'Tests::MBTI::Result';
 
                 # If the sets are different, then we assume it's a foreign key from
                 # us to another table.
-                if (!$source->compare_relationship_keys(\@keys, \@primary)) {
+                # OR: If is_foreign_key_constraint attr is explicity set (or set to false) on the relation
+                if ( ! exists $created_FK_rels{$rel_table}->{$key_test} &&
+                     ( exists $rel_info->{attrs}{is_foreign_key_constraint} && 
+                       $rel_info->{attrs}{is_foreign_key_constraint} ||
+                       !$source->compare_relationship_keys(\@keys, \@primary)
+                     )
+                   )
+                {
+                    $created_FK_rels{$rel_table}->{$key_test} = 1;
                     $table->add_constraint(
                                 type             => 'foreign_key',
                                 name             => "fk_$keys[0]",

Modified: trunk/DBIx-Class/t/03podcoverage.t
===================================================================
--- trunk/DBIx-Class/t/03podcoverage.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/03podcoverage.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -58,7 +58,7 @@
     'DBIx::Class::Relationship::ProxyMethods'           => { skip => 1 },
     'DBIx::Class::ResultSetProxy'                       => { skip => 1 },
     'DBIx::Class::ResultSourceProxy'                    => { skip => 1 },
-    'DBIx::Class::Storage'                              => { skip => 1 },
+    'DBIx::Class::Storage::DBI'                         => { skip => 1 },
     'DBIx::Class::Storage::DBI::DB2'                    => { skip => 1 },
     'DBIx::Class::Storage::DBI::MSSQL'                  => { skip => 1 },
     'DBIx::Class::Storage::DBI::MultiDistinctEmulation' => { skip => 1 },
@@ -70,6 +70,18 @@
     'DBIx::Class::Storage::DBI::mysql'                  => { skip => 1 },
     'SQL::Translator::Parser::DBIx::Class'              => { skip => 1 },
     'SQL::Translator::Producer::DBIx::Class::File'      => { skip => 1 },
+
+# skipped because the synopsis covers it clearly
+
+    'DBIx::Class::InflateColumn::File'                  => { skip => 1 },
+
+# skipped because two methods may not need to be public
+
+    'DBIx::Class::Schema::Versioned' => { ignore => [ qw(on_connect exists) ] },
+
+# must kill authors.
+
+    'DBIx::Class::Storage::DBI::Replication' => { skip => 1 },
 };
 
 foreach my $module (@modules) {

Added: trunk/DBIx-Class/t/100populate.t
===================================================================
--- trunk/DBIx-Class/t/100populate.t	                        (rev 0)
+++ trunk/DBIx-Class/t/100populate.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,10085 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 22;
+
+# perl -le'my $letter = 'a'; for my $i (4..10000) { $letter++; print "[ $i, \"$letter\" ]," }' > tests.txt
+
+my $schema = DBICTest->init_schema();
+$schema->populate('Artist', [
+[ qw/artistid name/ ],
+[ 4, "b" ],
+[ 5, "c" ],
+[ 6, "d" ],
+[ 7, "e" ],
+[ 8, "f" ],
+[ 9, "g" ],
+[ 10, "h" ],
+[ 11, "i" ],
+[ 12, "j" ],
+[ 13, "k" ],
+[ 14, "l" ],
+[ 15, "m" ],
+[ 16, "n" ],
+[ 17, "o" ],
+[ 18, "p" ],
+[ 19, "q" ],
+[ 20, "r" ],
+[ 21, "s" ],
+[ 22, "t" ],
+[ 23, "u" ],
+[ 24, "v" ],
+[ 25, "w" ],
+[ 26, "x" ],
+[ 27, "y" ],
+[ 28, "z" ],
+[ 29, "aa" ],
+[ 30, "ab" ],
+[ 31, "ac" ],
+[ 32, "ad" ],
+[ 33, "ae" ],
+[ 34, "af" ],
+[ 35, "ag" ],
+[ 36, "ah" ],
+[ 37, "ai" ],
+[ 38, "aj" ],
+[ 39, "ak" ],
+[ 40, "al" ],
+[ 41, "am" ],
+[ 42, "an" ],
+[ 43, "ao" ],
+[ 44, "ap" ],
+[ 45, "aq" ],
+[ 46, "ar" ],
+[ 47, "as" ],
+[ 48, "at" ],
+[ 49, "au" ],
+[ 50, "av" ],
+[ 51, "aw" ],
+[ 52, "ax" ],
+[ 53, "ay" ],
+[ 54, "az" ],
+[ 55, "ba" ],
+[ 56, "bb" ],
+[ 57, "bc" ],
+[ 58, "bd" ],
+[ 59, "be" ],
+[ 60, "bf" ],
+[ 61, "bg" ],
+[ 62, "bh" ],
+[ 63, "bi" ],
+[ 64, "bj" ],
+[ 65, "bk" ],
+[ 66, "bl" ],
+[ 67, "bm" ],
+[ 68, "bn" ],
+[ 69, "bo" ],
+[ 70, "bp" ],
+[ 71, "bq" ],
+[ 72, "br" ],
+[ 73, "bs" ],
+[ 74, "bt" ],
+[ 75, "bu" ],
+[ 76, "bv" ],
+[ 77, "bw" ],
+[ 78, "bx" ],
+[ 79, "by" ],
+[ 80, "bz" ],
+[ 81, "ca" ],
+[ 82, "cb" ],
+[ 83, "cc" ],
+[ 84, "cd" ],
+[ 85, "ce" ],
+[ 86, "cf" ],
+[ 87, "cg" ],
+[ 88, "ch" ],
+[ 89, "ci" ],
+[ 90, "cj" ],
+[ 91, "ck" ],
+[ 92, "cl" ],
+[ 93, "cm" ],
+[ 94, "cn" ],
+[ 95, "co" ],
+[ 96, "cp" ],
+[ 97, "cq" ],
+[ 98, "cr" ],
+[ 99, "cs" ],
+[ 100, "ct" ],
+[ 101, "cu" ],
+[ 102, "cv" ],
+[ 103, "cw" ],
+[ 104, "cx" ],
+[ 105, "cy" ],
+[ 106, "cz" ],
+[ 107, "da" ],
+[ 108, "db" ],
+[ 109, "dc" ],
+[ 110, "dd" ],
+[ 111, "de" ],
+[ 112, "df" ],
+[ 113, "dg" ],
+[ 114, "dh" ],
+[ 115, "di" ],
+[ 116, "dj" ],
+[ 117, "dk" ],
+[ 118, "dl" ],
+[ 119, "dm" ],
+[ 120, "dn" ],
+[ 121, "do" ],
+[ 122, "dp" ],
+[ 123, "dq" ],
+[ 124, "dr" ],
+[ 125, "ds" ],
+[ 126, "dt" ],
+[ 127, "du" ],
+[ 128, "dv" ],
+[ 129, "dw" ],
+[ 130, "dx" ],
+[ 131, "dy" ],
+[ 132, "dz" ],
+[ 133, "ea" ],
+[ 134, "eb" ],
+[ 135, "ec" ],
+[ 136, "ed" ],
+[ 137, "ee" ],
+[ 138, "ef" ],
+[ 139, "eg" ],
+[ 140, "eh" ],
+[ 141, "ei" ],
+[ 142, "ej" ],
+[ 143, "ek" ],
+[ 144, "el" ],
+[ 145, "em" ],
+[ 146, "en" ],
+[ 147, "eo" ],
+[ 148, "ep" ],
+[ 149, "eq" ],
+[ 150, "er" ],
+[ 151, "es" ],
+[ 152, "et" ],
+[ 153, "eu" ],
+[ 154, "ev" ],
+[ 155, "ew" ],
+[ 156, "ex" ],
+[ 157, "ey" ],
+[ 158, "ez" ],
+[ 159, "fa" ],
+[ 160, "fb" ],
+[ 161, "fc" ],
+[ 162, "fd" ],
+[ 163, "fe" ],
+[ 164, "ff" ],
+[ 165, "fg" ],
+[ 166, "fh" ],
+[ 167, "fi" ],
+[ 168, "fj" ],
+[ 169, "fk" ],
+[ 170, "fl" ],
+[ 171, "fm" ],
+[ 172, "fn" ],
+[ 173, "fo" ],
+[ 174, "fp" ],
+[ 175, "fq" ],
+[ 176, "fr" ],
+[ 177, "fs" ],
+[ 178, "ft" ],
+[ 179, "fu" ],
+[ 180, "fv" ],
+[ 181, "fw" ],
+[ 182, "fx" ],
+[ 183, "fy" ],
+[ 184, "fz" ],
+[ 185, "ga" ],
+[ 186, "gb" ],
+[ 187, "gc" ],
+[ 188, "gd" ],
+[ 189, "ge" ],
+[ 190, "gf" ],
+[ 191, "gg" ],
+[ 192, "gh" ],
+[ 193, "gi" ],
+[ 194, "gj" ],
+[ 195, "gk" ],
+[ 196, "gl" ],
+[ 197, "gm" ],
+[ 198, "gn" ],
+[ 199, "go" ],
+[ 200, "gp" ],
+[ 201, "gq" ],
+[ 202, "gr" ],
+[ 203, "gs" ],
+[ 204, "gt" ],
+[ 205, "gu" ],
+[ 206, "gv" ],
+[ 207, "gw" ],
+[ 208, "gx" ],
+[ 209, "gy" ],
+[ 210, "gz" ],
+[ 211, "ha" ],
+[ 212, "hb" ],
+[ 213, "hc" ],
+[ 214, "hd" ],
+[ 215, "he" ],
+[ 216, "hf" ],
+[ 217, "hg" ],
+[ 218, "hh" ],
+[ 219, "hi" ],
+[ 220, "hj" ],
+[ 221, "hk" ],
+[ 222, "hl" ],
+[ 223, "hm" ],
+[ 224, "hn" ],
+[ 225, "ho" ],
+[ 226, "hp" ],
+[ 227, "hq" ],
+[ 228, "hr" ],
+[ 229, "hs" ],
+[ 230, "ht" ],
+[ 231, "hu" ],
+[ 232, "hv" ],
+[ 233, "hw" ],
+[ 234, "hx" ],
+[ 235, "hy" ],
+[ 236, "hz" ],
+[ 237, "ia" ],
+[ 238, "ib" ],
+[ 239, "ic" ],
+[ 240, "id" ],
+[ 241, "ie" ],
+[ 242, "if" ],
+[ 243, "ig" ],
+[ 244, "ih" ],
+[ 245, "ii" ],
+[ 246, "ij" ],
+[ 247, "ik" ],
+[ 248, "il" ],
+[ 249, "im" ],
+[ 250, "in" ],
+[ 251, "io" ],
+[ 252, "ip" ],
+[ 253, "iq" ],
+[ 254, "ir" ],
+[ 255, "is" ],
+[ 256, "it" ],
+[ 257, "iu" ],
+[ 258, "iv" ],
+[ 259, "iw" ],
+[ 260, "ix" ],
+[ 261, "iy" ],
+[ 262, "iz" ],
+[ 263, "ja" ],
+[ 264, "jb" ],
+[ 265, "jc" ],
+[ 266, "jd" ],
+[ 267, "je" ],
+[ 268, "jf" ],
+[ 269, "jg" ],
+[ 270, "jh" ],
+[ 271, "ji" ],
+[ 272, "jj" ],
+[ 273, "jk" ],
+[ 274, "jl" ],
+[ 275, "jm" ],
+[ 276, "jn" ],
+[ 277, "jo" ],
+[ 278, "jp" ],
+[ 279, "jq" ],
+[ 280, "jr" ],
+[ 281, "js" ],
+[ 282, "jt" ],
+[ 283, "ju" ],
+[ 284, "jv" ],
+[ 285, "jw" ],
+[ 286, "jx" ],
+[ 287, "jy" ],
+[ 288, "jz" ],
+[ 289, "ka" ],
+[ 290, "kb" ],
+[ 291, "kc" ],
+[ 292, "kd" ],
+[ 293, "ke" ],
+[ 294, "kf" ],
+[ 295, "kg" ],
+[ 296, "kh" ],
+[ 297, "ki" ],
+[ 298, "kj" ],
+[ 299, "kk" ],
+[ 300, "kl" ],
+[ 301, "km" ],
+[ 302, "kn" ],
+[ 303, "ko" ],
+[ 304, "kp" ],
+[ 305, "kq" ],
+[ 306, "kr" ],
+[ 307, "ks" ],
+[ 308, "kt" ],
+[ 309, "ku" ],
+[ 310, "kv" ],
+[ 311, "kw" ],
+[ 312, "kx" ],
+[ 313, "ky" ],
+[ 314, "kz" ],
+[ 315, "la" ],
+[ 316, "lb" ],
+[ 317, "lc" ],
+[ 318, "ld" ],
+[ 319, "le" ],
+[ 320, "lf" ],
+[ 321, "lg" ],
+[ 322, "lh" ],
+[ 323, "li" ],
+[ 324, "lj" ],
+[ 325, "lk" ],
+[ 326, "ll" ],
+[ 327, "lm" ],
+[ 328, "ln" ],
+[ 329, "lo" ],
+[ 330, "lp" ],
+[ 331, "lq" ],
+[ 332, "lr" ],
+[ 333, "ls" ],
+[ 334, "lt" ],
+[ 335, "lu" ],
+[ 336, "lv" ],
+[ 337, "lw" ],
+[ 338, "lx" ],
+[ 339, "ly" ],
+[ 340, "lz" ],
+[ 341, "ma" ],
+[ 342, "mb" ],
+[ 343, "mc" ],
+[ 344, "md" ],
+[ 345, "me" ],
+[ 346, "mf" ],
+[ 347, "mg" ],
+[ 348, "mh" ],
+[ 349, "mi" ],
+[ 350, "mj" ],
+[ 351, "mk" ],
+[ 352, "ml" ],
+[ 353, "mm" ],
+[ 354, "mn" ],
+[ 355, "mo" ],
+[ 356, "mp" ],
+[ 357, "mq" ],
+[ 358, "mr" ],
+[ 359, "ms" ],
+[ 360, "mt" ],
+[ 361, "mu" ],
+[ 362, "mv" ],
+[ 363, "mw" ],
+[ 364, "mx" ],
+[ 365, "my" ],
+[ 366, "mz" ],
+[ 367, "na" ],
+[ 368, "nb" ],
+[ 369, "nc" ],
+[ 370, "nd" ],
+[ 371, "ne" ],
+[ 372, "nf" ],
+[ 373, "ng" ],
+[ 374, "nh" ],
+[ 375, "ni" ],
+[ 376, "nj" ],
+[ 377, "nk" ],
+[ 378, "nl" ],
+[ 379, "nm" ],
+[ 380, "nn" ],
+[ 381, "no" ],
+[ 382, "np" ],
+[ 383, "nq" ],
+[ 384, "nr" ],
+[ 385, "ns" ],
+[ 386, "nt" ],
+[ 387, "nu" ],
+[ 388, "nv" ],
+[ 389, "nw" ],
+[ 390, "nx" ],
+[ 391, "ny" ],
+[ 392, "nz" ],
+[ 393, "oa" ],
+[ 394, "ob" ],
+[ 395, "oc" ],
+[ 396, "od" ],
+[ 397, "oe" ],
+[ 398, "of" ],
+[ 399, "og" ],
+[ 400, "oh" ],
+[ 401, "oi" ],
+[ 402, "oj" ],
+[ 403, "ok" ],
+[ 404, "ol" ],
+[ 405, "om" ],
+[ 406, "on" ],
+[ 407, "oo" ],
+[ 408, "op" ],
+[ 409, "oq" ],
+[ 410, "or" ],
+[ 411, "os" ],
+[ 412, "ot" ],
+[ 413, "ou" ],
+[ 414, "ov" ],
+[ 415, "ow" ],
+[ 416, "ox" ],
+[ 417, "oy" ],
+[ 418, "oz" ],
+[ 419, "pa" ],
+[ 420, "pb" ],
+[ 421, "pc" ],
+[ 422, "pd" ],
+[ 423, "pe" ],
+[ 424, "pf" ],
+[ 425, "pg" ],
+[ 426, "ph" ],
+[ 427, "pi" ],
+[ 428, "pj" ],
+[ 429, "pk" ],
+[ 430, "pl" ],
+[ 431, "pm" ],
+[ 432, "pn" ],
+[ 433, "po" ],
+[ 434, "pp" ],
+[ 435, "pq" ],
+[ 436, "pr" ],
+[ 437, "ps" ],
+[ 438, "pt" ],
+[ 439, "pu" ],
+[ 440, "pv" ],
+[ 441, "pw" ],
+[ 442, "px" ],
+[ 443, "py" ],
+[ 444, "pz" ],
+[ 445, "qa" ],
+[ 446, "qb" ],
+[ 447, "qc" ],
+[ 448, "qd" ],
+[ 449, "qe" ],
+[ 450, "qf" ],
+[ 451, "qg" ],
+[ 452, "qh" ],
+[ 453, "qi" ],
+[ 454, "qj" ],
+[ 455, "qk" ],
+[ 456, "ql" ],
+[ 457, "qm" ],
+[ 458, "qn" ],
+[ 459, "qo" ],
+[ 460, "qp" ],
+[ 461, "qq" ],
+[ 462, "qr" ],
+[ 463, "qs" ],
+[ 464, "qt" ],
+[ 465, "qu" ],
+[ 466, "qv" ],
+[ 467, "qw" ],
+[ 468, "qx" ],
+[ 469, "qy" ],
+[ 470, "qz" ],
+[ 471, "ra" ],
+[ 472, "rb" ],
+[ 473, "rc" ],
+[ 474, "rd" ],
+[ 475, "re" ],
+[ 476, "rf" ],
+[ 477, "rg" ],
+[ 478, "rh" ],
+[ 479, "ri" ],
+[ 480, "rj" ],
+[ 481, "rk" ],
+[ 482, "rl" ],
+[ 483, "rm" ],
+[ 484, "rn" ],
+[ 485, "ro" ],
+[ 486, "rp" ],
+[ 487, "rq" ],
+[ 488, "rr" ],
+[ 489, "rs" ],
+[ 490, "rt" ],
+[ 491, "ru" ],
+[ 492, "rv" ],
+[ 493, "rw" ],
+[ 494, "rx" ],
+[ 495, "ry" ],
+[ 496, "rz" ],
+[ 497, "sa" ],
+[ 498, "sb" ],
+[ 499, "sc" ],
+[ 500, "sd" ],
+[ 501, "se" ],
+[ 502, "sf" ],
+[ 503, "sg" ],
+[ 504, "sh" ],
+[ 505, "si" ],
+[ 506, "sj" ],
+[ 507, "sk" ],
+[ 508, "sl" ],
+[ 509, "sm" ],
+[ 510, "sn" ],
+[ 511, "so" ],
+[ 512, "sp" ],
+[ 513, "sq" ],
+[ 514, "sr" ],
+[ 515, "ss" ],
+[ 516, "st" ],
+[ 517, "su" ],
+[ 518, "sv" ],
+[ 519, "sw" ],
+[ 520, "sx" ],
+[ 521, "sy" ],
+[ 522, "sz" ],
+[ 523, "ta" ],
+[ 524, "tb" ],
+[ 525, "tc" ],
+[ 526, "td" ],
+[ 527, "te" ],
+[ 528, "tf" ],
+[ 529, "tg" ],
+[ 530, "th" ],
+[ 531, "ti" ],
+[ 532, "tj" ],
+[ 533, "tk" ],
+[ 534, "tl" ],
+[ 535, "tm" ],
+[ 536, "tn" ],
+[ 537, "to" ],
+[ 538, "tp" ],
+[ 539, "tq" ],
+[ 540, "tr" ],
+[ 541, "ts" ],
+[ 542, "tt" ],
+[ 543, "tu" ],
+[ 544, "tv" ],
+[ 545, "tw" ],
+[ 546, "tx" ],
+[ 547, "ty" ],
+[ 548, "tz" ],
+[ 549, "ua" ],
+[ 550, "ub" ],
+[ 551, "uc" ],
+[ 552, "ud" ],
+[ 553, "ue" ],
+[ 554, "uf" ],
+[ 555, "ug" ],
+[ 556, "uh" ],
+[ 557, "ui" ],
+[ 558, "uj" ],
+[ 559, "uk" ],
+[ 560, "ul" ],
+[ 561, "um" ],
+[ 562, "un" ],
+[ 563, "uo" ],
+[ 564, "up" ],
+[ 565, "uq" ],
+[ 566, "ur" ],
+[ 567, "us" ],
+[ 568, "ut" ],
+[ 569, "uu" ],
+[ 570, "uv" ],
+[ 571, "uw" ],
+[ 572, "ux" ],
+[ 573, "uy" ],
+[ 574, "uz" ],
+[ 575, "va" ],
+[ 576, "vb" ],
+[ 577, "vc" ],
+[ 578, "vd" ],
+[ 579, "ve" ],
+[ 580, "vf" ],
+[ 581, "vg" ],
+[ 582, "vh" ],
+[ 583, "vi" ],
+[ 584, "vj" ],
+[ 585, "vk" ],
+[ 586, "vl" ],
+[ 587, "vm" ],
+[ 588, "vn" ],
+[ 589, "vo" ],
+[ 590, "vp" ],
+[ 591, "vq" ],
+[ 592, "vr" ],
+[ 593, "vs" ],
+[ 594, "vt" ],
+[ 595, "vu" ],
+[ 596, "vv" ],
+[ 597, "vw" ],
+[ 598, "vx" ],
+[ 599, "vy" ],
+[ 600, "vz" ],
+[ 601, "wa" ],
+[ 602, "wb" ],
+[ 603, "wc" ],
+[ 604, "wd" ],
+[ 605, "we" ],
+[ 606, "wf" ],
+[ 607, "wg" ],
+[ 608, "wh" ],
+[ 609, "wi" ],
+[ 610, "wj" ],
+[ 611, "wk" ],
+[ 612, "wl" ],
+[ 613, "wm" ],
+[ 614, "wn" ],
+[ 615, "wo" ],
+[ 616, "wp" ],
+[ 617, "wq" ],
+[ 618, "wr" ],
+[ 619, "ws" ],
+[ 620, "wt" ],
+[ 621, "wu" ],
+[ 622, "wv" ],
+[ 623, "ww" ],
+[ 624, "wx" ],
+[ 625, "wy" ],
+[ 626, "wz" ],
+[ 627, "xa" ],
+[ 628, "xb" ],
+[ 629, "xc" ],
+[ 630, "xd" ],
+[ 631, "xe" ],
+[ 632, "xf" ],
+[ 633, "xg" ],
+[ 634, "xh" ],
+[ 635, "xi" ],
+[ 636, "xj" ],
+[ 637, "xk" ],
+[ 638, "xl" ],
+[ 639, "xm" ],
+[ 640, "xn" ],
+[ 641, "xo" ],
+[ 642, "xp" ],
+[ 643, "xq" ],
+[ 644, "xr" ],
+[ 645, "xs" ],
+[ 646, "xt" ],
+[ 647, "xu" ],
+[ 648, "xv" ],
+[ 649, "xw" ],
+[ 650, "xx" ],
+[ 651, "xy" ],
+[ 652, "xz" ],
+[ 653, "ya" ],
+[ 654, "yb" ],
+[ 655, "yc" ],
+[ 656, "yd" ],
+[ 657, "ye" ],
+[ 658, "yf" ],
+[ 659, "yg" ],
+[ 660, "yh" ],
+[ 661, "yi" ],
+[ 662, "yj" ],
+[ 663, "yk" ],
+[ 664, "yl" ],
+[ 665, "ym" ],
+[ 666, "yn" ],
+[ 667, "yo" ],
+[ 668, "yp" ],
+[ 669, "yq" ],
+[ 670, "yr" ],
+[ 671, "ys" ],
+[ 672, "yt" ],
+[ 673, "yu" ],
+[ 674, "yv" ],
+[ 675, "yw" ],
+[ 676, "yx" ],
+[ 677, "yy" ],
+[ 678, "yz" ],
+[ 679, "za" ],
+[ 680, "zb" ],
+[ 681, "zc" ],
+[ 682, "zd" ],
+[ 683, "ze" ],
+[ 684, "zf" ],
+[ 685, "zg" ],
+[ 686, "zh" ],
+[ 687, "zi" ],
+[ 688, "zj" ],
+[ 689, "zk" ],
+[ 690, "zl" ],
+[ 691, "zm" ],
+[ 692, "zn" ],
+[ 693, "zo" ],
+[ 694, "zp" ],
+[ 695, "zq" ],
+[ 696, "zr" ],
+[ 697, "zs" ],
+[ 698, "zt" ],
+[ 699, "zu" ],
+[ 700, "zv" ],
+[ 701, "zw" ],
+[ 702, "zx" ],
+[ 703, "zy" ],
+[ 704, "zz" ],
+[ 705, "aaa" ],
+[ 706, "aab" ],
+[ 707, "aac" ],
+[ 708, "aad" ],
+[ 709, "aae" ],
+[ 710, "aaf" ],
+[ 711, "aag" ],
+[ 712, "aah" ],
+[ 713, "aai" ],
+[ 714, "aaj" ],
+[ 715, "aak" ],
+[ 716, "aal" ],
+[ 717, "aam" ],
+[ 718, "aan" ],
+[ 719, "aao" ],
+[ 720, "aap" ],
+[ 721, "aaq" ],
+[ 722, "aar" ],
+[ 723, "aas" ],
+[ 724, "aat" ],
+[ 725, "aau" ],
+[ 726, "aav" ],
+[ 727, "aaw" ],
+[ 728, "aax" ],
+[ 729, "aay" ],
+[ 730, "aaz" ],
+[ 731, "aba" ],
+[ 732, "abb" ],
+[ 733, "abc" ],
+[ 734, "abd" ],
+[ 735, "abe" ],
+[ 736, "abf" ],
+[ 737, "abg" ],
+[ 738, "abh" ],
+[ 739, "abi" ],
+[ 740, "abj" ],
+[ 741, "abk" ],
+[ 742, "abl" ],
+[ 743, "abm" ],
+[ 744, "abn" ],
+[ 745, "abo" ],
+[ 746, "abp" ],
+[ 747, "abq" ],
+[ 748, "abr" ],
+[ 749, "abs" ],
+[ 750, "abt" ],
+[ 751, "abu" ],
+[ 752, "abv" ],
+[ 753, "abw" ],
+[ 754, "abx" ],
+[ 755, "aby" ],
+[ 756, "abz" ],
+[ 757, "aca" ],
+[ 758, "acb" ],
+[ 759, "acc" ],
+[ 760, "acd" ],
+[ 761, "ace" ],
+[ 762, "acf" ],
+[ 763, "acg" ],
+[ 764, "ach" ],
+[ 765, "aci" ],
+[ 766, "acj" ],
+[ 767, "ack" ],
+[ 768, "acl" ],
+[ 769, "acm" ],
+[ 770, "acn" ],
+[ 771, "aco" ],
+[ 772, "acp" ],
+[ 773, "acq" ],
+[ 774, "acr" ],
+[ 775, "acs" ],
+[ 776, "act" ],
+[ 777, "acu" ],
+[ 778, "acv" ],
+[ 779, "acw" ],
+[ 780, "acx" ],
+[ 781, "acy" ],
+[ 782, "acz" ],
+[ 783, "ada" ],
+[ 784, "adb" ],
+[ 785, "adc" ],
+[ 786, "add" ],
+[ 787, "ade" ],
+[ 788, "adf" ],
+[ 789, "adg" ],
+[ 790, "adh" ],
+[ 791, "adi" ],
+[ 792, "adj" ],
+[ 793, "adk" ],
+[ 794, "adl" ],
+[ 795, "adm" ],
+[ 796, "adn" ],
+[ 797, "ado" ],
+[ 798, "adp" ],
+[ 799, "adq" ],
+[ 800, "adr" ],
+[ 801, "ads" ],
+[ 802, "adt" ],
+[ 803, "adu" ],
+[ 804, "adv" ],
+[ 805, "adw" ],
+[ 806, "adx" ],
+[ 807, "ady" ],
+[ 808, "adz" ],
+[ 809, "aea" ],
+[ 810, "aeb" ],
+[ 811, "aec" ],
+[ 812, "aed" ],
+[ 813, "aee" ],
+[ 814, "aef" ],
+[ 815, "aeg" ],
+[ 816, "aeh" ],
+[ 817, "aei" ],
+[ 818, "aej" ],
+[ 819, "aek" ],
+[ 820, "ael" ],
+[ 821, "aem" ],
+[ 822, "aen" ],
+[ 823, "aeo" ],
+[ 824, "aep" ],
+[ 825, "aeq" ],
+[ 826, "aer" ],
+[ 827, "aes" ],
+[ 828, "aet" ],
+[ 829, "aeu" ],
+[ 830, "aev" ],
+[ 831, "aew" ],
+[ 832, "aex" ],
+[ 833, "aey" ],
+[ 834, "aez" ],
+[ 835, "afa" ],
+[ 836, "afb" ],
+[ 837, "afc" ],
+[ 838, "afd" ],
+[ 839, "afe" ],
+[ 840, "aff" ],
+[ 841, "afg" ],
+[ 842, "afh" ],
+[ 843, "afi" ],
+[ 844, "afj" ],
+[ 845, "afk" ],
+[ 846, "afl" ],
+[ 847, "afm" ],
+[ 848, "afn" ],
+[ 849, "afo" ],
+[ 850, "afp" ],
+[ 851, "afq" ],
+[ 852, "afr" ],
+[ 853, "afs" ],
+[ 854, "aft" ],
+[ 855, "afu" ],
+[ 856, "afv" ],
+[ 857, "afw" ],
+[ 858, "afx" ],
+[ 859, "afy" ],
+[ 860, "afz" ],
+[ 861, "aga" ],
+[ 862, "agb" ],
+[ 863, "agc" ],
+[ 864, "agd" ],
+[ 865, "age" ],
+[ 866, "agf" ],
+[ 867, "agg" ],
+[ 868, "agh" ],
+[ 869, "agi" ],
+[ 870, "agj" ],
+[ 871, "agk" ],
+[ 872, "agl" ],
+[ 873, "agm" ],
+[ 874, "agn" ],
+[ 875, "ago" ],
+[ 876, "agp" ],
+[ 877, "agq" ],
+[ 878, "agr" ],
+[ 879, "ags" ],
+[ 880, "agt" ],
+[ 881, "agu" ],
+[ 882, "agv" ],
+[ 883, "agw" ],
+[ 884, "agx" ],
+[ 885, "agy" ],
+[ 886, "agz" ],
+[ 887, "aha" ],
+[ 888, "ahb" ],
+[ 889, "ahc" ],
+[ 890, "ahd" ],
+[ 891, "ahe" ],
+[ 892, "ahf" ],
+[ 893, "ahg" ],
+[ 894, "ahh" ],
+[ 895, "ahi" ],
+[ 896, "ahj" ],
+[ 897, "ahk" ],
+[ 898, "ahl" ],
+[ 899, "ahm" ],
+[ 900, "ahn" ],
+[ 901, "aho" ],
+[ 902, "ahp" ],
+[ 903, "ahq" ],
+[ 904, "ahr" ],
+[ 905, "ahs" ],
+[ 906, "aht" ],
+[ 907, "ahu" ],
+[ 908, "ahv" ],
+[ 909, "ahw" ],
+[ 910, "ahx" ],
+[ 911, "ahy" ],
+[ 912, "ahz" ],
+[ 913, "aia" ],
+[ 914, "aib" ],
+[ 915, "aic" ],
+[ 916, "aid" ],
+[ 917, "aie" ],
+[ 918, "aif" ],
+[ 919, "aig" ],
+[ 920, "aih" ],
+[ 921, "aii" ],
+[ 922, "aij" ],
+[ 923, "aik" ],
+[ 924, "ail" ],
+[ 925, "aim" ],
+[ 926, "ain" ],
+[ 927, "aio" ],
+[ 928, "aip" ],
+[ 929, "aiq" ],
+[ 930, "air" ],
+[ 931, "ais" ],
+[ 932, "ait" ],
+[ 933, "aiu" ],
+[ 934, "aiv" ],
+[ 935, "aiw" ],
+[ 936, "aix" ],
+[ 937, "aiy" ],
+[ 938, "aiz" ],
+[ 939, "aja" ],
+[ 940, "ajb" ],
+[ 941, "ajc" ],
+[ 942, "ajd" ],
+[ 943, "aje" ],
+[ 944, "ajf" ],
+[ 945, "ajg" ],
+[ 946, "ajh" ],
+[ 947, "aji" ],
+[ 948, "ajj" ],
+[ 949, "ajk" ],
+[ 950, "ajl" ],
+[ 951, "ajm" ],
+[ 952, "ajn" ],
+[ 953, "ajo" ],
+[ 954, "ajp" ],
+[ 955, "ajq" ],
+[ 956, "ajr" ],
+[ 957, "ajs" ],
+[ 958, "ajt" ],
+[ 959, "aju" ],
+[ 960, "ajv" ],
+[ 961, "ajw" ],
+[ 962, "ajx" ],
+[ 963, "ajy" ],
+[ 964, "ajz" ],
+[ 965, "aka" ],
+[ 966, "akb" ],
+[ 967, "akc" ],
+[ 968, "akd" ],
+[ 969, "ake" ],
+[ 970, "akf" ],
+[ 971, "akg" ],
+[ 972, "akh" ],
+[ 973, "aki" ],
+[ 974, "akj" ],
+[ 975, "akk" ],
+[ 976, "akl" ],
+[ 977, "akm" ],
+[ 978, "akn" ],
+[ 979, "ako" ],
+[ 980, "akp" ],
+[ 981, "akq" ],
+[ 982, "akr" ],
+[ 983, "aks" ],
+[ 984, "akt" ],
+[ 985, "aku" ],
+[ 986, "akv" ],
+[ 987, "akw" ],
+[ 988, "akx" ],
+[ 989, "aky" ],
+[ 990, "akz" ],
+[ 991, "ala" ],
+[ 992, "alb" ],
+[ 993, "alc" ],
+[ 994, "ald" ],
+[ 995, "ale" ],
+[ 996, "alf" ],
+[ 997, "alg" ],
+[ 998, "alh" ],
+[ 999, "ali" ],
+[ 1000, "alj" ],
+[ 1001, "alk" ],
+[ 1002, "all" ],
+[ 1003, "alm" ],
+[ 1004, "aln" ],
+[ 1005, "alo" ],
+[ 1006, "alp" ],
+[ 1007, "alq" ],
+[ 1008, "alr" ],
+[ 1009, "als" ],
+[ 1010, "alt" ],
+[ 1011, "alu" ],
+[ 1012, "alv" ],
+[ 1013, "alw" ],
+[ 1014, "alx" ],
+[ 1015, "aly" ],
+[ 1016, "alz" ],
+[ 1017, "ama" ],
+[ 1018, "amb" ],
+[ 1019, "amc" ],
+[ 1020, "amd" ],
+[ 1021, "ame" ],
+[ 1022, "amf" ],
+[ 1023, "amg" ],
+[ 1024, "amh" ],
+[ 1025, "ami" ],
+[ 1026, "amj" ],
+[ 1027, "amk" ],
+[ 1028, "aml" ],
+[ 1029, "amm" ],
+[ 1030, "amn" ],
+[ 1031, "amo" ],
+[ 1032, "amp" ],
+[ 1033, "amq" ],
+[ 1034, "amr" ],
+[ 1035, "ams" ],
+[ 1036, "amt" ],
+[ 1037, "amu" ],
+[ 1038, "amv" ],
+[ 1039, "amw" ],
+[ 1040, "amx" ],
+[ 1041, "amy" ],
+[ 1042, "amz" ],
+[ 1043, "ana" ],
+[ 1044, "anb" ],
+[ 1045, "anc" ],
+[ 1046, "and" ],
+[ 1047, "ane" ],
+[ 1048, "anf" ],
+[ 1049, "ang" ],
+[ 1050, "anh" ],
+[ 1051, "ani" ],
+[ 1052, "anj" ],
+[ 1053, "ank" ],
+[ 1054, "anl" ],
+[ 1055, "anm" ],
+[ 1056, "ann" ],
+[ 1057, "ano" ],
+[ 1058, "anp" ],
+[ 1059, "anq" ],
+[ 1060, "anr" ],
+[ 1061, "ans" ],
+[ 1062, "ant" ],
+[ 1063, "anu" ],
+[ 1064, "anv" ],
+[ 1065, "anw" ],
+[ 1066, "anx" ],
+[ 1067, "any" ],
+[ 1068, "anz" ],
+[ 1069, "aoa" ],
+[ 1070, "aob" ],
+[ 1071, "aoc" ],
+[ 1072, "aod" ],
+[ 1073, "aoe" ],
+[ 1074, "aof" ],
+[ 1075, "aog" ],
+[ 1076, "aoh" ],
+[ 1077, "aoi" ],
+[ 1078, "aoj" ],
+[ 1079, "aok" ],
+[ 1080, "aol" ],
+[ 1081, "aom" ],
+[ 1082, "aon" ],
+[ 1083, "aoo" ],
+[ 1084, "aop" ],
+[ 1085, "aoq" ],
+[ 1086, "aor" ],
+[ 1087, "aos" ],
+[ 1088, "aot" ],
+[ 1089, "aou" ],
+[ 1090, "aov" ],
+[ 1091, "aow" ],
+[ 1092, "aox" ],
+[ 1093, "aoy" ],
+[ 1094, "aoz" ],
+[ 1095, "apa" ],
+[ 1096, "apb" ],
+[ 1097, "apc" ],
+[ 1098, "apd" ],
+[ 1099, "ape" ],
+[ 1100, "apf" ],
+[ 1101, "apg" ],
+[ 1102, "aph" ],
+[ 1103, "api" ],
+[ 1104, "apj" ],
+[ 1105, "apk" ],
+[ 1106, "apl" ],
+[ 1107, "apm" ],
+[ 1108, "apn" ],
+[ 1109, "apo" ],
+[ 1110, "app" ],
+[ 1111, "apq" ],
+[ 1112, "apr" ],
+[ 1113, "aps" ],
+[ 1114, "apt" ],
+[ 1115, "apu" ],
+[ 1116, "apv" ],
+[ 1117, "apw" ],
+[ 1118, "apx" ],
+[ 1119, "apy" ],
+[ 1120, "apz" ],
+[ 1121, "aqa" ],
+[ 1122, "aqb" ],
+[ 1123, "aqc" ],
+[ 1124, "aqd" ],
+[ 1125, "aqe" ],
+[ 1126, "aqf" ],
+[ 1127, "aqg" ],
+[ 1128, "aqh" ],
+[ 1129, "aqi" ],
+[ 1130, "aqj" ],
+[ 1131, "aqk" ],
+[ 1132, "aql" ],
+[ 1133, "aqm" ],
+[ 1134, "aqn" ],
+[ 1135, "aqo" ],
+[ 1136, "aqp" ],
+[ 1137, "aqq" ],
+[ 1138, "aqr" ],
+[ 1139, "aqs" ],
+[ 1140, "aqt" ],
+[ 1141, "aqu" ],
+[ 1142, "aqv" ],
+[ 1143, "aqw" ],
+[ 1144, "aqx" ],
+[ 1145, "aqy" ],
+[ 1146, "aqz" ],
+[ 1147, "ara" ],
+[ 1148, "arb" ],
+[ 1149, "arc" ],
+[ 1150, "ard" ],
+[ 1151, "are" ],
+[ 1152, "arf" ],
+[ 1153, "arg" ],
+[ 1154, "arh" ],
+[ 1155, "ari" ],
+[ 1156, "arj" ],
+[ 1157, "ark" ],
+[ 1158, "arl" ],
+[ 1159, "arm" ],
+[ 1160, "arn" ],
+[ 1161, "aro" ],
+[ 1162, "arp" ],
+[ 1163, "arq" ],
+[ 1164, "arr" ],
+[ 1165, "ars" ],
+[ 1166, "art" ],
+[ 1167, "aru" ],
+[ 1168, "arv" ],
+[ 1169, "arw" ],
+[ 1170, "arx" ],
+[ 1171, "ary" ],
+[ 1172, "arz" ],
+[ 1173, "asa" ],
+[ 1174, "asb" ],
+[ 1175, "asc" ],
+[ 1176, "asd" ],
+[ 1177, "ase" ],
+[ 1178, "asf" ],
+[ 1179, "asg" ],
+[ 1180, "ash" ],
+[ 1181, "asi" ],
+[ 1182, "asj" ],
+[ 1183, "ask" ],
+[ 1184, "asl" ],
+[ 1185, "asm" ],
+[ 1186, "asn" ],
+[ 1187, "aso" ],
+[ 1188, "asp" ],
+[ 1189, "asq" ],
+[ 1190, "asr" ],
+[ 1191, "ass" ],
+[ 1192, "ast" ],
+[ 1193, "asu" ],
+[ 1194, "asv" ],
+[ 1195, "asw" ],
+[ 1196, "asx" ],
+[ 1197, "asy" ],
+[ 1198, "asz" ],
+[ 1199, "ata" ],
+[ 1200, "atb" ],
+[ 1201, "atc" ],
+[ 1202, "atd" ],
+[ 1203, "ate" ],
+[ 1204, "atf" ],
+[ 1205, "atg" ],
+[ 1206, "ath" ],
+[ 1207, "ati" ],
+[ 1208, "atj" ],
+[ 1209, "atk" ],
+[ 1210, "atl" ],
+[ 1211, "atm" ],
+[ 1212, "atn" ],
+[ 1213, "ato" ],
+[ 1214, "atp" ],
+[ 1215, "atq" ],
+[ 1216, "atr" ],
+[ 1217, "ats" ],
+[ 1218, "att" ],
+[ 1219, "atu" ],
+[ 1220, "atv" ],
+[ 1221, "atw" ],
+[ 1222, "atx" ],
+[ 1223, "aty" ],
+[ 1224, "atz" ],
+[ 1225, "aua" ],
+[ 1226, "aub" ],
+[ 1227, "auc" ],
+[ 1228, "aud" ],
+[ 1229, "aue" ],
+[ 1230, "auf" ],
+[ 1231, "aug" ],
+[ 1232, "auh" ],
+[ 1233, "aui" ],
+[ 1234, "auj" ],
+[ 1235, "auk" ],
+[ 1236, "aul" ],
+[ 1237, "aum" ],
+[ 1238, "aun" ],
+[ 1239, "auo" ],
+[ 1240, "aup" ],
+[ 1241, "auq" ],
+[ 1242, "aur" ],
+[ 1243, "aus" ],
+[ 1244, "aut" ],
+[ 1245, "auu" ],
+[ 1246, "auv" ],
+[ 1247, "auw" ],
+[ 1248, "aux" ],
+[ 1249, "auy" ],
+[ 1250, "auz" ],
+[ 1251, "ava" ],
+[ 1252, "avb" ],
+[ 1253, "avc" ],
+[ 1254, "avd" ],
+[ 1255, "ave" ],
+[ 1256, "avf" ],
+[ 1257, "avg" ],
+[ 1258, "avh" ],
+[ 1259, "avi" ],
+[ 1260, "avj" ],
+[ 1261, "avk" ],
+[ 1262, "avl" ],
+[ 1263, "avm" ],
+[ 1264, "avn" ],
+[ 1265, "avo" ],
+[ 1266, "avp" ],
+[ 1267, "avq" ],
+[ 1268, "avr" ],
+[ 1269, "avs" ],
+[ 1270, "avt" ],
+[ 1271, "avu" ],
+[ 1272, "avv" ],
+[ 1273, "avw" ],
+[ 1274, "avx" ],
+[ 1275, "avy" ],
+[ 1276, "avz" ],
+[ 1277, "awa" ],
+[ 1278, "awb" ],
+[ 1279, "awc" ],
+[ 1280, "awd" ],
+[ 1281, "awe" ],
+[ 1282, "awf" ],
+[ 1283, "awg" ],
+[ 1284, "awh" ],
+[ 1285, "awi" ],
+[ 1286, "awj" ],
+[ 1287, "awk" ],
+[ 1288, "awl" ],
+[ 1289, "awm" ],
+[ 1290, "awn" ],
+[ 1291, "awo" ],
+[ 1292, "awp" ],
+[ 1293, "awq" ],
+[ 1294, "awr" ],
+[ 1295, "aws" ],
+[ 1296, "awt" ],
+[ 1297, "awu" ],
+[ 1298, "awv" ],
+[ 1299, "aww" ],
+[ 1300, "awx" ],
+[ 1301, "awy" ],
+[ 1302, "awz" ],
+[ 1303, "axa" ],
+[ 1304, "axb" ],
+[ 1305, "axc" ],
+[ 1306, "axd" ],
+[ 1307, "axe" ],
+[ 1308, "axf" ],
+[ 1309, "axg" ],
+[ 1310, "axh" ],
+[ 1311, "axi" ],
+[ 1312, "axj" ],
+[ 1313, "axk" ],
+[ 1314, "axl" ],
+[ 1315, "axm" ],
+[ 1316, "axn" ],
+[ 1317, "axo" ],
+[ 1318, "axp" ],
+[ 1319, "axq" ],
+[ 1320, "axr" ],
+[ 1321, "axs" ],
+[ 1322, "axt" ],
+[ 1323, "axu" ],
+[ 1324, "axv" ],
+[ 1325, "axw" ],
+[ 1326, "axx" ],
+[ 1327, "axy" ],
+[ 1328, "axz" ],
+[ 1329, "aya" ],
+[ 1330, "ayb" ],
+[ 1331, "ayc" ],
+[ 1332, "ayd" ],
+[ 1333, "aye" ],
+[ 1334, "ayf" ],
+[ 1335, "ayg" ],
+[ 1336, "ayh" ],
+[ 1337, "ayi" ],
+[ 1338, "ayj" ],
+[ 1339, "ayk" ],
+[ 1340, "ayl" ],
+[ 1341, "aym" ],
+[ 1342, "ayn" ],
+[ 1343, "ayo" ],
+[ 1344, "ayp" ],
+[ 1345, "ayq" ],
+[ 1346, "ayr" ],
+[ 1347, "ays" ],
+[ 1348, "ayt" ],
+[ 1349, "ayu" ],
+[ 1350, "ayv" ],
+[ 1351, "ayw" ],
+[ 1352, "ayx" ],
+[ 1353, "ayy" ],
+[ 1354, "ayz" ],
+[ 1355, "aza" ],
+[ 1356, "azb" ],
+[ 1357, "azc" ],
+[ 1358, "azd" ],
+[ 1359, "aze" ],
+[ 1360, "azf" ],
+[ 1361, "azg" ],
+[ 1362, "azh" ],
+[ 1363, "azi" ],
+[ 1364, "azj" ],
+[ 1365, "azk" ],
+[ 1366, "azl" ],
+[ 1367, "azm" ],
+[ 1368, "azn" ],
+[ 1369, "azo" ],
+[ 1370, "azp" ],
+[ 1371, "azq" ],
+[ 1372, "azr" ],
+[ 1373, "azs" ],
+[ 1374, "azt" ],
+[ 1375, "azu" ],
+[ 1376, "azv" ],
+[ 1377, "azw" ],
+[ 1378, "azx" ],
+[ 1379, "azy" ],
+[ 1380, "azz" ],
+[ 1381, "baa" ],
+[ 1382, "bab" ],
+[ 1383, "bac" ],
+[ 1384, "bad" ],
+[ 1385, "bae" ],
+[ 1386, "baf" ],
+[ 1387, "bag" ],
+[ 1388, "bah" ],
+[ 1389, "bai" ],
+[ 1390, "baj" ],
+[ 1391, "bak" ],
+[ 1392, "bal" ],
+[ 1393, "bam" ],
+[ 1394, "ban" ],
+[ 1395, "bao" ],
+[ 1396, "bap" ],
+[ 1397, "baq" ],
+[ 1398, "bar" ],
+[ 1399, "bas" ],
+[ 1400, "bat" ],
+[ 1401, "bau" ],
+[ 1402, "bav" ],
+[ 1403, "baw" ],
+[ 1404, "bax" ],
+[ 1405, "bay" ],
+[ 1406, "baz" ],
+[ 1407, "bba" ],
+[ 1408, "bbb" ],
+[ 1409, "bbc" ],
+[ 1410, "bbd" ],
+[ 1411, "bbe" ],
+[ 1412, "bbf" ],
+[ 1413, "bbg" ],
+[ 1414, "bbh" ],
+[ 1415, "bbi" ],
+[ 1416, "bbj" ],
+[ 1417, "bbk" ],
+[ 1418, "bbl" ],
+[ 1419, "bbm" ],
+[ 1420, "bbn" ],
+[ 1421, "bbo" ],
+[ 1422, "bbp" ],
+[ 1423, "bbq" ],
+[ 1424, "bbr" ],
+[ 1425, "bbs" ],
+[ 1426, "bbt" ],
+[ 1427, "bbu" ],
+[ 1428, "bbv" ],
+[ 1429, "bbw" ],
+[ 1430, "bbx" ],
+[ 1431, "bby" ],
+[ 1432, "bbz" ],
+[ 1433, "bca" ],
+[ 1434, "bcb" ],
+[ 1435, "bcc" ],
+[ 1436, "bcd" ],
+[ 1437, "bce" ],
+[ 1438, "bcf" ],
+[ 1439, "bcg" ],
+[ 1440, "bch" ],
+[ 1441, "bci" ],
+[ 1442, "bcj" ],
+[ 1443, "bck" ],
+[ 1444, "bcl" ],
+[ 1445, "bcm" ],
+[ 1446, "bcn" ],
+[ 1447, "bco" ],
+[ 1448, "bcp" ],
+[ 1449, "bcq" ],
+[ 1450, "bcr" ],
+[ 1451, "bcs" ],
+[ 1452, "bct" ],
+[ 1453, "bcu" ],
+[ 1454, "bcv" ],
+[ 1455, "bcw" ],
+[ 1456, "bcx" ],
+[ 1457, "bcy" ],
+[ 1458, "bcz" ],
+[ 1459, "bda" ],
+[ 1460, "bdb" ],
+[ 1461, "bdc" ],
+[ 1462, "bdd" ],
+[ 1463, "bde" ],
+[ 1464, "bdf" ],
+[ 1465, "bdg" ],
+[ 1466, "bdh" ],
+[ 1467, "bdi" ],
+[ 1468, "bdj" ],
+[ 1469, "bdk" ],
+[ 1470, "bdl" ],
+[ 1471, "bdm" ],
+[ 1472, "bdn" ],
+[ 1473, "bdo" ],
+[ 1474, "bdp" ],
+[ 1475, "bdq" ],
+[ 1476, "bdr" ],
+[ 1477, "bds" ],
+[ 1478, "bdt" ],
+[ 1479, "bdu" ],
+[ 1480, "bdv" ],
+[ 1481, "bdw" ],
+[ 1482, "bdx" ],
+[ 1483, "bdy" ],
+[ 1484, "bdz" ],
+[ 1485, "bea" ],
+[ 1486, "beb" ],
+[ 1487, "bec" ],
+[ 1488, "bed" ],
+[ 1489, "bee" ],
+[ 1490, "bef" ],
+[ 1491, "beg" ],
+[ 1492, "beh" ],
+[ 1493, "bei" ],
+[ 1494, "bej" ],
+[ 1495, "bek" ],
+[ 1496, "bel" ],
+[ 1497, "bem" ],
+[ 1498, "ben" ],
+[ 1499, "beo" ],
+[ 1500, "bep" ],
+[ 1501, "beq" ],
+[ 1502, "ber" ],
+[ 1503, "bes" ],
+[ 1504, "bet" ],
+[ 1505, "beu" ],
+[ 1506, "bev" ],
+[ 1507, "bew" ],
+[ 1508, "bex" ],
+[ 1509, "bey" ],
+[ 1510, "bez" ],
+[ 1511, "bfa" ],
+[ 1512, "bfb" ],
+[ 1513, "bfc" ],
+[ 1514, "bfd" ],
+[ 1515, "bfe" ],
+[ 1516, "bff" ],
+[ 1517, "bfg" ],
+[ 1518, "bfh" ],
+[ 1519, "bfi" ],
+[ 1520, "bfj" ],
+[ 1521, "bfk" ],
+[ 1522, "bfl" ],
+[ 1523, "bfm" ],
+[ 1524, "bfn" ],
+[ 1525, "bfo" ],
+[ 1526, "bfp" ],
+[ 1527, "bfq" ],
+[ 1528, "bfr" ],
+[ 1529, "bfs" ],
+[ 1530, "bft" ],
+[ 1531, "bfu" ],
+[ 1532, "bfv" ],
+[ 1533, "bfw" ],
+[ 1534, "bfx" ],
+[ 1535, "bfy" ],
+[ 1536, "bfz" ],
+[ 1537, "bga" ],
+[ 1538, "bgb" ],
+[ 1539, "bgc" ],
+[ 1540, "bgd" ],
+[ 1541, "bge" ],
+[ 1542, "bgf" ],
+[ 1543, "bgg" ],
+[ 1544, "bgh" ],
+[ 1545, "bgi" ],
+[ 1546, "bgj" ],
+[ 1547, "bgk" ],
+[ 1548, "bgl" ],
+[ 1549, "bgm" ],
+[ 1550, "bgn" ],
+[ 1551, "bgo" ],
+[ 1552, "bgp" ],
+[ 1553, "bgq" ],
+[ 1554, "bgr" ],
+[ 1555, "bgs" ],
+[ 1556, "bgt" ],
+[ 1557, "bgu" ],
+[ 1558, "bgv" ],
+[ 1559, "bgw" ],
+[ 1560, "bgx" ],
+[ 1561, "bgy" ],
+[ 1562, "bgz" ],
+[ 1563, "bha" ],
+[ 1564, "bhb" ],
+[ 1565, "bhc" ],
+[ 1566, "bhd" ],
+[ 1567, "bhe" ],
+[ 1568, "bhf" ],
+[ 1569, "bhg" ],
+[ 1570, "bhh" ],
+[ 1571, "bhi" ],
+[ 1572, "bhj" ],
+[ 1573, "bhk" ],
+[ 1574, "bhl" ],
+[ 1575, "bhm" ],
+[ 1576, "bhn" ],
+[ 1577, "bho" ],
+[ 1578, "bhp" ],
+[ 1579, "bhq" ],
+[ 1580, "bhr" ],
+[ 1581, "bhs" ],
+[ 1582, "bht" ],
+[ 1583, "bhu" ],
+[ 1584, "bhv" ],
+[ 1585, "bhw" ],
+[ 1586, "bhx" ],
+[ 1587, "bhy" ],
+[ 1588, "bhz" ],
+[ 1589, "bia" ],
+[ 1590, "bib" ],
+[ 1591, "bic" ],
+[ 1592, "bid" ],
+[ 1593, "bie" ],
+[ 1594, "bif" ],
+[ 1595, "big" ],
+[ 1596, "bih" ],
+[ 1597, "bii" ],
+[ 1598, "bij" ],
+[ 1599, "bik" ],
+[ 1600, "bil" ],
+[ 1601, "bim" ],
+[ 1602, "bin" ],
+[ 1603, "bio" ],
+[ 1604, "bip" ],
+[ 1605, "biq" ],
+[ 1606, "bir" ],
+[ 1607, "bis" ],
+[ 1608, "bit" ],
+[ 1609, "biu" ],
+[ 1610, "biv" ],
+[ 1611, "biw" ],
+[ 1612, "bix" ],
+[ 1613, "biy" ],
+[ 1614, "biz" ],
+[ 1615, "bja" ],
+[ 1616, "bjb" ],
+[ 1617, "bjc" ],
+[ 1618, "bjd" ],
+[ 1619, "bje" ],
+[ 1620, "bjf" ],
+[ 1621, "bjg" ],
+[ 1622, "bjh" ],
+[ 1623, "bji" ],
+[ 1624, "bjj" ],
+[ 1625, "bjk" ],
+[ 1626, "bjl" ],
+[ 1627, "bjm" ],
+[ 1628, "bjn" ],
+[ 1629, "bjo" ],
+[ 1630, "bjp" ],
+[ 1631, "bjq" ],
+[ 1632, "bjr" ],
+[ 1633, "bjs" ],
+[ 1634, "bjt" ],
+[ 1635, "bju" ],
+[ 1636, "bjv" ],
+[ 1637, "bjw" ],
+[ 1638, "bjx" ],
+[ 1639, "bjy" ],
+[ 1640, "bjz" ],
+[ 1641, "bka" ],
+[ 1642, "bkb" ],
+[ 1643, "bkc" ],
+[ 1644, "bkd" ],
+[ 1645, "bke" ],
+[ 1646, "bkf" ],
+[ 1647, "bkg" ],
+[ 1648, "bkh" ],
+[ 1649, "bki" ],
+[ 1650, "bkj" ],
+[ 1651, "bkk" ],
+[ 1652, "bkl" ],
+[ 1653, "bkm" ],
+[ 1654, "bkn" ],
+[ 1655, "bko" ],
+[ 1656, "bkp" ],
+[ 1657, "bkq" ],
+[ 1658, "bkr" ],
+[ 1659, "bks" ],
+[ 1660, "bkt" ],
+[ 1661, "bku" ],
+[ 1662, "bkv" ],
+[ 1663, "bkw" ],
+[ 1664, "bkx" ],
+[ 1665, "bky" ],
+[ 1666, "bkz" ],
+[ 1667, "bla" ],
+[ 1668, "blb" ],
+[ 1669, "blc" ],
+[ 1670, "bld" ],
+[ 1671, "ble" ],
+[ 1672, "blf" ],
+[ 1673, "blg" ],
+[ 1674, "blh" ],
+[ 1675, "bli" ],
+[ 1676, "blj" ],
+[ 1677, "blk" ],
+[ 1678, "bll" ],
+[ 1679, "blm" ],
+[ 1680, "bln" ],
+[ 1681, "blo" ],
+[ 1682, "blp" ],
+[ 1683, "blq" ],
+[ 1684, "blr" ],
+[ 1685, "bls" ],
+[ 1686, "blt" ],
+[ 1687, "blu" ],
+[ 1688, "blv" ],
+[ 1689, "blw" ],
+[ 1690, "blx" ],
+[ 1691, "bly" ],
+[ 1692, "blz" ],
+[ 1693, "bma" ],
+[ 1694, "bmb" ],
+[ 1695, "bmc" ],
+[ 1696, "bmd" ],
+[ 1697, "bme" ],
+[ 1698, "bmf" ],
+[ 1699, "bmg" ],
+[ 1700, "bmh" ],
+[ 1701, "bmi" ],
+[ 1702, "bmj" ],
+[ 1703, "bmk" ],
+[ 1704, "bml" ],
+[ 1705, "bmm" ],
+[ 1706, "bmn" ],
+[ 1707, "bmo" ],
+[ 1708, "bmp" ],
+[ 1709, "bmq" ],
+[ 1710, "bmr" ],
+[ 1711, "bms" ],
+[ 1712, "bmt" ],
+[ 1713, "bmu" ],
+[ 1714, "bmv" ],
+[ 1715, "bmw" ],
+[ 1716, "bmx" ],
+[ 1717, "bmy" ],
+[ 1718, "bmz" ],
+[ 1719, "bna" ],
+[ 1720, "bnb" ],
+[ 1721, "bnc" ],
+[ 1722, "bnd" ],
+[ 1723, "bne" ],
+[ 1724, "bnf" ],
+[ 1725, "bng" ],
+[ 1726, "bnh" ],
+[ 1727, "bni" ],
+[ 1728, "bnj" ],
+[ 1729, "bnk" ],
+[ 1730, "bnl" ],
+[ 1731, "bnm" ],
+[ 1732, "bnn" ],
+[ 1733, "bno" ],
+[ 1734, "bnp" ],
+[ 1735, "bnq" ],
+[ 1736, "bnr" ],
+[ 1737, "bns" ],
+[ 1738, "bnt" ],
+[ 1739, "bnu" ],
+[ 1740, "bnv" ],
+[ 1741, "bnw" ],
+[ 1742, "bnx" ],
+[ 1743, "bny" ],
+[ 1744, "bnz" ],
+[ 1745, "boa" ],
+[ 1746, "bob" ],
+[ 1747, "boc" ],
+[ 1748, "bod" ],
+[ 1749, "boe" ],
+[ 1750, "bof" ],
+[ 1751, "bog" ],
+[ 1752, "boh" ],
+[ 1753, "boi" ],
+[ 1754, "boj" ],
+[ 1755, "bok" ],
+[ 1756, "bol" ],
+[ 1757, "bom" ],
+[ 1758, "bon" ],
+[ 1759, "boo" ],
+[ 1760, "bop" ],
+[ 1761, "boq" ],
+[ 1762, "bor" ],
+[ 1763, "bos" ],
+[ 1764, "bot" ],
+[ 1765, "bou" ],
+[ 1766, "bov" ],
+[ 1767, "bow" ],
+[ 1768, "box" ],
+[ 1769, "boy" ],
+[ 1770, "boz" ],
+[ 1771, "bpa" ],
+[ 1772, "bpb" ],
+[ 1773, "bpc" ],
+[ 1774, "bpd" ],
+[ 1775, "bpe" ],
+[ 1776, "bpf" ],
+[ 1777, "bpg" ],
+[ 1778, "bph" ],
+[ 1779, "bpi" ],
+[ 1780, "bpj" ],
+[ 1781, "bpk" ],
+[ 1782, "bpl" ],
+[ 1783, "bpm" ],
+[ 1784, "bpn" ],
+[ 1785, "bpo" ],
+[ 1786, "bpp" ],
+[ 1787, "bpq" ],
+[ 1788, "bpr" ],
+[ 1789, "bps" ],
+[ 1790, "bpt" ],
+[ 1791, "bpu" ],
+[ 1792, "bpv" ],
+[ 1793, "bpw" ],
+[ 1794, "bpx" ],
+[ 1795, "bpy" ],
+[ 1796, "bpz" ],
+[ 1797, "bqa" ],
+[ 1798, "bqb" ],
+[ 1799, "bqc" ],
+[ 1800, "bqd" ],
+[ 1801, "bqe" ],
+[ 1802, "bqf" ],
+[ 1803, "bqg" ],
+[ 1804, "bqh" ],
+[ 1805, "bqi" ],
+[ 1806, "bqj" ],
+[ 1807, "bqk" ],
+[ 1808, "bql" ],
+[ 1809, "bqm" ],
+[ 1810, "bqn" ],
+[ 1811, "bqo" ],
+[ 1812, "bqp" ],
+[ 1813, "bqq" ],
+[ 1814, "bqr" ],
+[ 1815, "bqs" ],
+[ 1816, "bqt" ],
+[ 1817, "bqu" ],
+[ 1818, "bqv" ],
+[ 1819, "bqw" ],
+[ 1820, "bqx" ],
+[ 1821, "bqy" ],
+[ 1822, "bqz" ],
+[ 1823, "bra" ],
+[ 1824, "brb" ],
+[ 1825, "brc" ],
+[ 1826, "brd" ],
+[ 1827, "bre" ],
+[ 1828, "brf" ],
+[ 1829, "brg" ],
+[ 1830, "brh" ],
+[ 1831, "bri" ],
+[ 1832, "brj" ],
+[ 1833, "brk" ],
+[ 1834, "brl" ],
+[ 1835, "brm" ],
+[ 1836, "brn" ],
+[ 1837, "bro" ],
+[ 1838, "brp" ],
+[ 1839, "brq" ],
+[ 1840, "brr" ],
+[ 1841, "brs" ],
+[ 1842, "brt" ],
+[ 1843, "bru" ],
+[ 1844, "brv" ],
+[ 1845, "brw" ],
+[ 1846, "brx" ],
+[ 1847, "bry" ],
+[ 1848, "brz" ],
+[ 1849, "bsa" ],
+[ 1850, "bsb" ],
+[ 1851, "bsc" ],
+[ 1852, "bsd" ],
+[ 1853, "bse" ],
+[ 1854, "bsf" ],
+[ 1855, "bsg" ],
+[ 1856, "bsh" ],
+[ 1857, "bsi" ],
+[ 1858, "bsj" ],
+[ 1859, "bsk" ],
+[ 1860, "bsl" ],
+[ 1861, "bsm" ],
+[ 1862, "bsn" ],
+[ 1863, "bso" ],
+[ 1864, "bsp" ],
+[ 1865, "bsq" ],
+[ 1866, "bsr" ],
+[ 1867, "bss" ],
+[ 1868, "bst" ],
+[ 1869, "bsu" ],
+[ 1870, "bsv" ],
+[ 1871, "bsw" ],
+[ 1872, "bsx" ],
+[ 1873, "bsy" ],
+[ 1874, "bsz" ],
+[ 1875, "bta" ],
+[ 1876, "btb" ],
+[ 1877, "btc" ],
+[ 1878, "btd" ],
+[ 1879, "bte" ],
+[ 1880, "btf" ],
+[ 1881, "btg" ],
+[ 1882, "bth" ],
+[ 1883, "bti" ],
+[ 1884, "btj" ],
+[ 1885, "btk" ],
+[ 1886, "btl" ],
+[ 1887, "btm" ],
+[ 1888, "btn" ],
+[ 1889, "bto" ],
+[ 1890, "btp" ],
+[ 1891, "btq" ],
+[ 1892, "btr" ],
+[ 1893, "bts" ],
+[ 1894, "btt" ],
+[ 1895, "btu" ],
+[ 1896, "btv" ],
+[ 1897, "btw" ],
+[ 1898, "btx" ],
+[ 1899, "bty" ],
+[ 1900, "btz" ],
+[ 1901, "bua" ],
+[ 1902, "bub" ],
+[ 1903, "buc" ],
+[ 1904, "bud" ],
+[ 1905, "bue" ],
+[ 1906, "buf" ],
+[ 1907, "bug" ],
+[ 1908, "buh" ],
+[ 1909, "bui" ],
+[ 1910, "buj" ],
+[ 1911, "buk" ],
+[ 1912, "bul" ],
+[ 1913, "bum" ],
+[ 1914, "bun" ],
+[ 1915, "buo" ],
+[ 1916, "bup" ],
+[ 1917, "buq" ],
+[ 1918, "bur" ],
+[ 1919, "bus" ],
+[ 1920, "but" ],
+[ 1921, "buu" ],
+[ 1922, "buv" ],
+[ 1923, "buw" ],
+[ 1924, "bux" ],
+[ 1925, "buy" ],
+[ 1926, "buz" ],
+[ 1927, "bva" ],
+[ 1928, "bvb" ],
+[ 1929, "bvc" ],
+[ 1930, "bvd" ],
+[ 1931, "bve" ],
+[ 1932, "bvf" ],
+[ 1933, "bvg" ],
+[ 1934, "bvh" ],
+[ 1935, "bvi" ],
+[ 1936, "bvj" ],
+[ 1937, "bvk" ],
+[ 1938, "bvl" ],
+[ 1939, "bvm" ],
+[ 1940, "bvn" ],
+[ 1941, "bvo" ],
+[ 1942, "bvp" ],
+[ 1943, "bvq" ],
+[ 1944, "bvr" ],
+[ 1945, "bvs" ],
+[ 1946, "bvt" ],
+[ 1947, "bvu" ],
+[ 1948, "bvv" ],
+[ 1949, "bvw" ],
+[ 1950, "bvx" ],
+[ 1951, "bvy" ],
+[ 1952, "bvz" ],
+[ 1953, "bwa" ],
+[ 1954, "bwb" ],
+[ 1955, "bwc" ],
+[ 1956, "bwd" ],
+[ 1957, "bwe" ],
+[ 1958, "bwf" ],
+[ 1959, "bwg" ],
+[ 1960, "bwh" ],
+[ 1961, "bwi" ],
+[ 1962, "bwj" ],
+[ 1963, "bwk" ],
+[ 1964, "bwl" ],
+[ 1965, "bwm" ],
+[ 1966, "bwn" ],
+[ 1967, "bwo" ],
+[ 1968, "bwp" ],
+[ 1969, "bwq" ],
+[ 1970, "bwr" ],
+[ 1971, "bws" ],
+[ 1972, "bwt" ],
+[ 1973, "bwu" ],
+[ 1974, "bwv" ],
+[ 1975, "bww" ],
+[ 1976, "bwx" ],
+[ 1977, "bwy" ],
+[ 1978, "bwz" ],
+[ 1979, "bxa" ],
+[ 1980, "bxb" ],
+[ 1981, "bxc" ],
+[ 1982, "bxd" ],
+[ 1983, "bxe" ],
+[ 1984, "bxf" ],
+[ 1985, "bxg" ],
+[ 1986, "bxh" ],
+[ 1987, "bxi" ],
+[ 1988, "bxj" ],
+[ 1989, "bxk" ],
+[ 1990, "bxl" ],
+[ 1991, "bxm" ],
+[ 1992, "bxn" ],
+[ 1993, "bxo" ],
+[ 1994, "bxp" ],
+[ 1995, "bxq" ],
+[ 1996, "bxr" ],
+[ 1997, "bxs" ],
+[ 1998, "bxt" ],
+[ 1999, "bxu" ],
+[ 2000, "bxv" ],
+[ 2001, "bxw" ],
+[ 2002, "bxx" ],
+[ 2003, "bxy" ],
+[ 2004, "bxz" ],
+[ 2005, "bya" ],
+[ 2006, "byb" ],
+[ 2007, "byc" ],
+[ 2008, "byd" ],
+[ 2009, "bye" ],
+[ 2010, "byf" ],
+[ 2011, "byg" ],
+[ 2012, "byh" ],
+[ 2013, "byi" ],
+[ 2014, "byj" ],
+[ 2015, "byk" ],
+[ 2016, "byl" ],
+[ 2017, "bym" ],
+[ 2018, "byn" ],
+[ 2019, "byo" ],
+[ 2020, "byp" ],
+[ 2021, "byq" ],
+[ 2022, "byr" ],
+[ 2023, "bys" ],
+[ 2024, "byt" ],
+[ 2025, "byu" ],
+[ 2026, "byv" ],
+[ 2027, "byw" ],
+[ 2028, "byx" ],
+[ 2029, "byy" ],
+[ 2030, "byz" ],
+[ 2031, "bza" ],
+[ 2032, "bzb" ],
+[ 2033, "bzc" ],
+[ 2034, "bzd" ],
+[ 2035, "bze" ],
+[ 2036, "bzf" ],
+[ 2037, "bzg" ],
+[ 2038, "bzh" ],
+[ 2039, "bzi" ],
+[ 2040, "bzj" ],
+[ 2041, "bzk" ],
+[ 2042, "bzl" ],
+[ 2043, "bzm" ],
+[ 2044, "bzn" ],
+[ 2045, "bzo" ],
+[ 2046, "bzp" ],
+[ 2047, "bzq" ],
+[ 2048, "bzr" ],
+[ 2049, "bzs" ],
+[ 2050, "bzt" ],
+[ 2051, "bzu" ],
+[ 2052, "bzv" ],
+[ 2053, "bzw" ],
+[ 2054, "bzx" ],
+[ 2055, "bzy" ],
+[ 2056, "bzz" ],
+[ 2057, "caa" ],
+[ 2058, "cab" ],
+[ 2059, "cac" ],
+[ 2060, "cad" ],
+[ 2061, "cae" ],
+[ 2062, "caf" ],
+[ 2063, "cag" ],
+[ 2064, "cah" ],
+[ 2065, "cai" ],
+[ 2066, "caj" ],
+[ 2067, "cak" ],
+[ 2068, "cal" ],
+[ 2069, "cam" ],
+[ 2070, "can" ],
+[ 2071, "cao" ],
+[ 2072, "cap" ],
+[ 2073, "caq" ],
+[ 2074, "car" ],
+[ 2075, "cas" ],
+[ 2076, "cat" ],
+[ 2077, "cau" ],
+[ 2078, "cav" ],
+[ 2079, "caw" ],
+[ 2080, "cax" ],
+[ 2081, "cay" ],
+[ 2082, "caz" ],
+[ 2083, "cba" ],
+[ 2084, "cbb" ],
+[ 2085, "cbc" ],
+[ 2086, "cbd" ],
+[ 2087, "cbe" ],
+[ 2088, "cbf" ],
+[ 2089, "cbg" ],
+[ 2090, "cbh" ],
+[ 2091, "cbi" ],
+[ 2092, "cbj" ],
+[ 2093, "cbk" ],
+[ 2094, "cbl" ],
+[ 2095, "cbm" ],
+[ 2096, "cbn" ],
+[ 2097, "cbo" ],
+[ 2098, "cbp" ],
+[ 2099, "cbq" ],
+[ 2100, "cbr" ],
+[ 2101, "cbs" ],
+[ 2102, "cbt" ],
+[ 2103, "cbu" ],
+[ 2104, "cbv" ],
+[ 2105, "cbw" ],
+[ 2106, "cbx" ],
+[ 2107, "cby" ],
+[ 2108, "cbz" ],
+[ 2109, "cca" ],
+[ 2110, "ccb" ],
+[ 2111, "ccc" ],
+[ 2112, "ccd" ],
+[ 2113, "cce" ],
+[ 2114, "ccf" ],
+[ 2115, "ccg" ],
+[ 2116, "cch" ],
+[ 2117, "cci" ],
+[ 2118, "ccj" ],
+[ 2119, "cck" ],
+[ 2120, "ccl" ],
+[ 2121, "ccm" ],
+[ 2122, "ccn" ],
+[ 2123, "cco" ],
+[ 2124, "ccp" ],
+[ 2125, "ccq" ],
+[ 2126, "ccr" ],
+[ 2127, "ccs" ],
+[ 2128, "cct" ],
+[ 2129, "ccu" ],
+[ 2130, "ccv" ],
+[ 2131, "ccw" ],
+[ 2132, "ccx" ],
+[ 2133, "ccy" ],
+[ 2134, "ccz" ],
+[ 2135, "cda" ],
+[ 2136, "cdb" ],
+[ 2137, "cdc" ],
+[ 2138, "cdd" ],
+[ 2139, "cde" ],
+[ 2140, "cdf" ],
+[ 2141, "cdg" ],
+[ 2142, "cdh" ],
+[ 2143, "cdi" ],
+[ 2144, "cdj" ],
+[ 2145, "cdk" ],
+[ 2146, "cdl" ],
+[ 2147, "cdm" ],
+[ 2148, "cdn" ],
+[ 2149, "cdo" ],
+[ 2150, "cdp" ],
+[ 2151, "cdq" ],
+[ 2152, "cdr" ],
+[ 2153, "cds" ],
+[ 2154, "cdt" ],
+[ 2155, "cdu" ],
+[ 2156, "cdv" ],
+[ 2157, "cdw" ],
+[ 2158, "cdx" ],
+[ 2159, "cdy" ],
+[ 2160, "cdz" ],
+[ 2161, "cea" ],
+[ 2162, "ceb" ],
+[ 2163, "cec" ],
+[ 2164, "ced" ],
+[ 2165, "cee" ],
+[ 2166, "cef" ],
+[ 2167, "ceg" ],
+[ 2168, "ceh" ],
+[ 2169, "cei" ],
+[ 2170, "cej" ],
+[ 2171, "cek" ],
+[ 2172, "cel" ],
+[ 2173, "cem" ],
+[ 2174, "cen" ],
+[ 2175, "ceo" ],
+[ 2176, "cep" ],
+[ 2177, "ceq" ],
+[ 2178, "cer" ],
+[ 2179, "ces" ],
+[ 2180, "cet" ],
+[ 2181, "ceu" ],
+[ 2182, "cev" ],
+[ 2183, "cew" ],
+[ 2184, "cex" ],
+[ 2185, "cey" ],
+[ 2186, "cez" ],
+[ 2187, "cfa" ],
+[ 2188, "cfb" ],
+[ 2189, "cfc" ],
+[ 2190, "cfd" ],
+[ 2191, "cfe" ],
+[ 2192, "cff" ],
+[ 2193, "cfg" ],
+[ 2194, "cfh" ],
+[ 2195, "cfi" ],
+[ 2196, "cfj" ],
+[ 2197, "cfk" ],
+[ 2198, "cfl" ],
+[ 2199, "cfm" ],
+[ 2200, "cfn" ],
+[ 2201, "cfo" ],
+[ 2202, "cfp" ],
+[ 2203, "cfq" ],
+[ 2204, "cfr" ],
+[ 2205, "cfs" ],
+[ 2206, "cft" ],
+[ 2207, "cfu" ],
+[ 2208, "cfv" ],
+[ 2209, "cfw" ],
+[ 2210, "cfx" ],
+[ 2211, "cfy" ],
+[ 2212, "cfz" ],
+[ 2213, "cga" ],
+[ 2214, "cgb" ],
+[ 2215, "cgc" ],
+[ 2216, "cgd" ],
+[ 2217, "cge" ],
+[ 2218, "cgf" ],
+[ 2219, "cgg" ],
+[ 2220, "cgh" ],
+[ 2221, "cgi" ],
+[ 2222, "cgj" ],
+[ 2223, "cgk" ],
+[ 2224, "cgl" ],
+[ 2225, "cgm" ],
+[ 2226, "cgn" ],
+[ 2227, "cgo" ],
+[ 2228, "cgp" ],
+[ 2229, "cgq" ],
+[ 2230, "cgr" ],
+[ 2231, "cgs" ],
+[ 2232, "cgt" ],
+[ 2233, "cgu" ],
+[ 2234, "cgv" ],
+[ 2235, "cgw" ],
+[ 2236, "cgx" ],
+[ 2237, "cgy" ],
+[ 2238, "cgz" ],
+[ 2239, "cha" ],
+[ 2240, "chb" ],
+[ 2241, "chc" ],
+[ 2242, "chd" ],
+[ 2243, "che" ],
+[ 2244, "chf" ],
+[ 2245, "chg" ],
+[ 2246, "chh" ],
+[ 2247, "chi" ],
+[ 2248, "chj" ],
+[ 2249, "chk" ],
+[ 2250, "chl" ],
+[ 2251, "chm" ],
+[ 2252, "chn" ],
+[ 2253, "cho" ],
+[ 2254, "chp" ],
+[ 2255, "chq" ],
+[ 2256, "chr" ],
+[ 2257, "chs" ],
+[ 2258, "cht" ],
+[ 2259, "chu" ],
+[ 2260, "chv" ],
+[ 2261, "chw" ],
+[ 2262, "chx" ],
+[ 2263, "chy" ],
+[ 2264, "chz" ],
+[ 2265, "cia" ],
+[ 2266, "cib" ],
+[ 2267, "cic" ],
+[ 2268, "cid" ],
+[ 2269, "cie" ],
+[ 2270, "cif" ],
+[ 2271, "cig" ],
+[ 2272, "cih" ],
+[ 2273, "cii" ],
+[ 2274, "cij" ],
+[ 2275, "cik" ],
+[ 2276, "cil" ],
+[ 2277, "cim" ],
+[ 2278, "cin" ],
+[ 2279, "cio" ],
+[ 2280, "cip" ],
+[ 2281, "ciq" ],
+[ 2282, "cir" ],
+[ 2283, "cis" ],
+[ 2284, "cit" ],
+[ 2285, "ciu" ],
+[ 2286, "civ" ],
+[ 2287, "ciw" ],
+[ 2288, "cix" ],
+[ 2289, "ciy" ],
+[ 2290, "ciz" ],
+[ 2291, "cja" ],
+[ 2292, "cjb" ],
+[ 2293, "cjc" ],
+[ 2294, "cjd" ],
+[ 2295, "cje" ],
+[ 2296, "cjf" ],
+[ 2297, "cjg" ],
+[ 2298, "cjh" ],
+[ 2299, "cji" ],
+[ 2300, "cjj" ],
+[ 2301, "cjk" ],
+[ 2302, "cjl" ],
+[ 2303, "cjm" ],
+[ 2304, "cjn" ],
+[ 2305, "cjo" ],
+[ 2306, "cjp" ],
+[ 2307, "cjq" ],
+[ 2308, "cjr" ],
+[ 2309, "cjs" ],
+[ 2310, "cjt" ],
+[ 2311, "cju" ],
+[ 2312, "cjv" ],
+[ 2313, "cjw" ],
+[ 2314, "cjx" ],
+[ 2315, "cjy" ],
+[ 2316, "cjz" ],
+[ 2317, "cka" ],
+[ 2318, "ckb" ],
+[ 2319, "ckc" ],
+[ 2320, "ckd" ],
+[ 2321, "cke" ],
+[ 2322, "ckf" ],
+[ 2323, "ckg" ],
+[ 2324, "ckh" ],
+[ 2325, "cki" ],
+[ 2326, "ckj" ],
+[ 2327, "ckk" ],
+[ 2328, "ckl" ],
+[ 2329, "ckm" ],
+[ 2330, "ckn" ],
+[ 2331, "cko" ],
+[ 2332, "ckp" ],
+[ 2333, "ckq" ],
+[ 2334, "ckr" ],
+[ 2335, "cks" ],
+[ 2336, "ckt" ],
+[ 2337, "cku" ],
+[ 2338, "ckv" ],
+[ 2339, "ckw" ],
+[ 2340, "ckx" ],
+[ 2341, "cky" ],
+[ 2342, "ckz" ],
+[ 2343, "cla" ],
+[ 2344, "clb" ],
+[ 2345, "clc" ],
+[ 2346, "cld" ],
+[ 2347, "cle" ],
+[ 2348, "clf" ],
+[ 2349, "clg" ],
+[ 2350, "clh" ],
+[ 2351, "cli" ],
+[ 2352, "clj" ],
+[ 2353, "clk" ],
+[ 2354, "cll" ],
+[ 2355, "clm" ],
+[ 2356, "cln" ],
+[ 2357, "clo" ],
+[ 2358, "clp" ],
+[ 2359, "clq" ],
+[ 2360, "clr" ],
+[ 2361, "cls" ],
+[ 2362, "clt" ],
+[ 2363, "clu" ],
+[ 2364, "clv" ],
+[ 2365, "clw" ],
+[ 2366, "clx" ],
+[ 2367, "cly" ],
+[ 2368, "clz" ],
+[ 2369, "cma" ],
+[ 2370, "cmb" ],
+[ 2371, "cmc" ],
+[ 2372, "cmd" ],
+[ 2373, "cme" ],
+[ 2374, "cmf" ],
+[ 2375, "cmg" ],
+[ 2376, "cmh" ],
+[ 2377, "cmi" ],
+[ 2378, "cmj" ],
+[ 2379, "cmk" ],
+[ 2380, "cml" ],
+[ 2381, "cmm" ],
+[ 2382, "cmn" ],
+[ 2383, "cmo" ],
+[ 2384, "cmp" ],
+[ 2385, "cmq" ],
+[ 2386, "cmr" ],
+[ 2387, "cms" ],
+[ 2388, "cmt" ],
+[ 2389, "cmu" ],
+[ 2390, "cmv" ],
+[ 2391, "cmw" ],
+[ 2392, "cmx" ],
+[ 2393, "cmy" ],
+[ 2394, "cmz" ],
+[ 2395, "cna" ],
+[ 2396, "cnb" ],
+[ 2397, "cnc" ],
+[ 2398, "cnd" ],
+[ 2399, "cne" ],
+[ 2400, "cnf" ],
+[ 2401, "cng" ],
+[ 2402, "cnh" ],
+[ 2403, "cni" ],
+[ 2404, "cnj" ],
+[ 2405, "cnk" ],
+[ 2406, "cnl" ],
+[ 2407, "cnm" ],
+[ 2408, "cnn" ],
+[ 2409, "cno" ],
+[ 2410, "cnp" ],
+[ 2411, "cnq" ],
+[ 2412, "cnr" ],
+[ 2413, "cns" ],
+[ 2414, "cnt" ],
+[ 2415, "cnu" ],
+[ 2416, "cnv" ],
+[ 2417, "cnw" ],
+[ 2418, "cnx" ],
+[ 2419, "cny" ],
+[ 2420, "cnz" ],
+[ 2421, "coa" ],
+[ 2422, "cob" ],
+[ 2423, "coc" ],
+[ 2424, "cod" ],
+[ 2425, "coe" ],
+[ 2426, "cof" ],
+[ 2427, "cog" ],
+[ 2428, "coh" ],
+[ 2429, "coi" ],
+[ 2430, "coj" ],
+[ 2431, "cok" ],
+[ 2432, "col" ],
+[ 2433, "com" ],
+[ 2434, "con" ],
+[ 2435, "coo" ],
+[ 2436, "cop" ],
+[ 2437, "coq" ],
+[ 2438, "cor" ],
+[ 2439, "cos" ],
+[ 2440, "cot" ],
+[ 2441, "cou" ],
+[ 2442, "cov" ],
+[ 2443, "cow" ],
+[ 2444, "cox" ],
+[ 2445, "coy" ],
+[ 2446, "coz" ],
+[ 2447, "cpa" ],
+[ 2448, "cpb" ],
+[ 2449, "cpc" ],
+[ 2450, "cpd" ],
+[ 2451, "cpe" ],
+[ 2452, "cpf" ],
+[ 2453, "cpg" ],
+[ 2454, "cph" ],
+[ 2455, "cpi" ],
+[ 2456, "cpj" ],
+[ 2457, "cpk" ],
+[ 2458, "cpl" ],
+[ 2459, "cpm" ],
+[ 2460, "cpn" ],
+[ 2461, "cpo" ],
+[ 2462, "cpp" ],
+[ 2463, "cpq" ],
+[ 2464, "cpr" ],
+[ 2465, "cps" ],
+[ 2466, "cpt" ],
+[ 2467, "cpu" ],
+[ 2468, "cpv" ],
+[ 2469, "cpw" ],
+[ 2470, "cpx" ],
+[ 2471, "cpy" ],
+[ 2472, "cpz" ],
+[ 2473, "cqa" ],
+[ 2474, "cqb" ],
+[ 2475, "cqc" ],
+[ 2476, "cqd" ],
+[ 2477, "cqe" ],
+[ 2478, "cqf" ],
+[ 2479, "cqg" ],
+[ 2480, "cqh" ],
+[ 2481, "cqi" ],
+[ 2482, "cqj" ],
+[ 2483, "cqk" ],
+[ 2484, "cql" ],
+[ 2485, "cqm" ],
+[ 2486, "cqn" ],
+[ 2487, "cqo" ],
+[ 2488, "cqp" ],
+[ 2489, "cqq" ],
+[ 2490, "cqr" ],
+[ 2491, "cqs" ],
+[ 2492, "cqt" ],
+[ 2493, "cqu" ],
+[ 2494, "cqv" ],
+[ 2495, "cqw" ],
+[ 2496, "cqx" ],
+[ 2497, "cqy" ],
+[ 2498, "cqz" ],
+[ 2499, "cra" ],
+[ 2500, "crb" ],
+[ 2501, "crc" ],
+[ 2502, "crd" ],
+[ 2503, "cre" ],
+[ 2504, "crf" ],
+[ 2505, "crg" ],
+[ 2506, "crh" ],
+[ 2507, "cri" ],
+[ 2508, "crj" ],
+[ 2509, "crk" ],
+[ 2510, "crl" ],
+[ 2511, "crm" ],
+[ 2512, "crn" ],
+[ 2513, "cro" ],
+[ 2514, "crp" ],
+[ 2515, "crq" ],
+[ 2516, "crr" ],
+[ 2517, "crs" ],
+[ 2518, "crt" ],
+[ 2519, "cru" ],
+[ 2520, "crv" ],
+[ 2521, "crw" ],
+[ 2522, "crx" ],
+[ 2523, "cry" ],
+[ 2524, "crz" ],
+[ 2525, "csa" ],
+[ 2526, "csb" ],
+[ 2527, "csc" ],
+[ 2528, "csd" ],
+[ 2529, "cse" ],
+[ 2530, "csf" ],
+[ 2531, "csg" ],
+[ 2532, "csh" ],
+[ 2533, "csi" ],
+[ 2534, "csj" ],
+[ 2535, "csk" ],
+[ 2536, "csl" ],
+[ 2537, "csm" ],
+[ 2538, "csn" ],
+[ 2539, "cso" ],
+[ 2540, "csp" ],
+[ 2541, "csq" ],
+[ 2542, "csr" ],
+[ 2543, "css" ],
+[ 2544, "cst" ],
+[ 2545, "csu" ],
+[ 2546, "csv" ],
+[ 2547, "csw" ],
+[ 2548, "csx" ],
+[ 2549, "csy" ],
+[ 2550, "csz" ],
+[ 2551, "cta" ],
+[ 2552, "ctb" ],
+[ 2553, "ctc" ],
+[ 2554, "ctd" ],
+[ 2555, "cte" ],
+[ 2556, "ctf" ],
+[ 2557, "ctg" ],
+[ 2558, "cth" ],
+[ 2559, "cti" ],
+[ 2560, "ctj" ],
+[ 2561, "ctk" ],
+[ 2562, "ctl" ],
+[ 2563, "ctm" ],
+[ 2564, "ctn" ],
+[ 2565, "cto" ],
+[ 2566, "ctp" ],
+[ 2567, "ctq" ],
+[ 2568, "ctr" ],
+[ 2569, "cts" ],
+[ 2570, "ctt" ],
+[ 2571, "ctu" ],
+[ 2572, "ctv" ],
+[ 2573, "ctw" ],
+[ 2574, "ctx" ],
+[ 2575, "cty" ],
+[ 2576, "ctz" ],
+[ 2577, "cua" ],
+[ 2578, "cub" ],
+[ 2579, "cuc" ],
+[ 2580, "cud" ],
+[ 2581, "cue" ],
+[ 2582, "cuf" ],
+[ 2583, "cug" ],
+[ 2584, "cuh" ],
+[ 2585, "cui" ],
+[ 2586, "cuj" ],
+[ 2587, "cuk" ],
+[ 2588, "cul" ],
+[ 2589, "cum" ],
+[ 2590, "cun" ],
+[ 2591, "cuo" ],
+[ 2592, "cup" ],
+[ 2593, "cuq" ],
+[ 2594, "cur" ],
+[ 2595, "cus" ],
+[ 2596, "cut" ],
+[ 2597, "cuu" ],
+[ 2598, "cuv" ],
+[ 2599, "cuw" ],
+[ 2600, "cux" ],
+[ 2601, "cuy" ],
+[ 2602, "cuz" ],
+[ 2603, "cva" ],
+[ 2604, "cvb" ],
+[ 2605, "cvc" ],
+[ 2606, "cvd" ],
+[ 2607, "cve" ],
+[ 2608, "cvf" ],
+[ 2609, "cvg" ],
+[ 2610, "cvh" ],
+[ 2611, "cvi" ],
+[ 2612, "cvj" ],
+[ 2613, "cvk" ],
+[ 2614, "cvl" ],
+[ 2615, "cvm" ],
+[ 2616, "cvn" ],
+[ 2617, "cvo" ],
+[ 2618, "cvp" ],
+[ 2619, "cvq" ],
+[ 2620, "cvr" ],
+[ 2621, "cvs" ],
+[ 2622, "cvt" ],
+[ 2623, "cvu" ],
+[ 2624, "cvv" ],
+[ 2625, "cvw" ],
+[ 2626, "cvx" ],
+[ 2627, "cvy" ],
+[ 2628, "cvz" ],
+[ 2629, "cwa" ],
+[ 2630, "cwb" ],
+[ 2631, "cwc" ],
+[ 2632, "cwd" ],
+[ 2633, "cwe" ],
+[ 2634, "cwf" ],
+[ 2635, "cwg" ],
+[ 2636, "cwh" ],
+[ 2637, "cwi" ],
+[ 2638, "cwj" ],
+[ 2639, "cwk" ],
+[ 2640, "cwl" ],
+[ 2641, "cwm" ],
+[ 2642, "cwn" ],
+[ 2643, "cwo" ],
+[ 2644, "cwp" ],
+[ 2645, "cwq" ],
+[ 2646, "cwr" ],
+[ 2647, "cws" ],
+[ 2648, "cwt" ],
+[ 2649, "cwu" ],
+[ 2650, "cwv" ],
+[ 2651, "cww" ],
+[ 2652, "cwx" ],
+[ 2653, "cwy" ],
+[ 2654, "cwz" ],
+[ 2655, "cxa" ],
+[ 2656, "cxb" ],
+[ 2657, "cxc" ],
+[ 2658, "cxd" ],
+[ 2659, "cxe" ],
+[ 2660, "cxf" ],
+[ 2661, "cxg" ],
+[ 2662, "cxh" ],
+[ 2663, "cxi" ],
+[ 2664, "cxj" ],
+[ 2665, "cxk" ],
+[ 2666, "cxl" ],
+[ 2667, "cxm" ],
+[ 2668, "cxn" ],
+[ 2669, "cxo" ],
+[ 2670, "cxp" ],
+[ 2671, "cxq" ],
+[ 2672, "cxr" ],
+[ 2673, "cxs" ],
+[ 2674, "cxt" ],
+[ 2675, "cxu" ],
+[ 2676, "cxv" ],
+[ 2677, "cxw" ],
+[ 2678, "cxx" ],
+[ 2679, "cxy" ],
+[ 2680, "cxz" ],
+[ 2681, "cya" ],
+[ 2682, "cyb" ],
+[ 2683, "cyc" ],
+[ 2684, "cyd" ],
+[ 2685, "cye" ],
+[ 2686, "cyf" ],
+[ 2687, "cyg" ],
+[ 2688, "cyh" ],
+[ 2689, "cyi" ],
+[ 2690, "cyj" ],
+[ 2691, "cyk" ],
+[ 2692, "cyl" ],
+[ 2693, "cym" ],
+[ 2694, "cyn" ],
+[ 2695, "cyo" ],
+[ 2696, "cyp" ],
+[ 2697, "cyq" ],
+[ 2698, "cyr" ],
+[ 2699, "cys" ],
+[ 2700, "cyt" ],
+[ 2701, "cyu" ],
+[ 2702, "cyv" ],
+[ 2703, "cyw" ],
+[ 2704, "cyx" ],
+[ 2705, "cyy" ],
+[ 2706, "cyz" ],
+[ 2707, "cza" ],
+[ 2708, "czb" ],
+[ 2709, "czc" ],
+[ 2710, "czd" ],
+[ 2711, "cze" ],
+[ 2712, "czf" ],
+[ 2713, "czg" ],
+[ 2714, "czh" ],
+[ 2715, "czi" ],
+[ 2716, "czj" ],
+[ 2717, "czk" ],
+[ 2718, "czl" ],
+[ 2719, "czm" ],
+[ 2720, "czn" ],
+[ 2721, "czo" ],
+[ 2722, "czp" ],
+[ 2723, "czq" ],
+[ 2724, "czr" ],
+[ 2725, "czs" ],
+[ 2726, "czt" ],
+[ 2727, "czu" ],
+[ 2728, "czv" ],
+[ 2729, "czw" ],
+[ 2730, "czx" ],
+[ 2731, "czy" ],
+[ 2732, "czz" ],
+[ 2733, "daa" ],
+[ 2734, "dab" ],
+[ 2735, "dac" ],
+[ 2736, "dad" ],
+[ 2737, "dae" ],
+[ 2738, "daf" ],
+[ 2739, "dag" ],
+[ 2740, "dah" ],
+[ 2741, "dai" ],
+[ 2742, "daj" ],
+[ 2743, "dak" ],
+[ 2744, "dal" ],
+[ 2745, "dam" ],
+[ 2746, "dan" ],
+[ 2747, "dao" ],
+[ 2748, "dap" ],
+[ 2749, "daq" ],
+[ 2750, "dar" ],
+[ 2751, "das" ],
+[ 2752, "dat" ],
+[ 2753, "dau" ],
+[ 2754, "dav" ],
+[ 2755, "daw" ],
+[ 2756, "dax" ],
+[ 2757, "day" ],
+[ 2758, "daz" ],
+[ 2759, "dba" ],
+[ 2760, "dbb" ],
+[ 2761, "dbc" ],
+[ 2762, "dbd" ],
+[ 2763, "dbe" ],
+[ 2764, "dbf" ],
+[ 2765, "dbg" ],
+[ 2766, "dbh" ],
+[ 2767, "dbi" ],
+[ 2768, "dbj" ],
+[ 2769, "dbk" ],
+[ 2770, "dbl" ],
+[ 2771, "dbm" ],
+[ 2772, "dbn" ],
+[ 2773, "dbo" ],
+[ 2774, "dbp" ],
+[ 2775, "dbq" ],
+[ 2776, "dbr" ],
+[ 2777, "dbs" ],
+[ 2778, "dbt" ],
+[ 2779, "dbu" ],
+[ 2780, "dbv" ],
+[ 2781, "dbw" ],
+[ 2782, "dbx" ],
+[ 2783, "dby" ],
+[ 2784, "dbz" ],
+[ 2785, "dca" ],
+[ 2786, "dcb" ],
+[ 2787, "dcc" ],
+[ 2788, "dcd" ],
+[ 2789, "dce" ],
+[ 2790, "dcf" ],
+[ 2791, "dcg" ],
+[ 2792, "dch" ],
+[ 2793, "dci" ],
+[ 2794, "dcj" ],
+[ 2795, "dck" ],
+[ 2796, "dcl" ],
+[ 2797, "dcm" ],
+[ 2798, "dcn" ],
+[ 2799, "dco" ],
+[ 2800, "dcp" ],
+[ 2801, "dcq" ],
+[ 2802, "dcr" ],
+[ 2803, "dcs" ],
+[ 2804, "dct" ],
+[ 2805, "dcu" ],
+[ 2806, "dcv" ],
+[ 2807, "dcw" ],
+[ 2808, "dcx" ],
+[ 2809, "dcy" ],
+[ 2810, "dcz" ],
+[ 2811, "dda" ],
+[ 2812, "ddb" ],
+[ 2813, "ddc" ],
+[ 2814, "ddd" ],
+[ 2815, "dde" ],
+[ 2816, "ddf" ],
+[ 2817, "ddg" ],
+[ 2818, "ddh" ],
+[ 2819, "ddi" ],
+[ 2820, "ddj" ],
+[ 2821, "ddk" ],
+[ 2822, "ddl" ],
+[ 2823, "ddm" ],
+[ 2824, "ddn" ],
+[ 2825, "ddo" ],
+[ 2826, "ddp" ],
+[ 2827, "ddq" ],
+[ 2828, "ddr" ],
+[ 2829, "dds" ],
+[ 2830, "ddt" ],
+[ 2831, "ddu" ],
+[ 2832, "ddv" ],
+[ 2833, "ddw" ],
+[ 2834, "ddx" ],
+[ 2835, "ddy" ],
+[ 2836, "ddz" ],
+[ 2837, "dea" ],
+[ 2838, "deb" ],
+[ 2839, "dec" ],
+[ 2840, "ded" ],
+[ 2841, "dee" ],
+[ 2842, "def" ],
+[ 2843, "deg" ],
+[ 2844, "deh" ],
+[ 2845, "dei" ],
+[ 2846, "dej" ],
+[ 2847, "dek" ],
+[ 2848, "del" ],
+[ 2849, "dem" ],
+[ 2850, "den" ],
+[ 2851, "deo" ],
+[ 2852, "dep" ],
+[ 2853, "deq" ],
+[ 2854, "der" ],
+[ 2855, "des" ],
+[ 2856, "det" ],
+[ 2857, "deu" ],
+[ 2858, "dev" ],
+[ 2859, "dew" ],
+[ 2860, "dex" ],
+[ 2861, "dey" ],
+[ 2862, "dez" ],
+[ 2863, "dfa" ],
+[ 2864, "dfb" ],
+[ 2865, "dfc" ],
+[ 2866, "dfd" ],
+[ 2867, "dfe" ],
+[ 2868, "dff" ],
+[ 2869, "dfg" ],
+[ 2870, "dfh" ],
+[ 2871, "dfi" ],
+[ 2872, "dfj" ],
+[ 2873, "dfk" ],
+[ 2874, "dfl" ],
+[ 2875, "dfm" ],
+[ 2876, "dfn" ],
+[ 2877, "dfo" ],
+[ 2878, "dfp" ],
+[ 2879, "dfq" ],
+[ 2880, "dfr" ],
+[ 2881, "dfs" ],
+[ 2882, "dft" ],
+[ 2883, "dfu" ],
+[ 2884, "dfv" ],
+[ 2885, "dfw" ],
+[ 2886, "dfx" ],
+[ 2887, "dfy" ],
+[ 2888, "dfz" ],
+[ 2889, "dga" ],
+[ 2890, "dgb" ],
+[ 2891, "dgc" ],
+[ 2892, "dgd" ],
+[ 2893, "dge" ],
+[ 2894, "dgf" ],
+[ 2895, "dgg" ],
+[ 2896, "dgh" ],
+[ 2897, "dgi" ],
+[ 2898, "dgj" ],
+[ 2899, "dgk" ],
+[ 2900, "dgl" ],
+[ 2901, "dgm" ],
+[ 2902, "dgn" ],
+[ 2903, "dgo" ],
+[ 2904, "dgp" ],
+[ 2905, "dgq" ],
+[ 2906, "dgr" ],
+[ 2907, "dgs" ],
+[ 2908, "dgt" ],
+[ 2909, "dgu" ],
+[ 2910, "dgv" ],
+[ 2911, "dgw" ],
+[ 2912, "dgx" ],
+[ 2913, "dgy" ],
+[ 2914, "dgz" ],
+[ 2915, "dha" ],
+[ 2916, "dhb" ],
+[ 2917, "dhc" ],
+[ 2918, "dhd" ],
+[ 2919, "dhe" ],
+[ 2920, "dhf" ],
+[ 2921, "dhg" ],
+[ 2922, "dhh" ],
+[ 2923, "dhi" ],
+[ 2924, "dhj" ],
+[ 2925, "dhk" ],
+[ 2926, "dhl" ],
+[ 2927, "dhm" ],
+[ 2928, "dhn" ],
+[ 2929, "dho" ],
+[ 2930, "dhp" ],
+[ 2931, "dhq" ],
+[ 2932, "dhr" ],
+[ 2933, "dhs" ],
+[ 2934, "dht" ],
+[ 2935, "dhu" ],
+[ 2936, "dhv" ],
+[ 2937, "dhw" ],
+[ 2938, "dhx" ],
+[ 2939, "dhy" ],
+[ 2940, "dhz" ],
+[ 2941, "dia" ],
+[ 2942, "dib" ],
+[ 2943, "dic" ],
+[ 2944, "did" ],
+[ 2945, "die" ],
+[ 2946, "dif" ],
+[ 2947, "dig" ],
+[ 2948, "dih" ],
+[ 2949, "dii" ],
+[ 2950, "dij" ],
+[ 2951, "dik" ],
+[ 2952, "dil" ],
+[ 2953, "dim" ],
+[ 2954, "din" ],
+[ 2955, "dio" ],
+[ 2956, "dip" ],
+[ 2957, "diq" ],
+[ 2958, "dir" ],
+[ 2959, "dis" ],
+[ 2960, "dit" ],
+[ 2961, "diu" ],
+[ 2962, "div" ],
+[ 2963, "diw" ],
+[ 2964, "dix" ],
+[ 2965, "diy" ],
+[ 2966, "diz" ],
+[ 2967, "dja" ],
+[ 2968, "djb" ],
+[ 2969, "djc" ],
+[ 2970, "djd" ],
+[ 2971, "dje" ],
+[ 2972, "djf" ],
+[ 2973, "djg" ],
+[ 2974, "djh" ],
+[ 2975, "dji" ],
+[ 2976, "djj" ],
+[ 2977, "djk" ],
+[ 2978, "djl" ],
+[ 2979, "djm" ],
+[ 2980, "djn" ],
+[ 2981, "djo" ],
+[ 2982, "djp" ],
+[ 2983, "djq" ],
+[ 2984, "djr" ],
+[ 2985, "djs" ],
+[ 2986, "djt" ],
+[ 2987, "dju" ],
+[ 2988, "djv" ],
+[ 2989, "djw" ],
+[ 2990, "djx" ],
+[ 2991, "djy" ],
+[ 2992, "djz" ],
+[ 2993, "dka" ],
+[ 2994, "dkb" ],
+[ 2995, "dkc" ],
+[ 2996, "dkd" ],
+[ 2997, "dke" ],
+[ 2998, "dkf" ],
+[ 2999, "dkg" ],
+[ 3000, "dkh" ],
+[ 3001, "dki" ],
+[ 3002, "dkj" ],
+[ 3003, "dkk" ],
+[ 3004, "dkl" ],
+[ 3005, "dkm" ],
+[ 3006, "dkn" ],
+[ 3007, "dko" ],
+[ 3008, "dkp" ],
+[ 3009, "dkq" ],
+[ 3010, "dkr" ],
+[ 3011, "dks" ],
+[ 3012, "dkt" ],
+[ 3013, "dku" ],
+[ 3014, "dkv" ],
+[ 3015, "dkw" ],
+[ 3016, "dkx" ],
+[ 3017, "dky" ],
+[ 3018, "dkz" ],
+[ 3019, "dla" ],
+[ 3020, "dlb" ],
+[ 3021, "dlc" ],
+[ 3022, "dld" ],
+[ 3023, "dle" ],
+[ 3024, "dlf" ],
+[ 3025, "dlg" ],
+[ 3026, "dlh" ],
+[ 3027, "dli" ],
+[ 3028, "dlj" ],
+[ 3029, "dlk" ],
+[ 3030, "dll" ],
+[ 3031, "dlm" ],
+[ 3032, "dln" ],
+[ 3033, "dlo" ],
+[ 3034, "dlp" ],
+[ 3035, "dlq" ],
+[ 3036, "dlr" ],
+[ 3037, "dls" ],
+[ 3038, "dlt" ],
+[ 3039, "dlu" ],
+[ 3040, "dlv" ],
+[ 3041, "dlw" ],
+[ 3042, "dlx" ],
+[ 3043, "dly" ],
+[ 3044, "dlz" ],
+[ 3045, "dma" ],
+[ 3046, "dmb" ],
+[ 3047, "dmc" ],
+[ 3048, "dmd" ],
+[ 3049, "dme" ],
+[ 3050, "dmf" ],
+[ 3051, "dmg" ],
+[ 3052, "dmh" ],
+[ 3053, "dmi" ],
+[ 3054, "dmj" ],
+[ 3055, "dmk" ],
+[ 3056, "dml" ],
+[ 3057, "dmm" ],
+[ 3058, "dmn" ],
+[ 3059, "dmo" ],
+[ 3060, "dmp" ],
+[ 3061, "dmq" ],
+[ 3062, "dmr" ],
+[ 3063, "dms" ],
+[ 3064, "dmt" ],
+[ 3065, "dmu" ],
+[ 3066, "dmv" ],
+[ 3067, "dmw" ],
+[ 3068, "dmx" ],
+[ 3069, "dmy" ],
+[ 3070, "dmz" ],
+[ 3071, "dna" ],
+[ 3072, "dnb" ],
+[ 3073, "dnc" ],
+[ 3074, "dnd" ],
+[ 3075, "dne" ],
+[ 3076, "dnf" ],
+[ 3077, "dng" ],
+[ 3078, "dnh" ],
+[ 3079, "dni" ],
+[ 3080, "dnj" ],
+[ 3081, "dnk" ],
+[ 3082, "dnl" ],
+[ 3083, "dnm" ],
+[ 3084, "dnn" ],
+[ 3085, "dno" ],
+[ 3086, "dnp" ],
+[ 3087, "dnq" ],
+[ 3088, "dnr" ],
+[ 3089, "dns" ],
+[ 3090, "dnt" ],
+[ 3091, "dnu" ],
+[ 3092, "dnv" ],
+[ 3093, "dnw" ],
+[ 3094, "dnx" ],
+[ 3095, "dny" ],
+[ 3096, "dnz" ],
+[ 3097, "doa" ],
+[ 3098, "dob" ],
+[ 3099, "doc" ],
+[ 3100, "dod" ],
+[ 3101, "doe" ],
+[ 3102, "dof" ],
+[ 3103, "dog" ],
+[ 3104, "doh" ],
+[ 3105, "doi" ],
+[ 3106, "doj" ],
+[ 3107, "dok" ],
+[ 3108, "dol" ],
+[ 3109, "dom" ],
+[ 3110, "don" ],
+[ 3111, "doo" ],
+[ 3112, "dop" ],
+[ 3113, "doq" ],
+[ 3114, "dor" ],
+[ 3115, "dos" ],
+[ 3116, "dot" ],
+[ 3117, "dou" ],
+[ 3118, "dov" ],
+[ 3119, "dow" ],
+[ 3120, "dox" ],
+[ 3121, "doy" ],
+[ 3122, "doz" ],
+[ 3123, "dpa" ],
+[ 3124, "dpb" ],
+[ 3125, "dpc" ],
+[ 3126, "dpd" ],
+[ 3127, "dpe" ],
+[ 3128, "dpf" ],
+[ 3129, "dpg" ],
+[ 3130, "dph" ],
+[ 3131, "dpi" ],
+[ 3132, "dpj" ],
+[ 3133, "dpk" ],
+[ 3134, "dpl" ],
+[ 3135, "dpm" ],
+[ 3136, "dpn" ],
+[ 3137, "dpo" ],
+[ 3138, "dpp" ],
+[ 3139, "dpq" ],
+[ 3140, "dpr" ],
+[ 3141, "dps" ],
+[ 3142, "dpt" ],
+[ 3143, "dpu" ],
+[ 3144, "dpv" ],
+[ 3145, "dpw" ],
+[ 3146, "dpx" ],
+[ 3147, "dpy" ],
+[ 3148, "dpz" ],
+[ 3149, "dqa" ],
+[ 3150, "dqb" ],
+[ 3151, "dqc" ],
+[ 3152, "dqd" ],
+[ 3153, "dqe" ],
+[ 3154, "dqf" ],
+[ 3155, "dqg" ],
+[ 3156, "dqh" ],
+[ 3157, "dqi" ],
+[ 3158, "dqj" ],
+[ 3159, "dqk" ],
+[ 3160, "dql" ],
+[ 3161, "dqm" ],
+[ 3162, "dqn" ],
+[ 3163, "dqo" ],
+[ 3164, "dqp" ],
+[ 3165, "dqq" ],
+[ 3166, "dqr" ],
+[ 3167, "dqs" ],
+[ 3168, "dqt" ],
+[ 3169, "dqu" ],
+[ 3170, "dqv" ],
+[ 3171, "dqw" ],
+[ 3172, "dqx" ],
+[ 3173, "dqy" ],
+[ 3174, "dqz" ],
+[ 3175, "dra" ],
+[ 3176, "drb" ],
+[ 3177, "drc" ],
+[ 3178, "drd" ],
+[ 3179, "dre" ],
+[ 3180, "drf" ],
+[ 3181, "drg" ],
+[ 3182, "drh" ],
+[ 3183, "dri" ],
+[ 3184, "drj" ],
+[ 3185, "drk" ],
+[ 3186, "drl" ],
+[ 3187, "drm" ],
+[ 3188, "drn" ],
+[ 3189, "dro" ],
+[ 3190, "drp" ],
+[ 3191, "drq" ],
+[ 3192, "drr" ],
+[ 3193, "drs" ],
+[ 3194, "drt" ],
+[ 3195, "dru" ],
+[ 3196, "drv" ],
+[ 3197, "drw" ],
+[ 3198, "drx" ],
+[ 3199, "dry" ],
+[ 3200, "drz" ],
+[ 3201, "dsa" ],
+[ 3202, "dsb" ],
+[ 3203, "dsc" ],
+[ 3204, "dsd" ],
+[ 3205, "dse" ],
+[ 3206, "dsf" ],
+[ 3207, "dsg" ],
+[ 3208, "dsh" ],
+[ 3209, "dsi" ],
+[ 3210, "dsj" ],
+[ 3211, "dsk" ],
+[ 3212, "dsl" ],
+[ 3213, "dsm" ],
+[ 3214, "dsn" ],
+[ 3215, "dso" ],
+[ 3216, "dsp" ],
+[ 3217, "dsq" ],
+[ 3218, "dsr" ],
+[ 3219, "dss" ],
+[ 3220, "dst" ],
+[ 3221, "dsu" ],
+[ 3222, "dsv" ],
+[ 3223, "dsw" ],
+[ 3224, "dsx" ],
+[ 3225, "dsy" ],
+[ 3226, "dsz" ],
+[ 3227, "dta" ],
+[ 3228, "dtb" ],
+[ 3229, "dtc" ],
+[ 3230, "dtd" ],
+[ 3231, "dte" ],
+[ 3232, "dtf" ],
+[ 3233, "dtg" ],
+[ 3234, "dth" ],
+[ 3235, "dti" ],
+[ 3236, "dtj" ],
+[ 3237, "dtk" ],
+[ 3238, "dtl" ],
+[ 3239, "dtm" ],
+[ 3240, "dtn" ],
+[ 3241, "dto" ],
+[ 3242, "dtp" ],
+[ 3243, "dtq" ],
+[ 3244, "dtr" ],
+[ 3245, "dts" ],
+[ 3246, "dtt" ],
+[ 3247, "dtu" ],
+[ 3248, "dtv" ],
+[ 3249, "dtw" ],
+[ 3250, "dtx" ],
+[ 3251, "dty" ],
+[ 3252, "dtz" ],
+[ 3253, "dua" ],
+[ 3254, "dub" ],
+[ 3255, "duc" ],
+[ 3256, "dud" ],
+[ 3257, "due" ],
+[ 3258, "duf" ],
+[ 3259, "dug" ],
+[ 3260, "duh" ],
+[ 3261, "dui" ],
+[ 3262, "duj" ],
+[ 3263, "duk" ],
+[ 3264, "dul" ],
+[ 3265, "dum" ],
+[ 3266, "dun" ],
+[ 3267, "duo" ],
+[ 3268, "dup" ],
+[ 3269, "duq" ],
+[ 3270, "dur" ],
+[ 3271, "dus" ],
+[ 3272, "dut" ],
+[ 3273, "duu" ],
+[ 3274, "duv" ],
+[ 3275, "duw" ],
+[ 3276, "dux" ],
+[ 3277, "duy" ],
+[ 3278, "duz" ],
+[ 3279, "dva" ],
+[ 3280, "dvb" ],
+[ 3281, "dvc" ],
+[ 3282, "dvd" ],
+[ 3283, "dve" ],
+[ 3284, "dvf" ],
+[ 3285, "dvg" ],
+[ 3286, "dvh" ],
+[ 3287, "dvi" ],
+[ 3288, "dvj" ],
+[ 3289, "dvk" ],
+[ 3290, "dvl" ],
+[ 3291, "dvm" ],
+[ 3292, "dvn" ],
+[ 3293, "dvo" ],
+[ 3294, "dvp" ],
+[ 3295, "dvq" ],
+[ 3296, "dvr" ],
+[ 3297, "dvs" ],
+[ 3298, "dvt" ],
+[ 3299, "dvu" ],
+[ 3300, "dvv" ],
+[ 3301, "dvw" ],
+[ 3302, "dvx" ],
+[ 3303, "dvy" ],
+[ 3304, "dvz" ],
+[ 3305, "dwa" ],
+[ 3306, "dwb" ],
+[ 3307, "dwc" ],
+[ 3308, "dwd" ],
+[ 3309, "dwe" ],
+[ 3310, "dwf" ],
+[ 3311, "dwg" ],
+[ 3312, "dwh" ],
+[ 3313, "dwi" ],
+[ 3314, "dwj" ],
+[ 3315, "dwk" ],
+[ 3316, "dwl" ],
+[ 3317, "dwm" ],
+[ 3318, "dwn" ],
+[ 3319, "dwo" ],
+[ 3320, "dwp" ],
+[ 3321, "dwq" ],
+[ 3322, "dwr" ],
+[ 3323, "dws" ],
+[ 3324, "dwt" ],
+[ 3325, "dwu" ],
+[ 3326, "dwv" ],
+[ 3327, "dww" ],
+[ 3328, "dwx" ],
+[ 3329, "dwy" ],
+[ 3330, "dwz" ],
+[ 3331, "dxa" ],
+[ 3332, "dxb" ],
+[ 3333, "dxc" ],
+[ 3334, "dxd" ],
+[ 3335, "dxe" ],
+[ 3336, "dxf" ],
+[ 3337, "dxg" ],
+[ 3338, "dxh" ],
+[ 3339, "dxi" ],
+[ 3340, "dxj" ],
+[ 3341, "dxk" ],
+[ 3342, "dxl" ],
+[ 3343, "dxm" ],
+[ 3344, "dxn" ],
+[ 3345, "dxo" ],
+[ 3346, "dxp" ],
+[ 3347, "dxq" ],
+[ 3348, "dxr" ],
+[ 3349, "dxs" ],
+[ 3350, "dxt" ],
+[ 3351, "dxu" ],
+[ 3352, "dxv" ],
+[ 3353, "dxw" ],
+[ 3354, "dxx" ],
+[ 3355, "dxy" ],
+[ 3356, "dxz" ],
+[ 3357, "dya" ],
+[ 3358, "dyb" ],
+[ 3359, "dyc" ],
+[ 3360, "dyd" ],
+[ 3361, "dye" ],
+[ 3362, "dyf" ],
+[ 3363, "dyg" ],
+[ 3364, "dyh" ],
+[ 3365, "dyi" ],
+[ 3366, "dyj" ],
+[ 3367, "dyk" ],
+[ 3368, "dyl" ],
+[ 3369, "dym" ],
+[ 3370, "dyn" ],
+[ 3371, "dyo" ],
+[ 3372, "dyp" ],
+[ 3373, "dyq" ],
+[ 3374, "dyr" ],
+[ 3375, "dys" ],
+[ 3376, "dyt" ],
+[ 3377, "dyu" ],
+[ 3378, "dyv" ],
+[ 3379, "dyw" ],
+[ 3380, "dyx" ],
+[ 3381, "dyy" ],
+[ 3382, "dyz" ],
+[ 3383, "dza" ],
+[ 3384, "dzb" ],
+[ 3385, "dzc" ],
+[ 3386, "dzd" ],
+[ 3387, "dze" ],
+[ 3388, "dzf" ],
+[ 3389, "dzg" ],
+[ 3390, "dzh" ],
+[ 3391, "dzi" ],
+[ 3392, "dzj" ],
+[ 3393, "dzk" ],
+[ 3394, "dzl" ],
+[ 3395, "dzm" ],
+[ 3396, "dzn" ],
+[ 3397, "dzo" ],
+[ 3398, "dzp" ],
+[ 3399, "dzq" ],
+[ 3400, "dzr" ],
+[ 3401, "dzs" ],
+[ 3402, "dzt" ],
+[ 3403, "dzu" ],
+[ 3404, "dzv" ],
+[ 3405, "dzw" ],
+[ 3406, "dzx" ],
+[ 3407, "dzy" ],
+[ 3408, "dzz" ],
+[ 3409, "eaa" ],
+[ 3410, "eab" ],
+[ 3411, "eac" ],
+[ 3412, "ead" ],
+[ 3413, "eae" ],
+[ 3414, "eaf" ],
+[ 3415, "eag" ],
+[ 3416, "eah" ],
+[ 3417, "eai" ],
+[ 3418, "eaj" ],
+[ 3419, "eak" ],
+[ 3420, "eal" ],
+[ 3421, "eam" ],
+[ 3422, "ean" ],
+[ 3423, "eao" ],
+[ 3424, "eap" ],
+[ 3425, "eaq" ],
+[ 3426, "ear" ],
+[ 3427, "eas" ],
+[ 3428, "eat" ],
+[ 3429, "eau" ],
+[ 3430, "eav" ],
+[ 3431, "eaw" ],
+[ 3432, "eax" ],
+[ 3433, "eay" ],
+[ 3434, "eaz" ],
+[ 3435, "eba" ],
+[ 3436, "ebb" ],
+[ 3437, "ebc" ],
+[ 3438, "ebd" ],
+[ 3439, "ebe" ],
+[ 3440, "ebf" ],
+[ 3441, "ebg" ],
+[ 3442, "ebh" ],
+[ 3443, "ebi" ],
+[ 3444, "ebj" ],
+[ 3445, "ebk" ],
+[ 3446, "ebl" ],
+[ 3447, "ebm" ],
+[ 3448, "ebn" ],
+[ 3449, "ebo" ],
+[ 3450, "ebp" ],
+[ 3451, "ebq" ],
+[ 3452, "ebr" ],
+[ 3453, "ebs" ],
+[ 3454, "ebt" ],
+[ 3455, "ebu" ],
+[ 3456, "ebv" ],
+[ 3457, "ebw" ],
+[ 3458, "ebx" ],
+[ 3459, "eby" ],
+[ 3460, "ebz" ],
+[ 3461, "eca" ],
+[ 3462, "ecb" ],
+[ 3463, "ecc" ],
+[ 3464, "ecd" ],
+[ 3465, "ece" ],
+[ 3466, "ecf" ],
+[ 3467, "ecg" ],
+[ 3468, "ech" ],
+[ 3469, "eci" ],
+[ 3470, "ecj" ],
+[ 3471, "eck" ],
+[ 3472, "ecl" ],
+[ 3473, "ecm" ],
+[ 3474, "ecn" ],
+[ 3475, "eco" ],
+[ 3476, "ecp" ],
+[ 3477, "ecq" ],
+[ 3478, "ecr" ],
+[ 3479, "ecs" ],
+[ 3480, "ect" ],
+[ 3481, "ecu" ],
+[ 3482, "ecv" ],
+[ 3483, "ecw" ],
+[ 3484, "ecx" ],
+[ 3485, "ecy" ],
+[ 3486, "ecz" ],
+[ 3487, "eda" ],
+[ 3488, "edb" ],
+[ 3489, "edc" ],
+[ 3490, "edd" ],
+[ 3491, "ede" ],
+[ 3492, "edf" ],
+[ 3493, "edg" ],
+[ 3494, "edh" ],
+[ 3495, "edi" ],
+[ 3496, "edj" ],
+[ 3497, "edk" ],
+[ 3498, "edl" ],
+[ 3499, "edm" ],
+[ 3500, "edn" ],
+[ 3501, "edo" ],
+[ 3502, "edp" ],
+[ 3503, "edq" ],
+[ 3504, "edr" ],
+[ 3505, "eds" ],
+[ 3506, "edt" ],
+[ 3507, "edu" ],
+[ 3508, "edv" ],
+[ 3509, "edw" ],
+[ 3510, "edx" ],
+[ 3511, "edy" ],
+[ 3512, "edz" ],
+[ 3513, "eea" ],
+[ 3514, "eeb" ],
+[ 3515, "eec" ],
+[ 3516, "eed" ],
+[ 3517, "eee" ],
+[ 3518, "eef" ],
+[ 3519, "eeg" ],
+[ 3520, "eeh" ],
+[ 3521, "eei" ],
+[ 3522, "eej" ],
+[ 3523, "eek" ],
+[ 3524, "eel" ],
+[ 3525, "eem" ],
+[ 3526, "een" ],
+[ 3527, "eeo" ],
+[ 3528, "eep" ],
+[ 3529, "eeq" ],
+[ 3530, "eer" ],
+[ 3531, "ees" ],
+[ 3532, "eet" ],
+[ 3533, "eeu" ],
+[ 3534, "eev" ],
+[ 3535, "eew" ],
+[ 3536, "eex" ],
+[ 3537, "eey" ],
+[ 3538, "eez" ],
+[ 3539, "efa" ],
+[ 3540, "efb" ],
+[ 3541, "efc" ],
+[ 3542, "efd" ],
+[ 3543, "efe" ],
+[ 3544, "eff" ],
+[ 3545, "efg" ],
+[ 3546, "efh" ],
+[ 3547, "efi" ],
+[ 3548, "efj" ],
+[ 3549, "efk" ],
+[ 3550, "efl" ],
+[ 3551, "efm" ],
+[ 3552, "efn" ],
+[ 3553, "efo" ],
+[ 3554, "efp" ],
+[ 3555, "efq" ],
+[ 3556, "efr" ],
+[ 3557, "efs" ],
+[ 3558, "eft" ],
+[ 3559, "efu" ],
+[ 3560, "efv" ],
+[ 3561, "efw" ],
+[ 3562, "efx" ],
+[ 3563, "efy" ],
+[ 3564, "efz" ],
+[ 3565, "ega" ],
+[ 3566, "egb" ],
+[ 3567, "egc" ],
+[ 3568, "egd" ],
+[ 3569, "ege" ],
+[ 3570, "egf" ],
+[ 3571, "egg" ],
+[ 3572, "egh" ],
+[ 3573, "egi" ],
+[ 3574, "egj" ],
+[ 3575, "egk" ],
+[ 3576, "egl" ],
+[ 3577, "egm" ],
+[ 3578, "egn" ],
+[ 3579, "ego" ],
+[ 3580, "egp" ],
+[ 3581, "egq" ],
+[ 3582, "egr" ],
+[ 3583, "egs" ],
+[ 3584, "egt" ],
+[ 3585, "egu" ],
+[ 3586, "egv" ],
+[ 3587, "egw" ],
+[ 3588, "egx" ],
+[ 3589, "egy" ],
+[ 3590, "egz" ],
+[ 3591, "eha" ],
+[ 3592, "ehb" ],
+[ 3593, "ehc" ],
+[ 3594, "ehd" ],
+[ 3595, "ehe" ],
+[ 3596, "ehf" ],
+[ 3597, "ehg" ],
+[ 3598, "ehh" ],
+[ 3599, "ehi" ],
+[ 3600, "ehj" ],
+[ 3601, "ehk" ],
+[ 3602, "ehl" ],
+[ 3603, "ehm" ],
+[ 3604, "ehn" ],
+[ 3605, "eho" ],
+[ 3606, "ehp" ],
+[ 3607, "ehq" ],
+[ 3608, "ehr" ],
+[ 3609, "ehs" ],
+[ 3610, "eht" ],
+[ 3611, "ehu" ],
+[ 3612, "ehv" ],
+[ 3613, "ehw" ],
+[ 3614, "ehx" ],
+[ 3615, "ehy" ],
+[ 3616, "ehz" ],
+[ 3617, "eia" ],
+[ 3618, "eib" ],
+[ 3619, "eic" ],
+[ 3620, "eid" ],
+[ 3621, "eie" ],
+[ 3622, "eif" ],
+[ 3623, "eig" ],
+[ 3624, "eih" ],
+[ 3625, "eii" ],
+[ 3626, "eij" ],
+[ 3627, "eik" ],
+[ 3628, "eil" ],
+[ 3629, "eim" ],
+[ 3630, "ein" ],
+[ 3631, "eio" ],
+[ 3632, "eip" ],
+[ 3633, "eiq" ],
+[ 3634, "eir" ],
+[ 3635, "eis" ],
+[ 3636, "eit" ],
+[ 3637, "eiu" ],
+[ 3638, "eiv" ],
+[ 3639, "eiw" ],
+[ 3640, "eix" ],
+[ 3641, "eiy" ],
+[ 3642, "eiz" ],
+[ 3643, "eja" ],
+[ 3644, "ejb" ],
+[ 3645, "ejc" ],
+[ 3646, "ejd" ],
+[ 3647, "eje" ],
+[ 3648, "ejf" ],
+[ 3649, "ejg" ],
+[ 3650, "ejh" ],
+[ 3651, "eji" ],
+[ 3652, "ejj" ],
+[ 3653, "ejk" ],
+[ 3654, "ejl" ],
+[ 3655, "ejm" ],
+[ 3656, "ejn" ],
+[ 3657, "ejo" ],
+[ 3658, "ejp" ],
+[ 3659, "ejq" ],
+[ 3660, "ejr" ],
+[ 3661, "ejs" ],
+[ 3662, "ejt" ],
+[ 3663, "eju" ],
+[ 3664, "ejv" ],
+[ 3665, "ejw" ],
+[ 3666, "ejx" ],
+[ 3667, "ejy" ],
+[ 3668, "ejz" ],
+[ 3669, "eka" ],
+[ 3670, "ekb" ],
+[ 3671, "ekc" ],
+[ 3672, "ekd" ],
+[ 3673, "eke" ],
+[ 3674, "ekf" ],
+[ 3675, "ekg" ],
+[ 3676, "ekh" ],
+[ 3677, "eki" ],
+[ 3678, "ekj" ],
+[ 3679, "ekk" ],
+[ 3680, "ekl" ],
+[ 3681, "ekm" ],
+[ 3682, "ekn" ],
+[ 3683, "eko" ],
+[ 3684, "ekp" ],
+[ 3685, "ekq" ],
+[ 3686, "ekr" ],
+[ 3687, "eks" ],
+[ 3688, "ekt" ],
+[ 3689, "eku" ],
+[ 3690, "ekv" ],
+[ 3691, "ekw" ],
+[ 3692, "ekx" ],
+[ 3693, "eky" ],
+[ 3694, "ekz" ],
+[ 3695, "ela" ],
+[ 3696, "elb" ],
+[ 3697, "elc" ],
+[ 3698, "eld" ],
+[ 3699, "ele" ],
+[ 3700, "elf" ],
+[ 3701, "elg" ],
+[ 3702, "elh" ],
+[ 3703, "eli" ],
+[ 3704, "elj" ],
+[ 3705, "elk" ],
+[ 3706, "ell" ],
+[ 3707, "elm" ],
+[ 3708, "eln" ],
+[ 3709, "elo" ],
+[ 3710, "elp" ],
+[ 3711, "elq" ],
+[ 3712, "elr" ],
+[ 3713, "els" ],
+[ 3714, "elt" ],
+[ 3715, "elu" ],
+[ 3716, "elv" ],
+[ 3717, "elw" ],
+[ 3718, "elx" ],
+[ 3719, "ely" ],
+[ 3720, "elz" ],
+[ 3721, "ema" ],
+[ 3722, "emb" ],
+[ 3723, "emc" ],
+[ 3724, "emd" ],
+[ 3725, "eme" ],
+[ 3726, "emf" ],
+[ 3727, "emg" ],
+[ 3728, "emh" ],
+[ 3729, "emi" ],
+[ 3730, "emj" ],
+[ 3731, "emk" ],
+[ 3732, "eml" ],
+[ 3733, "emm" ],
+[ 3734, "emn" ],
+[ 3735, "emo" ],
+[ 3736, "emp" ],
+[ 3737, "emq" ],
+[ 3738, "emr" ],
+[ 3739, "ems" ],
+[ 3740, "emt" ],
+[ 3741, "emu" ],
+[ 3742, "emv" ],
+[ 3743, "emw" ],
+[ 3744, "emx" ],
+[ 3745, "emy" ],
+[ 3746, "emz" ],
+[ 3747, "ena" ],
+[ 3748, "enb" ],
+[ 3749, "enc" ],
+[ 3750, "end" ],
+[ 3751, "ene" ],
+[ 3752, "enf" ],
+[ 3753, "eng" ],
+[ 3754, "enh" ],
+[ 3755, "eni" ],
+[ 3756, "enj" ],
+[ 3757, "enk" ],
+[ 3758, "enl" ],
+[ 3759, "enm" ],
+[ 3760, "enn" ],
+[ 3761, "eno" ],
+[ 3762, "enp" ],
+[ 3763, "enq" ],
+[ 3764, "enr" ],
+[ 3765, "ens" ],
+[ 3766, "ent" ],
+[ 3767, "enu" ],
+[ 3768, "env" ],
+[ 3769, "enw" ],
+[ 3770, "enx" ],
+[ 3771, "eny" ],
+[ 3772, "enz" ],
+[ 3773, "eoa" ],
+[ 3774, "eob" ],
+[ 3775, "eoc" ],
+[ 3776, "eod" ],
+[ 3777, "eoe" ],
+[ 3778, "eof" ],
+[ 3779, "eog" ],
+[ 3780, "eoh" ],
+[ 3781, "eoi" ],
+[ 3782, "eoj" ],
+[ 3783, "eok" ],
+[ 3784, "eol" ],
+[ 3785, "eom" ],
+[ 3786, "eon" ],
+[ 3787, "eoo" ],
+[ 3788, "eop" ],
+[ 3789, "eoq" ],
+[ 3790, "eor" ],
+[ 3791, "eos" ],
+[ 3792, "eot" ],
+[ 3793, "eou" ],
+[ 3794, "eov" ],
+[ 3795, "eow" ],
+[ 3796, "eox" ],
+[ 3797, "eoy" ],
+[ 3798, "eoz" ],
+[ 3799, "epa" ],
+[ 3800, "epb" ],
+[ 3801, "epc" ],
+[ 3802, "epd" ],
+[ 3803, "epe" ],
+[ 3804, "epf" ],
+[ 3805, "epg" ],
+[ 3806, "eph" ],
+[ 3807, "epi" ],
+[ 3808, "epj" ],
+[ 3809, "epk" ],
+[ 3810, "epl" ],
+[ 3811, "epm" ],
+[ 3812, "epn" ],
+[ 3813, "epo" ],
+[ 3814, "epp" ],
+[ 3815, "epq" ],
+[ 3816, "epr" ],
+[ 3817, "eps" ],
+[ 3818, "ept" ],
+[ 3819, "epu" ],
+[ 3820, "epv" ],
+[ 3821, "epw" ],
+[ 3822, "epx" ],
+[ 3823, "epy" ],
+[ 3824, "epz" ],
+[ 3825, "eqa" ],
+[ 3826, "eqb" ],
+[ 3827, "eqc" ],
+[ 3828, "eqd" ],
+[ 3829, "eqe" ],
+[ 3830, "eqf" ],
+[ 3831, "eqg" ],
+[ 3832, "eqh" ],
+[ 3833, "eqi" ],
+[ 3834, "eqj" ],
+[ 3835, "eqk" ],
+[ 3836, "eql" ],
+[ 3837, "eqm" ],
+[ 3838, "eqn" ],
+[ 3839, "eqo" ],
+[ 3840, "eqp" ],
+[ 3841, "eqq" ],
+[ 3842, "eqr" ],
+[ 3843, "eqs" ],
+[ 3844, "eqt" ],
+[ 3845, "equ" ],
+[ 3846, "eqv" ],
+[ 3847, "eqw" ],
+[ 3848, "eqx" ],
+[ 3849, "eqy" ],
+[ 3850, "eqz" ],
+[ 3851, "era" ],
+[ 3852, "erb" ],
+[ 3853, "erc" ],
+[ 3854, "erd" ],
+[ 3855, "ere" ],
+[ 3856, "erf" ],
+[ 3857, "erg" ],
+[ 3858, "erh" ],
+[ 3859, "eri" ],
+[ 3860, "erj" ],
+[ 3861, "erk" ],
+[ 3862, "erl" ],
+[ 3863, "erm" ],
+[ 3864, "ern" ],
+[ 3865, "ero" ],
+[ 3866, "erp" ],
+[ 3867, "erq" ],
+[ 3868, "err" ],
+[ 3869, "ers" ],
+[ 3870, "ert" ],
+[ 3871, "eru" ],
+[ 3872, "erv" ],
+[ 3873, "erw" ],
+[ 3874, "erx" ],
+[ 3875, "ery" ],
+[ 3876, "erz" ],
+[ 3877, "esa" ],
+[ 3878, "esb" ],
+[ 3879, "esc" ],
+[ 3880, "esd" ],
+[ 3881, "ese" ],
+[ 3882, "esf" ],
+[ 3883, "esg" ],
+[ 3884, "esh" ],
+[ 3885, "esi" ],
+[ 3886, "esj" ],
+[ 3887, "esk" ],
+[ 3888, "esl" ],
+[ 3889, "esm" ],
+[ 3890, "esn" ],
+[ 3891, "eso" ],
+[ 3892, "esp" ],
+[ 3893, "esq" ],
+[ 3894, "esr" ],
+[ 3895, "ess" ],
+[ 3896, "est" ],
+[ 3897, "esu" ],
+[ 3898, "esv" ],
+[ 3899, "esw" ],
+[ 3900, "esx" ],
+[ 3901, "esy" ],
+[ 3902, "esz" ],
+[ 3903, "eta" ],
+[ 3904, "etb" ],
+[ 3905, "etc" ],
+[ 3906, "etd" ],
+[ 3907, "ete" ],
+[ 3908, "etf" ],
+[ 3909, "etg" ],
+[ 3910, "eth" ],
+[ 3911, "eti" ],
+[ 3912, "etj" ],
+[ 3913, "etk" ],
+[ 3914, "etl" ],
+[ 3915, "etm" ],
+[ 3916, "etn" ],
+[ 3917, "eto" ],
+[ 3918, "etp" ],
+[ 3919, "etq" ],
+[ 3920, "etr" ],
+[ 3921, "ets" ],
+[ 3922, "ett" ],
+[ 3923, "etu" ],
+[ 3924, "etv" ],
+[ 3925, "etw" ],
+[ 3926, "etx" ],
+[ 3927, "ety" ],
+[ 3928, "etz" ],
+[ 3929, "eua" ],
+[ 3930, "eub" ],
+[ 3931, "euc" ],
+[ 3932, "eud" ],
+[ 3933, "eue" ],
+[ 3934, "euf" ],
+[ 3935, "eug" ],
+[ 3936, "euh" ],
+[ 3937, "eui" ],
+[ 3938, "euj" ],
+[ 3939, "euk" ],
+[ 3940, "eul" ],
+[ 3941, "eum" ],
+[ 3942, "eun" ],
+[ 3943, "euo" ],
+[ 3944, "eup" ],
+[ 3945, "euq" ],
+[ 3946, "eur" ],
+[ 3947, "eus" ],
+[ 3948, "eut" ],
+[ 3949, "euu" ],
+[ 3950, "euv" ],
+[ 3951, "euw" ],
+[ 3952, "eux" ],
+[ 3953, "euy" ],
+[ 3954, "euz" ],
+[ 3955, "eva" ],
+[ 3956, "evb" ],
+[ 3957, "evc" ],
+[ 3958, "evd" ],
+[ 3959, "eve" ],
+[ 3960, "evf" ],
+[ 3961, "evg" ],
+[ 3962, "evh" ],
+[ 3963, "evi" ],
+[ 3964, "evj" ],
+[ 3965, "evk" ],
+[ 3966, "evl" ],
+[ 3967, "evm" ],
+[ 3968, "evn" ],
+[ 3969, "evo" ],
+[ 3970, "evp" ],
+[ 3971, "evq" ],
+[ 3972, "evr" ],
+[ 3973, "evs" ],
+[ 3974, "evt" ],
+[ 3975, "evu" ],
+[ 3976, "evv" ],
+[ 3977, "evw" ],
+[ 3978, "evx" ],
+[ 3979, "evy" ],
+[ 3980, "evz" ],
+[ 3981, "ewa" ],
+[ 3982, "ewb" ],
+[ 3983, "ewc" ],
+[ 3984, "ewd" ],
+[ 3985, "ewe" ],
+[ 3986, "ewf" ],
+[ 3987, "ewg" ],
+[ 3988, "ewh" ],
+[ 3989, "ewi" ],
+[ 3990, "ewj" ],
+[ 3991, "ewk" ],
+[ 3992, "ewl" ],
+[ 3993, "ewm" ],
+[ 3994, "ewn" ],
+[ 3995, "ewo" ],
+[ 3996, "ewp" ],
+[ 3997, "ewq" ],
+[ 3998, "ewr" ],
+[ 3999, "ews" ],
+[ 4000, "ewt" ],
+[ 4001, "ewu" ],
+[ 4002, "ewv" ],
+[ 4003, "eww" ],
+[ 4004, "ewx" ],
+[ 4005, "ewy" ],
+[ 4006, "ewz" ],
+[ 4007, "exa" ],
+[ 4008, "exb" ],
+[ 4009, "exc" ],
+[ 4010, "exd" ],
+[ 4011, "exe" ],
+[ 4012, "exf" ],
+[ 4013, "exg" ],
+[ 4014, "exh" ],
+[ 4015, "exi" ],
+[ 4016, "exj" ],
+[ 4017, "exk" ],
+[ 4018, "exl" ],
+[ 4019, "exm" ],
+[ 4020, "exn" ],
+[ 4021, "exo" ],
+[ 4022, "exp" ],
+[ 4023, "exq" ],
+[ 4024, "exr" ],
+[ 4025, "exs" ],
+[ 4026, "ext" ],
+[ 4027, "exu" ],
+[ 4028, "exv" ],
+[ 4029, "exw" ],
+[ 4030, "exx" ],
+[ 4031, "exy" ],
+[ 4032, "exz" ],
+[ 4033, "eya" ],
+[ 4034, "eyb" ],
+[ 4035, "eyc" ],
+[ 4036, "eyd" ],
+[ 4037, "eye" ],
+[ 4038, "eyf" ],
+[ 4039, "eyg" ],
+[ 4040, "eyh" ],
+[ 4041, "eyi" ],
+[ 4042, "eyj" ],
+[ 4043, "eyk" ],
+[ 4044, "eyl" ],
+[ 4045, "eym" ],
+[ 4046, "eyn" ],
+[ 4047, "eyo" ],
+[ 4048, "eyp" ],
+[ 4049, "eyq" ],
+[ 4050, "eyr" ],
+[ 4051, "eys" ],
+[ 4052, "eyt" ],
+[ 4053, "eyu" ],
+[ 4054, "eyv" ],
+[ 4055, "eyw" ],
+[ 4056, "eyx" ],
+[ 4057, "eyy" ],
+[ 4058, "eyz" ],
+[ 4059, "eza" ],
+[ 4060, "ezb" ],
+[ 4061, "ezc" ],
+[ 4062, "ezd" ],
+[ 4063, "eze" ],
+[ 4064, "ezf" ],
+[ 4065, "ezg" ],
+[ 4066, "ezh" ],
+[ 4067, "ezi" ],
+[ 4068, "ezj" ],
+[ 4069, "ezk" ],
+[ 4070, "ezl" ],
+[ 4071, "ezm" ],
+[ 4072, "ezn" ],
+[ 4073, "ezo" ],
+[ 4074, "ezp" ],
+[ 4075, "ezq" ],
+[ 4076, "ezr" ],
+[ 4077, "ezs" ],
+[ 4078, "ezt" ],
+[ 4079, "ezu" ],
+[ 4080, "ezv" ],
+[ 4081, "ezw" ],
+[ 4082, "ezx" ],
+[ 4083, "ezy" ],
+[ 4084, "ezz" ],
+[ 4085, "faa" ],
+[ 4086, "fab" ],
+[ 4087, "fac" ],
+[ 4088, "fad" ],
+[ 4089, "fae" ],
+[ 4090, "faf" ],
+[ 4091, "fag" ],
+[ 4092, "fah" ],
+[ 4093, "fai" ],
+[ 4094, "faj" ],
+[ 4095, "fak" ],
+[ 4096, "fal" ],
+[ 4097, "fam" ],
+[ 4098, "fan" ],
+[ 4099, "fao" ],
+[ 4100, "fap" ],
+[ 4101, "faq" ],
+[ 4102, "far" ],
+[ 4103, "fas" ],
+[ 4104, "fat" ],
+[ 4105, "fau" ],
+[ 4106, "fav" ],
+[ 4107, "faw" ],
+[ 4108, "fax" ],
+[ 4109, "fay" ],
+[ 4110, "faz" ],
+[ 4111, "fba" ],
+[ 4112, "fbb" ],
+[ 4113, "fbc" ],
+[ 4114, "fbd" ],
+[ 4115, "fbe" ],
+[ 4116, "fbf" ],
+[ 4117, "fbg" ],
+[ 4118, "fbh" ],
+[ 4119, "fbi" ],
+[ 4120, "fbj" ],
+[ 4121, "fbk" ],
+[ 4122, "fbl" ],
+[ 4123, "fbm" ],
+[ 4124, "fbn" ],
+[ 4125, "fbo" ],
+[ 4126, "fbp" ],
+[ 4127, "fbq" ],
+[ 4128, "fbr" ],
+[ 4129, "fbs" ],
+[ 4130, "fbt" ],
+[ 4131, "fbu" ],
+[ 4132, "fbv" ],
+[ 4133, "fbw" ],
+[ 4134, "fbx" ],
+[ 4135, "fby" ],
+[ 4136, "fbz" ],
+[ 4137, "fca" ],
+[ 4138, "fcb" ],
+[ 4139, "fcc" ],
+[ 4140, "fcd" ],
+[ 4141, "fce" ],
+[ 4142, "fcf" ],
+[ 4143, "fcg" ],
+[ 4144, "fch" ],
+[ 4145, "fci" ],
+[ 4146, "fcj" ],
+[ 4147, "fck" ],
+[ 4148, "fcl" ],
+[ 4149, "fcm" ],
+[ 4150, "fcn" ],
+[ 4151, "fco" ],
+[ 4152, "fcp" ],
+[ 4153, "fcq" ],
+[ 4154, "fcr" ],
+[ 4155, "fcs" ],
+[ 4156, "fct" ],
+[ 4157, "fcu" ],
+[ 4158, "fcv" ],
+[ 4159, "fcw" ],
+[ 4160, "fcx" ],
+[ 4161, "fcy" ],
+[ 4162, "fcz" ],
+[ 4163, "fda" ],
+[ 4164, "fdb" ],
+[ 4165, "fdc" ],
+[ 4166, "fdd" ],
+[ 4167, "fde" ],
+[ 4168, "fdf" ],
+[ 4169, "fdg" ],
+[ 4170, "fdh" ],
+[ 4171, "fdi" ],
+[ 4172, "fdj" ],
+[ 4173, "fdk" ],
+[ 4174, "fdl" ],
+[ 4175, "fdm" ],
+[ 4176, "fdn" ],
+[ 4177, "fdo" ],
+[ 4178, "fdp" ],
+[ 4179, "fdq" ],
+[ 4180, "fdr" ],
+[ 4181, "fds" ],
+[ 4182, "fdt" ],
+[ 4183, "fdu" ],
+[ 4184, "fdv" ],
+[ 4185, "fdw" ],
+[ 4186, "fdx" ],
+[ 4187, "fdy" ],
+[ 4188, "fdz" ],
+[ 4189, "fea" ],
+[ 4190, "feb" ],
+[ 4191, "fec" ],
+[ 4192, "fed" ],
+[ 4193, "fee" ],
+[ 4194, "fef" ],
+[ 4195, "feg" ],
+[ 4196, "feh" ],
+[ 4197, "fei" ],
+[ 4198, "fej" ],
+[ 4199, "fek" ],
+[ 4200, "fel" ],
+[ 4201, "fem" ],
+[ 4202, "fen" ],
+[ 4203, "feo" ],
+[ 4204, "fep" ],
+[ 4205, "feq" ],
+[ 4206, "fer" ],
+[ 4207, "fes" ],
+[ 4208, "fet" ],
+[ 4209, "feu" ],
+[ 4210, "fev" ],
+[ 4211, "few" ],
+[ 4212, "fex" ],
+[ 4213, "fey" ],
+[ 4214, "fez" ],
+[ 4215, "ffa" ],
+[ 4216, "ffb" ],
+[ 4217, "ffc" ],
+[ 4218, "ffd" ],
+[ 4219, "ffe" ],
+[ 4220, "fff" ],
+[ 4221, "ffg" ],
+[ 4222, "ffh" ],
+[ 4223, "ffi" ],
+[ 4224, "ffj" ],
+[ 4225, "ffk" ],
+[ 4226, "ffl" ],
+[ 4227, "ffm" ],
+[ 4228, "ffn" ],
+[ 4229, "ffo" ],
+[ 4230, "ffp" ],
+[ 4231, "ffq" ],
+[ 4232, "ffr" ],
+[ 4233, "ffs" ],
+[ 4234, "fft" ],
+[ 4235, "ffu" ],
+[ 4236, "ffv" ],
+[ 4237, "ffw" ],
+[ 4238, "ffx" ],
+[ 4239, "ffy" ],
+[ 4240, "ffz" ],
+[ 4241, "fga" ],
+[ 4242, "fgb" ],
+[ 4243, "fgc" ],
+[ 4244, "fgd" ],
+[ 4245, "fge" ],
+[ 4246, "fgf" ],
+[ 4247, "fgg" ],
+[ 4248, "fgh" ],
+[ 4249, "fgi" ],
+[ 4250, "fgj" ],
+[ 4251, "fgk" ],
+[ 4252, "fgl" ],
+[ 4253, "fgm" ],
+[ 4254, "fgn" ],
+[ 4255, "fgo" ],
+[ 4256, "fgp" ],
+[ 4257, "fgq" ],
+[ 4258, "fgr" ],
+[ 4259, "fgs" ],
+[ 4260, "fgt" ],
+[ 4261, "fgu" ],
+[ 4262, "fgv" ],
+[ 4263, "fgw" ],
+[ 4264, "fgx" ],
+[ 4265, "fgy" ],
+[ 4266, "fgz" ],
+[ 4267, "fha" ],
+[ 4268, "fhb" ],
+[ 4269, "fhc" ],
+[ 4270, "fhd" ],
+[ 4271, "fhe" ],
+[ 4272, "fhf" ],
+[ 4273, "fhg" ],
+[ 4274, "fhh" ],
+[ 4275, "fhi" ],
+[ 4276, "fhj" ],
+[ 4277, "fhk" ],
+[ 4278, "fhl" ],
+[ 4279, "fhm" ],
+[ 4280, "fhn" ],
+[ 4281, "fho" ],
+[ 4282, "fhp" ],
+[ 4283, "fhq" ],
+[ 4284, "fhr" ],
+[ 4285, "fhs" ],
+[ 4286, "fht" ],
+[ 4287, "fhu" ],
+[ 4288, "fhv" ],
+[ 4289, "fhw" ],
+[ 4290, "fhx" ],
+[ 4291, "fhy" ],
+[ 4292, "fhz" ],
+[ 4293, "fia" ],
+[ 4294, "fib" ],
+[ 4295, "fic" ],
+[ 4296, "fid" ],
+[ 4297, "fie" ],
+[ 4298, "fif" ],
+[ 4299, "fig" ],
+[ 4300, "fih" ],
+[ 4301, "fii" ],
+[ 4302, "fij" ],
+[ 4303, "fik" ],
+[ 4304, "fil" ],
+[ 4305, "fim" ],
+[ 4306, "fin" ],
+[ 4307, "fio" ],
+[ 4308, "fip" ],
+[ 4309, "fiq" ],
+[ 4310, "fir" ],
+[ 4311, "fis" ],
+[ 4312, "fit" ],
+[ 4313, "fiu" ],
+[ 4314, "fiv" ],
+[ 4315, "fiw" ],
+[ 4316, "fix" ],
+[ 4317, "fiy" ],
+[ 4318, "fiz" ],
+[ 4319, "fja" ],
+[ 4320, "fjb" ],
+[ 4321, "fjc" ],
+[ 4322, "fjd" ],
+[ 4323, "fje" ],
+[ 4324, "fjf" ],
+[ 4325, "fjg" ],
+[ 4326, "fjh" ],
+[ 4327, "fji" ],
+[ 4328, "fjj" ],
+[ 4329, "fjk" ],
+[ 4330, "fjl" ],
+[ 4331, "fjm" ],
+[ 4332, "fjn" ],
+[ 4333, "fjo" ],
+[ 4334, "fjp" ],
+[ 4335, "fjq" ],
+[ 4336, "fjr" ],
+[ 4337, "fjs" ],
+[ 4338, "fjt" ],
+[ 4339, "fju" ],
+[ 4340, "fjv" ],
+[ 4341, "fjw" ],
+[ 4342, "fjx" ],
+[ 4343, "fjy" ],
+[ 4344, "fjz" ],
+[ 4345, "fka" ],
+[ 4346, "fkb" ],
+[ 4347, "fkc" ],
+[ 4348, "fkd" ],
+[ 4349, "fke" ],
+[ 4350, "fkf" ],
+[ 4351, "fkg" ],
+[ 4352, "fkh" ],
+[ 4353, "fki" ],
+[ 4354, "fkj" ],
+[ 4355, "fkk" ],
+[ 4356, "fkl" ],
+[ 4357, "fkm" ],
+[ 4358, "fkn" ],
+[ 4359, "fko" ],
+[ 4360, "fkp" ],
+[ 4361, "fkq" ],
+[ 4362, "fkr" ],
+[ 4363, "fks" ],
+[ 4364, "fkt" ],
+[ 4365, "fku" ],
+[ 4366, "fkv" ],
+[ 4367, "fkw" ],
+[ 4368, "fkx" ],
+[ 4369, "fky" ],
+[ 4370, "fkz" ],
+[ 4371, "fla" ],
+[ 4372, "flb" ],
+[ 4373, "flc" ],
+[ 4374, "fld" ],
+[ 4375, "fle" ],
+[ 4376, "flf" ],
+[ 4377, "flg" ],
+[ 4378, "flh" ],
+[ 4379, "fli" ],
+[ 4380, "flj" ],
+[ 4381, "flk" ],
+[ 4382, "fll" ],
+[ 4383, "flm" ],
+[ 4384, "fln" ],
+[ 4385, "flo" ],
+[ 4386, "flp" ],
+[ 4387, "flq" ],
+[ 4388, "flr" ],
+[ 4389, "fls" ],
+[ 4390, "flt" ],
+[ 4391, "flu" ],
+[ 4392, "flv" ],
+[ 4393, "flw" ],
+[ 4394, "flx" ],
+[ 4395, "fly" ],
+[ 4396, "flz" ],
+[ 4397, "fma" ],
+[ 4398, "fmb" ],
+[ 4399, "fmc" ],
+[ 4400, "fmd" ],
+[ 4401, "fme" ],
+[ 4402, "fmf" ],
+[ 4403, "fmg" ],
+[ 4404, "fmh" ],
+[ 4405, "fmi" ],
+[ 4406, "fmj" ],
+[ 4407, "fmk" ],
+[ 4408, "fml" ],
+[ 4409, "fmm" ],
+[ 4410, "fmn" ],
+[ 4411, "fmo" ],
+[ 4412, "fmp" ],
+[ 4413, "fmq" ],
+[ 4414, "fmr" ],
+[ 4415, "fms" ],
+[ 4416, "fmt" ],
+[ 4417, "fmu" ],
+[ 4418, "fmv" ],
+[ 4419, "fmw" ],
+[ 4420, "fmx" ],
+[ 4421, "fmy" ],
+[ 4422, "fmz" ],
+[ 4423, "fna" ],
+[ 4424, "fnb" ],
+[ 4425, "fnc" ],
+[ 4426, "fnd" ],
+[ 4427, "fne" ],
+[ 4428, "fnf" ],
+[ 4429, "fng" ],
+[ 4430, "fnh" ],
+[ 4431, "fni" ],
+[ 4432, "fnj" ],
+[ 4433, "fnk" ],
+[ 4434, "fnl" ],
+[ 4435, "fnm" ],
+[ 4436, "fnn" ],
+[ 4437, "fno" ],
+[ 4438, "fnp" ],
+[ 4439, "fnq" ],
+[ 4440, "fnr" ],
+[ 4441, "fns" ],
+[ 4442, "fnt" ],
+[ 4443, "fnu" ],
+[ 4444, "fnv" ],
+[ 4445, "fnw" ],
+[ 4446, "fnx" ],
+[ 4447, "fny" ],
+[ 4448, "fnz" ],
+[ 4449, "foa" ],
+[ 4450, "fob" ],
+[ 4451, "foc" ],
+[ 4452, "fod" ],
+[ 4453, "foe" ],
+[ 4454, "fof" ],
+[ 4455, "fog" ],
+[ 4456, "foh" ],
+[ 4457, "foi" ],
+[ 4458, "foj" ],
+[ 4459, "fok" ],
+[ 4460, "fol" ],
+[ 4461, "fom" ],
+[ 4462, "fon" ],
+[ 4463, "foo" ],
+[ 4464, "fop" ],
+[ 4465, "foq" ],
+[ 4466, "for" ],
+[ 4467, "fos" ],
+[ 4468, "fot" ],
+[ 4469, "fou" ],
+[ 4470, "fov" ],
+[ 4471, "fow" ],
+[ 4472, "fox" ],
+[ 4473, "foy" ],
+[ 4474, "foz" ],
+[ 4475, "fpa" ],
+[ 4476, "fpb" ],
+[ 4477, "fpc" ],
+[ 4478, "fpd" ],
+[ 4479, "fpe" ],
+[ 4480, "fpf" ],
+[ 4481, "fpg" ],
+[ 4482, "fph" ],
+[ 4483, "fpi" ],
+[ 4484, "fpj" ],
+[ 4485, "fpk" ],
+[ 4486, "fpl" ],
+[ 4487, "fpm" ],
+[ 4488, "fpn" ],
+[ 4489, "fpo" ],
+[ 4490, "fpp" ],
+[ 4491, "fpq" ],
+[ 4492, "fpr" ],
+[ 4493, "fps" ],
+[ 4494, "fpt" ],
+[ 4495, "fpu" ],
+[ 4496, "fpv" ],
+[ 4497, "fpw" ],
+[ 4498, "fpx" ],
+[ 4499, "fpy" ],
+[ 4500, "fpz" ],
+[ 4501, "fqa" ],
+[ 4502, "fqb" ],
+[ 4503, "fqc" ],
+[ 4504, "fqd" ],
+[ 4505, "fqe" ],
+[ 4506, "fqf" ],
+[ 4507, "fqg" ],
+[ 4508, "fqh" ],
+[ 4509, "fqi" ],
+[ 4510, "fqj" ],
+[ 4511, "fqk" ],
+[ 4512, "fql" ],
+[ 4513, "fqm" ],
+[ 4514, "fqn" ],
+[ 4515, "fqo" ],
+[ 4516, "fqp" ],
+[ 4517, "fqq" ],
+[ 4518, "fqr" ],
+[ 4519, "fqs" ],
+[ 4520, "fqt" ],
+[ 4521, "fqu" ],
+[ 4522, "fqv" ],
+[ 4523, "fqw" ],
+[ 4524, "fqx" ],
+[ 4525, "fqy" ],
+[ 4526, "fqz" ],
+[ 4527, "fra" ],
+[ 4528, "frb" ],
+[ 4529, "frc" ],
+[ 4530, "frd" ],
+[ 4531, "fre" ],
+[ 4532, "frf" ],
+[ 4533, "frg" ],
+[ 4534, "frh" ],
+[ 4535, "fri" ],
+[ 4536, "frj" ],
+[ 4537, "frk" ],
+[ 4538, "frl" ],
+[ 4539, "frm" ],
+[ 4540, "frn" ],
+[ 4541, "fro" ],
+[ 4542, "frp" ],
+[ 4543, "frq" ],
+[ 4544, "frr" ],
+[ 4545, "frs" ],
+[ 4546, "frt" ],
+[ 4547, "fru" ],
+[ 4548, "frv" ],
+[ 4549, "frw" ],
+[ 4550, "frx" ],
+[ 4551, "fry" ],
+[ 4552, "frz" ],
+[ 4553, "fsa" ],
+[ 4554, "fsb" ],
+[ 4555, "fsc" ],
+[ 4556, "fsd" ],
+[ 4557, "fse" ],
+[ 4558, "fsf" ],
+[ 4559, "fsg" ],
+[ 4560, "fsh" ],
+[ 4561, "fsi" ],
+[ 4562, "fsj" ],
+[ 4563, "fsk" ],
+[ 4564, "fsl" ],
+[ 4565, "fsm" ],
+[ 4566, "fsn" ],
+[ 4567, "fso" ],
+[ 4568, "fsp" ],
+[ 4569, "fsq" ],
+[ 4570, "fsr" ],
+[ 4571, "fss" ],
+[ 4572, "fst" ],
+[ 4573, "fsu" ],
+[ 4574, "fsv" ],
+[ 4575, "fsw" ],
+[ 4576, "fsx" ],
+[ 4577, "fsy" ],
+[ 4578, "fsz" ],
+[ 4579, "fta" ],
+[ 4580, "ftb" ],
+[ 4581, "ftc" ],
+[ 4582, "ftd" ],
+[ 4583, "fte" ],
+[ 4584, "ftf" ],
+[ 4585, "ftg" ],
+[ 4586, "fth" ],
+[ 4587, "fti" ],
+[ 4588, "ftj" ],
+[ 4589, "ftk" ],
+[ 4590, "ftl" ],
+[ 4591, "ftm" ],
+[ 4592, "ftn" ],
+[ 4593, "fto" ],
+[ 4594, "ftp" ],
+[ 4595, "ftq" ],
+[ 4596, "ftr" ],
+[ 4597, "fts" ],
+[ 4598, "ftt" ],
+[ 4599, "ftu" ],
+[ 4600, "ftv" ],
+[ 4601, "ftw" ],
+[ 4602, "ftx" ],
+[ 4603, "fty" ],
+[ 4604, "ftz" ],
+[ 4605, "fua" ],
+[ 4606, "fub" ],
+[ 4607, "fuc" ],
+[ 4608, "fud" ],
+[ 4609, "fue" ],
+[ 4610, "fuf" ],
+[ 4611, "fug" ],
+[ 4612, "fuh" ],
+[ 4613, "fui" ],
+[ 4614, "fuj" ],
+[ 4615, "fuk" ],
+[ 4616, "ful" ],
+[ 4617, "fum" ],
+[ 4618, "fun" ],
+[ 4619, "fuo" ],
+[ 4620, "fup" ],
+[ 4621, "fuq" ],
+[ 4622, "fur" ],
+[ 4623, "fus" ],
+[ 4624, "fut" ],
+[ 4625, "fuu" ],
+[ 4626, "fuv" ],
+[ 4627, "fuw" ],
+[ 4628, "fux" ],
+[ 4629, "fuy" ],
+[ 4630, "fuz" ],
+[ 4631, "fva" ],
+[ 4632, "fvb" ],
+[ 4633, "fvc" ],
+[ 4634, "fvd" ],
+[ 4635, "fve" ],
+[ 4636, "fvf" ],
+[ 4637, "fvg" ],
+[ 4638, "fvh" ],
+[ 4639, "fvi" ],
+[ 4640, "fvj" ],
+[ 4641, "fvk" ],
+[ 4642, "fvl" ],
+[ 4643, "fvm" ],
+[ 4644, "fvn" ],
+[ 4645, "fvo" ],
+[ 4646, "fvp" ],
+[ 4647, "fvq" ],
+[ 4648, "fvr" ],
+[ 4649, "fvs" ],
+[ 4650, "fvt" ],
+[ 4651, "fvu" ],
+[ 4652, "fvv" ],
+[ 4653, "fvw" ],
+[ 4654, "fvx" ],
+[ 4655, "fvy" ],
+[ 4656, "fvz" ],
+[ 4657, "fwa" ],
+[ 4658, "fwb" ],
+[ 4659, "fwc" ],
+[ 4660, "fwd" ],
+[ 4661, "fwe" ],
+[ 4662, "fwf" ],
+[ 4663, "fwg" ],
+[ 4664, "fwh" ],
+[ 4665, "fwi" ],
+[ 4666, "fwj" ],
+[ 4667, "fwk" ],
+[ 4668, "fwl" ],
+[ 4669, "fwm" ],
+[ 4670, "fwn" ],
+[ 4671, "fwo" ],
+[ 4672, "fwp" ],
+[ 4673, "fwq" ],
+[ 4674, "fwr" ],
+[ 4675, "fws" ],
+[ 4676, "fwt" ],
+[ 4677, "fwu" ],
+[ 4678, "fwv" ],
+[ 4679, "fww" ],
+[ 4680, "fwx" ],
+[ 4681, "fwy" ],
+[ 4682, "fwz" ],
+[ 4683, "fxa" ],
+[ 4684, "fxb" ],
+[ 4685, "fxc" ],
+[ 4686, "fxd" ],
+[ 4687, "fxe" ],
+[ 4688, "fxf" ],
+[ 4689, "fxg" ],
+[ 4690, "fxh" ],
+[ 4691, "fxi" ],
+[ 4692, "fxj" ],
+[ 4693, "fxk" ],
+[ 4694, "fxl" ],
+[ 4695, "fxm" ],
+[ 4696, "fxn" ],
+[ 4697, "fxo" ],
+[ 4698, "fxp" ],
+[ 4699, "fxq" ],
+[ 4700, "fxr" ],
+[ 4701, "fxs" ],
+[ 4702, "fxt" ],
+[ 4703, "fxu" ],
+[ 4704, "fxv" ],
+[ 4705, "fxw" ],
+[ 4706, "fxx" ],
+[ 4707, "fxy" ],
+[ 4708, "fxz" ],
+[ 4709, "fya" ],
+[ 4710, "fyb" ],
+[ 4711, "fyc" ],
+[ 4712, "fyd" ],
+[ 4713, "fye" ],
+[ 4714, "fyf" ],
+[ 4715, "fyg" ],
+[ 4716, "fyh" ],
+[ 4717, "fyi" ],
+[ 4718, "fyj" ],
+[ 4719, "fyk" ],
+[ 4720, "fyl" ],
+[ 4721, "fym" ],
+[ 4722, "fyn" ],
+[ 4723, "fyo" ],
+[ 4724, "fyp" ],
+[ 4725, "fyq" ],
+[ 4726, "fyr" ],
+[ 4727, "fys" ],
+[ 4728, "fyt" ],
+[ 4729, "fyu" ],
+[ 4730, "fyv" ],
+[ 4731, "fyw" ],
+[ 4732, "fyx" ],
+[ 4733, "fyy" ],
+[ 4734, "fyz" ],
+[ 4735, "fza" ],
+[ 4736, "fzb" ],
+[ 4737, "fzc" ],
+[ 4738, "fzd" ],
+[ 4739, "fze" ],
+[ 4740, "fzf" ],
+[ 4741, "fzg" ],
+[ 4742, "fzh" ],
+[ 4743, "fzi" ],
+[ 4744, "fzj" ],
+[ 4745, "fzk" ],
+[ 4746, "fzl" ],
+[ 4747, "fzm" ],
+[ 4748, "fzn" ],
+[ 4749, "fzo" ],
+[ 4750, "fzp" ],
+[ 4751, "fzq" ],
+[ 4752, "fzr" ],
+[ 4753, "fzs" ],
+[ 4754, "fzt" ],
+[ 4755, "fzu" ],
+[ 4756, "fzv" ],
+[ 4757, "fzw" ],
+[ 4758, "fzx" ],
+[ 4759, "fzy" ],
+[ 4760, "fzz" ],
+[ 4761, "gaa" ],
+[ 4762, "gab" ],
+[ 4763, "gac" ],
+[ 4764, "gad" ],
+[ 4765, "gae" ],
+[ 4766, "gaf" ],
+[ 4767, "gag" ],
+[ 4768, "gah" ],
+[ 4769, "gai" ],
+[ 4770, "gaj" ],
+[ 4771, "gak" ],
+[ 4772, "gal" ],
+[ 4773, "gam" ],
+[ 4774, "gan" ],
+[ 4775, "gao" ],
+[ 4776, "gap" ],
+[ 4777, "gaq" ],
+[ 4778, "gar" ],
+[ 4779, "gas" ],
+[ 4780, "gat" ],
+[ 4781, "gau" ],
+[ 4782, "gav" ],
+[ 4783, "gaw" ],
+[ 4784, "gax" ],
+[ 4785, "gay" ],
+[ 4786, "gaz" ],
+[ 4787, "gba" ],
+[ 4788, "gbb" ],
+[ 4789, "gbc" ],
+[ 4790, "gbd" ],
+[ 4791, "gbe" ],
+[ 4792, "gbf" ],
+[ 4793, "gbg" ],
+[ 4794, "gbh" ],
+[ 4795, "gbi" ],
+[ 4796, "gbj" ],
+[ 4797, "gbk" ],
+[ 4798, "gbl" ],
+[ 4799, "gbm" ],
+[ 4800, "gbn" ],
+[ 4801, "gbo" ],
+[ 4802, "gbp" ],
+[ 4803, "gbq" ],
+[ 4804, "gbr" ],
+[ 4805, "gbs" ],
+[ 4806, "gbt" ],
+[ 4807, "gbu" ],
+[ 4808, "gbv" ],
+[ 4809, "gbw" ],
+[ 4810, "gbx" ],
+[ 4811, "gby" ],
+[ 4812, "gbz" ],
+[ 4813, "gca" ],
+[ 4814, "gcb" ],
+[ 4815, "gcc" ],
+[ 4816, "gcd" ],
+[ 4817, "gce" ],
+[ 4818, "gcf" ],
+[ 4819, "gcg" ],
+[ 4820, "gch" ],
+[ 4821, "gci" ],
+[ 4822, "gcj" ],
+[ 4823, "gck" ],
+[ 4824, "gcl" ],
+[ 4825, "gcm" ],
+[ 4826, "gcn" ],
+[ 4827, "gco" ],
+[ 4828, "gcp" ],
+[ 4829, "gcq" ],
+[ 4830, "gcr" ],
+[ 4831, "gcs" ],
+[ 4832, "gct" ],
+[ 4833, "gcu" ],
+[ 4834, "gcv" ],
+[ 4835, "gcw" ],
+[ 4836, "gcx" ],
+[ 4837, "gcy" ],
+[ 4838, "gcz" ],
+[ 4839, "gda" ],
+[ 4840, "gdb" ],
+[ 4841, "gdc" ],
+[ 4842, "gdd" ],
+[ 4843, "gde" ],
+[ 4844, "gdf" ],
+[ 4845, "gdg" ],
+[ 4846, "gdh" ],
+[ 4847, "gdi" ],
+[ 4848, "gdj" ],
+[ 4849, "gdk" ],
+[ 4850, "gdl" ],
+[ 4851, "gdm" ],
+[ 4852, "gdn" ],
+[ 4853, "gdo" ],
+[ 4854, "gdp" ],
+[ 4855, "gdq" ],
+[ 4856, "gdr" ],
+[ 4857, "gds" ],
+[ 4858, "gdt" ],
+[ 4859, "gdu" ],
+[ 4860, "gdv" ],
+[ 4861, "gdw" ],
+[ 4862, "gdx" ],
+[ 4863, "gdy" ],
+[ 4864, "gdz" ],
+[ 4865, "gea" ],
+[ 4866, "geb" ],
+[ 4867, "gec" ],
+[ 4868, "ged" ],
+[ 4869, "gee" ],
+[ 4870, "gef" ],
+[ 4871, "geg" ],
+[ 4872, "geh" ],
+[ 4873, "gei" ],
+[ 4874, "gej" ],
+[ 4875, "gek" ],
+[ 4876, "gel" ],
+[ 4877, "gem" ],
+[ 4878, "gen" ],
+[ 4879, "geo" ],
+[ 4880, "gep" ],
+[ 4881, "geq" ],
+[ 4882, "ger" ],
+[ 4883, "ges" ],
+[ 4884, "get" ],
+[ 4885, "geu" ],
+[ 4886, "gev" ],
+[ 4887, "gew" ],
+[ 4888, "gex" ],
+[ 4889, "gey" ],
+[ 4890, "gez" ],
+[ 4891, "gfa" ],
+[ 4892, "gfb" ],
+[ 4893, "gfc" ],
+[ 4894, "gfd" ],
+[ 4895, "gfe" ],
+[ 4896, "gff" ],
+[ 4897, "gfg" ],
+[ 4898, "gfh" ],
+[ 4899, "gfi" ],
+[ 4900, "gfj" ],
+[ 4901, "gfk" ],
+[ 4902, "gfl" ],
+[ 4903, "gfm" ],
+[ 4904, "gfn" ],
+[ 4905, "gfo" ],
+[ 4906, "gfp" ],
+[ 4907, "gfq" ],
+[ 4908, "gfr" ],
+[ 4909, "gfs" ],
+[ 4910, "gft" ],
+[ 4911, "gfu" ],
+[ 4912, "gfv" ],
+[ 4913, "gfw" ],
+[ 4914, "gfx" ],
+[ 4915, "gfy" ],
+[ 4916, "gfz" ],
+[ 4917, "gga" ],
+[ 4918, "ggb" ],
+[ 4919, "ggc" ],
+[ 4920, "ggd" ],
+[ 4921, "gge" ],
+[ 4922, "ggf" ],
+[ 4923, "ggg" ],
+[ 4924, "ggh" ],
+[ 4925, "ggi" ],
+[ 4926, "ggj" ],
+[ 4927, "ggk" ],
+[ 4928, "ggl" ],
+[ 4929, "ggm" ],
+[ 4930, "ggn" ],
+[ 4931, "ggo" ],
+[ 4932, "ggp" ],
+[ 4933, "ggq" ],
+[ 4934, "ggr" ],
+[ 4935, "ggs" ],
+[ 4936, "ggt" ],
+[ 4937, "ggu" ],
+[ 4938, "ggv" ],
+[ 4939, "ggw" ],
+[ 4940, "ggx" ],
+[ 4941, "ggy" ],
+[ 4942, "ggz" ],
+[ 4943, "gha" ],
+[ 4944, "ghb" ],
+[ 4945, "ghc" ],
+[ 4946, "ghd" ],
+[ 4947, "ghe" ],
+[ 4948, "ghf" ],
+[ 4949, "ghg" ],
+[ 4950, "ghh" ],
+[ 4951, "ghi" ],
+[ 4952, "ghj" ],
+[ 4953, "ghk" ],
+[ 4954, "ghl" ],
+[ 4955, "ghm" ],
+[ 4956, "ghn" ],
+[ 4957, "gho" ],
+[ 4958, "ghp" ],
+[ 4959, "ghq" ],
+[ 4960, "ghr" ],
+[ 4961, "ghs" ],
+[ 4962, "ght" ],
+[ 4963, "ghu" ],
+[ 4964, "ghv" ],
+[ 4965, "ghw" ],
+[ 4966, "ghx" ],
+[ 4967, "ghy" ],
+[ 4968, "ghz" ],
+[ 4969, "gia" ],
+[ 4970, "gib" ],
+[ 4971, "gic" ],
+[ 4972, "gid" ],
+[ 4973, "gie" ],
+[ 4974, "gif" ],
+[ 4975, "gig" ],
+[ 4976, "gih" ],
+[ 4977, "gii" ],
+[ 4978, "gij" ],
+[ 4979, "gik" ],
+[ 4980, "gil" ],
+[ 4981, "gim" ],
+[ 4982, "gin" ],
+[ 4983, "gio" ],
+[ 4984, "gip" ],
+[ 4985, "giq" ],
+[ 4986, "gir" ],
+[ 4987, "gis" ],
+[ 4988, "git" ],
+[ 4989, "giu" ],
+[ 4990, "giv" ],
+[ 4991, "giw" ],
+[ 4992, "gix" ],
+[ 4993, "giy" ],
+[ 4994, "giz" ],
+[ 4995, "gja" ],
+[ 4996, "gjb" ],
+[ 4997, "gjc" ],
+[ 4998, "gjd" ],
+[ 4999, "gje" ],
+[ 5000, "gjf" ],
+[ 5001, "gjg" ],
+[ 5002, "gjh" ],
+[ 5003, "gji" ],
+[ 5004, "gjj" ],
+[ 5005, "gjk" ],
+[ 5006, "gjl" ],
+[ 5007, "gjm" ],
+[ 5008, "gjn" ],
+[ 5009, "gjo" ],
+[ 5010, "gjp" ],
+[ 5011, "gjq" ],
+[ 5012, "gjr" ],
+[ 5013, "gjs" ],
+[ 5014, "gjt" ],
+[ 5015, "gju" ],
+[ 5016, "gjv" ],
+[ 5017, "gjw" ],
+[ 5018, "gjx" ],
+[ 5019, "gjy" ],
+[ 5020, "gjz" ],
+[ 5021, "gka" ],
+[ 5022, "gkb" ],
+[ 5023, "gkc" ],
+[ 5024, "gkd" ],
+[ 5025, "gke" ],
+[ 5026, "gkf" ],
+[ 5027, "gkg" ],
+[ 5028, "gkh" ],
+[ 5029, "gki" ],
+[ 5030, "gkj" ],
+[ 5031, "gkk" ],
+[ 5032, "gkl" ],
+[ 5033, "gkm" ],
+[ 5034, "gkn" ],
+[ 5035, "gko" ],
+[ 5036, "gkp" ],
+[ 5037, "gkq" ],
+[ 5038, "gkr" ],
+[ 5039, "gks" ],
+[ 5040, "gkt" ],
+[ 5041, "gku" ],
+[ 5042, "gkv" ],
+[ 5043, "gkw" ],
+[ 5044, "gkx" ],
+[ 5045, "gky" ],
+[ 5046, "gkz" ],
+[ 5047, "gla" ],
+[ 5048, "glb" ],
+[ 5049, "glc" ],
+[ 5050, "gld" ],
+[ 5051, "gle" ],
+[ 5052, "glf" ],
+[ 5053, "glg" ],
+[ 5054, "glh" ],
+[ 5055, "gli" ],
+[ 5056, "glj" ],
+[ 5057, "glk" ],
+[ 5058, "gll" ],
+[ 5059, "glm" ],
+[ 5060, "gln" ],
+[ 5061, "glo" ],
+[ 5062, "glp" ],
+[ 5063, "glq" ],
+[ 5064, "glr" ],
+[ 5065, "gls" ],
+[ 5066, "glt" ],
+[ 5067, "glu" ],
+[ 5068, "glv" ],
+[ 5069, "glw" ],
+[ 5070, "glx" ],
+[ 5071, "gly" ],
+[ 5072, "glz" ],
+[ 5073, "gma" ],
+[ 5074, "gmb" ],
+[ 5075, "gmc" ],
+[ 5076, "gmd" ],
+[ 5077, "gme" ],
+[ 5078, "gmf" ],
+[ 5079, "gmg" ],
+[ 5080, "gmh" ],
+[ 5081, "gmi" ],
+[ 5082, "gmj" ],
+[ 5083, "gmk" ],
+[ 5084, "gml" ],
+[ 5085, "gmm" ],
+[ 5086, "gmn" ],
+[ 5087, "gmo" ],
+[ 5088, "gmp" ],
+[ 5089, "gmq" ],
+[ 5090, "gmr" ],
+[ 5091, "gms" ],
+[ 5092, "gmt" ],
+[ 5093, "gmu" ],
+[ 5094, "gmv" ],
+[ 5095, "gmw" ],
+[ 5096, "gmx" ],
+[ 5097, "gmy" ],
+[ 5098, "gmz" ],
+[ 5099, "gna" ],
+[ 5100, "gnb" ],
+[ 5101, "gnc" ],
+[ 5102, "gnd" ],
+[ 5103, "gne" ],
+[ 5104, "gnf" ],
+[ 5105, "gng" ],
+[ 5106, "gnh" ],
+[ 5107, "gni" ],
+[ 5108, "gnj" ],
+[ 5109, "gnk" ],
+[ 5110, "gnl" ],
+[ 5111, "gnm" ],
+[ 5112, "gnn" ],
+[ 5113, "gno" ],
+[ 5114, "gnp" ],
+[ 5115, "gnq" ],
+[ 5116, "gnr" ],
+[ 5117, "gns" ],
+[ 5118, "gnt" ],
+[ 5119, "gnu" ],
+[ 5120, "gnv" ],
+[ 5121, "gnw" ],
+[ 5122, "gnx" ],
+[ 5123, "gny" ],
+[ 5124, "gnz" ],
+[ 5125, "goa" ],
+[ 5126, "gob" ],
+[ 5127, "goc" ],
+[ 5128, "god" ],
+[ 5129, "goe" ],
+[ 5130, "gof" ],
+[ 5131, "gog" ],
+[ 5132, "goh" ],
+[ 5133, "goi" ],
+[ 5134, "goj" ],
+[ 5135, "gok" ],
+[ 5136, "gol" ],
+[ 5137, "gom" ],
+[ 5138, "gon" ],
+[ 5139, "goo" ],
+[ 5140, "gop" ],
+[ 5141, "goq" ],
+[ 5142, "gor" ],
+[ 5143, "gos" ],
+[ 5144, "got" ],
+[ 5145, "gou" ],
+[ 5146, "gov" ],
+[ 5147, "gow" ],
+[ 5148, "gox" ],
+[ 5149, "goy" ],
+[ 5150, "goz" ],
+[ 5151, "gpa" ],
+[ 5152, "gpb" ],
+[ 5153, "gpc" ],
+[ 5154, "gpd" ],
+[ 5155, "gpe" ],
+[ 5156, "gpf" ],
+[ 5157, "gpg" ],
+[ 5158, "gph" ],
+[ 5159, "gpi" ],
+[ 5160, "gpj" ],
+[ 5161, "gpk" ],
+[ 5162, "gpl" ],
+[ 5163, "gpm" ],
+[ 5164, "gpn" ],
+[ 5165, "gpo" ],
+[ 5166, "gpp" ],
+[ 5167, "gpq" ],
+[ 5168, "gpr" ],
+[ 5169, "gps" ],
+[ 5170, "gpt" ],
+[ 5171, "gpu" ],
+[ 5172, "gpv" ],
+[ 5173, "gpw" ],
+[ 5174, "gpx" ],
+[ 5175, "gpy" ],
+[ 5176, "gpz" ],
+[ 5177, "gqa" ],
+[ 5178, "gqb" ],
+[ 5179, "gqc" ],
+[ 5180, "gqd" ],
+[ 5181, "gqe" ],
+[ 5182, "gqf" ],
+[ 5183, "gqg" ],
+[ 5184, "gqh" ],
+[ 5185, "gqi" ],
+[ 5186, "gqj" ],
+[ 5187, "gqk" ],
+[ 5188, "gql" ],
+[ 5189, "gqm" ],
+[ 5190, "gqn" ],
+[ 5191, "gqo" ],
+[ 5192, "gqp" ],
+[ 5193, "gqq" ],
+[ 5194, "gqr" ],
+[ 5195, "gqs" ],
+[ 5196, "gqt" ],
+[ 5197, "gqu" ],
+[ 5198, "gqv" ],
+[ 5199, "gqw" ],
+[ 5200, "gqx" ],
+[ 5201, "gqy" ],
+[ 5202, "gqz" ],
+[ 5203, "gra" ],
+[ 5204, "grb" ],
+[ 5205, "grc" ],
+[ 5206, "grd" ],
+[ 5207, "gre" ],
+[ 5208, "grf" ],
+[ 5209, "grg" ],
+[ 5210, "grh" ],
+[ 5211, "gri" ],
+[ 5212, "grj" ],
+[ 5213, "grk" ],
+[ 5214, "grl" ],
+[ 5215, "grm" ],
+[ 5216, "grn" ],
+[ 5217, "gro" ],
+[ 5218, "grp" ],
+[ 5219, "grq" ],
+[ 5220, "grr" ],
+[ 5221, "grs" ],
+[ 5222, "grt" ],
+[ 5223, "gru" ],
+[ 5224, "grv" ],
+[ 5225, "grw" ],
+[ 5226, "grx" ],
+[ 5227, "gry" ],
+[ 5228, "grz" ],
+[ 5229, "gsa" ],
+[ 5230, "gsb" ],
+[ 5231, "gsc" ],
+[ 5232, "gsd" ],
+[ 5233, "gse" ],
+[ 5234, "gsf" ],
+[ 5235, "gsg" ],
+[ 5236, "gsh" ],
+[ 5237, "gsi" ],
+[ 5238, "gsj" ],
+[ 5239, "gsk" ],
+[ 5240, "gsl" ],
+[ 5241, "gsm" ],
+[ 5242, "gsn" ],
+[ 5243, "gso" ],
+[ 5244, "gsp" ],
+[ 5245, "gsq" ],
+[ 5246, "gsr" ],
+[ 5247, "gss" ],
+[ 5248, "gst" ],
+[ 5249, "gsu" ],
+[ 5250, "gsv" ],
+[ 5251, "gsw" ],
+[ 5252, "gsx" ],
+[ 5253, "gsy" ],
+[ 5254, "gsz" ],
+[ 5255, "gta" ],
+[ 5256, "gtb" ],
+[ 5257, "gtc" ],
+[ 5258, "gtd" ],
+[ 5259, "gte" ],
+[ 5260, "gtf" ],
+[ 5261, "gtg" ],
+[ 5262, "gth" ],
+[ 5263, "gti" ],
+[ 5264, "gtj" ],
+[ 5265, "gtk" ],
+[ 5266, "gtl" ],
+[ 5267, "gtm" ],
+[ 5268, "gtn" ],
+[ 5269, "gto" ],
+[ 5270, "gtp" ],
+[ 5271, "gtq" ],
+[ 5272, "gtr" ],
+[ 5273, "gts" ],
+[ 5274, "gtt" ],
+[ 5275, "gtu" ],
+[ 5276, "gtv" ],
+[ 5277, "gtw" ],
+[ 5278, "gtx" ],
+[ 5279, "gty" ],
+[ 5280, "gtz" ],
+[ 5281, "gua" ],
+[ 5282, "gub" ],
+[ 5283, "guc" ],
+[ 5284, "gud" ],
+[ 5285, "gue" ],
+[ 5286, "guf" ],
+[ 5287, "gug" ],
+[ 5288, "guh" ],
+[ 5289, "gui" ],
+[ 5290, "guj" ],
+[ 5291, "guk" ],
+[ 5292, "gul" ],
+[ 5293, "gum" ],
+[ 5294, "gun" ],
+[ 5295, "guo" ],
+[ 5296, "gup" ],
+[ 5297, "guq" ],
+[ 5298, "gur" ],
+[ 5299, "gus" ],
+[ 5300, "gut" ],
+[ 5301, "guu" ],
+[ 5302, "guv" ],
+[ 5303, "guw" ],
+[ 5304, "gux" ],
+[ 5305, "guy" ],
+[ 5306, "guz" ],
+[ 5307, "gva" ],
+[ 5308, "gvb" ],
+[ 5309, "gvc" ],
+[ 5310, "gvd" ],
+[ 5311, "gve" ],
+[ 5312, "gvf" ],
+[ 5313, "gvg" ],
+[ 5314, "gvh" ],
+[ 5315, "gvi" ],
+[ 5316, "gvj" ],
+[ 5317, "gvk" ],
+[ 5318, "gvl" ],
+[ 5319, "gvm" ],
+[ 5320, "gvn" ],
+[ 5321, "gvo" ],
+[ 5322, "gvp" ],
+[ 5323, "gvq" ],
+[ 5324, "gvr" ],
+[ 5325, "gvs" ],
+[ 5326, "gvt" ],
+[ 5327, "gvu" ],
+[ 5328, "gvv" ],
+[ 5329, "gvw" ],
+[ 5330, "gvx" ],
+[ 5331, "gvy" ],
+[ 5332, "gvz" ],
+[ 5333, "gwa" ],
+[ 5334, "gwb" ],
+[ 5335, "gwc" ],
+[ 5336, "gwd" ],
+[ 5337, "gwe" ],
+[ 5338, "gwf" ],
+[ 5339, "gwg" ],
+[ 5340, "gwh" ],
+[ 5341, "gwi" ],
+[ 5342, "gwj" ],
+[ 5343, "gwk" ],
+[ 5344, "gwl" ],
+[ 5345, "gwm" ],
+[ 5346, "gwn" ],
+[ 5347, "gwo" ],
+[ 5348, "gwp" ],
+[ 5349, "gwq" ],
+[ 5350, "gwr" ],
+[ 5351, "gws" ],
+[ 5352, "gwt" ],
+[ 5353, "gwu" ],
+[ 5354, "gwv" ],
+[ 5355, "gww" ],
+[ 5356, "gwx" ],
+[ 5357, "gwy" ],
+[ 5358, "gwz" ],
+[ 5359, "gxa" ],
+[ 5360, "gxb" ],
+[ 5361, "gxc" ],
+[ 5362, "gxd" ],
+[ 5363, "gxe" ],
+[ 5364, "gxf" ],
+[ 5365, "gxg" ],
+[ 5366, "gxh" ],
+[ 5367, "gxi" ],
+[ 5368, "gxj" ],
+[ 5369, "gxk" ],
+[ 5370, "gxl" ],
+[ 5371, "gxm" ],
+[ 5372, "gxn" ],
+[ 5373, "gxo" ],
+[ 5374, "gxp" ],
+[ 5375, "gxq" ],
+[ 5376, "gxr" ],
+[ 5377, "gxs" ],
+[ 5378, "gxt" ],
+[ 5379, "gxu" ],
+[ 5380, "gxv" ],
+[ 5381, "gxw" ],
+[ 5382, "gxx" ],
+[ 5383, "gxy" ],
+[ 5384, "gxz" ],
+[ 5385, "gya" ],
+[ 5386, "gyb" ],
+[ 5387, "gyc" ],
+[ 5388, "gyd" ],
+[ 5389, "gye" ],
+[ 5390, "gyf" ],
+[ 5391, "gyg" ],
+[ 5392, "gyh" ],
+[ 5393, "gyi" ],
+[ 5394, "gyj" ],
+[ 5395, "gyk" ],
+[ 5396, "gyl" ],
+[ 5397, "gym" ],
+[ 5398, "gyn" ],
+[ 5399, "gyo" ],
+[ 5400, "gyp" ],
+[ 5401, "gyq" ],
+[ 5402, "gyr" ],
+[ 5403, "gys" ],
+[ 5404, "gyt" ],
+[ 5405, "gyu" ],
+[ 5406, "gyv" ],
+[ 5407, "gyw" ],
+[ 5408, "gyx" ],
+[ 5409, "gyy" ],
+[ 5410, "gyz" ],
+[ 5411, "gza" ],
+[ 5412, "gzb" ],
+[ 5413, "gzc" ],
+[ 5414, "gzd" ],
+[ 5415, "gze" ],
+[ 5416, "gzf" ],
+[ 5417, "gzg" ],
+[ 5418, "gzh" ],
+[ 5419, "gzi" ],
+[ 5420, "gzj" ],
+[ 5421, "gzk" ],
+[ 5422, "gzl" ],
+[ 5423, "gzm" ],
+[ 5424, "gzn" ],
+[ 5425, "gzo" ],
+[ 5426, "gzp" ],
+[ 5427, "gzq" ],
+[ 5428, "gzr" ],
+[ 5429, "gzs" ],
+[ 5430, "gzt" ],
+[ 5431, "gzu" ],
+[ 5432, "gzv" ],
+[ 5433, "gzw" ],
+[ 5434, "gzx" ],
+[ 5435, "gzy" ],
+[ 5436, "gzz" ],
+[ 5437, "haa" ],
+[ 5438, "hab" ],
+[ 5439, "hac" ],
+[ 5440, "had" ],
+[ 5441, "hae" ],
+[ 5442, "haf" ],
+[ 5443, "hag" ],
+[ 5444, "hah" ],
+[ 5445, "hai" ],
+[ 5446, "haj" ],
+[ 5447, "hak" ],
+[ 5448, "hal" ],
+[ 5449, "ham" ],
+[ 5450, "han" ],
+[ 5451, "hao" ],
+[ 5452, "hap" ],
+[ 5453, "haq" ],
+[ 5454, "har" ],
+[ 5455, "has" ],
+[ 5456, "hat" ],
+[ 5457, "hau" ],
+[ 5458, "hav" ],
+[ 5459, "haw" ],
+[ 5460, "hax" ],
+[ 5461, "hay" ],
+[ 5462, "haz" ],
+[ 5463, "hba" ],
+[ 5464, "hbb" ],
+[ 5465, "hbc" ],
+[ 5466, "hbd" ],
+[ 5467, "hbe" ],
+[ 5468, "hbf" ],
+[ 5469, "hbg" ],
+[ 5470, "hbh" ],
+[ 5471, "hbi" ],
+[ 5472, "hbj" ],
+[ 5473, "hbk" ],
+[ 5474, "hbl" ],
+[ 5475, "hbm" ],
+[ 5476, "hbn" ],
+[ 5477, "hbo" ],
+[ 5478, "hbp" ],
+[ 5479, "hbq" ],
+[ 5480, "hbr" ],
+[ 5481, "hbs" ],
+[ 5482, "hbt" ],
+[ 5483, "hbu" ],
+[ 5484, "hbv" ],
+[ 5485, "hbw" ],
+[ 5486, "hbx" ],
+[ 5487, "hby" ],
+[ 5488, "hbz" ],
+[ 5489, "hca" ],
+[ 5490, "hcb" ],
+[ 5491, "hcc" ],
+[ 5492, "hcd" ],
+[ 5493, "hce" ],
+[ 5494, "hcf" ],
+[ 5495, "hcg" ],
+[ 5496, "hch" ],
+[ 5497, "hci" ],
+[ 5498, "hcj" ],
+[ 5499, "hck" ],
+[ 5500, "hcl" ],
+[ 5501, "hcm" ],
+[ 5502, "hcn" ],
+[ 5503, "hco" ],
+[ 5504, "hcp" ],
+[ 5505, "hcq" ],
+[ 5506, "hcr" ],
+[ 5507, "hcs" ],
+[ 5508, "hct" ],
+[ 5509, "hcu" ],
+[ 5510, "hcv" ],
+[ 5511, "hcw" ],
+[ 5512, "hcx" ],
+[ 5513, "hcy" ],
+[ 5514, "hcz" ],
+[ 5515, "hda" ],
+[ 5516, "hdb" ],
+[ 5517, "hdc" ],
+[ 5518, "hdd" ],
+[ 5519, "hde" ],
+[ 5520, "hdf" ],
+[ 5521, "hdg" ],
+[ 5522, "hdh" ],
+[ 5523, "hdi" ],
+[ 5524, "hdj" ],
+[ 5525, "hdk" ],
+[ 5526, "hdl" ],
+[ 5527, "hdm" ],
+[ 5528, "hdn" ],
+[ 5529, "hdo" ],
+[ 5530, "hdp" ],
+[ 5531, "hdq" ],
+[ 5532, "hdr" ],
+[ 5533, "hds" ],
+[ 5534, "hdt" ],
+[ 5535, "hdu" ],
+[ 5536, "hdv" ],
+[ 5537, "hdw" ],
+[ 5538, "hdx" ],
+[ 5539, "hdy" ],
+[ 5540, "hdz" ],
+[ 5541, "hea" ],
+[ 5542, "heb" ],
+[ 5543, "hec" ],
+[ 5544, "hed" ],
+[ 5545, "hee" ],
+[ 5546, "hef" ],
+[ 5547, "heg" ],
+[ 5548, "heh" ],
+[ 5549, "hei" ],
+[ 5550, "hej" ],
+[ 5551, "hek" ],
+[ 5552, "hel" ],
+[ 5553, "hem" ],
+[ 5554, "hen" ],
+[ 5555, "heo" ],
+[ 5556, "hep" ],
+[ 5557, "heq" ],
+[ 5558, "her" ],
+[ 5559, "hes" ],
+[ 5560, "het" ],
+[ 5561, "heu" ],
+[ 5562, "hev" ],
+[ 5563, "hew" ],
+[ 5564, "hex" ],
+[ 5565, "hey" ],
+[ 5566, "hez" ],
+[ 5567, "hfa" ],
+[ 5568, "hfb" ],
+[ 5569, "hfc" ],
+[ 5570, "hfd" ],
+[ 5571, "hfe" ],
+[ 5572, "hff" ],
+[ 5573, "hfg" ],
+[ 5574, "hfh" ],
+[ 5575, "hfi" ],
+[ 5576, "hfj" ],
+[ 5577, "hfk" ],
+[ 5578, "hfl" ],
+[ 5579, "hfm" ],
+[ 5580, "hfn" ],
+[ 5581, "hfo" ],
+[ 5582, "hfp" ],
+[ 5583, "hfq" ],
+[ 5584, "hfr" ],
+[ 5585, "hfs" ],
+[ 5586, "hft" ],
+[ 5587, "hfu" ],
+[ 5588, "hfv" ],
+[ 5589, "hfw" ],
+[ 5590, "hfx" ],
+[ 5591, "hfy" ],
+[ 5592, "hfz" ],
+[ 5593, "hga" ],
+[ 5594, "hgb" ],
+[ 5595, "hgc" ],
+[ 5596, "hgd" ],
+[ 5597, "hge" ],
+[ 5598, "hgf" ],
+[ 5599, "hgg" ],
+[ 5600, "hgh" ],
+[ 5601, "hgi" ],
+[ 5602, "hgj" ],
+[ 5603, "hgk" ],
+[ 5604, "hgl" ],
+[ 5605, "hgm" ],
+[ 5606, "hgn" ],
+[ 5607, "hgo" ],
+[ 5608, "hgp" ],
+[ 5609, "hgq" ],
+[ 5610, "hgr" ],
+[ 5611, "hgs" ],
+[ 5612, "hgt" ],
+[ 5613, "hgu" ],
+[ 5614, "hgv" ],
+[ 5615, "hgw" ],
+[ 5616, "hgx" ],
+[ 5617, "hgy" ],
+[ 5618, "hgz" ],
+[ 5619, "hha" ],
+[ 5620, "hhb" ],
+[ 5621, "hhc" ],
+[ 5622, "hhd" ],
+[ 5623, "hhe" ],
+[ 5624, "hhf" ],
+[ 5625, "hhg" ],
+[ 5626, "hhh" ],
+[ 5627, "hhi" ],
+[ 5628, "hhj" ],
+[ 5629, "hhk" ],
+[ 5630, "hhl" ],
+[ 5631, "hhm" ],
+[ 5632, "hhn" ],
+[ 5633, "hho" ],
+[ 5634, "hhp" ],
+[ 5635, "hhq" ],
+[ 5636, "hhr" ],
+[ 5637, "hhs" ],
+[ 5638, "hht" ],
+[ 5639, "hhu" ],
+[ 5640, "hhv" ],
+[ 5641, "hhw" ],
+[ 5642, "hhx" ],
+[ 5643, "hhy" ],
+[ 5644, "hhz" ],
+[ 5645, "hia" ],
+[ 5646, "hib" ],
+[ 5647, "hic" ],
+[ 5648, "hid" ],
+[ 5649, "hie" ],
+[ 5650, "hif" ],
+[ 5651, "hig" ],
+[ 5652, "hih" ],
+[ 5653, "hii" ],
+[ 5654, "hij" ],
+[ 5655, "hik" ],
+[ 5656, "hil" ],
+[ 5657, "him" ],
+[ 5658, "hin" ],
+[ 5659, "hio" ],
+[ 5660, "hip" ],
+[ 5661, "hiq" ],
+[ 5662, "hir" ],
+[ 5663, "his" ],
+[ 5664, "hit" ],
+[ 5665, "hiu" ],
+[ 5666, "hiv" ],
+[ 5667, "hiw" ],
+[ 5668, "hix" ],
+[ 5669, "hiy" ],
+[ 5670, "hiz" ],
+[ 5671, "hja" ],
+[ 5672, "hjb" ],
+[ 5673, "hjc" ],
+[ 5674, "hjd" ],
+[ 5675, "hje" ],
+[ 5676, "hjf" ],
+[ 5677, "hjg" ],
+[ 5678, "hjh" ],
+[ 5679, "hji" ],
+[ 5680, "hjj" ],
+[ 5681, "hjk" ],
+[ 5682, "hjl" ],
+[ 5683, "hjm" ],
+[ 5684, "hjn" ],
+[ 5685, "hjo" ],
+[ 5686, "hjp" ],
+[ 5687, "hjq" ],
+[ 5688, "hjr" ],
+[ 5689, "hjs" ],
+[ 5690, "hjt" ],
+[ 5691, "hju" ],
+[ 5692, "hjv" ],
+[ 5693, "hjw" ],
+[ 5694, "hjx" ],
+[ 5695, "hjy" ],
+[ 5696, "hjz" ],
+[ 5697, "hka" ],
+[ 5698, "hkb" ],
+[ 5699, "hkc" ],
+[ 5700, "hkd" ],
+[ 5701, "hke" ],
+[ 5702, "hkf" ],
+[ 5703, "hkg" ],
+[ 5704, "hkh" ],
+[ 5705, "hki" ],
+[ 5706, "hkj" ],
+[ 5707, "hkk" ],
+[ 5708, "hkl" ],
+[ 5709, "hkm" ],
+[ 5710, "hkn" ],
+[ 5711, "hko" ],
+[ 5712, "hkp" ],
+[ 5713, "hkq" ],
+[ 5714, "hkr" ],
+[ 5715, "hks" ],
+[ 5716, "hkt" ],
+[ 5717, "hku" ],
+[ 5718, "hkv" ],
+[ 5719, "hkw" ],
+[ 5720, "hkx" ],
+[ 5721, "hky" ],
+[ 5722, "hkz" ],
+[ 5723, "hla" ],
+[ 5724, "hlb" ],
+[ 5725, "hlc" ],
+[ 5726, "hld" ],
+[ 5727, "hle" ],
+[ 5728, "hlf" ],
+[ 5729, "hlg" ],
+[ 5730, "hlh" ],
+[ 5731, "hli" ],
+[ 5732, "hlj" ],
+[ 5733, "hlk" ],
+[ 5734, "hll" ],
+[ 5735, "hlm" ],
+[ 5736, "hln" ],
+[ 5737, "hlo" ],
+[ 5738, "hlp" ],
+[ 5739, "hlq" ],
+[ 5740, "hlr" ],
+[ 5741, "hls" ],
+[ 5742, "hlt" ],
+[ 5743, "hlu" ],
+[ 5744, "hlv" ],
+[ 5745, "hlw" ],
+[ 5746, "hlx" ],
+[ 5747, "hly" ],
+[ 5748, "hlz" ],
+[ 5749, "hma" ],
+[ 5750, "hmb" ],
+[ 5751, "hmc" ],
+[ 5752, "hmd" ],
+[ 5753, "hme" ],
+[ 5754, "hmf" ],
+[ 5755, "hmg" ],
+[ 5756, "hmh" ],
+[ 5757, "hmi" ],
+[ 5758, "hmj" ],
+[ 5759, "hmk" ],
+[ 5760, "hml" ],
+[ 5761, "hmm" ],
+[ 5762, "hmn" ],
+[ 5763, "hmo" ],
+[ 5764, "hmp" ],
+[ 5765, "hmq" ],
+[ 5766, "hmr" ],
+[ 5767, "hms" ],
+[ 5768, "hmt" ],
+[ 5769, "hmu" ],
+[ 5770, "hmv" ],
+[ 5771, "hmw" ],
+[ 5772, "hmx" ],
+[ 5773, "hmy" ],
+[ 5774, "hmz" ],
+[ 5775, "hna" ],
+[ 5776, "hnb" ],
+[ 5777, "hnc" ],
+[ 5778, "hnd" ],
+[ 5779, "hne" ],
+[ 5780, "hnf" ],
+[ 5781, "hng" ],
+[ 5782, "hnh" ],
+[ 5783, "hni" ],
+[ 5784, "hnj" ],
+[ 5785, "hnk" ],
+[ 5786, "hnl" ],
+[ 5787, "hnm" ],
+[ 5788, "hnn" ],
+[ 5789, "hno" ],
+[ 5790, "hnp" ],
+[ 5791, "hnq" ],
+[ 5792, "hnr" ],
+[ 5793, "hns" ],
+[ 5794, "hnt" ],
+[ 5795, "hnu" ],
+[ 5796, "hnv" ],
+[ 5797, "hnw" ],
+[ 5798, "hnx" ],
+[ 5799, "hny" ],
+[ 5800, "hnz" ],
+[ 5801, "hoa" ],
+[ 5802, "hob" ],
+[ 5803, "hoc" ],
+[ 5804, "hod" ],
+[ 5805, "hoe" ],
+[ 5806, "hof" ],
+[ 5807, "hog" ],
+[ 5808, "hoh" ],
+[ 5809, "hoi" ],
+[ 5810, "hoj" ],
+[ 5811, "hok" ],
+[ 5812, "hol" ],
+[ 5813, "hom" ],
+[ 5814, "hon" ],
+[ 5815, "hoo" ],
+[ 5816, "hop" ],
+[ 5817, "hoq" ],
+[ 5818, "hor" ],
+[ 5819, "hos" ],
+[ 5820, "hot" ],
+[ 5821, "hou" ],
+[ 5822, "hov" ],
+[ 5823, "how" ],
+[ 5824, "hox" ],
+[ 5825, "hoy" ],
+[ 5826, "hoz" ],
+[ 5827, "hpa" ],
+[ 5828, "hpb" ],
+[ 5829, "hpc" ],
+[ 5830, "hpd" ],
+[ 5831, "hpe" ],
+[ 5832, "hpf" ],
+[ 5833, "hpg" ],
+[ 5834, "hph" ],
+[ 5835, "hpi" ],
+[ 5836, "hpj" ],
+[ 5837, "hpk" ],
+[ 5838, "hpl" ],
+[ 5839, "hpm" ],
+[ 5840, "hpn" ],
+[ 5841, "hpo" ],
+[ 5842, "hpp" ],
+[ 5843, "hpq" ],
+[ 5844, "hpr" ],
+[ 5845, "hps" ],
+[ 5846, "hpt" ],
+[ 5847, "hpu" ],
+[ 5848, "hpv" ],
+[ 5849, "hpw" ],
+[ 5850, "hpx" ],
+[ 5851, "hpy" ],
+[ 5852, "hpz" ],
+[ 5853, "hqa" ],
+[ 5854, "hqb" ],
+[ 5855, "hqc" ],
+[ 5856, "hqd" ],
+[ 5857, "hqe" ],
+[ 5858, "hqf" ],
+[ 5859, "hqg" ],
+[ 5860, "hqh" ],
+[ 5861, "hqi" ],
+[ 5862, "hqj" ],
+[ 5863, "hqk" ],
+[ 5864, "hql" ],
+[ 5865, "hqm" ],
+[ 5866, "hqn" ],
+[ 5867, "hqo" ],
+[ 5868, "hqp" ],
+[ 5869, "hqq" ],
+[ 5870, "hqr" ],
+[ 5871, "hqs" ],
+[ 5872, "hqt" ],
+[ 5873, "hqu" ],
+[ 5874, "hqv" ],
+[ 5875, "hqw" ],
+[ 5876, "hqx" ],
+[ 5877, "hqy" ],
+[ 5878, "hqz" ],
+[ 5879, "hra" ],
+[ 5880, "hrb" ],
+[ 5881, "hrc" ],
+[ 5882, "hrd" ],
+[ 5883, "hre" ],
+[ 5884, "hrf" ],
+[ 5885, "hrg" ],
+[ 5886, "hrh" ],
+[ 5887, "hri" ],
+[ 5888, "hrj" ],
+[ 5889, "hrk" ],
+[ 5890, "hrl" ],
+[ 5891, "hrm" ],
+[ 5892, "hrn" ],
+[ 5893, "hro" ],
+[ 5894, "hrp" ],
+[ 5895, "hrq" ],
+[ 5896, "hrr" ],
+[ 5897, "hrs" ],
+[ 5898, "hrt" ],
+[ 5899, "hru" ],
+[ 5900, "hrv" ],
+[ 5901, "hrw" ],
+[ 5902, "hrx" ],
+[ 5903, "hry" ],
+[ 5904, "hrz" ],
+[ 5905, "hsa" ],
+[ 5906, "hsb" ],
+[ 5907, "hsc" ],
+[ 5908, "hsd" ],
+[ 5909, "hse" ],
+[ 5910, "hsf" ],
+[ 5911, "hsg" ],
+[ 5912, "hsh" ],
+[ 5913, "hsi" ],
+[ 5914, "hsj" ],
+[ 5915, "hsk" ],
+[ 5916, "hsl" ],
+[ 5917, "hsm" ],
+[ 5918, "hsn" ],
+[ 5919, "hso" ],
+[ 5920, "hsp" ],
+[ 5921, "hsq" ],
+[ 5922, "hsr" ],
+[ 5923, "hss" ],
+[ 5924, "hst" ],
+[ 5925, "hsu" ],
+[ 5926, "hsv" ],
+[ 5927, "hsw" ],
+[ 5928, "hsx" ],
+[ 5929, "hsy" ],
+[ 5930, "hsz" ],
+[ 5931, "hta" ],
+[ 5932, "htb" ],
+[ 5933, "htc" ],
+[ 5934, "htd" ],
+[ 5935, "hte" ],
+[ 5936, "htf" ],
+[ 5937, "htg" ],
+[ 5938, "hth" ],
+[ 5939, "hti" ],
+[ 5940, "htj" ],
+[ 5941, "htk" ],
+[ 5942, "htl" ],
+[ 5943, "htm" ],
+[ 5944, "htn" ],
+[ 5945, "hto" ],
+[ 5946, "htp" ],
+[ 5947, "htq" ],
+[ 5948, "htr" ],
+[ 5949, "hts" ],
+[ 5950, "htt" ],
+[ 5951, "htu" ],
+[ 5952, "htv" ],
+[ 5953, "htw" ],
+[ 5954, "htx" ],
+[ 5955, "hty" ],
+[ 5956, "htz" ],
+[ 5957, "hua" ],
+[ 5958, "hub" ],
+[ 5959, "huc" ],
+[ 5960, "hud" ],
+[ 5961, "hue" ],
+[ 5962, "huf" ],
+[ 5963, "hug" ],
+[ 5964, "huh" ],
+[ 5965, "hui" ],
+[ 5966, "huj" ],
+[ 5967, "huk" ],
+[ 5968, "hul" ],
+[ 5969, "hum" ],
+[ 5970, "hun" ],
+[ 5971, "huo" ],
+[ 5972, "hup" ],
+[ 5973, "huq" ],
+[ 5974, "hur" ],
+[ 5975, "hus" ],
+[ 5976, "hut" ],
+[ 5977, "huu" ],
+[ 5978, "huv" ],
+[ 5979, "huw" ],
+[ 5980, "hux" ],
+[ 5981, "huy" ],
+[ 5982, "huz" ],
+[ 5983, "hva" ],
+[ 5984, "hvb" ],
+[ 5985, "hvc" ],
+[ 5986, "hvd" ],
+[ 5987, "hve" ],
+[ 5988, "hvf" ],
+[ 5989, "hvg" ],
+[ 5990, "hvh" ],
+[ 5991, "hvi" ],
+[ 5992, "hvj" ],
+[ 5993, "hvk" ],
+[ 5994, "hvl" ],
+[ 5995, "hvm" ],
+[ 5996, "hvn" ],
+[ 5997, "hvo" ],
+[ 5998, "hvp" ],
+[ 5999, "hvq" ],
+[ 6000, "hvr" ],
+[ 6001, "hvs" ],
+[ 6002, "hvt" ],
+[ 6003, "hvu" ],
+[ 6004, "hvv" ],
+[ 6005, "hvw" ],
+[ 6006, "hvx" ],
+[ 6007, "hvy" ],
+[ 6008, "hvz" ],
+[ 6009, "hwa" ],
+[ 6010, "hwb" ],
+[ 6011, "hwc" ],
+[ 6012, "hwd" ],
+[ 6013, "hwe" ],
+[ 6014, "hwf" ],
+[ 6015, "hwg" ],
+[ 6016, "hwh" ],
+[ 6017, "hwi" ],
+[ 6018, "hwj" ],
+[ 6019, "hwk" ],
+[ 6020, "hwl" ],
+[ 6021, "hwm" ],
+[ 6022, "hwn" ],
+[ 6023, "hwo" ],
+[ 6024, "hwp" ],
+[ 6025, "hwq" ],
+[ 6026, "hwr" ],
+[ 6027, "hws" ],
+[ 6028, "hwt" ],
+[ 6029, "hwu" ],
+[ 6030, "hwv" ],
+[ 6031, "hww" ],
+[ 6032, "hwx" ],
+[ 6033, "hwy" ],
+[ 6034, "hwz" ],
+[ 6035, "hxa" ],
+[ 6036, "hxb" ],
+[ 6037, "hxc" ],
+[ 6038, "hxd" ],
+[ 6039, "hxe" ],
+[ 6040, "hxf" ],
+[ 6041, "hxg" ],
+[ 6042, "hxh" ],
+[ 6043, "hxi" ],
+[ 6044, "hxj" ],
+[ 6045, "hxk" ],
+[ 6046, "hxl" ],
+[ 6047, "hxm" ],
+[ 6048, "hxn" ],
+[ 6049, "hxo" ],
+[ 6050, "hxp" ],
+[ 6051, "hxq" ],
+[ 6052, "hxr" ],
+[ 6053, "hxs" ],
+[ 6054, "hxt" ],
+[ 6055, "hxu" ],
+[ 6056, "hxv" ],
+[ 6057, "hxw" ],
+[ 6058, "hxx" ],
+[ 6059, "hxy" ],
+[ 6060, "hxz" ],
+[ 6061, "hya" ],
+[ 6062, "hyb" ],
+[ 6063, "hyc" ],
+[ 6064, "hyd" ],
+[ 6065, "hye" ],
+[ 6066, "hyf" ],
+[ 6067, "hyg" ],
+[ 6068, "hyh" ],
+[ 6069, "hyi" ],
+[ 6070, "hyj" ],
+[ 6071, "hyk" ],
+[ 6072, "hyl" ],
+[ 6073, "hym" ],
+[ 6074, "hyn" ],
+[ 6075, "hyo" ],
+[ 6076, "hyp" ],
+[ 6077, "hyq" ],
+[ 6078, "hyr" ],
+[ 6079, "hys" ],
+[ 6080, "hyt" ],
+[ 6081, "hyu" ],
+[ 6082, "hyv" ],
+[ 6083, "hyw" ],
+[ 6084, "hyx" ],
+[ 6085, "hyy" ],
+[ 6086, "hyz" ],
+[ 6087, "hza" ],
+[ 6088, "hzb" ],
+[ 6089, "hzc" ],
+[ 6090, "hzd" ],
+[ 6091, "hze" ],
+[ 6092, "hzf" ],
+[ 6093, "hzg" ],
+[ 6094, "hzh" ],
+[ 6095, "hzi" ],
+[ 6096, "hzj" ],
+[ 6097, "hzk" ],
+[ 6098, "hzl" ],
+[ 6099, "hzm" ],
+[ 6100, "hzn" ],
+[ 6101, "hzo" ],
+[ 6102, "hzp" ],
+[ 6103, "hzq" ],
+[ 6104, "hzr" ],
+[ 6105, "hzs" ],
+[ 6106, "hzt" ],
+[ 6107, "hzu" ],
+[ 6108, "hzv" ],
+[ 6109, "hzw" ],
+[ 6110, "hzx" ],
+[ 6111, "hzy" ],
+[ 6112, "hzz" ],
+[ 6113, "iaa" ],
+[ 6114, "iab" ],
+[ 6115, "iac" ],
+[ 6116, "iad" ],
+[ 6117, "iae" ],
+[ 6118, "iaf" ],
+[ 6119, "iag" ],
+[ 6120, "iah" ],
+[ 6121, "iai" ],
+[ 6122, "iaj" ],
+[ 6123, "iak" ],
+[ 6124, "ial" ],
+[ 6125, "iam" ],
+[ 6126, "ian" ],
+[ 6127, "iao" ],
+[ 6128, "iap" ],
+[ 6129, "iaq" ],
+[ 6130, "iar" ],
+[ 6131, "ias" ],
+[ 6132, "iat" ],
+[ 6133, "iau" ],
+[ 6134, "iav" ],
+[ 6135, "iaw" ],
+[ 6136, "iax" ],
+[ 6137, "iay" ],
+[ 6138, "iaz" ],
+[ 6139, "iba" ],
+[ 6140, "ibb" ],
+[ 6141, "ibc" ],
+[ 6142, "ibd" ],
+[ 6143, "ibe" ],
+[ 6144, "ibf" ],
+[ 6145, "ibg" ],
+[ 6146, "ibh" ],
+[ 6147, "ibi" ],
+[ 6148, "ibj" ],
+[ 6149, "ibk" ],
+[ 6150, "ibl" ],
+[ 6151, "ibm" ],
+[ 6152, "ibn" ],
+[ 6153, "ibo" ],
+[ 6154, "ibp" ],
+[ 6155, "ibq" ],
+[ 6156, "ibr" ],
+[ 6157, "ibs" ],
+[ 6158, "ibt" ],
+[ 6159, "ibu" ],
+[ 6160, "ibv" ],
+[ 6161, "ibw" ],
+[ 6162, "ibx" ],
+[ 6163, "iby" ],
+[ 6164, "ibz" ],
+[ 6165, "ica" ],
+[ 6166, "icb" ],
+[ 6167, "icc" ],
+[ 6168, "icd" ],
+[ 6169, "ice" ],
+[ 6170, "icf" ],
+[ 6171, "icg" ],
+[ 6172, "ich" ],
+[ 6173, "ici" ],
+[ 6174, "icj" ],
+[ 6175, "ick" ],
+[ 6176, "icl" ],
+[ 6177, "icm" ],
+[ 6178, "icn" ],
+[ 6179, "ico" ],
+[ 6180, "icp" ],
+[ 6181, "icq" ],
+[ 6182, "icr" ],
+[ 6183, "ics" ],
+[ 6184, "ict" ],
+[ 6185, "icu" ],
+[ 6186, "icv" ],
+[ 6187, "icw" ],
+[ 6188, "icx" ],
+[ 6189, "icy" ],
+[ 6190, "icz" ],
+[ 6191, "ida" ],
+[ 6192, "idb" ],
+[ 6193, "idc" ],
+[ 6194, "idd" ],
+[ 6195, "ide" ],
+[ 6196, "idf" ],
+[ 6197, "idg" ],
+[ 6198, "idh" ],
+[ 6199, "idi" ],
+[ 6200, "idj" ],
+[ 6201, "idk" ],
+[ 6202, "idl" ],
+[ 6203, "idm" ],
+[ 6204, "idn" ],
+[ 6205, "ido" ],
+[ 6206, "idp" ],
+[ 6207, "idq" ],
+[ 6208, "idr" ],
+[ 6209, "ids" ],
+[ 6210, "idt" ],
+[ 6211, "idu" ],
+[ 6212, "idv" ],
+[ 6213, "idw" ],
+[ 6214, "idx" ],
+[ 6215, "idy" ],
+[ 6216, "idz" ],
+[ 6217, "iea" ],
+[ 6218, "ieb" ],
+[ 6219, "iec" ],
+[ 6220, "ied" ],
+[ 6221, "iee" ],
+[ 6222, "ief" ],
+[ 6223, "ieg" ],
+[ 6224, "ieh" ],
+[ 6225, "iei" ],
+[ 6226, "iej" ],
+[ 6227, "iek" ],
+[ 6228, "iel" ],
+[ 6229, "iem" ],
+[ 6230, "ien" ],
+[ 6231, "ieo" ],
+[ 6232, "iep" ],
+[ 6233, "ieq" ],
+[ 6234, "ier" ],
+[ 6235, "ies" ],
+[ 6236, "iet" ],
+[ 6237, "ieu" ],
+[ 6238, "iev" ],
+[ 6239, "iew" ],
+[ 6240, "iex" ],
+[ 6241, "iey" ],
+[ 6242, "iez" ],
+[ 6243, "ifa" ],
+[ 6244, "ifb" ],
+[ 6245, "ifc" ],
+[ 6246, "ifd" ],
+[ 6247, "ife" ],
+[ 6248, "iff" ],
+[ 6249, "ifg" ],
+[ 6250, "ifh" ],
+[ 6251, "ifi" ],
+[ 6252, "ifj" ],
+[ 6253, "ifk" ],
+[ 6254, "ifl" ],
+[ 6255, "ifm" ],
+[ 6256, "ifn" ],
+[ 6257, "ifo" ],
+[ 6258, "ifp" ],
+[ 6259, "ifq" ],
+[ 6260, "ifr" ],
+[ 6261, "ifs" ],
+[ 6262, "ift" ],
+[ 6263, "ifu" ],
+[ 6264, "ifv" ],
+[ 6265, "ifw" ],
+[ 6266, "ifx" ],
+[ 6267, "ify" ],
+[ 6268, "ifz" ],
+[ 6269, "iga" ],
+[ 6270, "igb" ],
+[ 6271, "igc" ],
+[ 6272, "igd" ],
+[ 6273, "ige" ],
+[ 6274, "igf" ],
+[ 6275, "igg" ],
+[ 6276, "igh" ],
+[ 6277, "igi" ],
+[ 6278, "igj" ],
+[ 6279, "igk" ],
+[ 6280, "igl" ],
+[ 6281, "igm" ],
+[ 6282, "ign" ],
+[ 6283, "igo" ],
+[ 6284, "igp" ],
+[ 6285, "igq" ],
+[ 6286, "igr" ],
+[ 6287, "igs" ],
+[ 6288, "igt" ],
+[ 6289, "igu" ],
+[ 6290, "igv" ],
+[ 6291, "igw" ],
+[ 6292, "igx" ],
+[ 6293, "igy" ],
+[ 6294, "igz" ],
+[ 6295, "iha" ],
+[ 6296, "ihb" ],
+[ 6297, "ihc" ],
+[ 6298, "ihd" ],
+[ 6299, "ihe" ],
+[ 6300, "ihf" ],
+[ 6301, "ihg" ],
+[ 6302, "ihh" ],
+[ 6303, "ihi" ],
+[ 6304, "ihj" ],
+[ 6305, "ihk" ],
+[ 6306, "ihl" ],
+[ 6307, "ihm" ],
+[ 6308, "ihn" ],
+[ 6309, "iho" ],
+[ 6310, "ihp" ],
+[ 6311, "ihq" ],
+[ 6312, "ihr" ],
+[ 6313, "ihs" ],
+[ 6314, "iht" ],
+[ 6315, "ihu" ],
+[ 6316, "ihv" ],
+[ 6317, "ihw" ],
+[ 6318, "ihx" ],
+[ 6319, "ihy" ],
+[ 6320, "ihz" ],
+[ 6321, "iia" ],
+[ 6322, "iib" ],
+[ 6323, "iic" ],
+[ 6324, "iid" ],
+[ 6325, "iie" ],
+[ 6326, "iif" ],
+[ 6327, "iig" ],
+[ 6328, "iih" ],
+[ 6329, "iii" ],
+[ 6330, "iij" ],
+[ 6331, "iik" ],
+[ 6332, "iil" ],
+[ 6333, "iim" ],
+[ 6334, "iin" ],
+[ 6335, "iio" ],
+[ 6336, "iip" ],
+[ 6337, "iiq" ],
+[ 6338, "iir" ],
+[ 6339, "iis" ],
+[ 6340, "iit" ],
+[ 6341, "iiu" ],
+[ 6342, "iiv" ],
+[ 6343, "iiw" ],
+[ 6344, "iix" ],
+[ 6345, "iiy" ],
+[ 6346, "iiz" ],
+[ 6347, "ija" ],
+[ 6348, "ijb" ],
+[ 6349, "ijc" ],
+[ 6350, "ijd" ],
+[ 6351, "ije" ],
+[ 6352, "ijf" ],
+[ 6353, "ijg" ],
+[ 6354, "ijh" ],
+[ 6355, "iji" ],
+[ 6356, "ijj" ],
+[ 6357, "ijk" ],
+[ 6358, "ijl" ],
+[ 6359, "ijm" ],
+[ 6360, "ijn" ],
+[ 6361, "ijo" ],
+[ 6362, "ijp" ],
+[ 6363, "ijq" ],
+[ 6364, "ijr" ],
+[ 6365, "ijs" ],
+[ 6366, "ijt" ],
+[ 6367, "iju" ],
+[ 6368, "ijv" ],
+[ 6369, "ijw" ],
+[ 6370, "ijx" ],
+[ 6371, "ijy" ],
+[ 6372, "ijz" ],
+[ 6373, "ika" ],
+[ 6374, "ikb" ],
+[ 6375, "ikc" ],
+[ 6376, "ikd" ],
+[ 6377, "ike" ],
+[ 6378, "ikf" ],
+[ 6379, "ikg" ],
+[ 6380, "ikh" ],
+[ 6381, "iki" ],
+[ 6382, "ikj" ],
+[ 6383, "ikk" ],
+[ 6384, "ikl" ],
+[ 6385, "ikm" ],
+[ 6386, "ikn" ],
+[ 6387, "iko" ],
+[ 6388, "ikp" ],
+[ 6389, "ikq" ],
+[ 6390, "ikr" ],
+[ 6391, "iks" ],
+[ 6392, "ikt" ],
+[ 6393, "iku" ],
+[ 6394, "ikv" ],
+[ 6395, "ikw" ],
+[ 6396, "ikx" ],
+[ 6397, "iky" ],
+[ 6398, "ikz" ],
+[ 6399, "ila" ],
+[ 6400, "ilb" ],
+[ 6401, "ilc" ],
+[ 6402, "ild" ],
+[ 6403, "ile" ],
+[ 6404, "ilf" ],
+[ 6405, "ilg" ],
+[ 6406, "ilh" ],
+[ 6407, "ili" ],
+[ 6408, "ilj" ],
+[ 6409, "ilk" ],
+[ 6410, "ill" ],
+[ 6411, "ilm" ],
+[ 6412, "iln" ],
+[ 6413, "ilo" ],
+[ 6414, "ilp" ],
+[ 6415, "ilq" ],
+[ 6416, "ilr" ],
+[ 6417, "ils" ],
+[ 6418, "ilt" ],
+[ 6419, "ilu" ],
+[ 6420, "ilv" ],
+[ 6421, "ilw" ],
+[ 6422, "ilx" ],
+[ 6423, "ily" ],
+[ 6424, "ilz" ],
+[ 6425, "ima" ],
+[ 6426, "imb" ],
+[ 6427, "imc" ],
+[ 6428, "imd" ],
+[ 6429, "ime" ],
+[ 6430, "imf" ],
+[ 6431, "img" ],
+[ 6432, "imh" ],
+[ 6433, "imi" ],
+[ 6434, "imj" ],
+[ 6435, "imk" ],
+[ 6436, "iml" ],
+[ 6437, "imm" ],
+[ 6438, "imn" ],
+[ 6439, "imo" ],
+[ 6440, "imp" ],
+[ 6441, "imq" ],
+[ 6442, "imr" ],
+[ 6443, "ims" ],
+[ 6444, "imt" ],
+[ 6445, "imu" ],
+[ 6446, "imv" ],
+[ 6447, "imw" ],
+[ 6448, "imx" ],
+[ 6449, "imy" ],
+[ 6450, "imz" ],
+[ 6451, "ina" ],
+[ 6452, "inb" ],
+[ 6453, "inc" ],
+[ 6454, "ind" ],
+[ 6455, "ine" ],
+[ 6456, "inf" ],
+[ 6457, "ing" ],
+[ 6458, "inh" ],
+[ 6459, "ini" ],
+[ 6460, "inj" ],
+[ 6461, "ink" ],
+[ 6462, "inl" ],
+[ 6463, "inm" ],
+[ 6464, "inn" ],
+[ 6465, "ino" ],
+[ 6466, "inp" ],
+[ 6467, "inq" ],
+[ 6468, "inr" ],
+[ 6469, "ins" ],
+[ 6470, "int" ],
+[ 6471, "inu" ],
+[ 6472, "inv" ],
+[ 6473, "inw" ],
+[ 6474, "inx" ],
+[ 6475, "iny" ],
+[ 6476, "inz" ],
+[ 6477, "ioa" ],
+[ 6478, "iob" ],
+[ 6479, "ioc" ],
+[ 6480, "iod" ],
+[ 6481, "ioe" ],
+[ 6482, "iof" ],
+[ 6483, "iog" ],
+[ 6484, "ioh" ],
+[ 6485, "ioi" ],
+[ 6486, "ioj" ],
+[ 6487, "iok" ],
+[ 6488, "iol" ],
+[ 6489, "iom" ],
+[ 6490, "ion" ],
+[ 6491, "ioo" ],
+[ 6492, "iop" ],
+[ 6493, "ioq" ],
+[ 6494, "ior" ],
+[ 6495, "ios" ],
+[ 6496, "iot" ],
+[ 6497, "iou" ],
+[ 6498, "iov" ],
+[ 6499, "iow" ],
+[ 6500, "iox" ],
+[ 6501, "ioy" ],
+[ 6502, "ioz" ],
+[ 6503, "ipa" ],
+[ 6504, "ipb" ],
+[ 6505, "ipc" ],
+[ 6506, "ipd" ],
+[ 6507, "ipe" ],
+[ 6508, "ipf" ],
+[ 6509, "ipg" ],
+[ 6510, "iph" ],
+[ 6511, "ipi" ],
+[ 6512, "ipj" ],
+[ 6513, "ipk" ],
+[ 6514, "ipl" ],
+[ 6515, "ipm" ],
+[ 6516, "ipn" ],
+[ 6517, "ipo" ],
+[ 6518, "ipp" ],
+[ 6519, "ipq" ],
+[ 6520, "ipr" ],
+[ 6521, "ips" ],
+[ 6522, "ipt" ],
+[ 6523, "ipu" ],
+[ 6524, "ipv" ],
+[ 6525, "ipw" ],
+[ 6526, "ipx" ],
+[ 6527, "ipy" ],
+[ 6528, "ipz" ],
+[ 6529, "iqa" ],
+[ 6530, "iqb" ],
+[ 6531, "iqc" ],
+[ 6532, "iqd" ],
+[ 6533, "iqe" ],
+[ 6534, "iqf" ],
+[ 6535, "iqg" ],
+[ 6536, "iqh" ],
+[ 6537, "iqi" ],
+[ 6538, "iqj" ],
+[ 6539, "iqk" ],
+[ 6540, "iql" ],
+[ 6541, "iqm" ],
+[ 6542, "iqn" ],
+[ 6543, "iqo" ],
+[ 6544, "iqp" ],
+[ 6545, "iqq" ],
+[ 6546, "iqr" ],
+[ 6547, "iqs" ],
+[ 6548, "iqt" ],
+[ 6549, "iqu" ],
+[ 6550, "iqv" ],
+[ 6551, "iqw" ],
+[ 6552, "iqx" ],
+[ 6553, "iqy" ],
+[ 6554, "iqz" ],
+[ 6555, "ira" ],
+[ 6556, "irb" ],
+[ 6557, "irc" ],
+[ 6558, "ird" ],
+[ 6559, "ire" ],
+[ 6560, "irf" ],
+[ 6561, "irg" ],
+[ 6562, "irh" ],
+[ 6563, "iri" ],
+[ 6564, "irj" ],
+[ 6565, "irk" ],
+[ 6566, "irl" ],
+[ 6567, "irm" ],
+[ 6568, "irn" ],
+[ 6569, "iro" ],
+[ 6570, "irp" ],
+[ 6571, "irq" ],
+[ 6572, "irr" ],
+[ 6573, "irs" ],
+[ 6574, "irt" ],
+[ 6575, "iru" ],
+[ 6576, "irv" ],
+[ 6577, "irw" ],
+[ 6578, "irx" ],
+[ 6579, "iry" ],
+[ 6580, "irz" ],
+[ 6581, "isa" ],
+[ 6582, "isb" ],
+[ 6583, "isc" ],
+[ 6584, "isd" ],
+[ 6585, "ise" ],
+[ 6586, "isf" ],
+[ 6587, "isg" ],
+[ 6588, "ish" ],
+[ 6589, "isi" ],
+[ 6590, "isj" ],
+[ 6591, "isk" ],
+[ 6592, "isl" ],
+[ 6593, "ism" ],
+[ 6594, "isn" ],
+[ 6595, "iso" ],
+[ 6596, "isp" ],
+[ 6597, "isq" ],
+[ 6598, "isr" ],
+[ 6599, "iss" ],
+[ 6600, "ist" ],
+[ 6601, "isu" ],
+[ 6602, "isv" ],
+[ 6603, "isw" ],
+[ 6604, "isx" ],
+[ 6605, "isy" ],
+[ 6606, "isz" ],
+[ 6607, "ita" ],
+[ 6608, "itb" ],
+[ 6609, "itc" ],
+[ 6610, "itd" ],
+[ 6611, "ite" ],
+[ 6612, "itf" ],
+[ 6613, "itg" ],
+[ 6614, "ith" ],
+[ 6615, "iti" ],
+[ 6616, "itj" ],
+[ 6617, "itk" ],
+[ 6618, "itl" ],
+[ 6619, "itm" ],
+[ 6620, "itn" ],
+[ 6621, "ito" ],
+[ 6622, "itp" ],
+[ 6623, "itq" ],
+[ 6624, "itr" ],
+[ 6625, "its" ],
+[ 6626, "itt" ],
+[ 6627, "itu" ],
+[ 6628, "itv" ],
+[ 6629, "itw" ],
+[ 6630, "itx" ],
+[ 6631, "ity" ],
+[ 6632, "itz" ],
+[ 6633, "iua" ],
+[ 6634, "iub" ],
+[ 6635, "iuc" ],
+[ 6636, "iud" ],
+[ 6637, "iue" ],
+[ 6638, "iuf" ],
+[ 6639, "iug" ],
+[ 6640, "iuh" ],
+[ 6641, "iui" ],
+[ 6642, "iuj" ],
+[ 6643, "iuk" ],
+[ 6644, "iul" ],
+[ 6645, "ium" ],
+[ 6646, "iun" ],
+[ 6647, "iuo" ],
+[ 6648, "iup" ],
+[ 6649, "iuq" ],
+[ 6650, "iur" ],
+[ 6651, "ius" ],
+[ 6652, "iut" ],
+[ 6653, "iuu" ],
+[ 6654, "iuv" ],
+[ 6655, "iuw" ],
+[ 6656, "iux" ],
+[ 6657, "iuy" ],
+[ 6658, "iuz" ],
+[ 6659, "iva" ],
+[ 6660, "ivb" ],
+[ 6661, "ivc" ],
+[ 6662, "ivd" ],
+[ 6663, "ive" ],
+[ 6664, "ivf" ],
+[ 6665, "ivg" ],
+[ 6666, "ivh" ],
+[ 6667, "ivi" ],
+[ 6668, "ivj" ],
+[ 6669, "ivk" ],
+[ 6670, "ivl" ],
+[ 6671, "ivm" ],
+[ 6672, "ivn" ],
+[ 6673, "ivo" ],
+[ 6674, "ivp" ],
+[ 6675, "ivq" ],
+[ 6676, "ivr" ],
+[ 6677, "ivs" ],
+[ 6678, "ivt" ],
+[ 6679, "ivu" ],
+[ 6680, "ivv" ],
+[ 6681, "ivw" ],
+[ 6682, "ivx" ],
+[ 6683, "ivy" ],
+[ 6684, "ivz" ],
+[ 6685, "iwa" ],
+[ 6686, "iwb" ],
+[ 6687, "iwc" ],
+[ 6688, "iwd" ],
+[ 6689, "iwe" ],
+[ 6690, "iwf" ],
+[ 6691, "iwg" ],
+[ 6692, "iwh" ],
+[ 6693, "iwi" ],
+[ 6694, "iwj" ],
+[ 6695, "iwk" ],
+[ 6696, "iwl" ],
+[ 6697, "iwm" ],
+[ 6698, "iwn" ],
+[ 6699, "iwo" ],
+[ 6700, "iwp" ],
+[ 6701, "iwq" ],
+[ 6702, "iwr" ],
+[ 6703, "iws" ],
+[ 6704, "iwt" ],
+[ 6705, "iwu" ],
+[ 6706, "iwv" ],
+[ 6707, "iww" ],
+[ 6708, "iwx" ],
+[ 6709, "iwy" ],
+[ 6710, "iwz" ],
+[ 6711, "ixa" ],
+[ 6712, "ixb" ],
+[ 6713, "ixc" ],
+[ 6714, "ixd" ],
+[ 6715, "ixe" ],
+[ 6716, "ixf" ],
+[ 6717, "ixg" ],
+[ 6718, "ixh" ],
+[ 6719, "ixi" ],
+[ 6720, "ixj" ],
+[ 6721, "ixk" ],
+[ 6722, "ixl" ],
+[ 6723, "ixm" ],
+[ 6724, "ixn" ],
+[ 6725, "ixo" ],
+[ 6726, "ixp" ],
+[ 6727, "ixq" ],
+[ 6728, "ixr" ],
+[ 6729, "ixs" ],
+[ 6730, "ixt" ],
+[ 6731, "ixu" ],
+[ 6732, "ixv" ],
+[ 6733, "ixw" ],
+[ 6734, "ixx" ],
+[ 6735, "ixy" ],
+[ 6736, "ixz" ],
+[ 6737, "iya" ],
+[ 6738, "iyb" ],
+[ 6739, "iyc" ],
+[ 6740, "iyd" ],
+[ 6741, "iye" ],
+[ 6742, "iyf" ],
+[ 6743, "iyg" ],
+[ 6744, "iyh" ],
+[ 6745, "iyi" ],
+[ 6746, "iyj" ],
+[ 6747, "iyk" ],
+[ 6748, "iyl" ],
+[ 6749, "iym" ],
+[ 6750, "iyn" ],
+[ 6751, "iyo" ],
+[ 6752, "iyp" ],
+[ 6753, "iyq" ],
+[ 6754, "iyr" ],
+[ 6755, "iys" ],
+[ 6756, "iyt" ],
+[ 6757, "iyu" ],
+[ 6758, "iyv" ],
+[ 6759, "iyw" ],
+[ 6760, "iyx" ],
+[ 6761, "iyy" ],
+[ 6762, "iyz" ],
+[ 6763, "iza" ],
+[ 6764, "izb" ],
+[ 6765, "izc" ],
+[ 6766, "izd" ],
+[ 6767, "ize" ],
+[ 6768, "izf" ],
+[ 6769, "izg" ],
+[ 6770, "izh" ],
+[ 6771, "izi" ],
+[ 6772, "izj" ],
+[ 6773, "izk" ],
+[ 6774, "izl" ],
+[ 6775, "izm" ],
+[ 6776, "izn" ],
+[ 6777, "izo" ],
+[ 6778, "izp" ],
+[ 6779, "izq" ],
+[ 6780, "izr" ],
+[ 6781, "izs" ],
+[ 6782, "izt" ],
+[ 6783, "izu" ],
+[ 6784, "izv" ],
+[ 6785, "izw" ],
+[ 6786, "izx" ],
+[ 6787, "izy" ],
+[ 6788, "izz" ],
+[ 6789, "jaa" ],
+[ 6790, "jab" ],
+[ 6791, "jac" ],
+[ 6792, "jad" ],
+[ 6793, "jae" ],
+[ 6794, "jaf" ],
+[ 6795, "jag" ],
+[ 6796, "jah" ],
+[ 6797, "jai" ],
+[ 6798, "jaj" ],
+[ 6799, "jak" ],
+[ 6800, "jal" ],
+[ 6801, "jam" ],
+[ 6802, "jan" ],
+[ 6803, "jao" ],
+[ 6804, "jap" ],
+[ 6805, "jaq" ],
+[ 6806, "jar" ],
+[ 6807, "jas" ],
+[ 6808, "jat" ],
+[ 6809, "jau" ],
+[ 6810, "jav" ],
+[ 6811, "jaw" ],
+[ 6812, "jax" ],
+[ 6813, "jay" ],
+[ 6814, "jaz" ],
+[ 6815, "jba" ],
+[ 6816, "jbb" ],
+[ 6817, "jbc" ],
+[ 6818, "jbd" ],
+[ 6819, "jbe" ],
+[ 6820, "jbf" ],
+[ 6821, "jbg" ],
+[ 6822, "jbh" ],
+[ 6823, "jbi" ],
+[ 6824, "jbj" ],
+[ 6825, "jbk" ],
+[ 6826, "jbl" ],
+[ 6827, "jbm" ],
+[ 6828, "jbn" ],
+[ 6829, "jbo" ],
+[ 6830, "jbp" ],
+[ 6831, "jbq" ],
+[ 6832, "jbr" ],
+[ 6833, "jbs" ],
+[ 6834, "jbt" ],
+[ 6835, "jbu" ],
+[ 6836, "jbv" ],
+[ 6837, "jbw" ],
+[ 6838, "jbx" ],
+[ 6839, "jby" ],
+[ 6840, "jbz" ],
+[ 6841, "jca" ],
+[ 6842, "jcb" ],
+[ 6843, "jcc" ],
+[ 6844, "jcd" ],
+[ 6845, "jce" ],
+[ 6846, "jcf" ],
+[ 6847, "jcg" ],
+[ 6848, "jch" ],
+[ 6849, "jci" ],
+[ 6850, "jcj" ],
+[ 6851, "jck" ],
+[ 6852, "jcl" ],
+[ 6853, "jcm" ],
+[ 6854, "jcn" ],
+[ 6855, "jco" ],
+[ 6856, "jcp" ],
+[ 6857, "jcq" ],
+[ 6858, "jcr" ],
+[ 6859, "jcs" ],
+[ 6860, "jct" ],
+[ 6861, "jcu" ],
+[ 6862, "jcv" ],
+[ 6863, "jcw" ],
+[ 6864, "jcx" ],
+[ 6865, "jcy" ],
+[ 6866, "jcz" ],
+[ 6867, "jda" ],
+[ 6868, "jdb" ],
+[ 6869, "jdc" ],
+[ 6870, "jdd" ],
+[ 6871, "jde" ],
+[ 6872, "jdf" ],
+[ 6873, "jdg" ],
+[ 6874, "jdh" ],
+[ 6875, "jdi" ],
+[ 6876, "jdj" ],
+[ 6877, "jdk" ],
+[ 6878, "jdl" ],
+[ 6879, "jdm" ],
+[ 6880, "jdn" ],
+[ 6881, "jdo" ],
+[ 6882, "jdp" ],
+[ 6883, "jdq" ],
+[ 6884, "jdr" ],
+[ 6885, "jds" ],
+[ 6886, "jdt" ],
+[ 6887, "jdu" ],
+[ 6888, "jdv" ],
+[ 6889, "jdw" ],
+[ 6890, "jdx" ],
+[ 6891, "jdy" ],
+[ 6892, "jdz" ],
+[ 6893, "jea" ],
+[ 6894, "jeb" ],
+[ 6895, "jec" ],
+[ 6896, "jed" ],
+[ 6897, "jee" ],
+[ 6898, "jef" ],
+[ 6899, "jeg" ],
+[ 6900, "jeh" ],
+[ 6901, "jei" ],
+[ 6902, "jej" ],
+[ 6903, "jek" ],
+[ 6904, "jel" ],
+[ 6905, "jem" ],
+[ 6906, "jen" ],
+[ 6907, "jeo" ],
+[ 6908, "jep" ],
+[ 6909, "jeq" ],
+[ 6910, "jer" ],
+[ 6911, "jes" ],
+[ 6912, "jet" ],
+[ 6913, "jeu" ],
+[ 6914, "jev" ],
+[ 6915, "jew" ],
+[ 6916, "jex" ],
+[ 6917, "jey" ],
+[ 6918, "jez" ],
+[ 6919, "jfa" ],
+[ 6920, "jfb" ],
+[ 6921, "jfc" ],
+[ 6922, "jfd" ],
+[ 6923, "jfe" ],
+[ 6924, "jff" ],
+[ 6925, "jfg" ],
+[ 6926, "jfh" ],
+[ 6927, "jfi" ],
+[ 6928, "jfj" ],
+[ 6929, "jfk" ],
+[ 6930, "jfl" ],
+[ 6931, "jfm" ],
+[ 6932, "jfn" ],
+[ 6933, "jfo" ],
+[ 6934, "jfp" ],
+[ 6935, "jfq" ],
+[ 6936, "jfr" ],
+[ 6937, "jfs" ],
+[ 6938, "jft" ],
+[ 6939, "jfu" ],
+[ 6940, "jfv" ],
+[ 6941, "jfw" ],
+[ 6942, "jfx" ],
+[ 6943, "jfy" ],
+[ 6944, "jfz" ],
+[ 6945, "jga" ],
+[ 6946, "jgb" ],
+[ 6947, "jgc" ],
+[ 6948, "jgd" ],
+[ 6949, "jge" ],
+[ 6950, "jgf" ],
+[ 6951, "jgg" ],
+[ 6952, "jgh" ],
+[ 6953, "jgi" ],
+[ 6954, "jgj" ],
+[ 6955, "jgk" ],
+[ 6956, "jgl" ],
+[ 6957, "jgm" ],
+[ 6958, "jgn" ],
+[ 6959, "jgo" ],
+[ 6960, "jgp" ],
+[ 6961, "jgq" ],
+[ 6962, "jgr" ],
+[ 6963, "jgs" ],
+[ 6964, "jgt" ],
+[ 6965, "jgu" ],
+[ 6966, "jgv" ],
+[ 6967, "jgw" ],
+[ 6968, "jgx" ],
+[ 6969, "jgy" ],
+[ 6970, "jgz" ],
+[ 6971, "jha" ],
+[ 6972, "jhb" ],
+[ 6973, "jhc" ],
+[ 6974, "jhd" ],
+[ 6975, "jhe" ],
+[ 6976, "jhf" ],
+[ 6977, "jhg" ],
+[ 6978, "jhh" ],
+[ 6979, "jhi" ],
+[ 6980, "jhj" ],
+[ 6981, "jhk" ],
+[ 6982, "jhl" ],
+[ 6983, "jhm" ],
+[ 6984, "jhn" ],
+[ 6985, "jho" ],
+[ 6986, "jhp" ],
+[ 6987, "jhq" ],
+[ 6988, "jhr" ],
+[ 6989, "jhs" ],
+[ 6990, "jht" ],
+[ 6991, "jhu" ],
+[ 6992, "jhv" ],
+[ 6993, "jhw" ],
+[ 6994, "jhx" ],
+[ 6995, "jhy" ],
+[ 6996, "jhz" ],
+[ 6997, "jia" ],
+[ 6998, "jib" ],
+[ 6999, "jic" ],
+[ 7000, "jid" ],
+[ 7001, "jie" ],
+[ 7002, "jif" ],
+[ 7003, "jig" ],
+[ 7004, "jih" ],
+[ 7005, "jii" ],
+[ 7006, "jij" ],
+[ 7007, "jik" ],
+[ 7008, "jil" ],
+[ 7009, "jim" ],
+[ 7010, "jin" ],
+[ 7011, "jio" ],
+[ 7012, "jip" ],
+[ 7013, "jiq" ],
+[ 7014, "jir" ],
+[ 7015, "jis" ],
+[ 7016, "jit" ],
+[ 7017, "jiu" ],
+[ 7018, "jiv" ],
+[ 7019, "jiw" ],
+[ 7020, "jix" ],
+[ 7021, "jiy" ],
+[ 7022, "jiz" ],
+[ 7023, "jja" ],
+[ 7024, "jjb" ],
+[ 7025, "jjc" ],
+[ 7026, "jjd" ],
+[ 7027, "jje" ],
+[ 7028, "jjf" ],
+[ 7029, "jjg" ],
+[ 7030, "jjh" ],
+[ 7031, "jji" ],
+[ 7032, "jjj" ],
+[ 7033, "jjk" ],
+[ 7034, "jjl" ],
+[ 7035, "jjm" ],
+[ 7036, "jjn" ],
+[ 7037, "jjo" ],
+[ 7038, "jjp" ],
+[ 7039, "jjq" ],
+[ 7040, "jjr" ],
+[ 7041, "jjs" ],
+[ 7042, "jjt" ],
+[ 7043, "jju" ],
+[ 7044, "jjv" ],
+[ 7045, "jjw" ],
+[ 7046, "jjx" ],
+[ 7047, "jjy" ],
+[ 7048, "jjz" ],
+[ 7049, "jka" ],
+[ 7050, "jkb" ],
+[ 7051, "jkc" ],
+[ 7052, "jkd" ],
+[ 7053, "jke" ],
+[ 7054, "jkf" ],
+[ 7055, "jkg" ],
+[ 7056, "jkh" ],
+[ 7057, "jki" ],
+[ 7058, "jkj" ],
+[ 7059, "jkk" ],
+[ 7060, "jkl" ],
+[ 7061, "jkm" ],
+[ 7062, "jkn" ],
+[ 7063, "jko" ],
+[ 7064, "jkp" ],
+[ 7065, "jkq" ],
+[ 7066, "jkr" ],
+[ 7067, "jks" ],
+[ 7068, "jkt" ],
+[ 7069, "jku" ],
+[ 7070, "jkv" ],
+[ 7071, "jkw" ],
+[ 7072, "jkx" ],
+[ 7073, "jky" ],
+[ 7074, "jkz" ],
+[ 7075, "jla" ],
+[ 7076, "jlb" ],
+[ 7077, "jlc" ],
+[ 7078, "jld" ],
+[ 7079, "jle" ],
+[ 7080, "jlf" ],
+[ 7081, "jlg" ],
+[ 7082, "jlh" ],
+[ 7083, "jli" ],
+[ 7084, "jlj" ],
+[ 7085, "jlk" ],
+[ 7086, "jll" ],
+[ 7087, "jlm" ],
+[ 7088, "jln" ],
+[ 7089, "jlo" ],
+[ 7090, "jlp" ],
+[ 7091, "jlq" ],
+[ 7092, "jlr" ],
+[ 7093, "jls" ],
+[ 7094, "jlt" ],
+[ 7095, "jlu" ],
+[ 7096, "jlv" ],
+[ 7097, "jlw" ],
+[ 7098, "jlx" ],
+[ 7099, "jly" ],
+[ 7100, "jlz" ],
+[ 7101, "jma" ],
+[ 7102, "jmb" ],
+[ 7103, "jmc" ],
+[ 7104, "jmd" ],
+[ 7105, "jme" ],
+[ 7106, "jmf" ],
+[ 7107, "jmg" ],
+[ 7108, "jmh" ],
+[ 7109, "jmi" ],
+[ 7110, "jmj" ],
+[ 7111, "jmk" ],
+[ 7112, "jml" ],
+[ 7113, "jmm" ],
+[ 7114, "jmn" ],
+[ 7115, "jmo" ],
+[ 7116, "jmp" ],
+[ 7117, "jmq" ],
+[ 7118, "jmr" ],
+[ 7119, "jms" ],
+[ 7120, "jmt" ],
+[ 7121, "jmu" ],
+[ 7122, "jmv" ],
+[ 7123, "jmw" ],
+[ 7124, "jmx" ],
+[ 7125, "jmy" ],
+[ 7126, "jmz" ],
+[ 7127, "jna" ],
+[ 7128, "jnb" ],
+[ 7129, "jnc" ],
+[ 7130, "jnd" ],
+[ 7131, "jne" ],
+[ 7132, "jnf" ],
+[ 7133, "jng" ],
+[ 7134, "jnh" ],
+[ 7135, "jni" ],
+[ 7136, "jnj" ],
+[ 7137, "jnk" ],
+[ 7138, "jnl" ],
+[ 7139, "jnm" ],
+[ 7140, "jnn" ],
+[ 7141, "jno" ],
+[ 7142, "jnp" ],
+[ 7143, "jnq" ],
+[ 7144, "jnr" ],
+[ 7145, "jns" ],
+[ 7146, "jnt" ],
+[ 7147, "jnu" ],
+[ 7148, "jnv" ],
+[ 7149, "jnw" ],
+[ 7150, "jnx" ],
+[ 7151, "jny" ],
+[ 7152, "jnz" ],
+[ 7153, "joa" ],
+[ 7154, "job" ],
+[ 7155, "joc" ],
+[ 7156, "jod" ],
+[ 7157, "joe" ],
+[ 7158, "jof" ],
+[ 7159, "jog" ],
+[ 7160, "joh" ],
+[ 7161, "joi" ],
+[ 7162, "joj" ],
+[ 7163, "jok" ],
+[ 7164, "jol" ],
+[ 7165, "jom" ],
+[ 7166, "jon" ],
+[ 7167, "joo" ],
+[ 7168, "jop" ],
+[ 7169, "joq" ],
+[ 7170, "jor" ],
+[ 7171, "jos" ],
+[ 7172, "jot" ],
+[ 7173, "jou" ],
+[ 7174, "jov" ],
+[ 7175, "jow" ],
+[ 7176, "jox" ],
+[ 7177, "joy" ],
+[ 7178, "joz" ],
+[ 7179, "jpa" ],
+[ 7180, "jpb" ],
+[ 7181, "jpc" ],
+[ 7182, "jpd" ],
+[ 7183, "jpe" ],
+[ 7184, "jpf" ],
+[ 7185, "jpg" ],
+[ 7186, "jph" ],
+[ 7187, "jpi" ],
+[ 7188, "jpj" ],
+[ 7189, "jpk" ],
+[ 7190, "jpl" ],
+[ 7191, "jpm" ],
+[ 7192, "jpn" ],
+[ 7193, "jpo" ],
+[ 7194, "jpp" ],
+[ 7195, "jpq" ],
+[ 7196, "jpr" ],
+[ 7197, "jps" ],
+[ 7198, "jpt" ],
+[ 7199, "jpu" ],
+[ 7200, "jpv" ],
+[ 7201, "jpw" ],
+[ 7202, "jpx" ],
+[ 7203, "jpy" ],
+[ 7204, "jpz" ],
+[ 7205, "jqa" ],
+[ 7206, "jqb" ],
+[ 7207, "jqc" ],
+[ 7208, "jqd" ],
+[ 7209, "jqe" ],
+[ 7210, "jqf" ],
+[ 7211, "jqg" ],
+[ 7212, "jqh" ],
+[ 7213, "jqi" ],
+[ 7214, "jqj" ],
+[ 7215, "jqk" ],
+[ 7216, "jql" ],
+[ 7217, "jqm" ],
+[ 7218, "jqn" ],
+[ 7219, "jqo" ],
+[ 7220, "jqp" ],
+[ 7221, "jqq" ],
+[ 7222, "jqr" ],
+[ 7223, "jqs" ],
+[ 7224, "jqt" ],
+[ 7225, "jqu" ],
+[ 7226, "jqv" ],
+[ 7227, "jqw" ],
+[ 7228, "jqx" ],
+[ 7229, "jqy" ],
+[ 7230, "jqz" ],
+[ 7231, "jra" ],
+[ 7232, "jrb" ],
+[ 7233, "jrc" ],
+[ 7234, "jrd" ],
+[ 7235, "jre" ],
+[ 7236, "jrf" ],
+[ 7237, "jrg" ],
+[ 7238, "jrh" ],
+[ 7239, "jri" ],
+[ 7240, "jrj" ],
+[ 7241, "jrk" ],
+[ 7242, "jrl" ],
+[ 7243, "jrm" ],
+[ 7244, "jrn" ],
+[ 7245, "jro" ],
+[ 7246, "jrp" ],
+[ 7247, "jrq" ],
+[ 7248, "jrr" ],
+[ 7249, "jrs" ],
+[ 7250, "jrt" ],
+[ 7251, "jru" ],
+[ 7252, "jrv" ],
+[ 7253, "jrw" ],
+[ 7254, "jrx" ],
+[ 7255, "jry" ],
+[ 7256, "jrz" ],
+[ 7257, "jsa" ],
+[ 7258, "jsb" ],
+[ 7259, "jsc" ],
+[ 7260, "jsd" ],
+[ 7261, "jse" ],
+[ 7262, "jsf" ],
+[ 7263, "jsg" ],
+[ 7264, "jsh" ],
+[ 7265, "jsi" ],
+[ 7266, "jsj" ],
+[ 7267, "jsk" ],
+[ 7268, "jsl" ],
+[ 7269, "jsm" ],
+[ 7270, "jsn" ],
+[ 7271, "jso" ],
+[ 7272, "jsp" ],
+[ 7273, "jsq" ],
+[ 7274, "jsr" ],
+[ 7275, "jss" ],
+[ 7276, "jst" ],
+[ 7277, "jsu" ],
+[ 7278, "jsv" ],
+[ 7279, "jsw" ],
+[ 7280, "jsx" ],
+[ 7281, "jsy" ],
+[ 7282, "jsz" ],
+[ 7283, "jta" ],
+[ 7284, "jtb" ],
+[ 7285, "jtc" ],
+[ 7286, "jtd" ],
+[ 7287, "jte" ],
+[ 7288, "jtf" ],
+[ 7289, "jtg" ],
+[ 7290, "jth" ],
+[ 7291, "jti" ],
+[ 7292, "jtj" ],
+[ 7293, "jtk" ],
+[ 7294, "jtl" ],
+[ 7295, "jtm" ],
+[ 7296, "jtn" ],
+[ 7297, "jto" ],
+[ 7298, "jtp" ],
+[ 7299, "jtq" ],
+[ 7300, "jtr" ],
+[ 7301, "jts" ],
+[ 7302, "jtt" ],
+[ 7303, "jtu" ],
+[ 7304, "jtv" ],
+[ 7305, "jtw" ],
+[ 7306, "jtx" ],
+[ 7307, "jty" ],
+[ 7308, "jtz" ],
+[ 7309, "jua" ],
+[ 7310, "jub" ],
+[ 7311, "juc" ],
+[ 7312, "jud" ],
+[ 7313, "jue" ],
+[ 7314, "juf" ],
+[ 7315, "jug" ],
+[ 7316, "juh" ],
+[ 7317, "jui" ],
+[ 7318, "juj" ],
+[ 7319, "juk" ],
+[ 7320, "jul" ],
+[ 7321, "jum" ],
+[ 7322, "jun" ],
+[ 7323, "juo" ],
+[ 7324, "jup" ],
+[ 7325, "juq" ],
+[ 7326, "jur" ],
+[ 7327, "jus" ],
+[ 7328, "jut" ],
+[ 7329, "juu" ],
+[ 7330, "juv" ],
+[ 7331, "juw" ],
+[ 7332, "jux" ],
+[ 7333, "juy" ],
+[ 7334, "juz" ],
+[ 7335, "jva" ],
+[ 7336, "jvb" ],
+[ 7337, "jvc" ],
+[ 7338, "jvd" ],
+[ 7339, "jve" ],
+[ 7340, "jvf" ],
+[ 7341, "jvg" ],
+[ 7342, "jvh" ],
+[ 7343, "jvi" ],
+[ 7344, "jvj" ],
+[ 7345, "jvk" ],
+[ 7346, "jvl" ],
+[ 7347, "jvm" ],
+[ 7348, "jvn" ],
+[ 7349, "jvo" ],
+[ 7350, "jvp" ],
+[ 7351, "jvq" ],
+[ 7352, "jvr" ],
+[ 7353, "jvs" ],
+[ 7354, "jvt" ],
+[ 7355, "jvu" ],
+[ 7356, "jvv" ],
+[ 7357, "jvw" ],
+[ 7358, "jvx" ],
+[ 7359, "jvy" ],
+[ 7360, "jvz" ],
+[ 7361, "jwa" ],
+[ 7362, "jwb" ],
+[ 7363, "jwc" ],
+[ 7364, "jwd" ],
+[ 7365, "jwe" ],
+[ 7366, "jwf" ],
+[ 7367, "jwg" ],
+[ 7368, "jwh" ],
+[ 7369, "jwi" ],
+[ 7370, "jwj" ],
+[ 7371, "jwk" ],
+[ 7372, "jwl" ],
+[ 7373, "jwm" ],
+[ 7374, "jwn" ],
+[ 7375, "jwo" ],
+[ 7376, "jwp" ],
+[ 7377, "jwq" ],
+[ 7378, "jwr" ],
+[ 7379, "jws" ],
+[ 7380, "jwt" ],
+[ 7381, "jwu" ],
+[ 7382, "jwv" ],
+[ 7383, "jww" ],
+[ 7384, "jwx" ],
+[ 7385, "jwy" ],
+[ 7386, "jwz" ],
+[ 7387, "jxa" ],
+[ 7388, "jxb" ],
+[ 7389, "jxc" ],
+[ 7390, "jxd" ],
+[ 7391, "jxe" ],
+[ 7392, "jxf" ],
+[ 7393, "jxg" ],
+[ 7394, "jxh" ],
+[ 7395, "jxi" ],
+[ 7396, "jxj" ],
+[ 7397, "jxk" ],
+[ 7398, "jxl" ],
+[ 7399, "jxm" ],
+[ 7400, "jxn" ],
+[ 7401, "jxo" ],
+[ 7402, "jxp" ],
+[ 7403, "jxq" ],
+[ 7404, "jxr" ],
+[ 7405, "jxs" ],
+[ 7406, "jxt" ],
+[ 7407, "jxu" ],
+[ 7408, "jxv" ],
+[ 7409, "jxw" ],
+[ 7410, "jxx" ],
+[ 7411, "jxy" ],
+[ 7412, "jxz" ],
+[ 7413, "jya" ],
+[ 7414, "jyb" ],
+[ 7415, "jyc" ],
+[ 7416, "jyd" ],
+[ 7417, "jye" ],
+[ 7418, "jyf" ],
+[ 7419, "jyg" ],
+[ 7420, "jyh" ],
+[ 7421, "jyi" ],
+[ 7422, "jyj" ],
+[ 7423, "jyk" ],
+[ 7424, "jyl" ],
+[ 7425, "jym" ],
+[ 7426, "jyn" ],
+[ 7427, "jyo" ],
+[ 7428, "jyp" ],
+[ 7429, "jyq" ],
+[ 7430, "jyr" ],
+[ 7431, "jys" ],
+[ 7432, "jyt" ],
+[ 7433, "jyu" ],
+[ 7434, "jyv" ],
+[ 7435, "jyw" ],
+[ 7436, "jyx" ],
+[ 7437, "jyy" ],
+[ 7438, "jyz" ],
+[ 7439, "jza" ],
+[ 7440, "jzb" ],
+[ 7441, "jzc" ],
+[ 7442, "jzd" ],
+[ 7443, "jze" ],
+[ 7444, "jzf" ],
+[ 7445, "jzg" ],
+[ 7446, "jzh" ],
+[ 7447, "jzi" ],
+[ 7448, "jzj" ],
+[ 7449, "jzk" ],
+[ 7450, "jzl" ],
+[ 7451, "jzm" ],
+[ 7452, "jzn" ],
+[ 7453, "jzo" ],
+[ 7454, "jzp" ],
+[ 7455, "jzq" ],
+[ 7456, "jzr" ],
+[ 7457, "jzs" ],
+[ 7458, "jzt" ],
+[ 7459, "jzu" ],
+[ 7460, "jzv" ],
+[ 7461, "jzw" ],
+[ 7462, "jzx" ],
+[ 7463, "jzy" ],
+[ 7464, "jzz" ],
+[ 7465, "kaa" ],
+[ 7466, "kab" ],
+[ 7467, "kac" ],
+[ 7468, "kad" ],
+[ 7469, "kae" ],
+[ 7470, "kaf" ],
+[ 7471, "kag" ],
+[ 7472, "kah" ],
+[ 7473, "kai" ],
+[ 7474, "kaj" ],
+[ 7475, "kak" ],
+[ 7476, "kal" ],
+[ 7477, "kam" ],
+[ 7478, "kan" ],
+[ 7479, "kao" ],
+[ 7480, "kap" ],
+[ 7481, "kaq" ],
+[ 7482, "kar" ],
+[ 7483, "kas" ],
+[ 7484, "kat" ],
+[ 7485, "kau" ],
+[ 7486, "kav" ],
+[ 7487, "kaw" ],
+[ 7488, "kax" ],
+[ 7489, "kay" ],
+[ 7490, "kaz" ],
+[ 7491, "kba" ],
+[ 7492, "kbb" ],
+[ 7493, "kbc" ],
+[ 7494, "kbd" ],
+[ 7495, "kbe" ],
+[ 7496, "kbf" ],
+[ 7497, "kbg" ],
+[ 7498, "kbh" ],
+[ 7499, "kbi" ],
+[ 7500, "kbj" ],
+[ 7501, "kbk" ],
+[ 7502, "kbl" ],
+[ 7503, "kbm" ],
+[ 7504, "kbn" ],
+[ 7505, "kbo" ],
+[ 7506, "kbp" ],
+[ 7507, "kbq" ],
+[ 7508, "kbr" ],
+[ 7509, "kbs" ],
+[ 7510, "kbt" ],
+[ 7511, "kbu" ],
+[ 7512, "kbv" ],
+[ 7513, "kbw" ],
+[ 7514, "kbx" ],
+[ 7515, "kby" ],
+[ 7516, "kbz" ],
+[ 7517, "kca" ],
+[ 7518, "kcb" ],
+[ 7519, "kcc" ],
+[ 7520, "kcd" ],
+[ 7521, "kce" ],
+[ 7522, "kcf" ],
+[ 7523, "kcg" ],
+[ 7524, "kch" ],
+[ 7525, "kci" ],
+[ 7526, "kcj" ],
+[ 7527, "kck" ],
+[ 7528, "kcl" ],
+[ 7529, "kcm" ],
+[ 7530, "kcn" ],
+[ 7531, "kco" ],
+[ 7532, "kcp" ],
+[ 7533, "kcq" ],
+[ 7534, "kcr" ],
+[ 7535, "kcs" ],
+[ 7536, "kct" ],
+[ 7537, "kcu" ],
+[ 7538, "kcv" ],
+[ 7539, "kcw" ],
+[ 7540, "kcx" ],
+[ 7541, "kcy" ],
+[ 7542, "kcz" ],
+[ 7543, "kda" ],
+[ 7544, "kdb" ],
+[ 7545, "kdc" ],
+[ 7546, "kdd" ],
+[ 7547, "kde" ],
+[ 7548, "kdf" ],
+[ 7549, "kdg" ],
+[ 7550, "kdh" ],
+[ 7551, "kdi" ],
+[ 7552, "kdj" ],
+[ 7553, "kdk" ],
+[ 7554, "kdl" ],
+[ 7555, "kdm" ],
+[ 7556, "kdn" ],
+[ 7557, "kdo" ],
+[ 7558, "kdp" ],
+[ 7559, "kdq" ],
+[ 7560, "kdr" ],
+[ 7561, "kds" ],
+[ 7562, "kdt" ],
+[ 7563, "kdu" ],
+[ 7564, "kdv" ],
+[ 7565, "kdw" ],
+[ 7566, "kdx" ],
+[ 7567, "kdy" ],
+[ 7568, "kdz" ],
+[ 7569, "kea" ],
+[ 7570, "keb" ],
+[ 7571, "kec" ],
+[ 7572, "ked" ],
+[ 7573, "kee" ],
+[ 7574, "kef" ],
+[ 7575, "keg" ],
+[ 7576, "keh" ],
+[ 7577, "kei" ],
+[ 7578, "kej" ],
+[ 7579, "kek" ],
+[ 7580, "kel" ],
+[ 7581, "kem" ],
+[ 7582, "ken" ],
+[ 7583, "keo" ],
+[ 7584, "kep" ],
+[ 7585, "keq" ],
+[ 7586, "ker" ],
+[ 7587, "kes" ],
+[ 7588, "ket" ],
+[ 7589, "keu" ],
+[ 7590, "kev" ],
+[ 7591, "kew" ],
+[ 7592, "kex" ],
+[ 7593, "key" ],
+[ 7594, "kez" ],
+[ 7595, "kfa" ],
+[ 7596, "kfb" ],
+[ 7597, "kfc" ],
+[ 7598, "kfd" ],
+[ 7599, "kfe" ],
+[ 7600, "kff" ],
+[ 7601, "kfg" ],
+[ 7602, "kfh" ],
+[ 7603, "kfi" ],
+[ 7604, "kfj" ],
+[ 7605, "kfk" ],
+[ 7606, "kfl" ],
+[ 7607, "kfm" ],
+[ 7608, "kfn" ],
+[ 7609, "kfo" ],
+[ 7610, "kfp" ],
+[ 7611, "kfq" ],
+[ 7612, "kfr" ],
+[ 7613, "kfs" ],
+[ 7614, "kft" ],
+[ 7615, "kfu" ],
+[ 7616, "kfv" ],
+[ 7617, "kfw" ],
+[ 7618, "kfx" ],
+[ 7619, "kfy" ],
+[ 7620, "kfz" ],
+[ 7621, "kga" ],
+[ 7622, "kgb" ],
+[ 7623, "kgc" ],
+[ 7624, "kgd" ],
+[ 7625, "kge" ],
+[ 7626, "kgf" ],
+[ 7627, "kgg" ],
+[ 7628, "kgh" ],
+[ 7629, "kgi" ],
+[ 7630, "kgj" ],
+[ 7631, "kgk" ],
+[ 7632, "kgl" ],
+[ 7633, "kgm" ],
+[ 7634, "kgn" ],
+[ 7635, "kgo" ],
+[ 7636, "kgp" ],
+[ 7637, "kgq" ],
+[ 7638, "kgr" ],
+[ 7639, "kgs" ],
+[ 7640, "kgt" ],
+[ 7641, "kgu" ],
+[ 7642, "kgv" ],
+[ 7643, "kgw" ],
+[ 7644, "kgx" ],
+[ 7645, "kgy" ],
+[ 7646, "kgz" ],
+[ 7647, "kha" ],
+[ 7648, "khb" ],
+[ 7649, "khc" ],
+[ 7650, "khd" ],
+[ 7651, "khe" ],
+[ 7652, "khf" ],
+[ 7653, "khg" ],
+[ 7654, "khh" ],
+[ 7655, "khi" ],
+[ 7656, "khj" ],
+[ 7657, "khk" ],
+[ 7658, "khl" ],
+[ 7659, "khm" ],
+[ 7660, "khn" ],
+[ 7661, "kho" ],
+[ 7662, "khp" ],
+[ 7663, "khq" ],
+[ 7664, "khr" ],
+[ 7665, "khs" ],
+[ 7666, "kht" ],
+[ 7667, "khu" ],
+[ 7668, "khv" ],
+[ 7669, "khw" ],
+[ 7670, "khx" ],
+[ 7671, "khy" ],
+[ 7672, "khz" ],
+[ 7673, "kia" ],
+[ 7674, "kib" ],
+[ 7675, "kic" ],
+[ 7676, "kid" ],
+[ 7677, "kie" ],
+[ 7678, "kif" ],
+[ 7679, "kig" ],
+[ 7680, "kih" ],
+[ 7681, "kii" ],
+[ 7682, "kij" ],
+[ 7683, "kik" ],
+[ 7684, "kil" ],
+[ 7685, "kim" ],
+[ 7686, "kin" ],
+[ 7687, "kio" ],
+[ 7688, "kip" ],
+[ 7689, "kiq" ],
+[ 7690, "kir" ],
+[ 7691, "kis" ],
+[ 7692, "kit" ],
+[ 7693, "kiu" ],
+[ 7694, "kiv" ],
+[ 7695, "kiw" ],
+[ 7696, "kix" ],
+[ 7697, "kiy" ],
+[ 7698, "kiz" ],
+[ 7699, "kja" ],
+[ 7700, "kjb" ],
+[ 7701, "kjc" ],
+[ 7702, "kjd" ],
+[ 7703, "kje" ],
+[ 7704, "kjf" ],
+[ 7705, "kjg" ],
+[ 7706, "kjh" ],
+[ 7707, "kji" ],
+[ 7708, "kjj" ],
+[ 7709, "kjk" ],
+[ 7710, "kjl" ],
+[ 7711, "kjm" ],
+[ 7712, "kjn" ],
+[ 7713, "kjo" ],
+[ 7714, "kjp" ],
+[ 7715, "kjq" ],
+[ 7716, "kjr" ],
+[ 7717, "kjs" ],
+[ 7718, "kjt" ],
+[ 7719, "kju" ],
+[ 7720, "kjv" ],
+[ 7721, "kjw" ],
+[ 7722, "kjx" ],
+[ 7723, "kjy" ],
+[ 7724, "kjz" ],
+[ 7725, "kka" ],
+[ 7726, "kkb" ],
+[ 7727, "kkc" ],
+[ 7728, "kkd" ],
+[ 7729, "kke" ],
+[ 7730, "kkf" ],
+[ 7731, "kkg" ],
+[ 7732, "kkh" ],
+[ 7733, "kki" ],
+[ 7734, "kkj" ],
+[ 7735, "kkk" ],
+[ 7736, "kkl" ],
+[ 7737, "kkm" ],
+[ 7738, "kkn" ],
+[ 7739, "kko" ],
+[ 7740, "kkp" ],
+[ 7741, "kkq" ],
+[ 7742, "kkr" ],
+[ 7743, "kks" ],
+[ 7744, "kkt" ],
+[ 7745, "kku" ],
+[ 7746, "kkv" ],
+[ 7747, "kkw" ],
+[ 7748, "kkx" ],
+[ 7749, "kky" ],
+[ 7750, "kkz" ],
+[ 7751, "kla" ],
+[ 7752, "klb" ],
+[ 7753, "klc" ],
+[ 7754, "kld" ],
+[ 7755, "kle" ],
+[ 7756, "klf" ],
+[ 7757, "klg" ],
+[ 7758, "klh" ],
+[ 7759, "kli" ],
+[ 7760, "klj" ],
+[ 7761, "klk" ],
+[ 7762, "kll" ],
+[ 7763, "klm" ],
+[ 7764, "kln" ],
+[ 7765, "klo" ],
+[ 7766, "klp" ],
+[ 7767, "klq" ],
+[ 7768, "klr" ],
+[ 7769, "kls" ],
+[ 7770, "klt" ],
+[ 7771, "klu" ],
+[ 7772, "klv" ],
+[ 7773, "klw" ],
+[ 7774, "klx" ],
+[ 7775, "kly" ],
+[ 7776, "klz" ],
+[ 7777, "kma" ],
+[ 7778, "kmb" ],
+[ 7779, "kmc" ],
+[ 7780, "kmd" ],
+[ 7781, "kme" ],
+[ 7782, "kmf" ],
+[ 7783, "kmg" ],
+[ 7784, "kmh" ],
+[ 7785, "kmi" ],
+[ 7786, "kmj" ],
+[ 7787, "kmk" ],
+[ 7788, "kml" ],
+[ 7789, "kmm" ],
+[ 7790, "kmn" ],
+[ 7791, "kmo" ],
+[ 7792, "kmp" ],
+[ 7793, "kmq" ],
+[ 7794, "kmr" ],
+[ 7795, "kms" ],
+[ 7796, "kmt" ],
+[ 7797, "kmu" ],
+[ 7798, "kmv" ],
+[ 7799, "kmw" ],
+[ 7800, "kmx" ],
+[ 7801, "kmy" ],
+[ 7802, "kmz" ],
+[ 7803, "kna" ],
+[ 7804, "knb" ],
+[ 7805, "knc" ],
+[ 7806, "knd" ],
+[ 7807, "kne" ],
+[ 7808, "knf" ],
+[ 7809, "kng" ],
+[ 7810, "knh" ],
+[ 7811, "kni" ],
+[ 7812, "knj" ],
+[ 7813, "knk" ],
+[ 7814, "knl" ],
+[ 7815, "knm" ],
+[ 7816, "knn" ],
+[ 7817, "kno" ],
+[ 7818, "knp" ],
+[ 7819, "knq" ],
+[ 7820, "knr" ],
+[ 7821, "kns" ],
+[ 7822, "knt" ],
+[ 7823, "knu" ],
+[ 7824, "knv" ],
+[ 7825, "knw" ],
+[ 7826, "knx" ],
+[ 7827, "kny" ],
+[ 7828, "knz" ],
+[ 7829, "koa" ],
+[ 7830, "kob" ],
+[ 7831, "koc" ],
+[ 7832, "kod" ],
+[ 7833, "koe" ],
+[ 7834, "kof" ],
+[ 7835, "kog" ],
+[ 7836, "koh" ],
+[ 7837, "koi" ],
+[ 7838, "koj" ],
+[ 7839, "kok" ],
+[ 7840, "kol" ],
+[ 7841, "kom" ],
+[ 7842, "kon" ],
+[ 7843, "koo" ],
+[ 7844, "kop" ],
+[ 7845, "koq" ],
+[ 7846, "kor" ],
+[ 7847, "kos" ],
+[ 7848, "kot" ],
+[ 7849, "kou" ],
+[ 7850, "kov" ],
+[ 7851, "kow" ],
+[ 7852, "kox" ],
+[ 7853, "koy" ],
+[ 7854, "koz" ],
+[ 7855, "kpa" ],
+[ 7856, "kpb" ],
+[ 7857, "kpc" ],
+[ 7858, "kpd" ],
+[ 7859, "kpe" ],
+[ 7860, "kpf" ],
+[ 7861, "kpg" ],
+[ 7862, "kph" ],
+[ 7863, "kpi" ],
+[ 7864, "kpj" ],
+[ 7865, "kpk" ],
+[ 7866, "kpl" ],
+[ 7867, "kpm" ],
+[ 7868, "kpn" ],
+[ 7869, "kpo" ],
+[ 7870, "kpp" ],
+[ 7871, "kpq" ],
+[ 7872, "kpr" ],
+[ 7873, "kps" ],
+[ 7874, "kpt" ],
+[ 7875, "kpu" ],
+[ 7876, "kpv" ],
+[ 7877, "kpw" ],
+[ 7878, "kpx" ],
+[ 7879, "kpy" ],
+[ 7880, "kpz" ],
+[ 7881, "kqa" ],
+[ 7882, "kqb" ],
+[ 7883, "kqc" ],
+[ 7884, "kqd" ],
+[ 7885, "kqe" ],
+[ 7886, "kqf" ],
+[ 7887, "kqg" ],
+[ 7888, "kqh" ],
+[ 7889, "kqi" ],
+[ 7890, "kqj" ],
+[ 7891, "kqk" ],
+[ 7892, "kql" ],
+[ 7893, "kqm" ],
+[ 7894, "kqn" ],
+[ 7895, "kqo" ],
+[ 7896, "kqp" ],
+[ 7897, "kqq" ],
+[ 7898, "kqr" ],
+[ 7899, "kqs" ],
+[ 7900, "kqt" ],
+[ 7901, "kqu" ],
+[ 7902, "kqv" ],
+[ 7903, "kqw" ],
+[ 7904, "kqx" ],
+[ 7905, "kqy" ],
+[ 7906, "kqz" ],
+[ 7907, "kra" ],
+[ 7908, "krb" ],
+[ 7909, "krc" ],
+[ 7910, "krd" ],
+[ 7911, "kre" ],
+[ 7912, "krf" ],
+[ 7913, "krg" ],
+[ 7914, "krh" ],
+[ 7915, "kri" ],
+[ 7916, "krj" ],
+[ 7917, "krk" ],
+[ 7918, "krl" ],
+[ 7919, "krm" ],
+[ 7920, "krn" ],
+[ 7921, "kro" ],
+[ 7922, "krp" ],
+[ 7923, "krq" ],
+[ 7924, "krr" ],
+[ 7925, "krs" ],
+[ 7926, "krt" ],
+[ 7927, "kru" ],
+[ 7928, "krv" ],
+[ 7929, "krw" ],
+[ 7930, "krx" ],
+[ 7931, "kry" ],
+[ 7932, "krz" ],
+[ 7933, "ksa" ],
+[ 7934, "ksb" ],
+[ 7935, "ksc" ],
+[ 7936, "ksd" ],
+[ 7937, "kse" ],
+[ 7938, "ksf" ],
+[ 7939, "ksg" ],
+[ 7940, "ksh" ],
+[ 7941, "ksi" ],
+[ 7942, "ksj" ],
+[ 7943, "ksk" ],
+[ 7944, "ksl" ],
+[ 7945, "ksm" ],
+[ 7946, "ksn" ],
+[ 7947, "kso" ],
+[ 7948, "ksp" ],
+[ 7949, "ksq" ],
+[ 7950, "ksr" ],
+[ 7951, "kss" ],
+[ 7952, "kst" ],
+[ 7953, "ksu" ],
+[ 7954, "ksv" ],
+[ 7955, "ksw" ],
+[ 7956, "ksx" ],
+[ 7957, "ksy" ],
+[ 7958, "ksz" ],
+[ 7959, "kta" ],
+[ 7960, "ktb" ],
+[ 7961, "ktc" ],
+[ 7962, "ktd" ],
+[ 7963, "kte" ],
+[ 7964, "ktf" ],
+[ 7965, "ktg" ],
+[ 7966, "kth" ],
+[ 7967, "kti" ],
+[ 7968, "ktj" ],
+[ 7969, "ktk" ],
+[ 7970, "ktl" ],
+[ 7971, "ktm" ],
+[ 7972, "ktn" ],
+[ 7973, "kto" ],
+[ 7974, "ktp" ],
+[ 7975, "ktq" ],
+[ 7976, "ktr" ],
+[ 7977, "kts" ],
+[ 7978, "ktt" ],
+[ 7979, "ktu" ],
+[ 7980, "ktv" ],
+[ 7981, "ktw" ],
+[ 7982, "ktx" ],
+[ 7983, "kty" ],
+[ 7984, "ktz" ],
+[ 7985, "kua" ],
+[ 7986, "kub" ],
+[ 7987, "kuc" ],
+[ 7988, "kud" ],
+[ 7989, "kue" ],
+[ 7990, "kuf" ],
+[ 7991, "kug" ],
+[ 7992, "kuh" ],
+[ 7993, "kui" ],
+[ 7994, "kuj" ],
+[ 7995, "kuk" ],
+[ 7996, "kul" ],
+[ 7997, "kum" ],
+[ 7998, "kun" ],
+[ 7999, "kuo" ],
+[ 8000, "kup" ],
+[ 8001, "kuq" ],
+[ 8002, "kur" ],
+[ 8003, "kus" ],
+[ 8004, "kut" ],
+[ 8005, "kuu" ],
+[ 8006, "kuv" ],
+[ 8007, "kuw" ],
+[ 8008, "kux" ],
+[ 8009, "kuy" ],
+[ 8010, "kuz" ],
+[ 8011, "kva" ],
+[ 8012, "kvb" ],
+[ 8013, "kvc" ],
+[ 8014, "kvd" ],
+[ 8015, "kve" ],
+[ 8016, "kvf" ],
+[ 8017, "kvg" ],
+[ 8018, "kvh" ],
+[ 8019, "kvi" ],
+[ 8020, "kvj" ],
+[ 8021, "kvk" ],
+[ 8022, "kvl" ],
+[ 8023, "kvm" ],
+[ 8024, "kvn" ],
+[ 8025, "kvo" ],
+[ 8026, "kvp" ],
+[ 8027, "kvq" ],
+[ 8028, "kvr" ],
+[ 8029, "kvs" ],
+[ 8030, "kvt" ],
+[ 8031, "kvu" ],
+[ 8032, "kvv" ],
+[ 8033, "kvw" ],
+[ 8034, "kvx" ],
+[ 8035, "kvy" ],
+[ 8036, "kvz" ],
+[ 8037, "kwa" ],
+[ 8038, "kwb" ],
+[ 8039, "kwc" ],
+[ 8040, "kwd" ],
+[ 8041, "kwe" ],
+[ 8042, "kwf" ],
+[ 8043, "kwg" ],
+[ 8044, "kwh" ],
+[ 8045, "kwi" ],
+[ 8046, "kwj" ],
+[ 8047, "kwk" ],
+[ 8048, "kwl" ],
+[ 8049, "kwm" ],
+[ 8050, "kwn" ],
+[ 8051, "kwo" ],
+[ 8052, "kwp" ],
+[ 8053, "kwq" ],
+[ 8054, "kwr" ],
+[ 8055, "kws" ],
+[ 8056, "kwt" ],
+[ 8057, "kwu" ],
+[ 8058, "kwv" ],
+[ 8059, "kww" ],
+[ 8060, "kwx" ],
+[ 8061, "kwy" ],
+[ 8062, "kwz" ],
+[ 8063, "kxa" ],
+[ 8064, "kxb" ],
+[ 8065, "kxc" ],
+[ 8066, "kxd" ],
+[ 8067, "kxe" ],
+[ 8068, "kxf" ],
+[ 8069, "kxg" ],
+[ 8070, "kxh" ],
+[ 8071, "kxi" ],
+[ 8072, "kxj" ],
+[ 8073, "kxk" ],
+[ 8074, "kxl" ],
+[ 8075, "kxm" ],
+[ 8076, "kxn" ],
+[ 8077, "kxo" ],
+[ 8078, "kxp" ],
+[ 8079, "kxq" ],
+[ 8080, "kxr" ],
+[ 8081, "kxs" ],
+[ 8082, "kxt" ],
+[ 8083, "kxu" ],
+[ 8084, "kxv" ],
+[ 8085, "kxw" ],
+[ 8086, "kxx" ],
+[ 8087, "kxy" ],
+[ 8088, "kxz" ],
+[ 8089, "kya" ],
+[ 8090, "kyb" ],
+[ 8091, "kyc" ],
+[ 8092, "kyd" ],
+[ 8093, "kye" ],
+[ 8094, "kyf" ],
+[ 8095, "kyg" ],
+[ 8096, "kyh" ],
+[ 8097, "kyi" ],
+[ 8098, "kyj" ],
+[ 8099, "kyk" ],
+[ 8100, "kyl" ],
+[ 8101, "kym" ],
+[ 8102, "kyn" ],
+[ 8103, "kyo" ],
+[ 8104, "kyp" ],
+[ 8105, "kyq" ],
+[ 8106, "kyr" ],
+[ 8107, "kys" ],
+[ 8108, "kyt" ],
+[ 8109, "kyu" ],
+[ 8110, "kyv" ],
+[ 8111, "kyw" ],
+[ 8112, "kyx" ],
+[ 8113, "kyy" ],
+[ 8114, "kyz" ],
+[ 8115, "kza" ],
+[ 8116, "kzb" ],
+[ 8117, "kzc" ],
+[ 8118, "kzd" ],
+[ 8119, "kze" ],
+[ 8120, "kzf" ],
+[ 8121, "kzg" ],
+[ 8122, "kzh" ],
+[ 8123, "kzi" ],
+[ 8124, "kzj" ],
+[ 8125, "kzk" ],
+[ 8126, "kzl" ],
+[ 8127, "kzm" ],
+[ 8128, "kzn" ],
+[ 8129, "kzo" ],
+[ 8130, "kzp" ],
+[ 8131, "kzq" ],
+[ 8132, "kzr" ],
+[ 8133, "kzs" ],
+[ 8134, "kzt" ],
+[ 8135, "kzu" ],
+[ 8136, "kzv" ],
+[ 8137, "kzw" ],
+[ 8138, "kzx" ],
+[ 8139, "kzy" ],
+[ 8140, "kzz" ],
+[ 8141, "laa" ],
+[ 8142, "lab" ],
+[ 8143, "lac" ],
+[ 8144, "lad" ],
+[ 8145, "lae" ],
+[ 8146, "laf" ],
+[ 8147, "lag" ],
+[ 8148, "lah" ],
+[ 8149, "lai" ],
+[ 8150, "laj" ],
+[ 8151, "lak" ],
+[ 8152, "lal" ],
+[ 8153, "lam" ],
+[ 8154, "lan" ],
+[ 8155, "lao" ],
+[ 8156, "lap" ],
+[ 8157, "laq" ],
+[ 8158, "lar" ],
+[ 8159, "las" ],
+[ 8160, "lat" ],
+[ 8161, "lau" ],
+[ 8162, "lav" ],
+[ 8163, "law" ],
+[ 8164, "lax" ],
+[ 8165, "lay" ],
+[ 8166, "laz" ],
+[ 8167, "lba" ],
+[ 8168, "lbb" ],
+[ 8169, "lbc" ],
+[ 8170, "lbd" ],
+[ 8171, "lbe" ],
+[ 8172, "lbf" ],
+[ 8173, "lbg" ],
+[ 8174, "lbh" ],
+[ 8175, "lbi" ],
+[ 8176, "lbj" ],
+[ 8177, "lbk" ],
+[ 8178, "lbl" ],
+[ 8179, "lbm" ],
+[ 8180, "lbn" ],
+[ 8181, "lbo" ],
+[ 8182, "lbp" ],
+[ 8183, "lbq" ],
+[ 8184, "lbr" ],
+[ 8185, "lbs" ],
+[ 8186, "lbt" ],
+[ 8187, "lbu" ],
+[ 8188, "lbv" ],
+[ 8189, "lbw" ],
+[ 8190, "lbx" ],
+[ 8191, "lby" ],
+[ 8192, "lbz" ],
+[ 8193, "lca" ],
+[ 8194, "lcb" ],
+[ 8195, "lcc" ],
+[ 8196, "lcd" ],
+[ 8197, "lce" ],
+[ 8198, "lcf" ],
+[ 8199, "lcg" ],
+[ 8200, "lch" ],
+[ 8201, "lci" ],
+[ 8202, "lcj" ],
+[ 8203, "lck" ],
+[ 8204, "lcl" ],
+[ 8205, "lcm" ],
+[ 8206, "lcn" ],
+[ 8207, "lco" ],
+[ 8208, "lcp" ],
+[ 8209, "lcq" ],
+[ 8210, "lcr" ],
+[ 8211, "lcs" ],
+[ 8212, "lct" ],
+[ 8213, "lcu" ],
+[ 8214, "lcv" ],
+[ 8215, "lcw" ],
+[ 8216, "lcx" ],
+[ 8217, "lcy" ],
+[ 8218, "lcz" ],
+[ 8219, "lda" ],
+[ 8220, "ldb" ],
+[ 8221, "ldc" ],
+[ 8222, "ldd" ],
+[ 8223, "lde" ],
+[ 8224, "ldf" ],
+[ 8225, "ldg" ],
+[ 8226, "ldh" ],
+[ 8227, "ldi" ],
+[ 8228, "ldj" ],
+[ 8229, "ldk" ],
+[ 8230, "ldl" ],
+[ 8231, "ldm" ],
+[ 8232, "ldn" ],
+[ 8233, "ldo" ],
+[ 8234, "ldp" ],
+[ 8235, "ldq" ],
+[ 8236, "ldr" ],
+[ 8237, "lds" ],
+[ 8238, "ldt" ],
+[ 8239, "ldu" ],
+[ 8240, "ldv" ],
+[ 8241, "ldw" ],
+[ 8242, "ldx" ],
+[ 8243, "ldy" ],
+[ 8244, "ldz" ],
+[ 8245, "lea" ],
+[ 8246, "leb" ],
+[ 8247, "lec" ],
+[ 8248, "led" ],
+[ 8249, "lee" ],
+[ 8250, "lef" ],
+[ 8251, "leg" ],
+[ 8252, "leh" ],
+[ 8253, "lei" ],
+[ 8254, "lej" ],
+[ 8255, "lek" ],
+[ 8256, "lel" ],
+[ 8257, "lem" ],
+[ 8258, "len" ],
+[ 8259, "leo" ],
+[ 8260, "lep" ],
+[ 8261, "leq" ],
+[ 8262, "ler" ],
+[ 8263, "les" ],
+[ 8264, "let" ],
+[ 8265, "leu" ],
+[ 8266, "lev" ],
+[ 8267, "lew" ],
+[ 8268, "lex" ],
+[ 8269, "ley" ],
+[ 8270, "lez" ],
+[ 8271, "lfa" ],
+[ 8272, "lfb" ],
+[ 8273, "lfc" ],
+[ 8274, "lfd" ],
+[ 8275, "lfe" ],
+[ 8276, "lff" ],
+[ 8277, "lfg" ],
+[ 8278, "lfh" ],
+[ 8279, "lfi" ],
+[ 8280, "lfj" ],
+[ 8281, "lfk" ],
+[ 8282, "lfl" ],
+[ 8283, "lfm" ],
+[ 8284, "lfn" ],
+[ 8285, "lfo" ],
+[ 8286, "lfp" ],
+[ 8287, "lfq" ],
+[ 8288, "lfr" ],
+[ 8289, "lfs" ],
+[ 8290, "lft" ],
+[ 8291, "lfu" ],
+[ 8292, "lfv" ],
+[ 8293, "lfw" ],
+[ 8294, "lfx" ],
+[ 8295, "lfy" ],
+[ 8296, "lfz" ],
+[ 8297, "lga" ],
+[ 8298, "lgb" ],
+[ 8299, "lgc" ],
+[ 8300, "lgd" ],
+[ 8301, "lge" ],
+[ 8302, "lgf" ],
+[ 8303, "lgg" ],
+[ 8304, "lgh" ],
+[ 8305, "lgi" ],
+[ 8306, "lgj" ],
+[ 8307, "lgk" ],
+[ 8308, "lgl" ],
+[ 8309, "lgm" ],
+[ 8310, "lgn" ],
+[ 8311, "lgo" ],
+[ 8312, "lgp" ],
+[ 8313, "lgq" ],
+[ 8314, "lgr" ],
+[ 8315, "lgs" ],
+[ 8316, "lgt" ],
+[ 8317, "lgu" ],
+[ 8318, "lgv" ],
+[ 8319, "lgw" ],
+[ 8320, "lgx" ],
+[ 8321, "lgy" ],
+[ 8322, "lgz" ],
+[ 8323, "lha" ],
+[ 8324, "lhb" ],
+[ 8325, "lhc" ],
+[ 8326, "lhd" ],
+[ 8327, "lhe" ],
+[ 8328, "lhf" ],
+[ 8329, "lhg" ],
+[ 8330, "lhh" ],
+[ 8331, "lhi" ],
+[ 8332, "lhj" ],
+[ 8333, "lhk" ],
+[ 8334, "lhl" ],
+[ 8335, "lhm" ],
+[ 8336, "lhn" ],
+[ 8337, "lho" ],
+[ 8338, "lhp" ],
+[ 8339, "lhq" ],
+[ 8340, "lhr" ],
+[ 8341, "lhs" ],
+[ 8342, "lht" ],
+[ 8343, "lhu" ],
+[ 8344, "lhv" ],
+[ 8345, "lhw" ],
+[ 8346, "lhx" ],
+[ 8347, "lhy" ],
+[ 8348, "lhz" ],
+[ 8349, "lia" ],
+[ 8350, "lib" ],
+[ 8351, "lic" ],
+[ 8352, "lid" ],
+[ 8353, "lie" ],
+[ 8354, "lif" ],
+[ 8355, "lig" ],
+[ 8356, "lih" ],
+[ 8357, "lii" ],
+[ 8358, "lij" ],
+[ 8359, "lik" ],
+[ 8360, "lil" ],
+[ 8361, "lim" ],
+[ 8362, "lin" ],
+[ 8363, "lio" ],
+[ 8364, "lip" ],
+[ 8365, "liq" ],
+[ 8366, "lir" ],
+[ 8367, "lis" ],
+[ 8368, "lit" ],
+[ 8369, "liu" ],
+[ 8370, "liv" ],
+[ 8371, "liw" ],
+[ 8372, "lix" ],
+[ 8373, "liy" ],
+[ 8374, "liz" ],
+[ 8375, "lja" ],
+[ 8376, "ljb" ],
+[ 8377, "ljc" ],
+[ 8378, "ljd" ],
+[ 8379, "lje" ],
+[ 8380, "ljf" ],
+[ 8381, "ljg" ],
+[ 8382, "ljh" ],
+[ 8383, "lji" ],
+[ 8384, "ljj" ],
+[ 8385, "ljk" ],
+[ 8386, "ljl" ],
+[ 8387, "ljm" ],
+[ 8388, "ljn" ],
+[ 8389, "ljo" ],
+[ 8390, "ljp" ],
+[ 8391, "ljq" ],
+[ 8392, "ljr" ],
+[ 8393, "ljs" ],
+[ 8394, "ljt" ],
+[ 8395, "lju" ],
+[ 8396, "ljv" ],
+[ 8397, "ljw" ],
+[ 8398, "ljx" ],
+[ 8399, "ljy" ],
+[ 8400, "ljz" ],
+[ 8401, "lka" ],
+[ 8402, "lkb" ],
+[ 8403, "lkc" ],
+[ 8404, "lkd" ],
+[ 8405, "lke" ],
+[ 8406, "lkf" ],
+[ 8407, "lkg" ],
+[ 8408, "lkh" ],
+[ 8409, "lki" ],
+[ 8410, "lkj" ],
+[ 8411, "lkk" ],
+[ 8412, "lkl" ],
+[ 8413, "lkm" ],
+[ 8414, "lkn" ],
+[ 8415, "lko" ],
+[ 8416, "lkp" ],
+[ 8417, "lkq" ],
+[ 8418, "lkr" ],
+[ 8419, "lks" ],
+[ 8420, "lkt" ],
+[ 8421, "lku" ],
+[ 8422, "lkv" ],
+[ 8423, "lkw" ],
+[ 8424, "lkx" ],
+[ 8425, "lky" ],
+[ 8426, "lkz" ],
+[ 8427, "lla" ],
+[ 8428, "llb" ],
+[ 8429, "llc" ],
+[ 8430, "lld" ],
+[ 8431, "lle" ],
+[ 8432, "llf" ],
+[ 8433, "llg" ],
+[ 8434, "llh" ],
+[ 8435, "lli" ],
+[ 8436, "llj" ],
+[ 8437, "llk" ],
+[ 8438, "lll" ],
+[ 8439, "llm" ],
+[ 8440, "lln" ],
+[ 8441, "llo" ],
+[ 8442, "llp" ],
+[ 8443, "llq" ],
+[ 8444, "llr" ],
+[ 8445, "lls" ],
+[ 8446, "llt" ],
+[ 8447, "llu" ],
+[ 8448, "llv" ],
+[ 8449, "llw" ],
+[ 8450, "llx" ],
+[ 8451, "lly" ],
+[ 8452, "llz" ],
+[ 8453, "lma" ],
+[ 8454, "lmb" ],
+[ 8455, "lmc" ],
+[ 8456, "lmd" ],
+[ 8457, "lme" ],
+[ 8458, "lmf" ],
+[ 8459, "lmg" ],
+[ 8460, "lmh" ],
+[ 8461, "lmi" ],
+[ 8462, "lmj" ],
+[ 8463, "lmk" ],
+[ 8464, "lml" ],
+[ 8465, "lmm" ],
+[ 8466, "lmn" ],
+[ 8467, "lmo" ],
+[ 8468, "lmp" ],
+[ 8469, "lmq" ],
+[ 8470, "lmr" ],
+[ 8471, "lms" ],
+[ 8472, "lmt" ],
+[ 8473, "lmu" ],
+[ 8474, "lmv" ],
+[ 8475, "lmw" ],
+[ 8476, "lmx" ],
+[ 8477, "lmy" ],
+[ 8478, "lmz" ],
+[ 8479, "lna" ],
+[ 8480, "lnb" ],
+[ 8481, "lnc" ],
+[ 8482, "lnd" ],
+[ 8483, "lne" ],
+[ 8484, "lnf" ],
+[ 8485, "lng" ],
+[ 8486, "lnh" ],
+[ 8487, "lni" ],
+[ 8488, "lnj" ],
+[ 8489, "lnk" ],
+[ 8490, "lnl" ],
+[ 8491, "lnm" ],
+[ 8492, "lnn" ],
+[ 8493, "lno" ],
+[ 8494, "lnp" ],
+[ 8495, "lnq" ],
+[ 8496, "lnr" ],
+[ 8497, "lns" ],
+[ 8498, "lnt" ],
+[ 8499, "lnu" ],
+[ 8500, "lnv" ],
+[ 8501, "lnw" ],
+[ 8502, "lnx" ],
+[ 8503, "lny" ],
+[ 8504, "lnz" ],
+[ 8505, "loa" ],
+[ 8506, "lob" ],
+[ 8507, "loc" ],
+[ 8508, "lod" ],
+[ 8509, "loe" ],
+[ 8510, "lof" ],
+[ 8511, "log" ],
+[ 8512, "loh" ],
+[ 8513, "loi" ],
+[ 8514, "loj" ],
+[ 8515, "lok" ],
+[ 8516, "lol" ],
+[ 8517, "lom" ],
+[ 8518, "lon" ],
+[ 8519, "loo" ],
+[ 8520, "lop" ],
+[ 8521, "loq" ],
+[ 8522, "lor" ],
+[ 8523, "los" ],
+[ 8524, "lot" ],
+[ 8525, "lou" ],
+[ 8526, "lov" ],
+[ 8527, "low" ],
+[ 8528, "lox" ],
+[ 8529, "loy" ],
+[ 8530, "loz" ],
+[ 8531, "lpa" ],
+[ 8532, "lpb" ],
+[ 8533, "lpc" ],
+[ 8534, "lpd" ],
+[ 8535, "lpe" ],
+[ 8536, "lpf" ],
+[ 8537, "lpg" ],
+[ 8538, "lph" ],
+[ 8539, "lpi" ],
+[ 8540, "lpj" ],
+[ 8541, "lpk" ],
+[ 8542, "lpl" ],
+[ 8543, "lpm" ],
+[ 8544, "lpn" ],
+[ 8545, "lpo" ],
+[ 8546, "lpp" ],
+[ 8547, "lpq" ],
+[ 8548, "lpr" ],
+[ 8549, "lps" ],
+[ 8550, "lpt" ],
+[ 8551, "lpu" ],
+[ 8552, "lpv" ],
+[ 8553, "lpw" ],
+[ 8554, "lpx" ],
+[ 8555, "lpy" ],
+[ 8556, "lpz" ],
+[ 8557, "lqa" ],
+[ 8558, "lqb" ],
+[ 8559, "lqc" ],
+[ 8560, "lqd" ],
+[ 8561, "lqe" ],
+[ 8562, "lqf" ],
+[ 8563, "lqg" ],
+[ 8564, "lqh" ],
+[ 8565, "lqi" ],
+[ 8566, "lqj" ],
+[ 8567, "lqk" ],
+[ 8568, "lql" ],
+[ 8569, "lqm" ],
+[ 8570, "lqn" ],
+[ 8571, "lqo" ],
+[ 8572, "lqp" ],
+[ 8573, "lqq" ],
+[ 8574, "lqr" ],
+[ 8575, "lqs" ],
+[ 8576, "lqt" ],
+[ 8577, "lqu" ],
+[ 8578, "lqv" ],
+[ 8579, "lqw" ],
+[ 8580, "lqx" ],
+[ 8581, "lqy" ],
+[ 8582, "lqz" ],
+[ 8583, "lra" ],
+[ 8584, "lrb" ],
+[ 8585, "lrc" ],
+[ 8586, "lrd" ],
+[ 8587, "lre" ],
+[ 8588, "lrf" ],
+[ 8589, "lrg" ],
+[ 8590, "lrh" ],
+[ 8591, "lri" ],
+[ 8592, "lrj" ],
+[ 8593, "lrk" ],
+[ 8594, "lrl" ],
+[ 8595, "lrm" ],
+[ 8596, "lrn" ],
+[ 8597, "lro" ],
+[ 8598, "lrp" ],
+[ 8599, "lrq" ],
+[ 8600, "lrr" ],
+[ 8601, "lrs" ],
+[ 8602, "lrt" ],
+[ 8603, "lru" ],
+[ 8604, "lrv" ],
+[ 8605, "lrw" ],
+[ 8606, "lrx" ],
+[ 8607, "lry" ],
+[ 8608, "lrz" ],
+[ 8609, "lsa" ],
+[ 8610, "lsb" ],
+[ 8611, "lsc" ],
+[ 8612, "lsd" ],
+[ 8613, "lse" ],
+[ 8614, "lsf" ],
+[ 8615, "lsg" ],
+[ 8616, "lsh" ],
+[ 8617, "lsi" ],
+[ 8618, "lsj" ],
+[ 8619, "lsk" ],
+[ 8620, "lsl" ],
+[ 8621, "lsm" ],
+[ 8622, "lsn" ],
+[ 8623, "lso" ],
+[ 8624, "lsp" ],
+[ 8625, "lsq" ],
+[ 8626, "lsr" ],
+[ 8627, "lss" ],
+[ 8628, "lst" ],
+[ 8629, "lsu" ],
+[ 8630, "lsv" ],
+[ 8631, "lsw" ],
+[ 8632, "lsx" ],
+[ 8633, "lsy" ],
+[ 8634, "lsz" ],
+[ 8635, "lta" ],
+[ 8636, "ltb" ],
+[ 8637, "ltc" ],
+[ 8638, "ltd" ],
+[ 8639, "lte" ],
+[ 8640, "ltf" ],
+[ 8641, "ltg" ],
+[ 8642, "lth" ],
+[ 8643, "lti" ],
+[ 8644, "ltj" ],
+[ 8645, "ltk" ],
+[ 8646, "ltl" ],
+[ 8647, "ltm" ],
+[ 8648, "ltn" ],
+[ 8649, "lto" ],
+[ 8650, "ltp" ],
+[ 8651, "ltq" ],
+[ 8652, "ltr" ],
+[ 8653, "lts" ],
+[ 8654, "ltt" ],
+[ 8655, "ltu" ],
+[ 8656, "ltv" ],
+[ 8657, "ltw" ],
+[ 8658, "ltx" ],
+[ 8659, "lty" ],
+[ 8660, "ltz" ],
+[ 8661, "lua" ],
+[ 8662, "lub" ],
+[ 8663, "luc" ],
+[ 8664, "lud" ],
+[ 8665, "lue" ],
+[ 8666, "luf" ],
+[ 8667, "lug" ],
+[ 8668, "luh" ],
+[ 8669, "lui" ],
+[ 8670, "luj" ],
+[ 8671, "luk" ],
+[ 8672, "lul" ],
+[ 8673, "lum" ],
+[ 8674, "lun" ],
+[ 8675, "luo" ],
+[ 8676, "lup" ],
+[ 8677, "luq" ],
+[ 8678, "lur" ],
+[ 8679, "lus" ],
+[ 8680, "lut" ],
+[ 8681, "luu" ],
+[ 8682, "luv" ],
+[ 8683, "luw" ],
+[ 8684, "lux" ],
+[ 8685, "luy" ],
+[ 8686, "luz" ],
+[ 8687, "lva" ],
+[ 8688, "lvb" ],
+[ 8689, "lvc" ],
+[ 8690, "lvd" ],
+[ 8691, "lve" ],
+[ 8692, "lvf" ],
+[ 8693, "lvg" ],
+[ 8694, "lvh" ],
+[ 8695, "lvi" ],
+[ 8696, "lvj" ],
+[ 8697, "lvk" ],
+[ 8698, "lvl" ],
+[ 8699, "lvm" ],
+[ 8700, "lvn" ],
+[ 8701, "lvo" ],
+[ 8702, "lvp" ],
+[ 8703, "lvq" ],
+[ 8704, "lvr" ],
+[ 8705, "lvs" ],
+[ 8706, "lvt" ],
+[ 8707, "lvu" ],
+[ 8708, "lvv" ],
+[ 8709, "lvw" ],
+[ 8710, "lvx" ],
+[ 8711, "lvy" ],
+[ 8712, "lvz" ],
+[ 8713, "lwa" ],
+[ 8714, "lwb" ],
+[ 8715, "lwc" ],
+[ 8716, "lwd" ],
+[ 8717, "lwe" ],
+[ 8718, "lwf" ],
+[ 8719, "lwg" ],
+[ 8720, "lwh" ],
+[ 8721, "lwi" ],
+[ 8722, "lwj" ],
+[ 8723, "lwk" ],
+[ 8724, "lwl" ],
+[ 8725, "lwm" ],
+[ 8726, "lwn" ],
+[ 8727, "lwo" ],
+[ 8728, "lwp" ],
+[ 8729, "lwq" ],
+[ 8730, "lwr" ],
+[ 8731, "lws" ],
+[ 8732, "lwt" ],
+[ 8733, "lwu" ],
+[ 8734, "lwv" ],
+[ 8735, "lww" ],
+[ 8736, "lwx" ],
+[ 8737, "lwy" ],
+[ 8738, "lwz" ],
+[ 8739, "lxa" ],
+[ 8740, "lxb" ],
+[ 8741, "lxc" ],
+[ 8742, "lxd" ],
+[ 8743, "lxe" ],
+[ 8744, "lxf" ],
+[ 8745, "lxg" ],
+[ 8746, "lxh" ],
+[ 8747, "lxi" ],
+[ 8748, "lxj" ],
+[ 8749, "lxk" ],
+[ 8750, "lxl" ],
+[ 8751, "lxm" ],
+[ 8752, "lxn" ],
+[ 8753, "lxo" ],
+[ 8754, "lxp" ],
+[ 8755, "lxq" ],
+[ 8756, "lxr" ],
+[ 8757, "lxs" ],
+[ 8758, "lxt" ],
+[ 8759, "lxu" ],
+[ 8760, "lxv" ],
+[ 8761, "lxw" ],
+[ 8762, "lxx" ],
+[ 8763, "lxy" ],
+[ 8764, "lxz" ],
+[ 8765, "lya" ],
+[ 8766, "lyb" ],
+[ 8767, "lyc" ],
+[ 8768, "lyd" ],
+[ 8769, "lye" ],
+[ 8770, "lyf" ],
+[ 8771, "lyg" ],
+[ 8772, "lyh" ],
+[ 8773, "lyi" ],
+[ 8774, "lyj" ],
+[ 8775, "lyk" ],
+[ 8776, "lyl" ],
+[ 8777, "lym" ],
+[ 8778, "lyn" ],
+[ 8779, "lyo" ],
+[ 8780, "lyp" ],
+[ 8781, "lyq" ],
+[ 8782, "lyr" ],
+[ 8783, "lys" ],
+[ 8784, "lyt" ],
+[ 8785, "lyu" ],
+[ 8786, "lyv" ],
+[ 8787, "lyw" ],
+[ 8788, "lyx" ],
+[ 8789, "lyy" ],
+[ 8790, "lyz" ],
+[ 8791, "lza" ],
+[ 8792, "lzb" ],
+[ 8793, "lzc" ],
+[ 8794, "lzd" ],
+[ 8795, "lze" ],
+[ 8796, "lzf" ],
+[ 8797, "lzg" ],
+[ 8798, "lzh" ],
+[ 8799, "lzi" ],
+[ 8800, "lzj" ],
+[ 8801, "lzk" ],
+[ 8802, "lzl" ],
+[ 8803, "lzm" ],
+[ 8804, "lzn" ],
+[ 8805, "lzo" ],
+[ 8806, "lzp" ],
+[ 8807, "lzq" ],
+[ 8808, "lzr" ],
+[ 8809, "lzs" ],
+[ 8810, "lzt" ],
+[ 8811, "lzu" ],
+[ 8812, "lzv" ],
+[ 8813, "lzw" ],
+[ 8814, "lzx" ],
+[ 8815, "lzy" ],
+[ 8816, "lzz" ],
+[ 8817, "maa" ],
+[ 8818, "mab" ],
+[ 8819, "mac" ],
+[ 8820, "mad" ],
+[ 8821, "mae" ],
+[ 8822, "maf" ],
+[ 8823, "mag" ],
+[ 8824, "mah" ],
+[ 8825, "mai" ],
+[ 8826, "maj" ],
+[ 8827, "mak" ],
+[ 8828, "mal" ],
+[ 8829, "mam" ],
+[ 8830, "man" ],
+[ 8831, "mao" ],
+[ 8832, "map" ],
+[ 8833, "maq" ],
+[ 8834, "mar" ],
+[ 8835, "mas" ],
+[ 8836, "mat" ],
+[ 8837, "mau" ],
+[ 8838, "mav" ],
+[ 8839, "maw" ],
+[ 8840, "max" ],
+[ 8841, "may" ],
+[ 8842, "maz" ],
+[ 8843, "mba" ],
+[ 8844, "mbb" ],
+[ 8845, "mbc" ],
+[ 8846, "mbd" ],
+[ 8847, "mbe" ],
+[ 8848, "mbf" ],
+[ 8849, "mbg" ],
+[ 8850, "mbh" ],
+[ 8851, "mbi" ],
+[ 8852, "mbj" ],
+[ 8853, "mbk" ],
+[ 8854, "mbl" ],
+[ 8855, "mbm" ],
+[ 8856, "mbn" ],
+[ 8857, "mbo" ],
+[ 8858, "mbp" ],
+[ 8859, "mbq" ],
+[ 8860, "mbr" ],
+[ 8861, "mbs" ],
+[ 8862, "mbt" ],
+[ 8863, "mbu" ],
+[ 8864, "mbv" ],
+[ 8865, "mbw" ],
+[ 8866, "mbx" ],
+[ 8867, "mby" ],
+[ 8868, "mbz" ],
+[ 8869, "mca" ],
+[ 8870, "mcb" ],
+[ 8871, "mcc" ],
+[ 8872, "mcd" ],
+[ 8873, "mce" ],
+[ 8874, "mcf" ],
+[ 8875, "mcg" ],
+[ 8876, "mch" ],
+[ 8877, "mci" ],
+[ 8878, "mcj" ],
+[ 8879, "mck" ],
+[ 8880, "mcl" ],
+[ 8881, "mcm" ],
+[ 8882, "mcn" ],
+[ 8883, "mco" ],
+[ 8884, "mcp" ],
+[ 8885, "mcq" ],
+[ 8886, "mcr" ],
+[ 8887, "mcs" ],
+[ 8888, "mct" ],
+[ 8889, "mcu" ],
+[ 8890, "mcv" ],
+[ 8891, "mcw" ],
+[ 8892, "mcx" ],
+[ 8893, "mcy" ],
+[ 8894, "mcz" ],
+[ 8895, "mda" ],
+[ 8896, "mdb" ],
+[ 8897, "mdc" ],
+[ 8898, "mdd" ],
+[ 8899, "mde" ],
+[ 8900, "mdf" ],
+[ 8901, "mdg" ],
+[ 8902, "mdh" ],
+[ 8903, "mdi" ],
+[ 8904, "mdj" ],
+[ 8905, "mdk" ],
+[ 8906, "mdl" ],
+[ 8907, "mdm" ],
+[ 8908, "mdn" ],
+[ 8909, "mdo" ],
+[ 8910, "mdp" ],
+[ 8911, "mdq" ],
+[ 8912, "mdr" ],
+[ 8913, "mds" ],
+[ 8914, "mdt" ],
+[ 8915, "mdu" ],
+[ 8916, "mdv" ],
+[ 8917, "mdw" ],
+[ 8918, "mdx" ],
+[ 8919, "mdy" ],
+[ 8920, "mdz" ],
+[ 8921, "mea" ],
+[ 8922, "meb" ],
+[ 8923, "mec" ],
+[ 8924, "med" ],
+[ 8925, "mee" ],
+[ 8926, "mef" ],
+[ 8927, "meg" ],
+[ 8928, "meh" ],
+[ 8929, "mei" ],
+[ 8930, "mej" ],
+[ 8931, "mek" ],
+[ 8932, "mel" ],
+[ 8933, "mem" ],
+[ 8934, "men" ],
+[ 8935, "meo" ],
+[ 8936, "mep" ],
+[ 8937, "meq" ],
+[ 8938, "mer" ],
+[ 8939, "mes" ],
+[ 8940, "met" ],
+[ 8941, "meu" ],
+[ 8942, "mev" ],
+[ 8943, "mew" ],
+[ 8944, "mex" ],
+[ 8945, "mey" ],
+[ 8946, "mez" ],
+[ 8947, "mfa" ],
+[ 8948, "mfb" ],
+[ 8949, "mfc" ],
+[ 8950, "mfd" ],
+[ 8951, "mfe" ],
+[ 8952, "mff" ],
+[ 8953, "mfg" ],
+[ 8954, "mfh" ],
+[ 8955, "mfi" ],
+[ 8956, "mfj" ],
+[ 8957, "mfk" ],
+[ 8958, "mfl" ],
+[ 8959, "mfm" ],
+[ 8960, "mfn" ],
+[ 8961, "mfo" ],
+[ 8962, "mfp" ],
+[ 8963, "mfq" ],
+[ 8964, "mfr" ],
+[ 8965, "mfs" ],
+[ 8966, "mft" ],
+[ 8967, "mfu" ],
+[ 8968, "mfv" ],
+[ 8969, "mfw" ],
+[ 8970, "mfx" ],
+[ 8971, "mfy" ],
+[ 8972, "mfz" ],
+[ 8973, "mga" ],
+[ 8974, "mgb" ],
+[ 8975, "mgc" ],
+[ 8976, "mgd" ],
+[ 8977, "mge" ],
+[ 8978, "mgf" ],
+[ 8979, "mgg" ],
+[ 8980, "mgh" ],
+[ 8981, "mgi" ],
+[ 8982, "mgj" ],
+[ 8983, "mgk" ],
+[ 8984, "mgl" ],
+[ 8985, "mgm" ],
+[ 8986, "mgn" ],
+[ 8987, "mgo" ],
+[ 8988, "mgp" ],
+[ 8989, "mgq" ],
+[ 8990, "mgr" ],
+[ 8991, "mgs" ],
+[ 8992, "mgt" ],
+[ 8993, "mgu" ],
+[ 8994, "mgv" ],
+[ 8995, "mgw" ],
+[ 8996, "mgx" ],
+[ 8997, "mgy" ],
+[ 8998, "mgz" ],
+[ 8999, "mha" ],
+[ 9000, "mhb" ],
+[ 9001, "mhc" ],
+[ 9002, "mhd" ],
+[ 9003, "mhe" ],
+[ 9004, "mhf" ],
+[ 9005, "mhg" ],
+[ 9006, "mhh" ],
+[ 9007, "mhi" ],
+[ 9008, "mhj" ],
+[ 9009, "mhk" ],
+[ 9010, "mhl" ],
+[ 9011, "mhm" ],
+[ 9012, "mhn" ],
+[ 9013, "mho" ],
+[ 9014, "mhp" ],
+[ 9015, "mhq" ],
+[ 9016, "mhr" ],
+[ 9017, "mhs" ],
+[ 9018, "mht" ],
+[ 9019, "mhu" ],
+[ 9020, "mhv" ],
+[ 9021, "mhw" ],
+[ 9022, "mhx" ],
+[ 9023, "mhy" ],
+[ 9024, "mhz" ],
+[ 9025, "mia" ],
+[ 9026, "mib" ],
+[ 9027, "mic" ],
+[ 9028, "mid" ],
+[ 9029, "mie" ],
+[ 9030, "mif" ],
+[ 9031, "mig" ],
+[ 9032, "mih" ],
+[ 9033, "mii" ],
+[ 9034, "mij" ],
+[ 9035, "mik" ],
+[ 9036, "mil" ],
+[ 9037, "mim" ],
+[ 9038, "min" ],
+[ 9039, "mio" ],
+[ 9040, "mip" ],
+[ 9041, "miq" ],
+[ 9042, "mir" ],
+[ 9043, "mis" ],
+[ 9044, "mit" ],
+[ 9045, "miu" ],
+[ 9046, "miv" ],
+[ 9047, "miw" ],
+[ 9048, "mix" ],
+[ 9049, "miy" ],
+[ 9050, "miz" ],
+[ 9051, "mja" ],
+[ 9052, "mjb" ],
+[ 9053, "mjc" ],
+[ 9054, "mjd" ],
+[ 9055, "mje" ],
+[ 9056, "mjf" ],
+[ 9057, "mjg" ],
+[ 9058, "mjh" ],
+[ 9059, "mji" ],
+[ 9060, "mjj" ],
+[ 9061, "mjk" ],
+[ 9062, "mjl" ],
+[ 9063, "mjm" ],
+[ 9064, "mjn" ],
+[ 9065, "mjo" ],
+[ 9066, "mjp" ],
+[ 9067, "mjq" ],
+[ 9068, "mjr" ],
+[ 9069, "mjs" ],
+[ 9070, "mjt" ],
+[ 9071, "mju" ],
+[ 9072, "mjv" ],
+[ 9073, "mjw" ],
+[ 9074, "mjx" ],
+[ 9075, "mjy" ],
+[ 9076, "mjz" ],
+[ 9077, "mka" ],
+[ 9078, "mkb" ],
+[ 9079, "mkc" ],
+[ 9080, "mkd" ],
+[ 9081, "mke" ],
+[ 9082, "mkf" ],
+[ 9083, "mkg" ],
+[ 9084, "mkh" ],
+[ 9085, "mki" ],
+[ 9086, "mkj" ],
+[ 9087, "mkk" ],
+[ 9088, "mkl" ],
+[ 9089, "mkm" ],
+[ 9090, "mkn" ],
+[ 9091, "mko" ],
+[ 9092, "mkp" ],
+[ 9093, "mkq" ],
+[ 9094, "mkr" ],
+[ 9095, "mks" ],
+[ 9096, "mkt" ],
+[ 9097, "mku" ],
+[ 9098, "mkv" ],
+[ 9099, "mkw" ],
+[ 9100, "mkx" ],
+[ 9101, "mky" ],
+[ 9102, "mkz" ],
+[ 9103, "mla" ],
+[ 9104, "mlb" ],
+[ 9105, "mlc" ],
+[ 9106, "mld" ],
+[ 9107, "mle" ],
+[ 9108, "mlf" ],
+[ 9109, "mlg" ],
+[ 9110, "mlh" ],
+[ 9111, "mli" ],
+[ 9112, "mlj" ],
+[ 9113, "mlk" ],
+[ 9114, "mll" ],
+[ 9115, "mlm" ],
+[ 9116, "mln" ],
+[ 9117, "mlo" ],
+[ 9118, "mlp" ],
+[ 9119, "mlq" ],
+[ 9120, "mlr" ],
+[ 9121, "mls" ],
+[ 9122, "mlt" ],
+[ 9123, "mlu" ],
+[ 9124, "mlv" ],
+[ 9125, "mlw" ],
+[ 9126, "mlx" ],
+[ 9127, "mly" ],
+[ 9128, "mlz" ],
+[ 9129, "mma" ],
+[ 9130, "mmb" ],
+[ 9131, "mmc" ],
+[ 9132, "mmd" ],
+[ 9133, "mme" ],
+[ 9134, "mmf" ],
+[ 9135, "mmg" ],
+[ 9136, "mmh" ],
+[ 9137, "mmi" ],
+[ 9138, "mmj" ],
+[ 9139, "mmk" ],
+[ 9140, "mml" ],
+[ 9141, "mmm" ],
+[ 9142, "mmn" ],
+[ 9143, "mmo" ],
+[ 9144, "mmp" ],
+[ 9145, "mmq" ],
+[ 9146, "mmr" ],
+[ 9147, "mms" ],
+[ 9148, "mmt" ],
+[ 9149, "mmu" ],
+[ 9150, "mmv" ],
+[ 9151, "mmw" ],
+[ 9152, "mmx" ],
+[ 9153, "mmy" ],
+[ 9154, "mmz" ],
+[ 9155, "mna" ],
+[ 9156, "mnb" ],
+[ 9157, "mnc" ],
+[ 9158, "mnd" ],
+[ 9159, "mne" ],
+[ 9160, "mnf" ],
+[ 9161, "mng" ],
+[ 9162, "mnh" ],
+[ 9163, "mni" ],
+[ 9164, "mnj" ],
+[ 9165, "mnk" ],
+[ 9166, "mnl" ],
+[ 9167, "mnm" ],
+[ 9168, "mnn" ],
+[ 9169, "mno" ],
+[ 9170, "mnp" ],
+[ 9171, "mnq" ],
+[ 9172, "mnr" ],
+[ 9173, "mns" ],
+[ 9174, "mnt" ],
+[ 9175, "mnu" ],
+[ 9176, "mnv" ],
+[ 9177, "mnw" ],
+[ 9178, "mnx" ],
+[ 9179, "mny" ],
+[ 9180, "mnz" ],
+[ 9181, "moa" ],
+[ 9182, "mob" ],
+[ 9183, "moc" ],
+[ 9184, "mod" ],
+[ 9185, "moe" ],
+[ 9186, "mof" ],
+[ 9187, "mog" ],
+[ 9188, "moh" ],
+[ 9189, "moi" ],
+[ 9190, "moj" ],
+[ 9191, "mok" ],
+[ 9192, "mol" ],
+[ 9193, "mom" ],
+[ 9194, "mon" ],
+[ 9195, "moo" ],
+[ 9196, "mop" ],
+[ 9197, "moq" ],
+[ 9198, "mor" ],
+[ 9199, "mos" ],
+[ 9200, "mot" ],
+[ 9201, "mou" ],
+[ 9202, "mov" ],
+[ 9203, "mow" ],
+[ 9204, "mox" ],
+[ 9205, "moy" ],
+[ 9206, "moz" ],
+[ 9207, "mpa" ],
+[ 9208, "mpb" ],
+[ 9209, "mpc" ],
+[ 9210, "mpd" ],
+[ 9211, "mpe" ],
+[ 9212, "mpf" ],
+[ 9213, "mpg" ],
+[ 9214, "mph" ],
+[ 9215, "mpi" ],
+[ 9216, "mpj" ],
+[ 9217, "mpk" ],
+[ 9218, "mpl" ],
+[ 9219, "mpm" ],
+[ 9220, "mpn" ],
+[ 9221, "mpo" ],
+[ 9222, "mpp" ],
+[ 9223, "mpq" ],
+[ 9224, "mpr" ],
+[ 9225, "mps" ],
+[ 9226, "mpt" ],
+[ 9227, "mpu" ],
+[ 9228, "mpv" ],
+[ 9229, "mpw" ],
+[ 9230, "mpx" ],
+[ 9231, "mpy" ],
+[ 9232, "mpz" ],
+[ 9233, "mqa" ],
+[ 9234, "mqb" ],
+[ 9235, "mqc" ],
+[ 9236, "mqd" ],
+[ 9237, "mqe" ],
+[ 9238, "mqf" ],
+[ 9239, "mqg" ],
+[ 9240, "mqh" ],
+[ 9241, "mqi" ],
+[ 9242, "mqj" ],
+[ 9243, "mqk" ],
+[ 9244, "mql" ],
+[ 9245, "mqm" ],
+[ 9246, "mqn" ],
+[ 9247, "mqo" ],
+[ 9248, "mqp" ],
+[ 9249, "mqq" ],
+[ 9250, "mqr" ],
+[ 9251, "mqs" ],
+[ 9252, "mqt" ],
+[ 9253, "mqu" ],
+[ 9254, "mqv" ],
+[ 9255, "mqw" ],
+[ 9256, "mqx" ],
+[ 9257, "mqy" ],
+[ 9258, "mqz" ],
+[ 9259, "mra" ],
+[ 9260, "mrb" ],
+[ 9261, "mrc" ],
+[ 9262, "mrd" ],
+[ 9263, "mre" ],
+[ 9264, "mrf" ],
+[ 9265, "mrg" ],
+[ 9266, "mrh" ],
+[ 9267, "mri" ],
+[ 9268, "mrj" ],
+[ 9269, "mrk" ],
+[ 9270, "mrl" ],
+[ 9271, "mrm" ],
+[ 9272, "mrn" ],
+[ 9273, "mro" ],
+[ 9274, "mrp" ],
+[ 9275, "mrq" ],
+[ 9276, "mrr" ],
+[ 9277, "mrs" ],
+[ 9278, "mrt" ],
+[ 9279, "mru" ],
+[ 9280, "mrv" ],
+[ 9281, "mrw" ],
+[ 9282, "mrx" ],
+[ 9283, "mry" ],
+[ 9284, "mrz" ],
+[ 9285, "msa" ],
+[ 9286, "msb" ],
+[ 9287, "msc" ],
+[ 9288, "msd" ],
+[ 9289, "mse" ],
+[ 9290, "msf" ],
+[ 9291, "msg" ],
+[ 9292, "msh" ],
+[ 9293, "msi" ],
+[ 9294, "msj" ],
+[ 9295, "msk" ],
+[ 9296, "msl" ],
+[ 9297, "msm" ],
+[ 9298, "msn" ],
+[ 9299, "mso" ],
+[ 9300, "msp" ],
+[ 9301, "msq" ],
+[ 9302, "msr" ],
+[ 9303, "mss" ],
+[ 9304, "mst" ],
+[ 9305, "msu" ],
+[ 9306, "msv" ],
+[ 9307, "msw" ],
+[ 9308, "msx" ],
+[ 9309, "msy" ],
+[ 9310, "msz" ],
+[ 9311, "mta" ],
+[ 9312, "mtb" ],
+[ 9313, "mtc" ],
+[ 9314, "mtd" ],
+[ 9315, "mte" ],
+[ 9316, "mtf" ],
+[ 9317, "mtg" ],
+[ 9318, "mth" ],
+[ 9319, "mti" ],
+[ 9320, "mtj" ],
+[ 9321, "mtk" ],
+[ 9322, "mtl" ],
+[ 9323, "mtm" ],
+[ 9324, "mtn" ],
+[ 9325, "mto" ],
+[ 9326, "mtp" ],
+[ 9327, "mtq" ],
+[ 9328, "mtr" ],
+[ 9329, "mts" ],
+[ 9330, "mtt" ],
+[ 9331, "mtu" ],
+[ 9332, "mtv" ],
+[ 9333, "mtw" ],
+[ 9334, "mtx" ],
+[ 9335, "mty" ],
+[ 9336, "mtz" ],
+[ 9337, "mua" ],
+[ 9338, "mub" ],
+[ 9339, "muc" ],
+[ 9340, "mud" ],
+[ 9341, "mue" ],
+[ 9342, "muf" ],
+[ 9343, "mug" ],
+[ 9344, "muh" ],
+[ 9345, "mui" ],
+[ 9346, "muj" ],
+[ 9347, "muk" ],
+[ 9348, "mul" ],
+[ 9349, "mum" ],
+[ 9350, "mun" ],
+[ 9351, "muo" ],
+[ 9352, "mup" ],
+[ 9353, "muq" ],
+[ 9354, "mur" ],
+[ 9355, "mus" ],
+[ 9356, "mut" ],
+[ 9357, "muu" ],
+[ 9358, "muv" ],
+[ 9359, "muw" ],
+[ 9360, "mux" ],
+[ 9361, "muy" ],
+[ 9362, "muz" ],
+[ 9363, "mva" ],
+[ 9364, "mvb" ],
+[ 9365, "mvc" ],
+[ 9366, "mvd" ],
+[ 9367, "mve" ],
+[ 9368, "mvf" ],
+[ 9369, "mvg" ],
+[ 9370, "mvh" ],
+[ 9371, "mvi" ],
+[ 9372, "mvj" ],
+[ 9373, "mvk" ],
+[ 9374, "mvl" ],
+[ 9375, "mvm" ],
+[ 9376, "mvn" ],
+[ 9377, "mvo" ],
+[ 9378, "mvp" ],
+[ 9379, "mvq" ],
+[ 9380, "mvr" ],
+[ 9381, "mvs" ],
+[ 9382, "mvt" ],
+[ 9383, "mvu" ],
+[ 9384, "mvv" ],
+[ 9385, "mvw" ],
+[ 9386, "mvx" ],
+[ 9387, "mvy" ],
+[ 9388, "mvz" ],
+[ 9389, "mwa" ],
+[ 9390, "mwb" ],
+[ 9391, "mwc" ],
+[ 9392, "mwd" ],
+[ 9393, "mwe" ],
+[ 9394, "mwf" ],
+[ 9395, "mwg" ],
+[ 9396, "mwh" ],
+[ 9397, "mwi" ],
+[ 9398, "mwj" ],
+[ 9399, "mwk" ],
+[ 9400, "mwl" ],
+[ 9401, "mwm" ],
+[ 9402, "mwn" ],
+[ 9403, "mwo" ],
+[ 9404, "mwp" ],
+[ 9405, "mwq" ],
+[ 9406, "mwr" ],
+[ 9407, "mws" ],
+[ 9408, "mwt" ],
+[ 9409, "mwu" ],
+[ 9410, "mwv" ],
+[ 9411, "mww" ],
+[ 9412, "mwx" ],
+[ 9413, "mwy" ],
+[ 9414, "mwz" ],
+[ 9415, "mxa" ],
+[ 9416, "mxb" ],
+[ 9417, "mxc" ],
+[ 9418, "mxd" ],
+[ 9419, "mxe" ],
+[ 9420, "mxf" ],
+[ 9421, "mxg" ],
+[ 9422, "mxh" ],
+[ 9423, "mxi" ],
+[ 9424, "mxj" ],
+[ 9425, "mxk" ],
+[ 9426, "mxl" ],
+[ 9427, "mxm" ],
+[ 9428, "mxn" ],
+[ 9429, "mxo" ],
+[ 9430, "mxp" ],
+[ 9431, "mxq" ],
+[ 9432, "mxr" ],
+[ 9433, "mxs" ],
+[ 9434, "mxt" ],
+[ 9435, "mxu" ],
+[ 9436, "mxv" ],
+[ 9437, "mxw" ],
+[ 9438, "mxx" ],
+[ 9439, "mxy" ],
+[ 9440, "mxz" ],
+[ 9441, "mya" ],
+[ 9442, "myb" ],
+[ 9443, "myc" ],
+[ 9444, "myd" ],
+[ 9445, "mye" ],
+[ 9446, "myf" ],
+[ 9447, "myg" ],
+[ 9448, "myh" ],
+[ 9449, "myi" ],
+[ 9450, "myj" ],
+[ 9451, "myk" ],
+[ 9452, "myl" ],
+[ 9453, "mym" ],
+[ 9454, "myn" ],
+[ 9455, "myo" ],
+[ 9456, "myp" ],
+[ 9457, "myq" ],
+[ 9458, "myr" ],
+[ 9459, "mys" ],
+[ 9460, "myt" ],
+[ 9461, "myu" ],
+[ 9462, "myv" ],
+[ 9463, "myw" ],
+[ 9464, "myx" ],
+[ 9465, "myy" ],
+[ 9466, "myz" ],
+[ 9467, "mza" ],
+[ 9468, "mzb" ],
+[ 9469, "mzc" ],
+[ 9470, "mzd" ],
+[ 9471, "mze" ],
+[ 9472, "mzf" ],
+[ 9473, "mzg" ],
+[ 9474, "mzh" ],
+[ 9475, "mzi" ],
+[ 9476, "mzj" ],
+[ 9477, "mzk" ],
+[ 9478, "mzl" ],
+[ 9479, "mzm" ],
+[ 9480, "mzn" ],
+[ 9481, "mzo" ],
+[ 9482, "mzp" ],
+[ 9483, "mzq" ],
+[ 9484, "mzr" ],
+[ 9485, "mzs" ],
+[ 9486, "mzt" ],
+[ 9487, "mzu" ],
+[ 9488, "mzv" ],
+[ 9489, "mzw" ],
+[ 9490, "mzx" ],
+[ 9491, "mzy" ],
+[ 9492, "mzz" ],
+[ 9493, "naa" ],
+[ 9494, "nab" ],
+[ 9495, "nac" ],
+[ 9496, "nad" ],
+[ 9497, "nae" ],
+[ 9498, "naf" ],
+[ 9499, "nag" ],
+[ 9500, "nah" ],
+[ 9501, "nai" ],
+[ 9502, "naj" ],
+[ 9503, "nak" ],
+[ 9504, "nal" ],
+[ 9505, "nam" ],
+[ 9506, "nan" ],
+[ 9507, "nao" ],
+[ 9508, "nap" ],
+[ 9509, "naq" ],
+[ 9510, "nar" ],
+[ 9511, "nas" ],
+[ 9512, "nat" ],
+[ 9513, "nau" ],
+[ 9514, "nav" ],
+[ 9515, "naw" ],
+[ 9516, "nax" ],
+[ 9517, "nay" ],
+[ 9518, "naz" ],
+[ 9519, "nba" ],
+[ 9520, "nbb" ],
+[ 9521, "nbc" ],
+[ 9522, "nbd" ],
+[ 9523, "nbe" ],
+[ 9524, "nbf" ],
+[ 9525, "nbg" ],
+[ 9526, "nbh" ],
+[ 9527, "nbi" ],
+[ 9528, "nbj" ],
+[ 9529, "nbk" ],
+[ 9530, "nbl" ],
+[ 9531, "nbm" ],
+[ 9532, "nbn" ],
+[ 9533, "nbo" ],
+[ 9534, "nbp" ],
+[ 9535, "nbq" ],
+[ 9536, "nbr" ],
+[ 9537, "nbs" ],
+[ 9538, "nbt" ],
+[ 9539, "nbu" ],
+[ 9540, "nbv" ],
+[ 9541, "nbw" ],
+[ 9542, "nbx" ],
+[ 9543, "nby" ],
+[ 9544, "nbz" ],
+[ 9545, "nca" ],
+[ 9546, "ncb" ],
+[ 9547, "ncc" ],
+[ 9548, "ncd" ],
+[ 9549, "nce" ],
+[ 9550, "ncf" ],
+[ 9551, "ncg" ],
+[ 9552, "nch" ],
+[ 9553, "nci" ],
+[ 9554, "ncj" ],
+[ 9555, "nck" ],
+[ 9556, "ncl" ],
+[ 9557, "ncm" ],
+[ 9558, "ncn" ],
+[ 9559, "nco" ],
+[ 9560, "ncp" ],
+[ 9561, "ncq" ],
+[ 9562, "ncr" ],
+[ 9563, "ncs" ],
+[ 9564, "nct" ],
+[ 9565, "ncu" ],
+[ 9566, "ncv" ],
+[ 9567, "ncw" ],
+[ 9568, "ncx" ],
+[ 9569, "ncy" ],
+[ 9570, "ncz" ],
+[ 9571, "nda" ],
+[ 9572, "ndb" ],
+[ 9573, "ndc" ],
+[ 9574, "ndd" ],
+[ 9575, "nde" ],
+[ 9576, "ndf" ],
+[ 9577, "ndg" ],
+[ 9578, "ndh" ],
+[ 9579, "ndi" ],
+[ 9580, "ndj" ],
+[ 9581, "ndk" ],
+[ 9582, "ndl" ],
+[ 9583, "ndm" ],
+[ 9584, "ndn" ],
+[ 9585, "ndo" ],
+[ 9586, "ndp" ],
+[ 9587, "ndq" ],
+[ 9588, "ndr" ],
+[ 9589, "nds" ],
+[ 9590, "ndt" ],
+[ 9591, "ndu" ],
+[ 9592, "ndv" ],
+[ 9593, "ndw" ],
+[ 9594, "ndx" ],
+[ 9595, "ndy" ],
+[ 9596, "ndz" ],
+[ 9597, "nea" ],
+[ 9598, "neb" ],
+[ 9599, "nec" ],
+[ 9600, "ned" ],
+[ 9601, "nee" ],
+[ 9602, "nef" ],
+[ 9603, "neg" ],
+[ 9604, "neh" ],
+[ 9605, "nei" ],
+[ 9606, "nej" ],
+[ 9607, "nek" ],
+[ 9608, "nel" ],
+[ 9609, "nem" ],
+[ 9610, "nen" ],
+[ 9611, "neo" ],
+[ 9612, "nep" ],
+[ 9613, "neq" ],
+[ 9614, "ner" ],
+[ 9615, "nes" ],
+[ 9616, "net" ],
+[ 9617, "neu" ],
+[ 9618, "nev" ],
+[ 9619, "new" ],
+[ 9620, "nex" ],
+[ 9621, "ney" ],
+[ 9622, "nez" ],
+[ 9623, "nfa" ],
+[ 9624, "nfb" ],
+[ 9625, "nfc" ],
+[ 9626, "nfd" ],
+[ 9627, "nfe" ],
+[ 9628, "nff" ],
+[ 9629, "nfg" ],
+[ 9630, "nfh" ],
+[ 9631, "nfi" ],
+[ 9632, "nfj" ],
+[ 9633, "nfk" ],
+[ 9634, "nfl" ],
+[ 9635, "nfm" ],
+[ 9636, "nfn" ],
+[ 9637, "nfo" ],
+[ 9638, "nfp" ],
+[ 9639, "nfq" ],
+[ 9640, "nfr" ],
+[ 9641, "nfs" ],
+[ 9642, "nft" ],
+[ 9643, "nfu" ],
+[ 9644, "nfv" ],
+[ 9645, "nfw" ],
+[ 9646, "nfx" ],
+[ 9647, "nfy" ],
+[ 9648, "nfz" ],
+[ 9649, "nga" ],
+[ 9650, "ngb" ],
+[ 9651, "ngc" ],
+[ 9652, "ngd" ],
+[ 9653, "nge" ],
+[ 9654, "ngf" ],
+[ 9655, "ngg" ],
+[ 9656, "ngh" ],
+[ 9657, "ngi" ],
+[ 9658, "ngj" ],
+[ 9659, "ngk" ],
+[ 9660, "ngl" ],
+[ 9661, "ngm" ],
+[ 9662, "ngn" ],
+[ 9663, "ngo" ],
+[ 9664, "ngp" ],
+[ 9665, "ngq" ],
+[ 9666, "ngr" ],
+[ 9667, "ngs" ],
+[ 9668, "ngt" ],
+[ 9669, "ngu" ],
+[ 9670, "ngv" ],
+[ 9671, "ngw" ],
+[ 9672, "ngx" ],
+[ 9673, "ngy" ],
+[ 9674, "ngz" ],
+[ 9675, "nha" ],
+[ 9676, "nhb" ],
+[ 9677, "nhc" ],
+[ 9678, "nhd" ],
+[ 9679, "nhe" ],
+[ 9680, "nhf" ],
+[ 9681, "nhg" ],
+[ 9682, "nhh" ],
+[ 9683, "nhi" ],
+[ 9684, "nhj" ],
+[ 9685, "nhk" ],
+[ 9686, "nhl" ],
+[ 9687, "nhm" ],
+[ 9688, "nhn" ],
+[ 9689, "nho" ],
+[ 9690, "nhp" ],
+[ 9691, "nhq" ],
+[ 9692, "nhr" ],
+[ 9693, "nhs" ],
+[ 9694, "nht" ],
+[ 9695, "nhu" ],
+[ 9696, "nhv" ],
+[ 9697, "nhw" ],
+[ 9698, "nhx" ],
+[ 9699, "nhy" ],
+[ 9700, "nhz" ],
+[ 9701, "nia" ],
+[ 9702, "nib" ],
+[ 9703, "nic" ],
+[ 9704, "nid" ],
+[ 9705, "nie" ],
+[ 9706, "nif" ],
+[ 9707, "nig" ],
+[ 9708, "nih" ],
+[ 9709, "nii" ],
+[ 9710, "nij" ],
+[ 9711, "nik" ],
+[ 9712, "nil" ],
+[ 9713, "nim" ],
+[ 9714, "nin" ],
+[ 9715, "nio" ],
+[ 9716, "nip" ],
+[ 9717, "niq" ],
+[ 9718, "nir" ],
+[ 9719, "nis" ],
+[ 9720, "nit" ],
+[ 9721, "niu" ],
+[ 9722, "niv" ],
+[ 9723, "niw" ],
+[ 9724, "nix" ],
+[ 9725, "niy" ],
+[ 9726, "niz" ],
+[ 9727, "nja" ],
+[ 9728, "njb" ],
+[ 9729, "njc" ],
+[ 9730, "njd" ],
+[ 9731, "nje" ],
+[ 9732, "njf" ],
+[ 9733, "njg" ],
+[ 9734, "njh" ],
+[ 9735, "nji" ],
+[ 9736, "njj" ],
+[ 9737, "njk" ],
+[ 9738, "njl" ],
+[ 9739, "njm" ],
+[ 9740, "njn" ],
+[ 9741, "njo" ],
+[ 9742, "njp" ],
+[ 9743, "njq" ],
+[ 9744, "njr" ],
+[ 9745, "njs" ],
+[ 9746, "njt" ],
+[ 9747, "nju" ],
+[ 9748, "njv" ],
+[ 9749, "njw" ],
+[ 9750, "njx" ],
+[ 9751, "njy" ],
+[ 9752, "njz" ],
+[ 9753, "nka" ],
+[ 9754, "nkb" ],
+[ 9755, "nkc" ],
+[ 9756, "nkd" ],
+[ 9757, "nke" ],
+[ 9758, "nkf" ],
+[ 9759, "nkg" ],
+[ 9760, "nkh" ],
+[ 9761, "nki" ],
+[ 9762, "nkj" ],
+[ 9763, "nkk" ],
+[ 9764, "nkl" ],
+[ 9765, "nkm" ],
+[ 9766, "nkn" ],
+[ 9767, "nko" ],
+[ 9768, "nkp" ],
+[ 9769, "nkq" ],
+[ 9770, "nkr" ],
+[ 9771, "nks" ],
+[ 9772, "nkt" ],
+[ 9773, "nku" ],
+[ 9774, "nkv" ],
+[ 9775, "nkw" ],
+[ 9776, "nkx" ],
+[ 9777, "nky" ],
+[ 9778, "nkz" ],
+[ 9779, "nla" ],
+[ 9780, "nlb" ],
+[ 9781, "nlc" ],
+[ 9782, "nld" ],
+[ 9783, "nle" ],
+[ 9784, "nlf" ],
+[ 9785, "nlg" ],
+[ 9786, "nlh" ],
+[ 9787, "nli" ],
+[ 9788, "nlj" ],
+[ 9789, "nlk" ],
+[ 9790, "nll" ],
+[ 9791, "nlm" ],
+[ 9792, "nln" ],
+[ 9793, "nlo" ],
+[ 9794, "nlp" ],
+[ 9795, "nlq" ],
+[ 9796, "nlr" ],
+[ 9797, "nls" ],
+[ 9798, "nlt" ],
+[ 9799, "nlu" ],
+[ 9800, "nlv" ],
+[ 9801, "nlw" ],
+[ 9802, "nlx" ],
+[ 9803, "nly" ],
+[ 9804, "nlz" ],
+[ 9805, "nma" ],
+[ 9806, "nmb" ],
+[ 9807, "nmc" ],
+[ 9808, "nmd" ],
+[ 9809, "nme" ],
+[ 9810, "nmf" ],
+[ 9811, "nmg" ],
+[ 9812, "nmh" ],
+[ 9813, "nmi" ],
+[ 9814, "nmj" ],
+[ 9815, "nmk" ],
+[ 9816, "nml" ],
+[ 9817, "nmm" ],
+[ 9818, "nmn" ],
+[ 9819, "nmo" ],
+[ 9820, "nmp" ],
+[ 9821, "nmq" ],
+[ 9822, "nmr" ],
+[ 9823, "nms" ],
+[ 9824, "nmt" ],
+[ 9825, "nmu" ],
+[ 9826, "nmv" ],
+[ 9827, "nmw" ],
+[ 9828, "nmx" ],
+[ 9829, "nmy" ],
+[ 9830, "nmz" ],
+[ 9831, "nna" ],
+[ 9832, "nnb" ],
+[ 9833, "nnc" ],
+[ 9834, "nnd" ],
+[ 9835, "nne" ],
+[ 9836, "nnf" ],
+[ 9837, "nng" ],
+[ 9838, "nnh" ],
+[ 9839, "nni" ],
+[ 9840, "nnj" ],
+[ 9841, "nnk" ],
+[ 9842, "nnl" ],
+[ 9843, "nnm" ],
+[ 9844, "nnn" ],
+[ 9845, "nno" ],
+[ 9846, "nnp" ],
+[ 9847, "nnq" ],
+[ 9848, "nnr" ],
+[ 9849, "nns" ],
+[ 9850, "nnt" ],
+[ 9851, "nnu" ],
+[ 9852, "nnv" ],
+[ 9853, "nnw" ],
+[ 9854, "nnx" ],
+[ 9855, "nny" ],
+[ 9856, "nnz" ],
+[ 9857, "noa" ],
+[ 9858, "nob" ],
+[ 9859, "noc" ],
+[ 9860, "nod" ],
+[ 9861, "noe" ],
+[ 9862, "nof" ],
+[ 9863, "nog" ],
+[ 9864, "noh" ],
+[ 9865, "noi" ],
+[ 9866, "noj" ],
+[ 9867, "nok" ],
+[ 9868, "nol" ],
+[ 9869, "nom" ],
+[ 9870, "non" ],
+[ 9871, "noo" ],
+[ 9872, "nop" ],
+[ 9873, "noq" ],
+[ 9874, "nor" ],
+[ 9875, "nos" ],
+[ 9876, "not" ],
+[ 9877, "nou" ],
+[ 9878, "nov" ],
+[ 9879, "now" ],
+[ 9880, "nox" ],
+[ 9881, "noy" ],
+[ 9882, "noz" ],
+[ 9883, "npa" ],
+[ 9884, "npb" ],
+[ 9885, "npc" ],
+[ 9886, "npd" ],
+[ 9887, "npe" ],
+[ 9888, "npf" ],
+[ 9889, "npg" ],
+[ 9890, "nph" ],
+[ 9891, "npi" ],
+[ 9892, "npj" ],
+[ 9893, "npk" ],
+[ 9894, "npl" ],
+[ 9895, "npm" ],
+[ 9896, "npn" ],
+[ 9897, "npo" ],
+[ 9898, "npp" ],
+[ 9899, "npq" ],
+[ 9900, "npr" ],
+[ 9901, "nps" ],
+[ 9902, "npt" ],
+[ 9903, "npu" ],
+[ 9904, "npv" ],
+[ 9905, "npw" ],
+[ 9906, "npx" ],
+[ 9907, "npy" ],
+[ 9908, "npz" ],
+[ 9909, "nqa" ],
+[ 9910, "nqb" ],
+[ 9911, "nqc" ],
+[ 9912, "nqd" ],
+[ 9913, "nqe" ],
+[ 9914, "nqf" ],
+[ 9915, "nqg" ],
+[ 9916, "nqh" ],
+[ 9917, "nqi" ],
+[ 9918, "nqj" ],
+[ 9919, "nqk" ],
+[ 9920, "nql" ],
+[ 9921, "nqm" ],
+[ 9922, "nqn" ],
+[ 9923, "nqo" ],
+[ 9924, "nqp" ],
+[ 9925, "nqq" ],
+[ 9926, "nqr" ],
+[ 9927, "nqs" ],
+[ 9928, "nqt" ],
+[ 9929, "nqu" ],
+[ 9930, "nqv" ],
+[ 9931, "nqw" ],
+[ 9932, "nqx" ],
+[ 9933, "nqy" ],
+[ 9934, "nqz" ],
+[ 9935, "nra" ],
+[ 9936, "nrb" ],
+[ 9937, "nrc" ],
+[ 9938, "nrd" ],
+[ 9939, "nre" ],
+[ 9940, "nrf" ],
+[ 9941, "nrg" ],
+[ 9942, "nrh" ],
+[ 9943, "nri" ],
+[ 9944, "nrj" ],
+[ 9945, "nrk" ],
+[ 9946, "nrl" ],
+[ 9947, "nrm" ],
+[ 9948, "nrn" ],
+[ 9949, "nro" ],
+[ 9950, "nrp" ],
+[ 9951, "nrq" ],
+[ 9952, "nrr" ],
+[ 9953, "nrs" ],
+[ 9954, "nrt" ],
+[ 9955, "nru" ],
+[ 9956, "nrv" ],
+[ 9957, "nrw" ],
+[ 9958, "nrx" ],
+[ 9959, "nry" ],
+[ 9960, "nrz" ],
+[ 9961, "nsa" ],
+[ 9962, "nsb" ],
+[ 9963, "nsc" ],
+[ 9964, "nsd" ],
+[ 9965, "nse" ],
+[ 9966, "nsf" ],
+[ 9967, "nsg" ],
+[ 9968, "nsh" ],
+[ 9969, "nsi" ],
+[ 9970, "nsj" ],
+[ 9971, "nsk" ],
+[ 9972, "nsl" ],
+[ 9973, "nsm" ],
+[ 9974, "nsn" ],
+[ 9975, "nso" ],
+[ 9976, "nsp" ],
+[ 9977, "nsq" ],
+[ 9978, "nsr" ],
+[ 9979, "nss" ],
+[ 9980, "nst" ],
+[ 9981, "nsu" ],
+[ 9982, "nsv" ],
+[ 9983, "nsw" ],
+[ 9984, "nsx" ],
+[ 9985, "nsy" ],
+[ 9986, "nsz" ],
+[ 9987, "nta" ],
+[ 9988, "ntb" ],
+[ 9989, "ntc" ],
+[ 9990, "ntd" ],
+[ 9991, "nte" ],
+[ 9992, "ntf" ],
+[ 9993, "ntg" ],
+[ 9994, "nth" ],
+[ 9995, "nti" ],
+[ 9996, "ntj" ],
+[ 9997, "ntk" ],
+[ 9998, "ntl" ],
+[ 9999, "ntm" ],
+[ 10000, "ntn" ],
+    ]);
+
+
+## make sure populate honors fields/orders in list context
+## schema order
+my @links = $schema->populate('Link', [
+[ qw/id url title/ ],
+[ qw/2 burl btitle/ ]
+]);
+is(scalar @links, 1);
+
+my $link2 = shift @links;
+is($link2->id, 2, 'Link 2 id');
+is($link2->url, 'burl', 'Link 2 url');
+is($link2->title, 'btitle', 'Link 2 title');
+
+## non-schema order
+ at links = $schema->populate('Link', [
+[ qw/id title url/ ],
+[ qw/3 ctitle curl/ ]
+]);
+is(scalar @links, 1);
+
+my $link3 = shift @links;
+is($link3->id, 3, 'Link 3 id');
+is($link3->url, 'curl', 'Link 3 url');
+is($link3->title, 'ctitle', 'Link 3 title');
+
+## not all physical columns
+ at links = $schema->populate('Link', [
+[ qw/id title/ ],
+[ qw/4 dtitle/ ]
+]);
+is(scalar @links, 1);
+
+my $link4 = shift @links;
+is($link4->id, 4, 'Link 4 id');
+is($link4->url, undef, 'Link 4 url');
+is($link4->title, 'dtitle', 'Link 4 title');
+
+
+## make sure populate -> insert_bulk honors fields/orders in void context
+## schema order
+$schema->populate('Link', [
+[ qw/id url title/ ],
+[ qw/5 eurl etitle/ ]
+]);
+my $link5 = $schema->resultset('Link')->find(5);
+is($link5->id, 5, 'Link 5 id');
+is($link5->url, 'eurl', 'Link 5 url');
+is($link5->title, 'etitle', 'Link 5 title');
+
+## non-schema order
+$schema->populate('Link', [
+[ qw/id title url/ ],
+[ qw/6 ftitle furl/ ]
+]);
+my $link6 = $schema->resultset('Link')->find(6);
+is($link6->id, 6, 'Link 6 id');
+is($link6->url, 'furl', 'Link 6 url');
+is($link6->title, 'ftitle', 'Link 6 title');
+
+## not all physical columns
+$schema->populate('Link', [
+[ qw/id title/ ],
+[ qw/7 gtitle/ ]
+]);
+my $link7 = $schema->resultset('Link')->find(7);
+is($link7->id, 7, 'Link 7 id');
+is($link7->url, undef, 'Link 7 url');
+is($link7->title, 'gtitle', 'Link 7 title');
+
+
+ok(-f "t/var/DBIxClass.db", 'Database created');

Added: trunk/DBIx-Class/t/101populate_rs.t
===================================================================
--- trunk/DBIx-Class/t/101populate_rs.t	                        (rev 0)
+++ trunk/DBIx-Class/t/101populate_rs.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,492 @@
+## ----------------------------------------------------------------------------
+## Tests for the $resultset->populate method.
+##
+## GOALS:  We need to test the method for both void and array context for all
+## the following relationship types: belongs_to, has_many.  Additionally we
+## need to each each of those for both specified PK's and autogenerated PK's
+##
+## Also need to test some stuff that should generate errors.
+## ----------------------------------------------------------------------------
+
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 98;
+
+
+## ----------------------------------------------------------------------------
+## Get a Schema and some ResultSets we can play with.
+## ----------------------------------------------------------------------------
+
+my $schema	= DBICTest->init_schema();
+my $art_rs	= $schema->resultset('Artist');
+my $cd_rs	= $schema->resultset('CD');
+
+ok( $schema, 'Got a Schema object');
+ok( $art_rs, 'Got Good Artist Resultset');
+ok( $cd_rs, 'Got Good CD Resultset');
+
+
+## ----------------------------------------------------------------------------
+## Array context tests
+## ----------------------------------------------------------------------------
+
+ARRAY_CONTEXT: {
+
+	## These first set of tests are cake because array context just delegates
+	## all it's processing to $resultset->create
+	
+	HAS_MANY_NO_PKS: {
+	
+		## This first group of tests checks to make sure we can call populate
+		## with the parent having many children and let the keys be automatic
+
+		my $artists = [
+			{	
+				name => 'Angsty-Whiny Girl',
+				cds => [
+					{ title => 'My First CD', year => 2006 },
+					{ title => 'Yet More Tweeny-Pop crap', year => 2007 },
+				],					
+			},		
+			{
+				name => 'Manufactured Crap',
+			},
+			{
+				name => 'Like I Give a Damn',
+				cds => [
+					{ title => 'My parents sold me to a record company' ,year => 2005 },
+					{ title => 'Why Am I So Ugly?', year => 2006 },
+					{ title => 'I Got Surgery and am now Popular', year => 2007 }				
+				],
+			},
+			{	
+				name => 'Formerly Named',
+				cds => [
+					{ title => 'One Hit Wonder', year => 2006 },
+				],					
+			},			
+		];
+		
+		## Get the result row objects.
+		
+		my ($girl, $crap, $damn, $formerly) = $art_rs->populate($artists);
+		
+		## Do we have the right object?
+		
+		isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");	
+		isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");	
+		
+		## Find the expected information?
+
+		ok( $crap->name eq 'Manufactured Crap', "Got Correct name for result object");
+		ok( $girl->name eq 'Angsty-Whiny Girl', "Got Correct name for result object");
+		ok( $damn->name eq 'Like I Give a Damn', "Got Correct name for result object");	
+		ok( $formerly->name eq 'Formerly Named', "Got Correct name for result object");
+		
+		## Create the expected children sub objects?
+		
+		ok( $crap->cds->count == 0, "got Expected Number of Cds");
+		ok( $girl->cds->count == 2, "got Expected Number of Cds");	
+		ok( $damn->cds->count == 3, "got Expected Number of Cds");
+		ok( $formerly->cds->count == 1, "got Expected Number of Cds");
+
+		## Did the cds get expected information?
+		
+		my ($cd1, $cd2) = $girl->cds->search({},{order_by=>'year ASC'});
+		
+		ok( $cd1->title eq "My First CD", "Got Expected CD Title");
+		ok( $cd2->title eq "Yet More Tweeny-Pop crap", "Got Expected CD Title");
+	}
+	
+	HAS_MANY_WITH_PKS: {
+	
+		## This group tests the ability to specify the PK in the parent and let
+		## DBIC transparently pass the PK down to the Child and also let's the
+		## child create any other needed PK's for itself.
+		
+		my $aid		=  $art_rs->get_column('artistid')->max || 0;
+		
+		my $first_aid = ++$aid;
+		
+		my $artists = [
+			{
+				artistid => $first_aid,
+				name => 'PK_Angsty-Whiny Girl',
+				cds => [
+					{ artist => $first_aid, title => 'PK_My First CD', year => 2006 },
+					{ artist => $first_aid, title => 'PK_Yet More Tweeny-Pop crap', year => 2007 },
+				],					
+			},		
+			{
+				artistid => ++$aid,
+				name => 'PK_Manufactured Crap',
+			},
+			{
+				artistid => ++$aid,
+				name => 'PK_Like I Give a Damn',
+				cds => [
+					{ title => 'PK_My parents sold me to a record company' ,year => 2005 },
+					{ title => 'PK_Why Am I So Ugly?', year => 2006 },
+					{ title => 'PK_I Got Surgery and am now Popular', year => 2007 }				
+				],
+			},
+			{
+				artistid => ++$aid,
+				name => 'PK_Formerly Named',
+				cds => [
+					{ title => 'PK_One Hit Wonder', year => 2006 },
+				],					
+			},			
+		];
+		
+		## Get the result row objects.
+		
+		my ($girl, $crap, $damn, $formerly) = $art_rs->populate($artists);
+		
+		## Do we have the right object?
+		
+		isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");	
+		isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");	
+		
+		## Find the expected information?
+
+		ok( $crap->name eq 'PK_Manufactured Crap', "Got Correct name for result object");
+		ok( $girl->name eq 'PK_Angsty-Whiny Girl', "Got Correct name for result object");
+		ok( $girl->artistid == $first_aid, "Got Correct artist PK for result object");		
+		ok( $damn->name eq 'PK_Like I Give a Damn', "Got Correct name for result object");	
+		ok( $formerly->name eq 'PK_Formerly Named', "Got Correct name for result object");
+		
+		## Create the expected children sub objects?
+		
+		ok( $crap->cds->count == 0, "got Expected Number of Cds");
+		ok( $girl->cds->count == 2, "got Expected Number of Cds");	
+		ok( $damn->cds->count == 3, "got Expected Number of Cds");
+		ok( $formerly->cds->count == 1, "got Expected Number of Cds");
+
+		## Did the cds get expected information?
+		
+		my ($cd1, $cd2) = $girl->cds->search({},{order_by=>'year ASC'});
+		
+		ok( $cd1->title eq "PK_My First CD", "Got Expected CD Title");
+		ok( $cd2->title eq "PK_Yet More Tweeny-Pop crap", "Got Expected CD Title");
+	}
+	
+	BELONGS_TO_NO_PKs: {
+
+		## Test from a belongs_to perspective, should create artist first, 
+		## then CD with artistid.  This test we let the system automatically
+		## create the PK's.  Chances are good you'll use it this way mostly.
+		
+		my $cds = [
+			{
+				title => 'Some CD3',
+				year => '1997',
+				artist => { name => 'Fred BloggsC'},
+			},
+			{
+				title => 'Some CD4',
+				year => '1997',
+				artist => { name => 'Fred BloggsD'},
+			},		
+		];
+		
+		my ($cdA, $cdB) = $cd_rs->populate($cds);
+		
+
+		isa_ok($cdA, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdA->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdA->artist->name, 'Fred BloggsC', 'Set Artist to FredC');
+
+		
+		isa_ok($cdB, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdB->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdB->artist->name, 'Fred BloggsD', 'Set Artist to FredD');
+	}
+
+	BELONGS_TO_WITH_PKs: {
+
+		## Test from a belongs_to perspective, should create artist first, 
+		## then CD with artistid.  This time we try setting the PK's
+		
+		my $aid	= $art_rs->get_column('artistid')->max || 0;
+
+		my $cds = [
+			{
+				title => 'Some CD3',
+				year => '1997',
+				artist => { artistid=> ++$aid, name => 'Fred BloggsC'},
+			},
+			{
+				title => 'Some CD4',
+				year => '1997',
+				artist => { artistid=> ++$aid, name => 'Fred BloggsD'},
+			},		
+		];
+		
+		my ($cdA, $cdB) = $cd_rs->populate($cds);
+		
+		isa_ok($cdA, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdA->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdA->artist->name, 'Fred BloggsC', 'Set Artist to FredC');
+		
+		isa_ok($cdB, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdB->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdB->artist->name, 'Fred BloggsD', 'Set Artist to FredD');
+		ok($cdB->artist->artistid == $aid, "Got Expected Artist ID");
+	}
+}
+
+
+## ----------------------------------------------------------------------------
+## Void context tests
+## ----------------------------------------------------------------------------
+
+VOID_CONTEXT: {
+
+	## All these tests check the ability to use populate without asking for 
+	## any returned resultsets.  This uses bulk_insert as much as possible
+	## in order to increase speed.
+	
+	HAS_MANY_WITH_PKS: {
+	
+		## This first group of tests checks to make sure we can call populate
+		## with the parent having many children and the parent PK is set
+
+		my $aid		=  $art_rs->get_column('artistid')->max || 0;
+		
+		my $first_aid = ++$aid;
+		
+		my $artists = [
+			{
+				artistid => $first_aid,
+				name => 'VOID_PK_Angsty-Whiny Girl',
+				cds => [
+					{ artist => $first_aid, title => 'VOID_PK_My First CD', year => 2006 },
+					{ artist => $first_aid, title => 'VOID_PK_Yet More Tweeny-Pop crap', year => 2007 },
+				],					
+			},		
+			{
+				artistid => ++$aid,
+				name => 'VOID_PK_Manufactured Crap',
+			},
+			{
+				artistid => ++$aid,
+				name => 'VOID_PK_Like I Give a Damn',
+				cds => [
+					{ title => 'VOID_PK_My parents sold me to a record company' ,year => 2005 },
+					{ title => 'VOID_PK_Why Am I So Ugly?', year => 2006 },
+					{ title => 'VOID_PK_I Got Surgery and am now Popular', year => 2007 }				
+				],
+			},
+			{
+				artistid => ++$aid,
+				name => 'VOID_PK_Formerly Named',
+				cds => [
+					{ title => 'VOID_PK_One Hit Wonder', year => 2006 },
+				],					
+			},			
+		];
+		
+		## Get the result row objects.
+		
+		$art_rs->populate($artists);
+		
+		my ($girl, $formerly, $damn, $crap) = $art_rs->search(
+			{name=>[sort map {$_->{name}} @$artists]},
+			{order_by=>'name ASC'},
+		);
+		
+		## Do we have the right object?
+		
+		isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");	
+		isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");	
+		
+		## Find the expected information?
+
+		ok( $crap->name eq 'VOID_PK_Manufactured Crap', "Got Correct name for result object");
+		ok( $girl->name eq 'VOID_PK_Angsty-Whiny Girl', "Got Correct name for result object");
+		ok( $damn->name eq 'VOID_PK_Like I Give a Damn', "Got Correct name for result object");	
+		ok( $formerly->name eq 'VOID_PK_Formerly Named', "Got Correct name for result object");
+		
+		## Create the expected children sub objects?
+		ok( $crap->can('cds'), "Has cds relationship");
+		ok( $girl->can('cds'), "Has cds relationship");
+		ok( $damn->can('cds'), "Has cds relationship");
+		ok( $formerly->can('cds'), "Has cds relationship");
+		
+		ok( $crap->cds->count == 0, "got Expected Number of Cds");
+		ok( $girl->cds->count == 2, "got Expected Number of Cds");	
+		ok( $damn->cds->count == 3, "got Expected Number of Cds");
+		ok( $formerly->cds->count == 1, "got Expected Number of Cds");
+
+		## Did the cds get expected information?
+		
+		my ($cd1, $cd2) = $girl->cds->search({},{order_by=>'year ASC'});
+		
+		ok( $cd1->title eq "VOID_PK_My First CD", "Got Expected CD Title");
+		ok( $cd2->title eq "VOID_PK_Yet More Tweeny-Pop crap", "Got Expected CD Title");
+	}
+	
+	
+	BELONGS_TO_WITH_PKs: {
+
+		## Test from a belongs_to perspective, should create artist first, 
+		## then CD with artistid.  This time we try setting the PK's
+		
+		my $aid	= $art_rs->get_column('artistid')->max || 0;
+
+		my $cds = [
+			{
+				title => 'Some CD3B',
+				year => '1997',
+				artist => { artistid=> ++$aid, name => 'Fred BloggsCB'},
+			},
+			{
+				title => 'Some CD4B',
+				year => '1997',
+				artist => { artistid=> ++$aid, name => 'Fred BloggsDB'},
+			},		
+		];
+		
+		$cd_rs->populate($cds);
+		
+		my ($cdA, $cdB) = $cd_rs->search(
+			{title=>[sort map {$_->{title}} @$cds]},
+			{order_by=>'title ASC'},
+		);
+		
+		isa_ok($cdA, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdA->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdA->artist->name, 'Fred BloggsCB', 'Set Artist to FredCB');
+		
+		isa_ok($cdB, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdB->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdB->artist->name, 'Fred BloggsDB', 'Set Artist to FredDB');
+		ok($cdB->artist->artistid == $aid, "Got Expected Artist ID");
+	}
+
+	BELONGS_TO_NO_PKs: {
+
+		## Test from a belongs_to perspective, should create artist first, 
+		## then CD with artistid.
+				
+		my $cds = [
+			{
+				title => 'Some CD3BB',
+				year => '1997',
+				artist => { name => 'Fred BloggsCBB'},
+			},
+			{
+				title => 'Some CD4BB',
+				year => '1997',
+				artist => { name => 'Fred BloggsDBB'},
+			},		
+		];
+		
+		$cd_rs->populate($cds);
+		
+		my ($cdA, $cdB) = $cd_rs->search(
+			{title=>[sort map {$_->{title}} @$cds]},
+			{order_by=>'title ASC'},
+		);
+		
+		isa_ok($cdA, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdA->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdA->title, 'Some CD3BB', 'Found Expected title');
+		is($cdA->artist->name, 'Fred BloggsCBB', 'Set Artist to FredCBB');
+		
+		isa_ok($cdB, 'DBICTest::CD', 'Created CD');
+		isa_ok($cdB->artist, 'DBICTest::Artist', 'Set Artist');
+		is($cdB->title, 'Some CD4BB', 'Found Expected title');
+		is($cdB->artist->name, 'Fred BloggsDBB', 'Set Artist to FredDBB');
+	}
+	
+	
+	HAS_MANY_NO_PKS: {
+	
+		## This first group of tests checks to make sure we can call populate
+		## with the parent having many children and let the keys be automatic
+
+		my $artists = [
+			{	
+				name => 'VOID_Angsty-Whiny Girl',
+				cds => [
+					{ title => 'VOID_My First CD', year => 2006 },
+					{ title => 'VOID_Yet More Tweeny-Pop crap', year => 2007 },
+				],					
+			},		
+			{
+				name => 'VOID_Manufactured Crap',
+			},
+			{
+				name => 'VOID_Like I Give a Damn',
+				cds => [
+					{ title => 'VOID_My parents sold me to a record company' ,year => 2005 },
+					{ title => 'VOID_Why Am I So Ugly?', year => 2006 },
+					{ title => 'VOID_I Got Surgery and am now Popular', year => 2007 }				
+				],
+			},
+			{	
+				name => 'VOID_Formerly Named',
+				cds => [
+					{ title => 'VOID_One Hit Wonder', year => 2006 },
+				],					
+			},			
+		];
+		
+		## Get the result row objects.
+		
+		$art_rs->populate($artists);
+		
+		my ($girl, $formerly, $damn, $crap) = $art_rs->search(
+			{name=>[sort map {$_->{name}} @$artists]},
+			{order_by=>'name ASC'},
+		);
+		
+		## Do we have the right object?
+		
+		isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
+		isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");	
+		isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");	
+		
+		## Find the expected information?
+
+		ok( $crap->name eq 'VOID_Manufactured Crap', "Got Correct name for result object");
+		ok( $girl->name eq 'VOID_Angsty-Whiny Girl', "Got Correct name for result object");
+		ok( $damn->name eq 'VOID_Like I Give a Damn', "Got Correct name for result object");	
+		ok( $formerly->name eq 'VOID_Formerly Named', "Got Correct name for result object");
+		
+		## Create the expected children sub objects?
+		ok( $crap->can('cds'), "Has cds relationship");
+		ok( $girl->can('cds'), "Has cds relationship");
+		ok( $damn->can('cds'), "Has cds relationship");
+		ok( $formerly->can('cds'), "Has cds relationship");
+		
+		ok( $crap->cds->count == 0, "got Expected Number of Cds");
+		ok( $girl->cds->count == 2, "got Expected Number of Cds");	
+		ok( $damn->cds->count == 3, "got Expected Number of Cds");
+		ok( $formerly->cds->count == 1, "got Expected Number of Cds");
+
+		## Did the cds get expected information?
+		
+		my ($cd1, $cd2) = $girl->cds->search({},{order_by=>'year ASC'});
+
+		ok($cd1, "Got a got CD");
+		ok($cd2, "Got a got CD");
+		ok( $cd1->title eq "VOID_My First CD", "Got Expected CD Title");
+		ok( $cd2->title eq "VOID_Yet More Tweeny-Pop crap", "Got Expected CD Title");
+	}
+
+}
\ No newline at end of file

Modified: trunk/DBIx-Class/t/19quotes.t
===================================================================
--- trunk/DBIx-Class/t/19quotes.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/19quotes.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -14,44 +14,44 @@
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
-my $orig_debugcb = DBICTest->schema->storage->debugcb;
-my $orig_debug = DBICTest->schema->storage->debug;
+my $orig_debugcb = $schema->storage->debugcb;
+my $orig_debug = $schema->storage->debug;
 
-diag('Testing against ' . join(' ', map { DBICTest->schema->storage->dbh->get_info($_) } qw/17 18/));
+diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
-DBICTest->schema->storage->sql_maker->quote_char('`');
-DBICTest->schema->storage->sql_maker->name_sep('.');
+$schema->storage->sql_maker->quote_char('`');
+$schema->storage->sql_maker->name_sep('.');
 
 my $sql = '';
 
-DBICTest->schema->storage->debugcb(sub { $sql = $_[1] });
-DBICTest->schema->storage->debug(1);
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
 
 my $rs;
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
 eval { $rs->count };
 like($sql, qr/\QSELECT COUNT( * ) FROM `cd` `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )\E/, 'got correct SQL for count query with quoting');
 
 my $order = 'year DESC';
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => $order });
 eval { $rs->first };
 like($sql, qr/ORDER BY `\Q${order}\E`/, 'quoted ORDER BY with DESC (should use a scalarref anyway)');
 
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => \$order });
 eval { $rs->first };
 like($sql, qr/ORDER BY \Q${order}\E/, 'did not quote ORDER BY with scalarref');
 
-DBICTest->schema->storage->sql_maker->quote_char([qw/[ ]/]);
-DBICTest->schema->storage->sql_maker->name_sep('.');
+$schema->storage->sql_maker->quote_char([qw/[ ]/]);
+$schema->storage->sql_maker->name_sep('.');
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
 eval { $rs->count };
@@ -62,10 +62,10 @@
        order => '12'
 );
 
-DBICTest->schema->storage->sql_maker->quote_char('`');
-DBICTest->schema->storage->sql_maker->name_sep('.');
+$schema->storage->sql_maker->quote_char('`');
+$schema->storage->sql_maker->name_sep('.');
 
-is(DBICTest->schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
+is($schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
 
-DBICTest->schema->storage->debugcb($orig_debugcb);
-DBICTest->schema->storage->debug($orig_debug);
+$schema->storage->debugcb($orig_debugcb);
+$schema->storage->debug($orig_debug);

Modified: trunk/DBIx-Class/t/19quotes_newstyle.t
===================================================================
--- trunk/DBIx-Class/t/19quotes_newstyle.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/19quotes_newstyle.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -14,44 +14,55 @@
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
-my $orig_debugcb = DBICTest->schema->storage->debugcb;
-my $orig_debug = DBICTest->schema->storage->debug;
+my $orig_debugcb = $schema->storage->debugcb;
+my $orig_debug = $schema->storage->debug;
 
-diag('Testing against ' . join(' ', map { DBICTest->schema->storage->dbh->get_info($_) } qw/17 18/));
+diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
-my $dsn = DBICTest->schema->storage->connect_info->[0];
-DBICTest->schema->connection($dsn, { quote_char => '`', name_sep => '.' });
+my $dsn = $schema->storage->connect_info->[0];
+$schema->connection(
+  $dsn,
+  undef,
+  undef,
+  { AutoCommit => 1 },
+  { quote_char => '`', name_sep => '.' },
+);
 
 my $sql = '';
-DBICTest->schema->storage->debugcb(sub { $sql = $_[1] });
-DBICTest->schema->storage->debug(1);
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
 
 my $rs;
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
 eval { $rs->count };
 like($sql, qr/\QSELECT COUNT( * ) FROM `cd` `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )\E/, 'got correct SQL for count query with quoting');
 
 my $order = 'year DESC';
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => $order });
 eval { $rs->first };
 like($sql, qr/ORDER BY `\Q${order}\E`/, 'quoted ORDER BY with DESC (should use a scalarref anyway)');
 
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => \$order });
 eval { $rs->first };
 like($sql, qr/ORDER BY \Q${order}\E/, 'did not quote ORDER BY with scalarref');
 
-DBICTest->schema->connection($dsn, { quote_char => [qw/[ ]/], name_sep => '.' });
-DBICTest->schema->storage->debugcb(sub { $sql = $_[1] });
-DBICTest->schema->storage->debug(1);
+$schema->connection(
+  $dsn,
+  undef,
+  undef,
+  { AutoCommit => 1, quote_char => [qw/[ ]/], name_sep => '.' }
+);
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
 eval { $rs->count };
@@ -62,9 +73,14 @@
        order => '12'
 );
 
-DBICTest->schema->connection($dsn, { quote_char => '`', name_sep => '.' });
+$schema->connection(
+  $dsn,
+  undef,
+  undef,
+  { AutoCommit => 1, quote_char => '`', name_sep => '.' }
+);
 
-is(DBICTest->schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
+is($schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
 
-DBICTest->schema->storage->debugcb($orig_debugcb);
-DBICTest->schema->storage->debug($orig_debug);
+$schema->storage->debugcb($orig_debugcb);
+$schema->storage->debug($orig_debug);

Modified: trunk/DBIx-Class/t/30dbicplain.t
===================================================================
--- trunk/DBIx-Class/t/30dbicplain.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/30dbicplain.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,8 +5,17 @@
 use Test::More;
 
 use lib qw(t/lib);
-use DBICTest::Plain;
 
-plan tests => 1;
+plan tests => 3;
 
+my @warnings;
+
+{
+  local $SIG{__WARN__} = sub { push(@warnings, $_[0]); };
+  require DBICTest::Plain;
+}
+
+like($warnings[0], qr/compose_connection deprecated as of 0\.08000/,
+      'deprecation warning emitted ok');
+cmp_ok(@warnings, '==', 1, 'no unexpected warnings');
 cmp_ok(DBICTest::Plain->resultset('Test')->count, '>', 0, 'count is valid');

Modified: trunk/DBIx-Class/t/31stats.t
===================================================================
--- trunk/DBIx-Class/t/31stats.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/31stats.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -14,23 +14,23 @@
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
 my $cbworks = 0;
 
-DBICTest->schema->storage->debugcb(sub { $cbworks = 1; });
-DBICTest->schema->storage->debug(0);
-my $rs = DBICTest::CD->search({});
+$schema->storage->debugcb(sub { $cbworks = 1; });
+$schema->storage->debug(0);
+my $rs = $schema->resultset('CD')->search({});
 $rs->count();
 ok(!$cbworks, 'Callback not called with debug disabled');
 
-DBICTest->schema->storage->debug(1);
+$schema->storage->debug(1);
 
 $rs->count();
 ok($cbworks, 'Debug callback worked.');
 
 my $prof = new DBIx::Test::Profiler();
-DBICTest->schema->storage->debugobj($prof);
+$schema->storage->debugobj($prof);
 
 # Test non-transaction calls.
 $rs->count();
@@ -42,27 +42,27 @@
 $prof->reset();
 
 # Test transaction calls
-DBICTest->schema->txn_begin();
+$schema->txn_begin();
 ok($prof->{'txn_begin'}, 'txn_begin called');
 
-$rs = DBICTest::CD->search({});
+$rs = $schema->resultset('CD')->search({});
 $rs->count();
 ok($prof->{'query_start'}, 'query_start called');
 ok($prof->{'query_end'}, 'query_end called');
 
-DBICTest->schema->txn_commit();
+$schema->txn_commit();
 ok($prof->{'txn_commit'}, 'txn_commit called');
 
 $prof->reset();
 
 # Test a rollback
-DBICTest->schema->txn_begin();
-$rs = DBICTest::CD->search({});
+$schema->txn_begin();
+$rs = $schema->resultset('CD')->search({});
 $rs->count();
-DBICTest->schema->txn_rollback();
+$schema->txn_rollback();
 ok($prof->{'txn_rollback'}, 'txn_rollback called');
 
-DBICTest->schema->storage->debug(0);
+$schema->storage->debug(0);
 
 package DBIx::Test::Profiler;
 use strict;

Added: trunk/DBIx-Class/t/33storage_reconnect.t
===================================================================
--- trunk/DBIx-Class/t/33storage_reconnect.t	                        (rev 0)
+++ trunk/DBIx-Class/t/33storage_reconnect.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,26 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 2;
+
+# Set up the "usual" sqlite for DBICTest
+my $schema = DBICTest->init_schema;
+
+# Make sure we're connected by doing something
+my @art = $schema->resultset("Artist")->search({ }, { order_by => 'name DESC'});
+cmp_ok(@art, '==', 3, "Three artists returned");
+
+# Disconnect the dbh, and be sneaky about it
+$schema->storage->_dbh->disconnect;
+
+# Try the operation again - What should happen here is:
+#   1. S::DBI blindly attempts the SELECT, which throws an exception
+#   2. It catches the exception, checks ->{Active}/->ping, sees the disconnected state...
+#   3. Reconnects, and retries the operation
+#   4. Success!
+my @art_two = $schema->resultset("Artist")->search({ }, { order_by => 'name DESC'});
+cmp_ok(@art_two, '==', 3, "Three artists returned");

Added: trunk/DBIx-Class/t/34exception_action.t
===================================================================
--- trunk/DBIx-Class/t/34exception_action.t	                        (rev 0)
+++ trunk/DBIx-Class/t/34exception_action.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,64 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 6;
+
+# Set up the "usual" sqlite for DBICTest
+my $schema = DBICTest->init_schema;
+
+# This is how we're generating exceptions in the rest of these tests,
+#  which might need updating at some future time to be some other
+#  exception-generating statement:
+
+sub throwex { $schema->resultset("Artist")->search(1,1,1); }
+my $ex_regex = qr/Odd number of arguments to search/;
+
+# Basic check, normal exception
+eval { throwex };
+like($@, $ex_regex);
+
+# Now lets rethrow via exception_action
+$schema->exception_action(sub { die @_ });
+eval { throwex };
+like($@, $ex_regex);
+
+# Now lets suppress the error
+$schema->exception_action(sub { 1 });
+eval { throwex };
+ok(!$@, "Suppress exception");
+
+# Now lets fall through and let croak take back over
+$schema->exception_action(sub { return });
+eval { throwex };
+like($@, $ex_regex);
+
+# Whacky useless exception class
+{
+    package DBICTest::Exception;
+    use overload '""' => \&stringify, fallback => 1;
+    sub new {
+        my $class = shift;
+        bless { msg => shift }, $class;
+    }
+    sub throw {
+        my $self = shift;
+        die $self if ref $self eq __PACKAGE__;
+        die $self->new(shift);
+    }
+    sub stringify {
+        "DBICTest::Exception is handling this: " . shift->{msg};
+    }
+}
+
+# Try the exception class
+$schema->exception_action(sub { DBICTest::Exception->throw(@_) });
+eval { throwex };
+like($@, qr/DBICTest::Exception is handling this: $ex_regex/);
+
+# While we're at it, lets throw a custom exception through Storage::DBI
+eval { $schema->storage->throw_exception('floob') };
+like($@, qr/DBICTest::Exception is handling this: floob/);

Added: trunk/DBIx-Class/t/35disable_sth_caching.t
===================================================================
--- trunk/DBIx-Class/t/35disable_sth_caching.t	                        (rev 0)
+++ trunk/DBIx-Class/t/35disable_sth_caching.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,19 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 2;
+
+# Set up the "usual" sqlite for DBICTest
+my $schema = DBICTest->init_schema;
+
+my $sth_one = $schema->storage->sth('SELECT 42');
+my $sth_two = $schema->storage->sth('SELECT 42');
+$schema->storage->disable_sth_caching(1);
+my $sth_three = $schema->storage->sth('SELECT 42');
+
+ok($sth_one == $sth_two, "statement caching works");
+ok($sth_two != $sth_three, "disabling statement caching works");

Added: trunk/DBIx-Class/t/39load_namespaces_1.t
===================================================================
--- trunk/DBIx-Class/t/39load_namespaces_1.t	                        (rev 0)
+++ trunk/DBIx-Class/t/39load_namespaces_1.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+
+unshift(@INC, './t/lib');
+
+plan tests => 6;
+
+my $warnings;
+eval {
+    local $SIG{__WARN__} = sub { $warnings .= shift };
+    package DBICNSTest;
+    use base qw/DBIx::Class::Schema/;
+    __PACKAGE__->load_namespaces;
+};
+ok(!$@) or diag $@;
+like($warnings, qr/load_namespaces found ResultSet class C with no corresponding Result class/);
+
+my $source_a = DBICNSTest->source('A');
+isa_ok($source_a, 'DBIx::Class::ResultSource::Table');
+my $rset_a   = DBICNSTest->resultset('A');
+isa_ok($rset_a, 'DBICNSTest::ResultSet::A');
+
+my $source_b = DBICNSTest->source('B');
+isa_ok($source_b, 'DBIx::Class::ResultSource::Table');
+my $rset_b   = DBICNSTest->resultset('B');
+isa_ok($rset_b, 'DBIx::Class::ResultSet');

Added: trunk/DBIx-Class/t/39load_namespaces_2.t
===================================================================
--- trunk/DBIx-Class/t/39load_namespaces_2.t	                        (rev 0)
+++ trunk/DBIx-Class/t/39load_namespaces_2.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+
+unshift(@INC, './t/lib');
+
+plan tests => 6;
+
+my $warnings;
+eval {
+    local $SIG{__WARN__} = sub { $warnings .= shift };
+    package DBICNSTest;
+    use base qw/DBIx::Class::Schema/;
+    __PACKAGE__->load_namespaces(
+        result_namespace => 'Rslt',
+        resultset_namespace => 'RSet',
+    );
+};
+ok(!$@) or diag $@;
+like($warnings, qr/load_namespaces found ResultSet class C with no corresponding Result class/);
+
+my $source_a = DBICNSTest->source('A');
+isa_ok($source_a, 'DBIx::Class::ResultSource::Table');
+my $rset_a   = DBICNSTest->resultset('A');
+isa_ok($rset_a, 'DBICNSTest::RSet::A');
+
+my $source_b = DBICNSTest->source('B');
+isa_ok($source_b, 'DBIx::Class::ResultSource::Table');
+my $rset_b   = DBICNSTest->resultset('B');
+isa_ok($rset_b, 'DBIx::Class::ResultSet');

Added: trunk/DBIx-Class/t/39load_namespaces_3.t
===================================================================
--- trunk/DBIx-Class/t/39load_namespaces_3.t	                        (rev 0)
+++ trunk/DBIx-Class/t/39load_namespaces_3.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+
+unshift(@INC, './t/lib');
+
+plan tests => 7;
+
+my $warnings;
+eval {
+    local $SIG{__WARN__} = sub { $warnings .= shift };
+    package DBICNSTestOther;
+    use base qw/DBIx::Class::Schema/;
+    __PACKAGE__->load_namespaces(
+        result_namespace => [ '+DBICNSTest::Rslt', '+DBICNSTest::OtherRslt' ],
+        resultset_namespace => '+DBICNSTest::RSet',
+    );
+};
+ok(!$@) or diag $@;
+like($warnings, qr/load_namespaces found ResultSet class C with no corresponding Result class/);
+
+my $source_a = DBICNSTestOther->source('A');
+isa_ok($source_a, 'DBIx::Class::ResultSource::Table');
+my $rset_a   = DBICNSTestOther->resultset('A');
+isa_ok($rset_a, 'DBICNSTest::RSet::A');
+
+my $source_b = DBICNSTestOther->source('B');
+isa_ok($source_b, 'DBIx::Class::ResultSource::Table');
+my $rset_b   = DBICNSTestOther->resultset('B');
+isa_ok($rset_b, 'DBIx::Class::ResultSet');
+
+my $source_d = DBICNSTestOther->source('D');
+isa_ok($source_d, 'DBIx::Class::ResultSource::Table');

Added: trunk/DBIx-Class/t/39load_namespaces_4.t
===================================================================
--- trunk/DBIx-Class/t/39load_namespaces_4.t	                        (rev 0)
+++ trunk/DBIx-Class/t/39load_namespaces_4.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+
+unshift(@INC, './t/lib');
+
+plan tests => 6;
+
+my $warnings;
+eval {
+    local $SIG{__WARN__} = sub { $warnings .= shift };
+    package DBICNSTest;
+    use base qw/DBIx::Class::Schema/;
+    __PACKAGE__->load_namespaces( default_resultset_class => 'RSBase' );
+};
+ok(!$@) or diag $@;
+like($warnings, qr/load_namespaces found ResultSet class C with no corresponding Result class/);
+
+my $source_a = DBICNSTest->source('A');
+isa_ok($source_a, 'DBIx::Class::ResultSource::Table');
+my $rset_a   = DBICNSTest->resultset('A');
+isa_ok($rset_a, 'DBICNSTest::ResultSet::A');
+
+my $source_b = DBICNSTest->source('B');
+isa_ok($source_b, 'DBIx::Class::ResultSource::Table');
+my $rset_b   = DBICNSTest->resultset('B');
+isa_ok($rset_b, 'DBICNSTest::RSBase');

Modified: trunk/DBIx-Class/t/40resultsetmanager.t
===================================================================
--- trunk/DBIx-Class/t/40resultsetmanager.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/40resultsetmanager.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -17,7 +17,7 @@
 
 use DBICTest::ResultSetManager; # uses Class::Inspector
 
-my $schema = DBICTest::ResultSetManager->compose_connection('DB', 'foo');
+my $schema = DBICTest::ResultSetManager->compose_namespace('DB');
 my $rs = $schema->resultset('Foo');
 
 ok( !DB::Foo->can('bar'), 'Foo class does not have bar method' );

Modified: trunk/DBIx-Class/t/41orrible.t
===================================================================
--- trunk/DBIx-Class/t/41orrible.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/41orrible.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -2,11 +2,12 @@
 use warnings;
 
 use Test::More;
-use DBIx::Class::Storage::DBI;
+#use DBIx::Class::Storage::DBI;
+use DBIx::Class::Storage::DBI::Oracle::WhereJoins;
 
-plan tests => 1;
+plan tests => 4;
 
-my $sa = new DBIC::SQL::Abstract;
+my $sa = new DBIC::SQL::Abstract::Oracle;
 
 $sa->limit_dialect('RowNum');
 
@@ -23,3 +24,45 @@
 ) B
 WHERE r >= 4
 ', 'Munged stuff to make Oracle not explode');
+
+# test WhereJoins
+# search with undefined or empty $cond
+
+#  my ($self, $table, $fields, $where, $order, @rest) = @_;
+is($sa->select([
+        { me => "cd" },
+        [
+            { "-join_type" => "LEFT", artist => "artist" },
+            { "artist.artistid" => "me.artist" },
+        ],
+    ],
+    [ 'cd.cdid', 'cd.artist', 'cd.title', 'cd.year', 'artist.artistid', 'artist.name' ],
+    undef,
+    undef),
+   'SELECT cd.cdid, cd.artist, cd.title, cd.year, artist.artistid, artist.name FROM cd me, artist artist WHERE ( artist.artistid(+) = me.artist )', 'WhereJoins search with empty where clause');
+
+is($sa->select([
+        { me => "cd" },
+        [
+            { "-join_type" => "", artist => "artist" },
+            { "artist.artistid" => "me.artist" },
+        ],
+    ],
+    [ 'cd.cdid', 'cd.artist', 'cd.title', 'cd.year', 'artist.artistid', 'artist.name' ],
+    { 'artist.artistid' => 3 },
+    undef),
+   'SELECT cd.cdid, cd.artist, cd.title, cd.year, artist.artistid, artist.name FROM cd me, artist artist WHERE ( ( ( artist.artistid = me.artist ) AND ( artist.artistid = ? ) ) )', 'WhereJoins search with where clause');
+
+is($sa->select([
+        { me => "cd" },
+        [
+            { "-join_type" => "LEFT", artist => "artist" },
+            { "artist.artistid" => "me.artist" },
+        ],
+    ],
+    [ 'cd.cdid', 'cd.artist', 'cd.title', 'cd.year', 'artist.artistid', 'artist.name' ],
+    [{ 'artist.artistid' => 3 }, { 'me.cdid' => 5 }],
+    undef),
+   'SELECT cd.cdid, cd.artist, cd.title, cd.year, artist.artistid, artist.name FROM cd me, artist artist WHERE ( ( ( artist.artistid(+) = me.artist ) AND ( ( ( artist.artistid = ? ) OR ( me.cdid = ? ) ) ) ) )', 'WhereJoins search with or in where clause');
+
+

Added: trunk/DBIx-Class/t/55storage_stress.t
===================================================================
--- trunk/DBIx-Class/t/55storage_stress.t	                        (rev 0)
+++ trunk/DBIx-Class/t/55storage_stress.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,55 @@
+use strict;
+use warnings;
+use Test::More;
+
+# XXX obviously, the guts of this test haven't been written yet --blblack
+
+use lib qw(t/lib);
+
+plan skip_all => 'Set $ENV{DBICTEST_STORAGE_STRESS} to run this test'
+    . ' (it is very resource intensive!)'
+        unless $ENV{DBICTEST_STORAGE_STRESS};
+
+my $NKIDS = 20;
+my $CYCLES = 5;
+my @KILL_RATES = qw/0 0.001 0.01 0.1 0.2 0.5 0.75 1.0/;
+
+# Stress the storage with these parameters...
+sub stress_storage {
+    my ($connect_info, $num_kids, $cycles, $kill_rate) = @_;
+
+    foreach my $cycle (1..$cycles) {
+        my $schema = DBICTest::Schema->connection(@$connect_info, { AutoCommit => 1 });
+        foreach my $kidno (1..$num_kids) {
+            ok(1);
+        }
+    }
+}
+
+# Get a set of connection information -
+#  whatever the user has supplied for the vendor-specific tests
+sub get_connect_infos {
+    my @connect_infos;
+    foreach my $db_prefix (qw/PG MYSQL DB2 MSSQL ORA/) {
+        my @conn_info = @ENV{
+            map { "DBICTEST_${db_prefix}_${_}" } qw/DSN USER PASS/
+        };
+        push(@connect_infos, \@conn_info) if $conn_info[0];
+    }
+    \@connect_infos;
+}
+
+my $connect_infos = get_connect_infos();
+
+plan skip_all => 'This test needs some non-sqlite connect info!'
+    unless @$connect_infos;
+
+plan tests => (1 * @$connect_infos * $NKIDS * $CYCLES * @KILL_RATES) + 1;
+
+use_ok('DBICTest::Schema');
+
+foreach my $connect_info (@$connect_infos) {
+    foreach my $kill_rate (@KILL_RATES) {
+        stress_storage($connect_info, $NKIDS, $CYCLES, $kill_rate);
+    }
+}

Modified: trunk/DBIx-Class/t/60core.t
===================================================================
--- trunk/DBIx-Class/t/60core.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/60core.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,8 +7,11 @@
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 63;
+plan tests => 77;
 
+eval { require DateTime::Format::MySQL };
+my $NO_DTFM = $@ ? 1 : 0;
+
 # figure out if we've got a version of sqlite that is older than 3.2.6, in
 # which case COUNT(DISTINCT()) doesn't work
 my $is_broken_sqlite = 0;
@@ -166,6 +169,7 @@
   cd => 1,
   position => 4,
   title => 'Insert or Update',
+  last_updated_on => '1973-07-19 12:01:02'
 } );
 $new->update_or_insert;
 ok($new->in_storage, 'update_or_insert insert ok');
@@ -175,6 +179,21 @@
 $new->update_or_insert;
 is( $schema->resultset("Track")->find(100)->pos, 5, 'update_or_insert update ok');
 
+# get_inflated_columns w/relation and accessor alias
+SKIP: {
+    skip "This test requires DateTime::Format::MySQL", 8 if $NO_DTFM;
+
+    isa_ok($new->updated_date, 'DateTime', 'have inflated object via accessor');
+    my %tdata = $new->get_inflated_columns;
+    is($tdata{'trackid'}, 100, 'got id');
+    isa_ok($tdata{'cd'}, 'DBICTest::CD', 'cd is CD object');
+    is($tdata{'cd'}->id, 1, 'cd object is id 1');
+    is($tdata{'position'}, 5, 'got position from pos');
+    is($tdata{'title'}, 'Insert or Update');
+    is($tdata{'last_updated_on'}, '1973-07-19T12:01:02');
+    isa_ok($tdata{'last_updated_on'}, 'DateTime', 'inflated accessored column');
+}
+
 eval { $schema->class("Track")->load_components('DoesNotExist'); };
 
 ok $@, $@;
@@ -255,7 +274,7 @@
   cmp_ok(@artsn, '==', 4, "Four artists returned");
   
   # make sure subclasses that don't set source_name are ok
-  ok($schema->source('ArtistSubclass', 'ArtistSubclass exists'));
+  ok($schema->source('ArtistSubclass'), 'ArtistSubclass exists');
 }
 
 my $newbook = $schema->resultset( 'Bookmark' )->find(1);
@@ -277,6 +296,7 @@
 # test column_info
 {
   $schema->source("Artist")->{_columns}{'artistid'} = {};
+  $schema->source("Artist")->column_info_from_storage(1);
 
   my $typeinfo = $schema->source("Artist")->column_info('artistid');
   is($typeinfo->{data_type}, 'INTEGER', 'column_info ok');
@@ -284,6 +304,19 @@
   ok($schema->source("Artist")->{_columns_info_loaded} == 1, 'Columns info flag set');
 }
 
+# test source_info
+{
+  my $expected = {
+    "source_info_key_A" => "source_info_value_A",
+    "source_info_key_B" => "source_info_value_B",
+    "source_info_key_C" => "source_info_value_C",
+  };
+
+  my $sinfo = $schema->source("Artist")->source_info;
+
+  is_deeply($sinfo, $expected, 'source_info data works');
+}
+
 # test remove_columns
 {
   is_deeply([$schema->source('CD')->columns], [qw/cdid artist title year/]);
@@ -292,3 +325,15 @@
   ok(! exists $schema->source('CD')->_columns->{'year'}, 'year still exists in _columns');
 }
 
+# test get_inflated_columns with objects
+SKIP: {
+    skip "This test requires DateTime::Format::MySQL", 5 if $NO_DTFM;
+    my $event = $schema->resultset('Event')->search->first;
+    my %edata = $event->get_inflated_columns;
+    is($edata{'id'}, $event->id, 'got id');
+    isa_ok($edata{'starts_at'}, 'DateTime', 'start_at is DateTime object');
+    isa_ok($edata{'created_on'}, 'DateTime', 'create_on DateTime object');
+    is($edata{'starts_at'}, $event->starts_at, 'got start date');
+    is($edata{'created_on'}, $event->created_on, 'got created date');
+}
+

Added: trunk/DBIx-Class/t/61findnot.t
===================================================================
--- trunk/DBIx-Class/t/61findnot.t	                        (rev 0)
+++ trunk/DBIx-Class/t/61findnot.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,46 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 17;
+
+my $art = $schema->resultset("Artist")->find(4);
+ok(!defined($art), 'Find on primary id: artist not found');
+my @cd = $schema->resultset("CD")->find(6);
+cmp_ok(@cd, '==', 1, 'Return something even in array context');
+ok(@cd && !defined($cd[0]), 'Array contains an undef as only element');
+
+$art = $schema->resultset("Artist")->find({artistid => '4'});
+ok(!defined($art), 'Find on unique constraint: artist not found');
+ at cd = $schema->resultset("CD")->find({artist => '2', title => 'Lada-Di Lada-Da'});
+cmp_ok(@cd, '==', 1, 'Return something even in array context');
+ok(@cd && !defined($cd[0]), 'Array contains an undef as only element');
+
+$art = $schema->resultset("Artist")->search({name => 'The Jesus And Mary Chain'});
+isa_ok($art, 'DBIx::Class::ResultSet', 'get a DBIx::Class::ResultSet object');
+my $next = $art->next;
+ok(!defined($next), 'Nothing next in ResultSet');
+my $cd = $schema->resultset("CD")->search({title => 'Rubbersoul'});
+ at cd = $cd->next;
+cmp_ok(@cd, '==', 1, 'Return something even in array context');
+ok(@cd && !defined($cd[0]), 'Array contains an undef as only element');
+
+$art = $schema->resultset("Artist")->single({name => 'Bikini Bottom Boys'});
+ok(!defined($art), 'Find on primary id: artist not found');
+ at cd = $schema->resultset("CD")->single({title => 'The Singles 1962-2006'});
+cmp_ok(@cd, '==', 1, 'Return something even in array context');
+ok(@cd && !defined($cd[0]), 'Array contains an undef as only element');
+
+$art = $schema->resultset("Artist")->search({name => 'Random Girl Band'});
+isa_ok($art, 'DBIx::Class::ResultSet', 'get a DBIx::Class::ResultSet object');
+$next = $art->single;
+ok(!defined($next), 'Nothing next in ResultSet');
+$cd = $schema->resultset("CD")->search({title => 'Call of the West'});
+ at cd = $cd->single;
+cmp_ok(@cd, '==', 1, 'Return something even in array context');
+ok(@cd && !defined($cd[0]), 'Array contains an undef as only element');

Added: trunk/DBIx-Class/t/63register_class.t
===================================================================
--- trunk/DBIx-Class/t/63register_class.t	                        (rev 0)
+++ trunk/DBIx-Class/t/63register_class.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,17 @@
+use strict;
+use warnings;  
+
+use Test::More tests => 2;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::Schema;
+use DBICTest::Schema::Artist;
+
+DBICTest::Schema::Artist->source_name('MyArtist');
+DBICTest::Schema->register_class('FooA', 'DBICTest::Schema::Artist');
+
+my $schema = DBICTest->init_schema();
+
+my $a = $schema->resultset('FooA')->search;
+is($a->count, 3, 'have 3 artists');
+is($schema->class('FooA'), 'DBICTest::FooA', 'Correct artist class');

Modified: trunk/DBIx-Class/t/65multipk.t
===================================================================
--- trunk/DBIx-Class/t/65multipk.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/65multipk.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -9,7 +9,7 @@
 
 plan tests => 5;
 
-my $artist = DBICTest::Artist->find(1);
+my $artist = $schema->resultset("Artist")->find(1);
 ok($artist->find_related('twokeys', {cd => 1}), "find multiple pks using relationships + args");
 
 ok($schema->resultset("FourKeys")->search({ foo => 1, bar => 2 })->find({ hello => 3, goodbye => 4 }), "search on partial key followed by a find");

Modified: trunk/DBIx-Class/t/67pager.t
===================================================================
--- trunk/DBIx-Class/t/67pager.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/67pager.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -7,7 +7,7 @@
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 12;
+plan tests => 13;
 
 # first page
 my $it = $schema->resultset("CD")->search(
@@ -68,3 +68,11 @@
 
 is( $it->next->title, "Generic Manufactured Singles", "software iterator->next ok" );
 
+# test paging with chained searches
+$it = $schema->resultset("CD")->search(
+    {},
+    { rows => 2,
+      page => 2 }
+)->search( undef, { order_by => 'title' } );
+
+is( $it->count, 2, "chained searches paging ok" );

Modified: trunk/DBIx-Class/t/68inflate.t
===================================================================
--- trunk/DBIx-Class/t/68inflate.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/68inflate.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,7 +5,6 @@
 use lib qw(t/lib);
 use DBICTest;
 
-DBICTest::Schema::CD->add_column('year');
 my $schema = DBICTest->init_schema();
 
 eval { require DateTime };
@@ -13,7 +12,9 @@
 
 plan tests => 20;
 
-DBICTest::Schema::CD->inflate_column( 'year',
+$schema->class('CD')
+#DBICTest::Schema::CD
+->inflate_column( 'year',
     { inflate => sub { DateTime->new( year => shift ) },
       deflate => sub { shift->year } }
 );

Added: trunk/DBIx-Class/t/68inflate_resultclass_hashrefinflator.t
===================================================================
--- trunk/DBIx-Class/t/68inflate_resultclass_hashrefinflator.t	                        (rev 0)
+++ trunk/DBIx-Class/t/68inflate_resultclass_hashrefinflator.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,87 @@
+use strict;
+use warnings;  
+
+use Test::More qw(no_plan);
+use lib qw(t/lib);
+use DBICTest;
+use DBIx::Class::ResultClass::HashRefInflator;
+my $schema = DBICTest->init_schema();
+
+
+# Under some versions of SQLite if the $rs is left hanging around it will lock
+# So we create a scope here cos I'm lazy
+{
+    my $rs = $schema->resultset('CD');
+
+    # get the defined columns
+    my @dbic_cols = sort $rs->result_source->columns;
+
+    # use the hashref inflator class as result class
+    $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+    # fetch first record
+    my $datahashref1 = $rs->first;
+
+    my @hashref_cols = sort keys %$datahashref1;
+
+    is_deeply( \@dbic_cols, \@hashref_cols, 'returned columns' );
+}
+
+
+sub check_cols_of {
+    my ($dbic_obj, $datahashref) = @_;
+    
+    foreach my $col (keys %$datahashref) {
+        # plain column
+        if (not ref ($datahashref->{$col}) ) {
+            is ($datahashref->{$col}, $dbic_obj->get_column($col), 'same value');
+        }
+        # related table entry (belongs_to)
+        elsif (ref ($datahashref->{$col}) eq 'HASH') {
+            check_cols_of($dbic_obj->$col, $datahashref->{$col});
+        }
+        # multiple related entries (has_many)
+        elsif (ref ($datahashref->{$col}) eq 'ARRAY') {
+            my @dbic_reltable = $dbic_obj->$col;
+            my @hashref_reltable = @{$datahashref->{$col}};
+  
+            is (scalar @hashref_reltable, scalar @dbic_reltable, 'number of related entries');
+
+            # for my $index (0..scalar @hashref_reltable) {
+            for my $index (0..scalar @dbic_reltable) {
+                my $dbic_reltable_obj       = $dbic_reltable[$index];
+                my $hashref_reltable_entry  = $hashref_reltable[$index];
+                
+                check_cols_of($dbic_reltable_obj, $hashref_reltable_entry);
+            }
+        }
+    }
+}
+
+# create a cd without tracks for testing empty has_many relationship
+$schema->resultset('CD')->create({ title => 'Silence is golden', artist => 3, year => 2006 });
+
+# order_by to ensure both resultsets have the rows in the same order
+my $rs_dbic = $schema->resultset('CD')->search(undef,
+    {
+        prefetch    => [ qw/ artist tracks / ],
+        order_by    => [ 'me.cdid', 'tracks.position' ],
+    }
+);
+my $rs_hashrefinf = $schema->resultset('CD')->search(undef,
+    {
+        prefetch    => [ qw/ artist tracks / ],
+        order_by    => [ 'me.cdid', 'tracks.position' ],
+    }
+);
+$rs_hashrefinf->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+my @dbic        = $rs_dbic->all;
+my @hashrefinf  = $rs_hashrefinf->all;
+
+for my $index (0..scalar @hashrefinf) {
+    my $dbic_obj    = $dbic[$index];
+    my $datahashref = $hashrefinf[$index];
+
+    check_cols_of($dbic_obj, $datahashref);
+}

Modified: trunk/DBIx-Class/t/71mysql.t
===================================================================
--- trunk/DBIx-Class/t/71mysql.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/71mysql.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -15,9 +15,9 @@
 
 plan tests => 5;
 
-DBICTest::Schema->compose_connection('MySQLTest' => $dsn, $user, $pass);
+my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
-my $dbh = MySQLTest->schema->storage->dbh;
+my $dbh = $schema->storage->dbh;
 
 $dbh->do("DROP TABLE IF EXISTS artist;");
 
@@ -25,17 +25,18 @@
 
 #'dbi:mysql:host=localhost;database=dbic_test', 'dbic_test', '');
 
-MySQLTest::Artist->load_components('PK::Auto');
+# This is in Core now, but it's here just to test that it doesn't break
+$schema->class('Artist')->load_components('PK::Auto');
 
 # test primary key handling
-my $new = MySQLTest::Artist->create({ name => 'foo' });
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
 ok($new->artistid, "Auto-PK worked");
 
 # test LIMIT support
 for (1..6) {
-    MySQLTest::Artist->create({ name => 'Artist ' . $_ });
+    $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
 }
-my $it = MySQLTest::Artist->search( {},
+my $it = $schema->resultset('Artist')->search( {},
     { rows => 3,
       offset => 2,
       order_by => 'artistid' }
@@ -80,9 +81,11 @@
         $test_type_info->{charfield}->{data_type} = 'VARCHAR';
     }
 
-    my $type_info = MySQLTest->schema->storage->columns_info_for('artist');
+    my $type_info = $schema->storage->columns_info_for('artist');
     is_deeply($type_info, $test_type_info, 'columns_info_for - column data types');
 }
 
 # clean up our mess
-$dbh->do("DROP TABLE artist");
+END {
+    $dbh->do("DROP TABLE artist") if $dbh;
+}

Modified: trunk/DBIx-Class/t/72pg.t
===================================================================
--- trunk/DBIx-Class/t/72pg.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/72pg.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -12,9 +12,10 @@
   use warnings;
   use base 'DBIx::Class';
 
-  __PACKAGE__->load_components(qw/PK::Auto Core/);
+  __PACKAGE__->load_components(qw/Core/);
   __PACKAGE__->table('casecheck');
   __PACKAGE__->add_columns(qw/id name NAME uc_name/);
+  __PACKAGE__->column_info_from_storage(1);
   __PACKAGE__->set_primary_key('id');
 
 }
@@ -29,21 +30,22 @@
 plan tests => 8;
 
 DBICTest::Schema->load_classes( 'Casecheck' );
-DBICTest::Schema->compose_connection('PgTest' => $dsn, $user, $pass);
+my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
-my $dbh = PgTest->schema->storage->dbh;
-PgTest->schema->source("Artist")->name("testschema.artist");
+my $dbh = $schema->storage->dbh;
+$schema->source("Artist")->name("testschema.artist");
 $dbh->do("CREATE SCHEMA testschema;");
 $dbh->do("CREATE TABLE testschema.artist (artistid serial PRIMARY KEY, name VARCHAR(100), charfield CHAR(10));");
 ok ( $dbh->do('CREATE TABLE testschema.casecheck (id serial PRIMARY KEY, "name" VARCHAR(1), "NAME" VARCHAR(2), "UC_NAME" VARCHAR(3));'), 'Creation of casecheck table');
 
-PgTest::Artist->load_components('PK::Auto');
+# This is in Core now, but it's here just to test that it doesn't break
+$schema->class('Artist')->load_components('PK::Auto');
 
-my $new = PgTest::Artist->create({ name => 'foo' });
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
 
 is($new->artistid, 1, "Auto-PK worked");
 
-$new = PgTest::Artist->create({ name => 'bar' });
+$new = $schema->resultset('Artist')->create({ name => 'bar' });
 
 is($new->artistid, 2, "Auto-PK worked");
 
@@ -68,7 +70,7 @@
 };
 
 
-my $type_info = PgTest->schema->storage->columns_info_for('testschema.artist');
+my $type_info = $schema->storage->columns_info_for('testschema.artist');
 my $artistid_defval = delete $type_info->{artistid}->{default_value};
 like($artistid_defval,
      qr/^nextval\('([^\.]*\.){0,1}artist_artistid_seq'::(?:text|regclass)\)/,
@@ -76,16 +78,20 @@
 is_deeply($type_info, $test_type_info,
           'columns_info_for - column data types');
 
-my $name_info = PgTest::Casecheck->column_info( 'name' );
+my $name_info = $schema->source('Casecheck')->column_info( 'name' );
 is( $name_info->{size}, 1, "Case sensitive matching info for 'name'" );
 
-my $NAME_info = PgTest::Casecheck->column_info( 'NAME' );
+my $NAME_info = $schema->source('Casecheck')->column_info( 'NAME' );
 is( $NAME_info->{size}, 2, "Case sensitive matching info for 'NAME'" );
 
-my $uc_name_info = PgTest::Casecheck->column_info( 'uc_name' );
+my $uc_name_info = $schema->source('Casecheck')->column_info( 'uc_name' );
 is( $uc_name_info->{size}, 3, "Case insensitive matching info for 'uc_name'" );
 
-$dbh->do("DROP TABLE testschema.artist;");
-$dbh->do("DROP TABLE testschema.casecheck;");
-$dbh->do("DROP SCHEMA testschema;");
+END {
+    if($dbh) {
+        $dbh->do("DROP TABLE testschema.artist;");
+        $dbh->do("DROP TABLE testschema.casecheck;");
+        $dbh->do("DROP SCHEMA testschema;");
+    }
+}
 

Modified: trunk/DBIx-Class/t/73oracle.t
===================================================================
--- trunk/DBIx-Class/t/73oracle.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/73oracle.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -13,9 +13,9 @@
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('OraTest' => $dsn, $user, $pass);
+my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
-my $dbh = OraTest->schema->storage->dbh;
+my $dbh = $schema->storage->dbh;
 
 eval {
   $dbh->do("DROP SEQUENCE artist_seq");
@@ -42,18 +42,20 @@
   END;
 });
 
-OraTest::Artist->load_components('PK::Auto');
-OraTest::CD->load_components('PK::Auto::Oracle');
-OraTest::Track->load_components('PK::Auto::Oracle');
+# This is in Core now, but it's here just to test that it doesn't break
+$schema->class('Artist')->load_components('PK::Auto');
+# These are compat shims for PK::Auto...
+$schema->class('CD')->load_components('PK::Auto::Oracle');
+$schema->class('Track')->load_components('PK::Auto::Oracle');
 
 # test primary key handling
-my $new = OraTest::Artist->create({ name => 'foo' });
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
 is($new->artistid, 1, "Oracle Auto-PK worked");
 
 # test join with row count ambiguity
-my $cd = OraTest::CD->create({ cdid => 1, artist => 1, title => 'EP C', year => '2003' });
-my $track = OraTest::Track->create({ trackid => 1, cd => 1, position => 1, title => 'Track1' });
-my $tjoin = OraTest::Track->search({ 'me.title' => 'Track1'},
+my $cd = $schema->resultset('CD')->create({ cdid => 1, artist => 1, title => 'EP C', year => '2003' });
+my $track = $schema->resultset('Track')->create({ trackid => 1, cd => 1, position => 1, title => 'Track1' });
+my $tjoin = $schema->resultset('Track')->search({ 'me.title' => 'Track1'},
         { join => 'cd',
           rows => 2 }
 );
@@ -61,8 +63,8 @@
 is($tjoin->next->title, 'Track1', "ambiguous column ok");
 
 # check count distinct with multiple columns
-my $other_track = OraTest::Track->create({ trackid => 2, cd => 1, position => 1, title => 'Track2' });
-my $tcount = OraTest::Track->search(
+my $other_track = $schema->resultset('Track')->create({ trackid => 2, cd => 1, position => 1, title => 'Track2' });
+my $tcount = $schema->resultset('Track')->search(
     {},
     {
         select => [{count => {distinct => ['position', 'title']}}],
@@ -74,9 +76,9 @@
 
 # test LIMIT support
 for (1..6) {
-    OraTest::Artist->create({ name => 'Artist ' . $_ });
+    $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
 }
-my $it = OraTest::Artist->search( {},
+my $it = $schema->resultset('Artist')->search( {},
     { rows => 3,
       offset => 2,
       order_by => 'artistid' }
@@ -88,8 +90,12 @@
 is( $it->next, undef, "next past end of resultset ok" );
 
 # clean up our mess
-$dbh->do("DROP SEQUENCE artist_seq");
-$dbh->do("DROP TABLE artist");
-$dbh->do("DROP TABLE cd");
-$dbh->do("DROP TABLE track");
+END {
+    if($dbh) {
+        $dbh->do("DROP SEQUENCE artist_seq");
+        $dbh->do("DROP TABLE artist");
+        $dbh->do("DROP TABLE cd");
+        $dbh->do("DROP TABLE track");
+    }
+}
 

Modified: trunk/DBIx-Class/t/745db2.t
===================================================================
--- trunk/DBIx-Class/t/745db2.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/745db2.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -14,27 +14,26 @@
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('DB2Test' => $dsn, $user, $pass);
+my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
-my $dbh = DB2Test->schema->storage->dbh;
+my $dbh = $schema->storage->dbh;
 
 $dbh->do("DROP TABLE artist", { RaiseError => 0, PrintError => 0 });
 
 $dbh->do("CREATE TABLE artist (artistid INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), name VARCHAR(255), charfield CHAR(10));");
 
-#'dbi:mysql:host=localhost;database=dbic_test', 'dbic_test', '');
+# This is in core, just testing that it still loads ok
+$schema->class('Artist')->load_components('PK::Auto');
 
-DB2Test::Artist->load_components('PK::Auto');
-
 # test primary key handling
-my $new = DB2Test::Artist->create({ name => 'foo' });
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
 ok($new->artistid, "Auto-PK worked");
 
 # test LIMIT support
 for (1..6) {
-    DB2Test::Artist->create({ name => 'Artist ' . $_ });
+    $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
 }
-my $it = DB2Test::Artist->search( {},
+my $it = $schema->resultset('Artist')->search( {},
     { rows => 3,
       order_by => 'artistid'
       }
@@ -64,11 +63,10 @@
 };
 
 
-my $type_info = DB2Test->schema->storage->columns_info_for('artist');
+my $type_info = $schema->storage->columns_info_for('artist');
 is_deeply($type_info, $test_type_info, 'columns_info_for - column data types');
 
-
-
 # clean up our mess
-$dbh->do("DROP TABLE artist");
-
+END {
+    $dbh->do("DROP TABLE artist") if $dbh;
+}

Modified: trunk/DBIx-Class/t/746db2_400.t
===================================================================
--- trunk/DBIx-Class/t/746db2_400.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/746db2_400.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -17,25 +17,26 @@
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('DB2Test' => $dsn, $user, $pass);
+my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
-my $dbh = DB2Test->schema->storage->dbh;
+my $dbh = $schema->storage->dbh;
 
 $dbh->do("DROP TABLE artist", { RaiseError => 0, PrintError => 0 });
 
 $dbh->do("CREATE TABLE artist (artistid INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), name VARCHAR(255), charfield CHAR(10))");
 
-DB2Test::Artist->load_components('PK::Auto');
+# Just to test loading, already in Core
+$schema->class('Artist')->load_components('PK::Auto');
 
 # test primary key handling
-my $new = DB2Test::Artist->create({ name => 'foo' });
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
 ok($new->artistid, "Auto-PK worked");
 
 # test LIMIT support
 for (1..6) {
-    DB2Test::Artist->create({ name => 'Artist ' . $_ });
+    $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
 }
-my $it = DB2Test::Artist->search( {},
+my $it = $schema->resultset('Artist')->search( {},
     { rows => 3,
       order_by => 'artistid'
       }
@@ -65,11 +66,11 @@
 };
 
 
-my $type_info = DB2Test->schema->storage->columns_info_for('artist');
+my $type_info = $schema->storage->columns_info_for('artist');
 is_deeply($type_info, $test_type_info, 'columns_info_for - column data types');
 
-
-
 # clean up our mess
-$dbh->do("DROP TABLE artist");
+END {
+    $dbh->do("DROP TABLE artist") if $dbh;
+}
 

Modified: trunk/DBIx-Class/t/74mssql.t
===================================================================
--- trunk/DBIx-Class/t/74mssql.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/74mssql.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -18,28 +18,30 @@
 $storage_type = '::DBI::Sybase::MSSQL' if $dsn =~ /^dbi:Sybase:/;
 # Add more for others in the future when they exist (ODBC? ADO? JDBC?)
 
-DBICTest::Schema->storage_type($storage_type);
-DBICTest::Schema->compose_connection( 'MSSQLTest' => $dsn, $user, $pass );
+my $schema = DBICTest::Schema->clone;
+$schema->storage_type($storage_type);
+$schema->connection($dsn, $user, $pass);
 
-my $dbh = MSSQLTest->schema->storage->dbh;
+my $dbh = $schema->storage->dbh;
 
 $dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL
     DROP TABLE artist");
 
 $dbh->do("CREATE TABLE artist (artistid INT IDENTITY PRIMARY KEY, name VARCHAR(255));");
 
-MSSQLTest::Artist->load_components('PK::Auto::MSSQL');
+# Just to test compat shim, Auto is in Core
+$schema->class('Artist')->load_components('PK::Auto::MSSQL');
 
 # Test PK
-my $new = MSSQLTest::Artist->create( { name => 'foo' } );
+my $new = $schema->resultset('Artist')->create( { name => 'foo' } );
 ok($new->artistid, "Auto-PK worked");
 
 # Test LIMIT
 for (1..6) {
-    MSSQLTest::Artist->create( { name => 'Artist ' . $_ } );
+    $schema->resultset('Artist')->create( { name => 'Artist ' . $_ } );
 }
 
-my $it = MSSQLTest::Artist->search( { },
+my $it = $schema->resultset('Artist')->search( { },
     { rows     => 3,
       offset   => 2,
       order_by => 'artistid'
@@ -52,3 +54,8 @@
 $it->next;
 is( $it->next, undef, "next past end of resultset ok" );
 
+# clean up our mess
+END {
+    $dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL DROP TABLE artist")
+        if $dbh;
+}

Modified: trunk/DBIx-Class/t/76joins.t
===================================================================
--- trunk/DBIx-Class/t/76joins.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/76joins.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -16,7 +16,7 @@
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 53 );
+        : ( tests => 63 );
 }
 
 # figure out if we've got a version of sqlite that is older than 3.2.6, in
@@ -169,7 +169,7 @@
 cmp_ok($rs + 0, '==', 3, 'Correct number of records returned');
 
 my $queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debugcb(sub { $queries++; });
 $schema->storage->debug(1);
 
 my @cd = $rs->all;
@@ -222,12 +222,42 @@
 
 $queries = 0;
 
+is($tag->search_related('cd')->search_related('artist')->first->name,
+   'Caterwauler McCrae',
+   'chained belongs_to->belongs_to search_related ok');
+
+is($queries, 0, 'chained search_related after belontgs_to->belongs_to prefetch ran no queries');
+
+$queries = 0;
+
 $cd = $schema->resultset('CD')->find(1, { prefetch => 'artist' });
 
 is($cd->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'artist prefetched correctly on find');
 
 is($queries, 1, 'find with prefetch ran exactly 1 select statement (excluding column_info)');
 
+$queries = 0;
+
+$schema->storage->debugcb(sub { $queries++; });
+
+$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' } });
+
+is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
+
+TODO: {
+  local $TODO = 'use prefetched values for many_to_many accessor';
+
+  is($queries, 1, 'many_to_many accessor with nested prefetch ran exactly 1 query');
+}
+
+$queries = 0;
+
+my $producers = $cd->search_related('cd_to_producer')->search_related('producer');
+
+is($producers->first->name, 'Matt S Trout', 'chained many_to_many search_related ok');
+
+is($queries, 0, 'chained search_related after many_to_many prefetch ran no queries');
+
 $schema->storage->debug($orig_debug);
 $schema->storage->debugobj->callback(undef);
 
@@ -306,6 +336,19 @@
 
 is($rs->next->name, 'Caterwauler McCrae', "Correct artist returned");
 
+$cd = $schema->resultset('Artist')->first->create_related('cds',
+    {
+    title   => 'Unproduced Single',
+    year    => 2007
+});
+
+my $left_join = $schema->resultset('CD')->search(
+    { 'me.cdid' => $cd->cdid },
+    { prefetch => { cd_to_producer => 'producer' } }
+);
+
+cmp_ok($left_join, '==', 1, 'prefetch with no join record present');
+
 $queries = 0;
 $schema->storage->debugcb(sub { $queries++ });
 $schema->storage->debug(1);
@@ -380,7 +423,8 @@
     {},
     {
         join     => [ { cds => ['tracks'] } ],
-        prefetch => [ { cds => ['tracks'] } ]
+        prefetch => [ { cds => ['tracks'] } ],
+        cache    => 1 # last test needs this
     }
 );
 
@@ -405,11 +449,24 @@
     return $struc;
 }
 
+$queries = 0;
+$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debug(1);
+
 my $prefetch_result = make_hash_struc($art_rs_pr);
+
+is($queries, 1, 'nested prefetch across has_many->has_many ran exactly 1 query');
+
 my $nonpre_result   = make_hash_struc($art_rs);
 
-TODO: {
-  local $TODO = 'fixing collapse in -current';
 is_deeply( $prefetch_result, $nonpre_result,
     'Compare 2 level prefetch result to non-prefetch result' );
-}
+
+$queries = 0;
+
+is($art_rs_pr->search_related('cds')->search_related('tracks')->first->title,
+   'Fowlin',
+   'chained has_many->has_many search_related ok'
+  );
+
+is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');

Modified: trunk/DBIx-Class/t/81transactions.t
===================================================================
--- trunk/DBIx-Class/t/81transactions.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/81transactions.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -118,7 +118,7 @@
   # Force txn_rollback() to throw an exception
   no warnings 'redefine';
   no strict 'refs';
-  local *{"DBIx::Class::Schema::txn_rollback"} = sub{die 'FAILED'};
+  local *{"DBIx::Class::Storage::DBI::SQLite::txn_rollback"} = sub{die 'FAILED'};
 
   eval {
     $schema->txn_do($fail_code, $artist);

Modified: trunk/DBIx-Class/t/83cache.t
===================================================================
--- trunk/DBIx-Class/t/83cache.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/83cache.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -12,7 +12,7 @@
 
 eval "use DBD::SQLite";
 plan skip_all => 'needs DBD::SQLite for testing' if $@;
-plan tests => 22;
+plan tests => 23;
 
 my $rs = $schema->resultset("Artist")->search(
   { artistid => 1 }
@@ -158,8 +158,16 @@
   push @objs, $tag->id; #warn "tag: ", $tag->ID;
 }
 
-is_deeply( \@objs, [ 2, 5, 8 ], 'second cd has correct tags' );
+is_deeply( \@objs, [ 1 ], 'second cd has correct tags' );
 
+$tags = $cds->next->tags;
+ at objs = ();
+while( my $tag = $tags->next ) {
+  push @objs, $tag->id; #warn "tag: ", $tag->ID;
+}
+
+is_deeply( \@objs, [ 2, 5, 8 ], 'third cd has correct tags' );
+
 is( $queries, 0, 'no additional SQL statements while checking nested data' );
 
 # start test for prefetch SELECT count

Modified: trunk/DBIx-Class/t/86sqlt.t
===================================================================
--- trunk/DBIx-Class/t/86sqlt.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/86sqlt.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -10,7 +10,7 @@
 
 my $schema = DBICTest->init_schema;
 
-plan tests => 53;
+plan tests => 54;
 
 my $translator = SQL::Translator->new( 
   parser_args => {
@@ -24,6 +24,10 @@
 
 my $output = $translator->translate();
 
+
+ok($output, "SQLT produced someoutput")
+  or diag($translator->error);
+
 # Note that the constraints listed here are the only ones that are tested -- if
 # more exist in the Schema than are listed here and all listed constraints are
 # correct, the test will still pass. If you add a class with UNIQUE or FOREIGN

Modified: trunk/DBIx-Class/t/87ordered.t
===================================================================
--- trunk/DBIx-Class/t/87ordered.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/87ordered.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -6,9 +6,11 @@
 use lib qw(t/lib);
 use DBICTest;
 
+use POSIX qw(ceil);
+
 my $schema = DBICTest->init_schema();
 
-plan tests => 321;
+plan tests => 879;
 
 my $employees = $schema->resultset('Employee');
 $employees->delete();
@@ -23,20 +25,168 @@
 
 DBICTest::Employee->grouping_column('group_id');
 $employees->delete();
-foreach my $group_id (1..3) {
+foreach my $group_id (1..4) {
     foreach (1..6) {
         $employees->create({ name=>'temp', group_id=>$group_id });
     }
 }
 $employees = $employees->search(undef,{order_by=>'group_id,position'});
 
-foreach my $group_id (1..3) {
+foreach my $group_id (1..4) {
     my $group_employees = $employees->search({group_id=>$group_id});
     $group_employees->all();
     ok( check_rs($group_employees), "group intial positions" );
     hammer_rs( $group_employees );
 }
 
+my $group_3 = $employees->search({group_id=>3});
+my $to_group = 1;
+my $to_pos = undef;
+while (my $employee = $group_3->next) {
+	$employee->move_to_group($to_group, $to_pos);
+	$to_pos++;
+	$to_group = $to_group==1 ? 2 : 1;
+}
+foreach my $group_id (1..4) {
+    my $group_employees = $employees->search({group_id=>$group_id});
+    $group_employees->all();
+    ok( check_rs($group_employees), "group positions after move_to_group" );
+}
+
+my $employee = $employees->search({group_id=>4})->first;
+$employee->position(2);
+$employee->update;
+ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 1" );
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({position=>3});
+ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 2" );
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(1);
+$employee->update;
+ok(
+	check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+	"overloaded update 3"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({group_id=>2});
+ok(
+	check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
+	"overloaded update 4"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(1);
+$employee->position(3);
+$employee->update;
+ok(
+	check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+	"overloaded update 5"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(2);
+$employee->position(undef);
+$employee->update;
+ok(
+	check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
+	"overloaded update 6"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({group_id=>1,position=>undef});
+ok(
+	check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+	"overloaded update 7"
+);
+
+# multicol tests begin here
+DBICTest::Employee->grouping_column(['group_id', 'group_id_2']);
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+foreach my $group_id (1..3) {
+    foreach my $group_id_2 (1..3) {
+        my $group_employees = $employees->search({group_id=>$group_id, group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group intial positions" );
+        hammer_rs( $group_employees );
+    }
+}
+
+# move_to_group, specifying group by hash
+my $group_4 = $employees->search({group_id=>4});
+$to_group = 1;
+my $to_group_2_base = 7;
+my $to_group_2 = 1;
+$to_pos = undef;
+while (my $employee = $group_4->next) {
+	$employee->move_to_group({group_id=>$to_group, group_id_2=>$to_group_2}, $to_pos);
+	$to_pos++;
+    $to_group = ($to_group % 3) + 1;
+    $to_group_2_base++;
+    $to_group_2 = (ceil($to_group_2_base/3.0) %3) +1
+}
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        my $group_employees = $employees->search({group_id=>$group_id,group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group positions after move_to_group" );
+    }
+}
+
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->update;
+ok( 
+    check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>1})), 
+    "overloaded multicol update 1" 
+);
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->update({group_id=>2});
+ok( check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>1})), 
+    "overloaded multicol update 2" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->group_id_2(3);
+$employee->update();
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>3})),
+    "overloaded multicol update 3" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->update({group_id=>2, group_id_2=>3});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>3})), 
+    "overloaded multicol update 4" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>2})->first;
+$employee->update({group_id=>2, group_id_2=>4, position=>2});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>2}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>4})), 
+    "overloaded multicol update 5" 
+);
+
 sub hammer_rs {
     my $rs = shift;
     my $employee;

Modified: trunk/DBIx-Class/t/89dbicadmin.t
===================================================================
--- trunk/DBIx-Class/t/89dbicadmin.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/89dbicadmin.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -23,7 +23,7 @@
 # tests run on windows as well
 
 my $employees = $schema->resultset('Employee');
-my $cmd = qq|$^X script/dbicadmin --schema=DBICTest::Schema --class=Employee --tlibs --connect="['dbi:SQLite:dbname=t/var/DBIxClass.db','','']" --force --tlibs|;
+my $cmd = qq|$^X script/dbicadmin --schema=DBICTest::Schema --class=Employee --tlibs --connect="['dbi:SQLite:dbname=t/var/DBIxClass.db','','',{AutoCommit:1}]" --force --tlibs|;
 
 `$cmd --op=insert --set="{name:'Matt'}"`;
 ok( ($employees->count()==1), 'insert count' );

Modified: trunk/DBIx-Class/t/90join_torture.t
===================================================================
--- trunk/DBIx-Class/t/90join_torture.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/90join_torture.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -13,7 +13,7 @@
 is($rs1a_results[0]->title, 'Forkful of bees', "bare field conditions okay after search related");
 my $rs1 = $schema->resultset("Artist")->search({ 'tags.tag' => 'Blue' }, { join => {'cds' => 'tracks'}, prefetch => {'cds' => 'tags'} });
 my @artists = $rs1->all;
-cmp_ok(@artists, '==', 1, "Two artists returned");
+cmp_ok(@artists, '==', 2, "Two artists returned");
 
 my $rs2 = $rs1->search({ artistid => '1' }, { join => {'cds' => {'cd_to_producer' => 'producer'} } });
 
@@ -23,8 +23,8 @@
 
 #this is wrong, should accept me.title really
 my $rs3 = $rs2->search_related('cds');
-cmp_ok(scalar($rs3->all), '==', 27, "All cds for artist returned");
-cmp_ok($rs3->count, '==', 27, "All cds for artist returned via count");
+cmp_ok(scalar($rs3->all), '==', 45, "All cds for artist returned");
+cmp_ok($rs3->count, '==', 45, "All cds for artist returned via count");
 
 my $rs4 = $schema->resultset("CD")->search({ 'artist.artistid' => '1' }, { join => ['tracks', 'artist'], prefetch => 'artist' });
 my @rs4_results = $rs4->all;

Modified: trunk/DBIx-Class/t/92storage.t
===================================================================
--- trunk/DBIx-Class/t/92storage.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/92storage.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -5,11 +5,64 @@
 use lib qw(t/lib);
 use DBICTest;
 
-plan tests => 1;
+{
+    package DBICTest::ExplodingStorage::Sth;
+    use strict;
+    use warnings;
 
+    sub execute { die "Kablammo!" }
+
+    sub bind_param {}
+
+    package DBICTest::ExplodingStorage;
+    use strict;
+    use warnings;
+    use base 'DBIx::Class::Storage::DBI::SQLite';
+
+    my $count = 0;
+    sub sth {
+      my ($self, $sql) = @_;
+      return bless {},  "DBICTest::ExplodingStorage::Sth" unless $count++;
+      return $self->next::method($sql);
+    }
+
+    sub connected {
+      return 0 if $count == 1;
+      return shift->next::method(@_);
+    }
+}
+
+plan tests => 5;
+
 my $schema = DBICTest->init_schema();
 
 is( ref($schema->storage), 'DBIx::Class::Storage::DBI::SQLite',
     'Storage reblessed correctly into DBIx::Class::Storage::DBI::SQLite' );
 
+my $storage = $schema->storage;
+$storage->ensure_connected;
+
+eval {
+    $schema->storage->throw_exception('test_exception_42');
+};
+like($@, qr/\btest_exception_42\b/, 'basic exception');
+
+eval {
+    $schema->resultset('CD')->search_literal('broken +%$#$1')->all;
+};
+like($@, qr/prepare_cached failed/, 'exception via DBI->HandleError, etc');
+
+bless $storage, "DBICTest::ExplodingStorage";
+$schema->storage($storage);
+
+eval { 
+    $schema->resultset('Artist')->create({ name => "Exploding Sheep" });
+};
+
+is($@, "", "Exploding \$sth->execute was caught");
+
+is(1, $schema->resultset('Artist')->search({name => "Exploding Sheep" })->count,
+  "And the STH was retired");
+
+
 1;

Added: trunk/DBIx-Class/t/93nobindvars.t
===================================================================
--- trunk/DBIx-Class/t/93nobindvars.t	                        (rev 0)
+++ trunk/DBIx-Class/t/93nobindvars.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,69 @@
+use strict;
+use warnings;  
+
+# Copied from 71mysql.t, manually using NoBindVars.  This is to give that code
+#  wider testing, since virtually nobody who regularly runs the test suite
+#  is using DBD::Sybase+FreeTDS+MSSQL -- blblack
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBI::Const::GetInfoType;
+
+my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/};
+
+#warn "$dsn $user $pass";
+
+plan skip_all => 'Set $ENV{DBICTEST_MYSQL_DSN}, _USER and _PASS to run this test'
+  unless ($dsn && $user);
+
+plan tests => 4;
+
+{ # Fake storage driver for mysql + no bind variables
+    package DBIx::Class::Storage::DBI::MySQLNoBindVars;
+    use Class::C3;
+    use base qw/
+        DBIx::Class::Storage::DBI::NoBindVars
+        DBIx::Class::Storage::DBI::mysql
+    /;
+    $INC{'DBIx/Class/Storage/DBI/MySQLNoBindVars.pm'} = 1;
+}
+
+# XXX Class::C3 doesn't like some of the Storage stuff happening late...
+Class::C3::reinitialize();
+
+my $schema = DBICTest::Schema->clone;
+$schema->storage_type('::DBI::MySQLNoBindVars');
+$schema->connection($dsn, $user, $pass);
+
+my $dbh = $schema->storage->dbh;
+
+$dbh->do("DROP TABLE IF EXISTS artist;");
+
+$dbh->do("CREATE TABLE artist (artistid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), charfield CHAR(10));");
+
+$schema->class('Artist')->load_components('PK::Auto');
+
+# test primary key handling
+my $new = $schema->resultset('Artist')->create({ name => 'foo' });
+ok($new->artistid, "Auto-PK worked");
+
+# test LIMIT support
+for (1..6) {
+    $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
+}
+my $it = $schema->resultset('Artist')->search( {},
+    { rows => 3,
+      offset => 2,
+      order_by => 'artistid' }
+);
+is( $it->count, 3, "LIMIT count ok" );
+is( $it->next->name, "Artist 2", "iterator->next ok" );
+$it->next;
+$it->next;
+is( $it->next, undef, "next past end of resultset ok" );
+
+# clean up our mess
+END {
+    $dbh->do("DROP TABLE artist") if $dbh;
+}

Added: trunk/DBIx-Class/t/94versioning.t
===================================================================
--- trunk/DBIx-Class/t/94versioning.t	                        (rev 0)
+++ trunk/DBIx-Class/t/94versioning.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More;
+use File::Spec;
+
+BEGIN {
+    eval "use DBD::SQLite; use SQL::Translator 0.08;";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite and SQL::Translator 0.08 for testing' )
+        : ( tests => 6 );
+}
+
+use lib qw(t/lib);
+
+use_ok('DBICVersionOrig');
+
+my $db_file = "t/var/versioning.db";
+unlink($db_file) if -e $db_file;
+unlink($db_file . "-journal") if -e $db_file . "-journal";
+mkdir("t/var") unless -d "t/var";
+unlink('t/var/DBICVersion-Schema-1.0-SQLite.sql');
+
+my $schema_orig = DBICVersion::Schema->connect(
+  "dbi:SQLite:$db_file",
+  undef,
+  undef,
+  { AutoCommit => 1 },
+);
+# $schema->storage->ensure_connected();
+
+is($schema_orig->ddl_filename('SQLite', 't/var', '1.0'), File::Spec->catfile('t', 'var', 'DBICVersion-Schema-1.0-SQLite.sql'), 'Filename creation working');
+$schema_orig->create_ddl_dir('SQLite', undef, 't/var');
+
+ok(-f 't/var/DBICVersion-Schema-1.0-SQLite.sql', 'Created DDL file');
+## do this here or let Versioned.pm do it?
+# $schema->deploy();
+
+my $tvrs = $schema_orig->resultset('Table');
+is($schema_orig->exists($tvrs), 1, 'Created schema from DDL file');
+
+eval "use DBICVersionNew";
+my $schema_new = DBICVersion::Schema->connect(
+  "dbi:SQLite:$db_file",
+  undef,
+  undef,
+  { AutoCommit => 1 },
+);
+
+unlink('t/var/DBICVersion-Schema-2.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-1.0-2.0-SQLite.sql');
+$schema_new->create_ddl_dir('SQLite', undef, 't/var', '1.0');
+ok(-f 't/var/DBICVersion-Schema-1.0-2.0-SQLite.sql', 'Created DDL upgrade file');
+
+## create new to pick up filedata for upgrade files we just made (on_connect)
+my $schema_upgrade = DBICVersion::Schema->connect(
+  "dbi:SQLite:$db_file",
+  undef,
+  undef,
+  { AutoCommit => 1 },
+);
+
+## do this here or let Versioned.pm do it?
+$schema_upgrade->upgrade();
+$tvrs = $schema_upgrade->resultset('Table');
+is($schema_upgrade->exists($tvrs), 1, 'Upgraded schema from DDL file');
+
+unlink($db_file) if -e $db_file;
+unlink($db_file . "-journal") if -e $db_file . "-journal";
+unlink('t/var/DBICVersion-Schema-1.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-2.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-1.0-2.0-SQLite.sql');
+unlink(<t/var/backup/*>);

Modified: trunk/DBIx-Class/t/95sql_maker_quote.t
===================================================================
--- trunk/DBIx-Class/t/95sql_maker_quote.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/95sql_maker_quote.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -15,9 +15,9 @@
 
 use_ok('DBICTest');
 
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
-my $sql_maker = DBICTest->schema->storage->sql_maker;
+my $sql_maker = $schema->storage->sql_maker;
 
 $sql_maker->quote_char('`');
 $sql_maker->name_sep('.');

Added: trunk/DBIx-Class/t/96file_column.t
===================================================================
--- trunk/DBIx-Class/t/96file_column.t	                        (rev 0)
+++ trunk/DBIx-Class/t/96file_column.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,15 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use IO::File;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 1;
+
+my $fh = new IO::File('t/96file_column.t','r');
+eval { $schema->resultset('FileColumn')->create({file => {handle => $fh, filename =>'96file_column.t'}})};
+cmp_ok($@,'eq','','FileColumn checking if file handled properly.');

Added: trunk/DBIx-Class/t/96multi_create.t
===================================================================
--- trunk/DBIx-Class/t/96multi_create.t	                        (rev 0)
+++ trunk/DBIx-Class/t/96multi_create.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,122 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DateTime;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 17;
+
+my $cd2 = $schema->resultset('CD')->create({ artist => 
+                                   { name => 'Fred Bloggs' },
+                                   title => 'Some CD',
+                                   year => 1996
+                                 });
+
+is(ref $cd2->artist, 'DBICTest::Artist', 'Created CD and Artist object');
+is($cd2->artist->name, 'Fred Bloggs', 'Artist created correctly');
+
+my $artist = $schema->resultset('Artist')->create({ name => 'Fred 2',
+                                                     cds => [
+                                                             { title => 'Music to code by',
+                                                               year => 2007,
+                                                             },
+                                                             ],
+                                                     });
+is(ref $artist->cds->first, 'DBICTest::CD', 'Created Artist with CDs');
+is($artist->cds->first->title, 'Music to code by', 'CD created correctly');
+
+# Add a new CD
+$artist->update({cds => [ $artist->cds, 
+                          { title => 'Yet another CD',
+                            year => 2006,
+                          },
+                        ],
+                });
+is(($artist->cds->search({}, { order_by => 'year' }))[0]->title, 'Yet another CD', 'Updated and added another CD');
+
+my $newartist = $schema->resultset('Artist')->find_or_create({ name => 'Fred 2'});
+
+is($newartist->name, 'Fred 2', 'Retrieved the artist');
+
+
+my $newartist2 = $schema->resultset('Artist')->find_or_create({ name => 'Fred 3',
+                                                                cds => [
+                                                                        { title => 'Noah Act',
+                                                                          year => 2007,
+                                                                        },
+                                                                       ],
+
+                                                              });
+
+is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create');
+
+
+CREATE_RELATED1 :{
+
+	my $artist = $schema->resultset('Artist')->first;
+	
+	my $cd_result = $artist->create_related('cds', {
+	
+		title => 'TestOneCD1',
+		year => 2007,
+		tracks => [
+		
+			{ position=>111,
+			  title => 'TrackOne',
+			},
+			{ position=>112,
+			  title => 'TrackTwo',
+			}
+		],
+
+	});
+	
+	ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class");
+	ok( $cd_result->title eq "TestOneCD1", "Got Expected Title");
+	
+	my $tracks = $cd_result->tracks;
+	
+	ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet");
+	
+	foreach my $track ($tracks->all)
+	{
+		ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class');
+	}
+}
+
+CREATE_RELATED2 :{
+
+	my $artist = $schema->resultset('Artist')->first;
+	
+	my $cd_result = $artist->create_related('cds', {
+	
+		title => 'TestOneCD2',
+		year => 2007,
+		tracks => [
+		
+			{ position=>111,
+			  title => 'TrackOne',
+			},
+			{ position=>112,
+			  title => 'TrackTwo',
+			}
+		],
+
+	});
+	
+	ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class");
+	ok( $cd_result->title eq "TestOneCD2", "Got Expected Title");
+	
+	my $tracks = $cd_result->tracks;
+	
+	ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet");
+	
+	foreach my $track ($tracks->all)
+	{
+		ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class');
+	}
+}

Added: trunk/DBIx-Class/t/97result_class.t
===================================================================
--- trunk/DBIx-Class/t/97result_class.t	                        (rev 0)
+++ trunk/DBIx-Class/t/97result_class.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,44 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 9;
+
+{
+  my $cd_rc = $schema->resultset("CD")->result_class;
+  
+  my $artist_rs = $schema->resultset("Artist")
+    ->search_rs({}, {result_class => "IWillExplode"});
+  is($artist_rs->result_class, 'IWillExplode', 'Correct artist result_class');
+  
+  my $cd_rs = $artist_rs->related_resultset('cds');
+  is($cd_rs->result_class, $cd_rc, 'Correct cd result_class');
+
+  my $cd_rs2 = $schema->resultset("Artist")->search_rs({})->related_resultset('cds');
+  is($cd_rs->result_class, $cd_rc, 'Correct cd2 result_class');
+
+  my $cd_rs3 = $schema->resultset("Artist")->search_rs({},{})->related_resultset('cds');
+  is($cd_rs->result_class, $cd_rc, 'Correct cd3 result_class');
+  
+  isa_ok(eval{ $cd_rs->find(1) }, $cd_rc, 'Inflated into correct cd result_class');
+}
+
+
+{
+  my $cd_rc = $schema->resultset("CD")->result_class;
+  
+  my $artist_rs = $schema->resultset("Artist")
+    ->search_rs({}, {result_class => "IWillExplode"})->search({artistid => 1});
+  is($artist_rs->result_class, 'IWillExplode', 'Correct artist result_class');
+  
+  my $cd_rs = $artist_rs->related_resultset('cds');
+  is($cd_rs->result_class, $cd_rc, 'Correct cd result_class');
+  
+  isa_ok(eval{ $cd_rs->find(1) }, $cd_rc, 'Inflated into correct cd result_class');   
+  isa_ok(eval{ $cd_rs->search({ cdid => 1 })->first }, $cd_rc, 'Inflated into correct cd result_class');
+}

Added: trunk/DBIx-Class/t/bindtype_columns.t
===================================================================
--- trunk/DBIx-Class/t/bindtype_columns.t	                        (rev 0)
+++ trunk/DBIx-Class/t/bindtype_columns.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,60 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my ($dsn, $dbuser, $dbpass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
+
+plan skip_all => 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test'
+  unless ($dsn && $dbuser);
+  
+plan tests => 3;
+
+my $schema = DBICTest::Schema->connection($dsn, $dbuser, $dbpass, { AutoCommit => 1 });
+
+my $dbh = $schema->storage->dbh;
+
+$dbh->do(qq[
+
+	CREATE TABLE artist
+	(
+		artistid		serial	NOT NULL	PRIMARY KEY,
+		media			bytea	NOT NULL,
+		name			varchar NULL
+	);
+],{ RaiseError => 1, PrintError => 1 });
+
+
+$schema->class('Artist')->load_components(qw/ 
+
+	PK::Auto 
+	Core 
+/);
+
+$schema->class('Artist')->add_columns(
+	
+	"media", { 
+	
+		data_type => "bytea", 
+		is_nullable => 0,
+	},
+);
+
+# test primary key handling
+my $big_long_string	= 'abcd' x 250000;
+
+my $new = $schema->resultset('Artist')->create({ media => $big_long_string });
+
+ok($new->artistid, "Created a blob row");
+is($new->media, 	$big_long_string, "Set the blob correctly.");
+
+my $rs = $schema->resultset('Artist')->find({artistid=>$new->artistid});
+
+is($rs->get_column('media'), $big_long_string, "Created the blob correctly.");
+
+$dbh->do("DROP TABLE artist");
+
+
+

Modified: trunk/DBIx-Class/t/cdbi-sweet-t/08pager.t
===================================================================
--- trunk/DBIx-Class/t/cdbi-sweet-t/08pager.t	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/cdbi-sweet-t/08pager.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -16,10 +16,13 @@
 use lib 't/lib';
 
 use_ok('DBICTest');
-DBICTest->init_schema();
 
-DBICTest::CD->load_components(qw/CDBICompat::Pager/);
+DBICTest::Schema::CD->load_components(qw/CDBICompat CDBICompat::Pager/);
 
+my $schema = DBICTest->init_schema(compose_connection => 1);
+
+DBICTest::CD->result_source_instance->schema->storage($schema->storage);
+
 my ( $pager, $it ) = DBICTest::CD->page(
     {},
     { order_by => 'title',

Added: trunk/DBIx-Class/t/lib/DBICNSTest/OtherRslt/D.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/OtherRslt/D.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/OtherRslt/D.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,6 @@
+package DBICNSTest::OtherRslt::D;
+use base qw/DBIx::Class/;
+__PACKAGE__->load_components(qw/PK::Auto Core/);
+__PACKAGE__->table('d');
+__PACKAGE__->add_columns('d');
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/RSBase.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/RSBase.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/RSBase.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,3 @@
+package DBICNSTest::RSBase;
+use base qw/DBIx::Class::ResultSet/;
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/RSet/A.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/RSet/A.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/RSet/A.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,3 @@
+package DBICNSTest::RSet::A;
+use base qw/DBIx::Class::ResultSet/;
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/RSet/C.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/RSet/C.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/RSet/C.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,3 @@
+package DBICNSTest::RSet::C;
+use base qw/DBIx::Class::ResultSet/;
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/Result/A.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/Result/A.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/Result/A.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,6 @@
+package DBICNSTest::Result::A;
+use base qw/DBIx::Class/;
+__PACKAGE__->load_components(qw/PK::Auto Core/);
+__PACKAGE__->table('a');
+__PACKAGE__->add_columns('a');
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/Result/B.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/Result/B.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/Result/B.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,6 @@
+package DBICNSTest::Result::B;
+use base qw/DBIx::Class/;
+__PACKAGE__->load_components(qw/PK::Auto Core/);
+__PACKAGE__->table('b');
+__PACKAGE__->add_columns('b');
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/A.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/A.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/A.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,3 @@
+package DBICNSTest::ResultSet::A;
+use base qw/DBIx::Class::ResultSet/;
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/C.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/C.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/ResultSet/C.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,3 @@
+package DBICNSTest::ResultSet::C;
+use base qw/DBIx::Class::ResultSet/;
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/A.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/A.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/A.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,6 @@
+package DBICNSTest::Rslt::A;
+use base qw/DBIx::Class/;
+__PACKAGE__->load_components(qw/PK::Auto Core/);
+__PACKAGE__->table('a');
+__PACKAGE__->add_columns('a');
+1;

Added: trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/B.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/B.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICNSTest/Rslt/B.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,6 @@
+package DBICNSTest::Rslt::B;
+use base qw/DBIx::Class/;
+__PACKAGE__->load_components(qw/PK::Auto Core/);
+__PACKAGE__->table('b');
+__PACKAGE__->add_columns('b');
+1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Plain.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Plain.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Plain.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -15,7 +15,13 @@
 my $dsn = "dbi:SQLite:${db_file}";
 
 __PACKAGE__->load_classes("Test");
-my $schema = __PACKAGE__->compose_connection(__PACKAGE__, $dsn);
+my $schema = __PACKAGE__->compose_connection(
+  __PACKAGE__,
+  $dsn,
+  undef,
+  undef,
+  { AutoCommit => 1 }
+);
 
 my $dbh = DBI->connect($dsn);
 

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/Artist.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/Artist.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/Artist.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -4,10 +4,15 @@
 use base 'DBIx::Class::Core';
 
 __PACKAGE__->table('artist');
+__PACKAGE__->source_info({
+    "source_info_key_A" => "source_info_value_A",
+    "source_info_key_B" => "source_info_value_B",
+    "source_info_key_C" => "source_info_value_C",
+});
 __PACKAGE__->add_columns(
   'artistid' => {
     data_type => 'integer',
-    is_auto_increment => 1
+    is_auto_increment => 1,
   },
   'name' => {
     data_type => 'varchar',

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/ArtistSourceName.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/ArtistSourceName.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/ArtistSourceName.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -2,7 +2,7 @@
     DBICTest::Schema::ArtistSourceName;
 
 use base 'DBICTest::Schema::Artist';
-
+__PACKAGE__->table(__PACKAGE__->table);
 __PACKAGE__->source_name('SourceNameArtists');
 
 1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/Employee.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/Employee.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/Employee.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -19,6 +19,10 @@
         data_type => 'integer',
         is_nullable => 1,
     },
+    group_id_2 => {
+        data_type => 'integer',
+        is_nullable => 1,
+    },
     name => {
         data_type => 'varchar',
         size      => 100,

Added: trunk/DBIx-Class/t/lib/DBICTest/Schema/FileColumn.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/FileColumn.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/FileColumn.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,19 @@
+package 
+DBICTest::Schema::FileColumn;
+
+use strict;
+use warnings;
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->load_components(qw/InflateColumn::File/);
+
+__PACKAGE__->table('file_columns');
+
+__PACKAGE__->add_columns(
+  id => { data_type => 'integer', is_auto_increment => 1 },
+  file => { data_type => 'varchar', is_file_column => 1, file_column_path => '/tmp', size=>255 }
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/FourKeys.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/FourKeys.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/FourKeys.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,17 +3,17 @@
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::FourKeys->table('fourkeys');
-DBICTest::Schema::FourKeys->add_columns(
+__PACKAGE__->table('fourkeys');
+__PACKAGE__->add_columns(
   'foo' => { data_type => 'integer' },
   'bar' => { data_type => 'integer' },
   'hello' => { data_type => 'integer' },
   'goodbye' => { data_type => 'integer' },
   'sensors' => { data_type => 'character' },
 );
-DBICTest::Schema::FourKeys->set_primary_key(qw/foo bar hello goodbye/);
+__PACKAGE__->set_primary_key(qw/foo bar hello goodbye/);
 
-DBICTest::Schema::FourKeys->has_many(
+__PACKAGE__->has_many(
   'fourkeys_to_twokeys', 'DBICTest::Schema::FourKeys_to_TwoKeys', {
     'foreign.f_foo' => 'self.foo',
     'foreign.f_bar' => 'self.bar',
@@ -21,7 +21,7 @@
     'foreign.f_goodbye' => 'self.goodbye',
 });
 
-DBICTest::Schema::FourKeys->many_to_many(
+__PACKAGE__->many_to_many(
   'twokeys', 'fourkeys_to_twokeys', 'twokeys',
 );
 

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/LinerNotes.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/LinerNotes.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/LinerNotes.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,8 +3,8 @@
 
 use base qw/DBIx::Class::Core/;
 
-DBICTest::Schema::LinerNotes->table('liner_notes');
-DBICTest::Schema::LinerNotes->add_columns(
+__PACKAGE__->table('liner_notes');
+__PACKAGE__->add_columns(
   'liner_id' => {
     data_type => 'integer',
   },
@@ -13,8 +13,8 @@
     size      => 100,
   },
 );
-DBICTest::Schema::LinerNotes->set_primary_key('liner_id');
-DBICTest::Schema::LinerNotes->belongs_to(
+__PACKAGE__->set_primary_key('liner_id');
+__PACKAGE__->belongs_to(
   'cd', 'DBICTest::Schema::CD', 'liner_id'
 );
 

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/NoPrimaryKey.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/NoPrimaryKey.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/NoPrimaryKey.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,13 +3,13 @@
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::NoPrimaryKey->table('noprimarykey');
-DBICTest::Schema::NoPrimaryKey->add_columns(
+__PACKAGE__->table('noprimarykey');
+__PACKAGE__->add_columns(
   'foo' => { data_type => 'integer' },
   'bar' => { data_type => 'integer' },
   'baz' => { data_type => 'integer' },
 );
 
-DBICTest::Schema::NoPrimaryKey->add_unique_constraint(foo_bar => [ qw/foo bar/ ]);
+__PACKAGE__->add_unique_constraint(foo_bar => [ qw/foo bar/ ]);
 
 1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/OneKey.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/OneKey.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/OneKey.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,8 +3,8 @@
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::OneKey->table('onekey');
-DBICTest::Schema::OneKey->add_columns(
+__PACKAGE__->table('onekey');
+__PACKAGE__->add_columns(
   'id' => {
     data_type => 'integer',
     is_auto_increment => 1,
@@ -16,7 +16,7 @@
     data_type => 'integer',
   },
 );
-DBICTest::Schema::OneKey->set_primary_key('id');
+__PACKAGE__->set_primary_key('id');
 
 
 1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/Serialized.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/Serialized.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/Serialized.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -3,11 +3,11 @@
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::Serialized->table('serialized');
-DBICTest::Schema::Serialized->add_columns(
+__PACKAGE__->table('serialized');
+__PACKAGE__->add_columns(
   'id' => { data_type => 'integer' },
   'serialized' => { data_type => 'text' },
 );
-DBICTest::Schema::Serialized->set_primary_key('id');
+__PACKAGE__->set_primary_key('id');
 
 1;

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema/Track.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema/Track.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema/Track.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -2,6 +2,7 @@
     DBICTest::Schema::Track;
 
 use base 'DBIx::Class::Core';
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
 
 __PACKAGE__->table('track');
 __PACKAGE__->add_columns(
@@ -20,6 +21,11 @@
     data_type => 'varchar',
     size      => 100,
   },
+  last_updated_on => {
+    data_type => 'datetime',
+    accessor => 'updated_date',
+    is_nullable => 1
+  },
 );
 __PACKAGE__->set_primary_key('trackid');
 

Modified: trunk/DBIx-Class/t/lib/DBICTest/Schema.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest/Schema.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest/Schema.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -9,6 +9,7 @@
   Artist
   Employee
   CD
+  FileColumn
   Link
   Bookmark
   #dummy

Modified: trunk/DBIx-Class/t/lib/DBICTest.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICTest.pm	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/DBICTest.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -55,7 +55,18 @@
     my $dbuser = $ENV{"DBICTEST_DBUSER"} || '';
     my $dbpass = $ENV{"DBICTEST_DBPASS"} || '';
 
-    my $schema = DBICTest::Schema->compose_connection('DBICTest' => $dsn, $dbuser, $dbpass);
+    my $schema;
+
+    my @connect_info = ($dsn, $dbuser, $dbpass, { AutoCommit => 1 });
+
+    if ($args{compose_connection}) {
+      $schema = DBICTest::Schema->compose_connection(
+                  'DBICTest', @connect_info
+                );
+    } else {
+      $schema = DBICTest::Schema->compose_namespace('DBICTest')
+                                ->connect(@connect_info);
+    }
     $schema->storage->on_connect_do(['PRAGMA synchronous = OFF']);
     if ( !$args{no_deploy} ) {
         __PACKAGE__->deploy_schema( $schema );
@@ -225,8 +236,8 @@
     ]);
 
     $schema->populate('Link', [
-        [ qw/id title/ ],
-        [ 1, 'aaa' ]
+        [ qw/id url title/ ],
+        [ 1, '', 'aaa' ]
     ]);
 
     $schema->populate('Bookmark', [

Added: trunk/DBIx-Class/t/lib/DBICVersionNew.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICVersionNew.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICVersionNew.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,48 @@
+package DBICVersion::Table;
+
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('TestVersion');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'INTEGER',
+        'is_auto_increment' => 1,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => ''
+        },
+      'VersionName' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 1,
+        'size' => '20'
+        },
+      );
+
+__PACKAGE__->set_primary_key('Version');
+
+package DBICVersion::Schema;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+our $VERSION = '2.0';
+
+__PACKAGE__->register_class('Table', 'DBICVersion::Table');
+__PACKAGE__->load_components('+DBIx::Class::Schema::Versioned');
+__PACKAGE__->upgrade_directory('t/var/');
+__PACKAGE__->backup_directory('t/var/backup/');
+
+#sub upgrade_directory
+#{
+#    return 't/var/';
+#}
+
+1;

Added: trunk/DBIx-Class/t/lib/DBICVersionOrig.pm
===================================================================
--- trunk/DBIx-Class/t/lib/DBICVersionOrig.pm	                        (rev 0)
+++ trunk/DBIx-Class/t/lib/DBICVersionOrig.pm	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,46 @@
+package DBICVersion::Table;
+
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('TestVersion');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'INTEGER',
+        'is_auto_increment' => 1,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => ''
+        },
+      'VersionName' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => '10'
+        },
+      );
+
+__PACKAGE__->set_primary_key('Version');
+
+package DBICVersion::Schema;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+our $VERSION = '1.0';
+
+__PACKAGE__->register_class('Table', 'DBICVersion::Table');
+__PACKAGE__->load_components('+DBIx::Class::Schema::Versioned');
+
+sub upgrade_directory
+{
+    return 't/var/';
+}
+
+1;

Modified: trunk/DBIx-Class/t/lib/sqlite.sql
===================================================================
--- trunk/DBIx-Class/t/lib/sqlite.sql	2007-06-17 19:07:27 UTC (rev 3501)
+++ trunk/DBIx-Class/t/lib/sqlite.sql	2007-06-17 19:27:08 UTC (rev 3502)
@@ -11,6 +11,7 @@
   employee_id INTEGER PRIMARY KEY NOT NULL,
   position integer NOT NULL,
   group_id integer,
+  group_id_2 integer,  
   name varchar(100)
 );
 
@@ -107,7 +108,8 @@
   trackid INTEGER PRIMARY KEY NOT NULL,
   cd integer NOT NULL,
   position integer NOT NULL,
-  title varchar(100) NOT NULL
+  title varchar(100) NOT NULL,
+  last_updated_on datetime NULL
 );
 
 --
@@ -128,6 +130,14 @@
 );
 
 --
+-- Table: file_columns
+--
+CREATE TABLE file_columns (
+  id INTEGER PRIMARY KEY NOT NULL,
+  file varchar(255)
+);
+
+--
 -- Table: tags
 --
 CREATE TABLE tags (

Added: trunk/DBIx-Class/t/resultset_class.t
===================================================================
--- trunk/DBIx-Class/t/resultset_class.t	                        (rev 0)
+++ trunk/DBIx-Class/t/resultset_class.t	2007-06-17 19:27:08 UTC (rev 3502)
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+use Class::Inspector ();
+
+unshift(@INC, './t/lib');
+use lib 't/lib';
+plan tests => 5;
+
+use DBICTest;
+
+is(DBICTest::Schema->source('Artist')->resultset_class, 'DBIx::Class::ResultSet', 'default resultset class');
+ok(!Class::Inspector->loaded('DBICNSTest::ResultSet::A'), 'custom resultset class not loaded');
+DBICTest::Schema->source('Artist')->resultset_class('DBICNSTest::ResultSet::A');
+ok(Class::Inspector->loaded('DBICNSTest::ResultSet::A'), 'custom resultset class loaded automatically');
+is(DBICTest::Schema->source('Artist')->resultset_class, 'DBICNSTest::ResultSet::A', 'custom resultset class set');
+
+my $schema = DBICTest->init_schema;
+my $resultset = $schema->resultset('Artist')->search;
+isa_ok($resultset, 'DBICNSTest::ResultSet::A', 'resultset is custom class');




More information about the Bast-commits mailing list