[DRE-commits] [SCM] ruby-bio.git branch, master, updated. upstream/1.4.1-9-g2e56981

Lucas Nussbaum lucas at lucas-nussbaum.net
Sun Sep 25 09:21:06 UTC 2011


The following commit has been merged in the master branch:
commit 7b58395725778b32b397cb7c82fe700472cde7df
Author: Lucas Nussbaum <lucas at lucas-nussbaum.net>
Date:   Sun Sep 25 10:46:35 2011 +0200

    Imported Upstream version 1.4.2

diff --git a/ChangeLog b/ChangeLog
index b4c8842..a05a8a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,957 @@
+commit 3acc1e098839cacbe85b5c23367ab14e0c4fe3ea
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 15:01:49 2011 +0900
+
+    Preparation for bioruby-1.4.2 release.
+
+ bioruby.gemspec    |    2 +-
+ lib/bio/version.rb |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit bf69125192fa01ae3495e094e7ef1b5e895954ad
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 14:42:02 2011 +0900
+
+    updated bioruby.gemspec
+
+ bioruby.gemspec |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+commit e0a3ead917812199c6a0e495f3afa6a636bbf0c5
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 14:39:54 2011 +0900
+
+    Added PLUGIN section to README.rdoc, and some changes made.
+
+ README.rdoc |   20 +++++++++++++++++---
+ 1 files changed, 17 insertions(+), 3 deletions(-)
+
+commit 1da0a1ce6eddcef8f8fc811b0a2cf8d58f880642
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 14:38:13 2011 +0900
+
+    updated doc/Tutorial.rd.html
+
+ doc/Tutorial.rd.html |   41 ++++++++++++++++++++---------------------
+ 1 files changed, 20 insertions(+), 21 deletions(-)
+
+commit a8b90367b830e58b397536be3dada10cdde97aab
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 14:36:24 2011 +0900
+
+    Removed sections contain obsolete (404 Not Found) URL in Tutorial.rd.
+
+ doc/Tutorial.rd |   12 ------------
+ 1 files changed, 0 insertions(+), 12 deletions(-)
+
+commit e17546cb90a012cd1f51674ceb4c8da5dd516bdf
+Author: Michael O'Keefe <okeefm at rpi.edu>
+Date:   Tue Aug 23 20:15:44 2011 -0400
+
+    Updated tutorial
+    
+     * Updated tutorial
+       (original commit id: 7b9108657961cf2354278e04971c32059b3ed4e2
+        and some preceding commits)
+
+ doc/Tutorial.rd |   55 ++++++++++++++++++++++++++++++++-----------------------
+ 1 files changed, 32 insertions(+), 23 deletions(-)
+
+commit de8a394129c752a0b9a5975a73c5eb582d9681d3
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 13:24:27 2011 +0900
+
+    fix typo and change order of lines
+
+ RELEASE_NOTES.rdoc |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 1cf2a11199655e4c9f5fc49c5a588b99c18ab7ca
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 13:16:11 2011 +0900
+
+    RELEASE_NOTE.rdoc modified to reflect recent changes
+
+ RELEASE_NOTES.rdoc |   14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
+
+commit b44871a5866eeb2d379f080b39b09693c9e9e3cc
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 13:15:14 2011 +0900
+
+    In BioRuby Shell, getent() fails when EMBOSS seqret does not found.
+
+ lib/bio/shell/plugin/entry.rb |   10 +++++++---
+ 1 files changed, 7 insertions(+), 3 deletions(-)
+
+commit 179e7506b008a220d5dd42ce1a6c7ce589c3fcda
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 26 12:26:52 2011 +0900
+
+    New methods Bio::NCBI::REST::EFetch.nucleotide and protein
+    
+     * New methods Bio::NCBI::REST::EFetch.nucleotide and protein,
+       to get data from "nucleotide" and "protein" database respectively.
+       Because NCBI changed not to accept "gb" format for the database
+       "sequence", the two new methods are added for convenience.
+     * In BioRuby Shell, efetch method uses the above new methods.
+
+ lib/bio/io/ncbirest.rb           |  122 +++++++++++++++++++++++++++++++++++++-
+ lib/bio/shell/plugin/ncbirest.rb |    6 ++-
+ 2 files changed, 126 insertions(+), 2 deletions(-)
+
+commit 99b31379bb41c7cad34c1e7dc00f802da37de1cd
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Aug 25 19:03:43 2011 +0900
+
+    New method Bio::Fastq#to_s
+    
+     * New method Bio::Fastq#to_s.
+       Thanks to Tomoaki NISHIYAMA who wrote a patch.
+       (https://github.com/bioruby/bioruby/pull/37)
+
+ lib/bio/db/fastq.rb            |   14 ++++++++++++++
+ test/unit/bio/db/test_fastq.rb |   14 ++++++++++++++
+ 2 files changed, 28 insertions(+), 0 deletions(-)
+
+commit 8ab772b37850c3874b55cf37d091046394cda5bd
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Aug 25 15:23:00 2011 +0900
+
+    RELEASE_NOTES.rdoc changed to reflect recent changes.
+
+ RELEASE_NOTES.rdoc |   16 ++++++++++++++++
+ 1 files changed, 16 insertions(+), 0 deletions(-)
+
+commit 8db6abdcc81db6a58bdd99e7f8d410b1a74496b1
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Aug 25 14:28:42 2011 +0900
+
+    A test connecting to DDBJ BLAST web service is enabled.
+
+ test/functional/bio/appl/test_blast.rb |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit 121ad93c0c1f018ee389972ac5e5e8cc395f00d1
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Aug 25 14:15:23 2011 +0900
+
+    Bio::DDBJ::REST::*. new classes for DDBJ REST web services.
+    
+     * Bio::DDBJ::REST::*: new classes for DDBJ REST web services (WABI).
+       Currently not all services are covered. (lib/bio/io/ddbjrest.rb)
+     * autoload of the above (lib/bio/db/genbank/ddbj.rb, lib/bio.rb)
+     * Tests for the above (but still incomplete)
+       (test/functional/bio/io/test_ddbjrest.rb)
+     * Remote BLAST using DDBJ server now uses REST interface instead
+       of SOAP, for Ruby 1.9.x support.
+       (lib/bio/appl/blast/ddbj.rb)
+
+ lib/bio.rb                              |    1 +
+ lib/bio/appl/blast/ddbj.rb              |   33 +---
+ lib/bio/db/genbank/ddbj.rb              |    3 +-
+ lib/bio/io/ddbjrest.rb                  |  344 +++++++++++++++++++++++++++++++
+ test/functional/bio/io/test_ddbjrest.rb |   47 +++++
+ 5 files changed, 399 insertions(+), 29 deletions(-)
+ create mode 100644 lib/bio/io/ddbjrest.rb
+ create mode 100644 test/functional/bio/io/test_ddbjrest.rb
+
+commit 7e8ba7c1388204daa5245d2128d01f6f40298185
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Aug 18 00:08:51 2011 +0900
+
+    In Fastq formatter, default width value changed to nil
+    
+     * In Bio::Sequence#output(:fastq) (Fastq output formatter),
+       default width value is changed from 70 to nil, which means
+       "without wrapping".  close [Feature #3191]
+       (https://redmine.open-bio.org/issues/3191)
+
+ RELEASE_NOTES.rdoc               |    8 ++++++--
+ lib/bio/db/fastq/format_fastq.rb |    4 ++--
+ test/unit/bio/db/test_fastq.rb   |   12 ++++++++++++
+ 3 files changed, 20 insertions(+), 4 deletions(-)
+
+commit 0fb65211519febff18413c589fe7af753ee2e61d
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Wed Aug 17 22:02:03 2011 +0900
+
+    Bug fix: Bio::SPTR follow-up of UniProtKB format changes
+    
+     * Bug fix: Bio::SPTR follow-up of UniProtKB format changes.
+     * Tests are added about the fix.
+     * Bug fix: Bio::SPTR#cc_web_resource should be private.
+     * Incompatible changes in Bio::SPTR#cc("WEB RESOURCE") is
+       documented in RELEASE_NOTES.rdoc.
+     * KNOWN_ISSUES.rdoc: description about incompleteness of the fix.
+     * Thanks to Nicholas Letourneau who reports the issue.
+       (https://github.com/bioruby/bioruby/pull/36)
+
+ KNOWN_ISSUES.rdoc                              |    5 +
+ RELEASE_NOTES.rdoc                             |   20 ++-
+ lib/bio/db/embl/sptr.rb                        |  214 +++++++++++++++++++++---
+ test/unit/bio/db/embl/test_sptr.rb             |   12 +-
+ test/unit/bio/db/embl/test_uniprot_new_part.rb |  208 +++++++++++++++++++++++
+ 5 files changed, 430 insertions(+), 29 deletions(-)
+ create mode 100644 test/unit/bio/db/embl/test_uniprot_new_part.rb
+
+commit 0d066ab6b8fc19f1cf6e66e07c2065775739cccd
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Sat Aug 13 00:58:51 2011 +0900
+
+    preparation for release: alpha test version 1.4.2-alpha1
+
+ bioruby.gemspec    |   23 +++++++++++++++++++++--
+ lib/bio/version.rb |    4 ++--
+ 2 files changed, 23 insertions(+), 4 deletions(-)
+
+commit 55ece17775f5d24cf62f93d54ded5dc6eed53584
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 12 21:57:25 2011 +0900
+
+    Test bug fix: use sort command in PATH
+    
+     * Test bug fix: FuncTestCommandQuery: use sort command in PATH.
+       Thanks to Tomoaki Nishiyama who reports the issue.
+       (https://github.com/bioruby/bioruby/pull/13)
+
+ test/functional/bio/test_command.rb |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 2f464aae016387cd50031f9d9664e78e220e2d01
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 12 20:37:18 2011 +0900
+
+    RELEASE_NOTES.rdoc is updated following recent changes.
+
+ RELEASE_NOTES.rdoc |   21 ++++++++++++++-------
+ 1 files changed, 14 insertions(+), 7 deletions(-)
+
+commit d1a193684afdfd4c632ef75a978d4f3680d1bdf3
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Aug 12 20:30:53 2011 +0900
+
+    README.rdoc: changed required Ruby version etc.
+    
+     * README.rdoc: now Ruby 1.8.6 or later is required.
+     * README.rdoc: removed old obsolete descriptions.
+     * README.rdoc: modified about RubyGems.
+     * KNOWN_ISSUES.rdoc: moved descriptions about older RubyGems and CVS
+       from README.rdoc.
+     * KNOWN_ISSUES.rdoc: modified about end-of-life Ruby versions.
+
+ KNOWN_ISSUES.rdoc |   40 ++++++++++++++++++++++++++++++----
+ README.rdoc       |   61 ++++++++++++++++++++--------------------------------
+ 2 files changed, 59 insertions(+), 42 deletions(-)
+
+commit b5cbdc6ab7e81aae4db9aeb708fac57ffbce5636
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Sat Jul 16 00:12:17 2011 +0900
+
+    Added topics for the release notes
+
+ RELEASE_NOTES.rdoc |   39 ++++++++++++++++++++++++++++++++++++++-
+ 1 files changed, 38 insertions(+), 1 deletions(-)
+
+commit f062b5f37a6d8ad35b5b10c942fd61e1a4d37e08
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Sat Jul 2 01:05:42 2011 +0900
+
+    Speedup of Bio::RestrictionEnzyme::Analysis.cut.
+    
+     * Speedup of Bio::RestrictionEnzyme::Analysis.cut. The new code
+       is 50 to 80 fold faster than the previous code when cutting
+       1Mbp sequence running on Ruby 1.9.2p180.
+     * Thanks to Tomoaki NISHIYAMA who wrote the first version of the
+       patch. Thanks to ray1729 (on GitHub) who reports the issue.
+       (https://github.com/bioruby/bioruby/issues/10)
+
+ lib/bio/util/restriction_enzyme.rb                 |    3 +
+ .../restriction_enzyme/range/sequence_range.rb     |   14 ++--
+ .../range/sequence_range/calculated_cuts.rb        |   75 +++++++++++++++-----
+ .../range/sequence_range/fragment.rb               |    4 +-
+ 4 files changed, 69 insertions(+), 27 deletions(-)
+
+commit 735379421d9d6b7ceb06b91dcfcca6d5ff841236
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Sat Jul 2 00:59:58 2011 +0900
+
+    New classes (for internal use only) for restriction enzyme classes
+    
+     * New classes Bio::RestrictionEnzyme::SortedNumArray and
+       Bio::RestrictionEnzyme::DenseIntArray. Both of them are for
+       Bio::RestrictionEnzyme internal use only. They will be used
+       for the speedup of restriction enzyme analysis.
+
+ lib/bio/util/restriction_enzyme/dense_int_array.rb |  195 ++++++++++++++
+ .../util/restriction_enzyme/sorted_num_array.rb    |  219 +++++++++++++++
+ .../restriction_enzyme/test_dense_int_array.rb     |  201 ++++++++++++++
+ .../restriction_enzyme/test_sorted_num_array.rb    |  281 ++++++++++++++++++++
+ 4 files changed, 896 insertions(+), 0 deletions(-)
+ create mode 100644 lib/bio/util/restriction_enzyme/dense_int_array.rb
+ create mode 100644 lib/bio/util/restriction_enzyme/sorted_num_array.rb
+ create mode 100644 test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb
+ create mode 100644 test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb
+
+commit 6cbb0c230d1a0bf3125c3b0fdb9ec3333d9564f8
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jun 30 20:47:26 2011 +0900
+
+    A sample benchmark script for Bio::RestrictionEnzyme::Analysis.cut
+
+ sample/test_restriction_enzyme_long.rb | 4403 ++++++++++++++++++++++++++++++++
+ 1 files changed, 4403 insertions(+), 0 deletions(-)
+ create mode 100644 sample/test_restriction_enzyme_long.rb
+
+commit 413442bd7424f837c73d8170ced8e01a01f87a59
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue May 24 23:26:41 2011 +0900
+
+    Added a test for Bio::FastaFormat#entry_overrun etc.
+    
+     * Added a test for Bio::FastaFormat#entry_overrun.
+     * Removed a void test class.
+
+ test/unit/bio/db/test_fasta.rb |   24 ++++++++++++------------
+ 1 files changed, 12 insertions(+), 12 deletions(-)
+
+commit b74020ff9b5c9fc8531c584898a329987008870e
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue May 24 22:21:17 2011 +0900
+
+    Bug fix: Bio::FastaFormat#query passes nil to the given factory
+    
+     * Bug fix: Bio::FastaFormat#query passes nil to the given factory
+       object. Thanks to Philipp Comans who reports the bug.
+       (https://github.com/bioruby/bioruby/issues/35)
+     * Test method for Bio::FastaFormat#query is added.
+
+ lib/bio/db/fasta.rb            |    2 +-
+ test/unit/bio/db/test_fasta.rb |   22 ++++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 1 deletions(-)
+
+commit 80e49373e0e9013442680ba33499be80c58471db
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue May 17 22:33:56 2011 +0900
+
+    Changed database name in the example.
+    
+     * Changed database name in the example.
+       Thanks to Philipp Comans who reports the issue.
+
+ lib/bio/appl/blast.rb |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit 7427d1f1355a6c190c6bf8522978e462dea64134
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu May 12 22:15:37 2011 +0900
+
+    Bug fix: changed GenomeNet remote BLAST URL.
+    
+     * Bug fix: changed GenomeNet remote BLAST host name and path.
+       Thanks to Philipp Comans who reports the bug.
+       ( https://github.com/bioruby/bioruby/issues/34 )
+
+ lib/bio/appl/blast/genomenet.rb |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+commit c1c231b0a17c06ec042534245ed903e0256a59ed
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue May 10 20:57:17 2011 +0900
+
+    updated doc/Tutorial.rd.html
+
+ doc/Tutorial.rd.html |   34 ++++++++++++++++++----------------
+ 1 files changed, 18 insertions(+), 16 deletions(-)
+
+commit 5261c926cae8dac890d7d0380e84f2eb88912417
+Author: Pjotr Prins <pjotr.public01 at thebird.nl>
+Date:   Thu May 5 12:07:54 2011 +0200
+
+    Tutorial: Fixed URL and the intro
+
+ doc/Tutorial.rd |   34 ++++++++++++++++++++--------------
+ 1 files changed, 20 insertions(+), 14 deletions(-)
+
+commit 71de394053376f4759d705c52e6f16eca3da9d62
+Author: Pjotr Prins <pjotr.public01 at thebird.nl>
+Date:   Wed Mar 9 10:26:53 2011 +0100
+
+    Tutorial: Added a commnet for rubydoctest, changed Ruby version
+    
+     * Added a comment for rubydoctest
+     * Changed example Ruby version representation
+     * This is part of commit ba5b9c2d29223860252451110a99d4ff0250395d
+       and modified to merge with the current HEAD.
+
+ doc/Tutorial.rd |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 1d27153065b8e8595a470b2201961b0a39bf8ca1
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Apr 28 23:58:57 2011 +0900
+
+    updated doc/Tutorial.rd.html
+
+ doc/Tutorial.rd.html |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit ae9beff3bc43db3724a292b10a214583d9fbc111
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Wed Apr 6 11:46:54 2011 -0400
+
+    Updated through the section on Homology searching with BLAST
+
+ doc/Tutorial.rd      |   64 ++++++++++++++++++++--------------------------
+ doc/Tutorial.rd.html |   68 ++++++++++++++++++++++----------------------------
+ 2 files changed, 58 insertions(+), 74 deletions(-)
+
+commit 971da799b16628a927abd7dd6c218994506f8fd8
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 18:29:20 2011 -0400
+
+    Updated the html file generated from the RDoc
+
+ doc/Tutorial.rd.html |  224 ++++++++++++++++++++++++++------------------------
+ 1 files changed, 117 insertions(+), 107 deletions(-)
+
+commit c6afd7eeed121926b56d300cb4170b5024f29eb0
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 18:08:17 2011 -0400
+
+    Finished updating the tutorial
+
+ doc/Tutorial.rd |   16 ++++++++--------
+ 1 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 7349ac550ec03e2c5266496297becbdb3f4e0edd
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 15:56:37 2011 -0400
+
+    Edited tutorial up through the extra stuff section
+
+ doc/Tutorial.rd |   28 ++++++++++++++--------------
+ 1 files changed, 14 insertions(+), 14 deletions(-)
+
+commit 32ba3b15ad00d02b12ef2b44636505e23caaf620
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 15:26:48 2011 -0400
+
+    Updated tutorial up through BioSQL
+
+ doc/Tutorial.rd |  172 ++++++++++++++++++-------------------------------------
+ 1 files changed, 57 insertions(+), 115 deletions(-)
+
+commit 249580edb49a13545708fdcb559104217e37f162
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 12:09:03 2011 -0400
+
+    Updated tutorial through the section on alignments
+
+ doc/Tutorial.rd |   40 +++++++++++++++++++++++++++++++++-------
+ 1 files changed, 33 insertions(+), 7 deletions(-)
+
+commit 54f7b54044bb245ec5953dc7426f1c434b41f24f
+Author: Michael O'Keefe <okeemf at rpi.edu>
+Date:   Thu Mar 24 11:51:23 2011 -0400
+
+    Updated the tutorial (mostly grammar fixes) up until GenBank
+
+ doc/Tutorial.rd |   31 +++++++++++++++----------------
+ 1 files changed, 15 insertions(+), 16 deletions(-)
+
+commit f046a52081a8af0e9afbf65fd2673c29689be769
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 8 12:58:50 2011 +0900
+
+    Added a test protein sequence data for BLAST test.
+
+ test/data/fasta/EFTU_BACSU.fasta |    8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+ create mode 100644 test/data/fasta/EFTU_BACSU.fasta
+
+commit f61a5f4bdde16fa051f43cbe3efef4570b415a6a
+Author: Anthony Underwood <email2ants at gmail.com>
+Date:   Mon Jan 31 12:44:55 2011 +0000
+
+    Bug fix: GenBank sequence output should format date as 27-JAN-2011
+    
+     * Bug fix: GenBank sequence output should format date as 27-JAN-2011
+       rather than 2011-01-27 as specified by offical GenBank specs.
+
+ lib/bio/db/genbank/format_genbank.rb |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit be144e75a059058ab000a55d7bf535597e7e2617
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Feb 3 20:28:03 2011 +0900
+
+    Added tests for remote BLAST execution via GenomeNet and DDBJ.
+    
+     * Added tests for remote BLAST execution via GenomeNet and DDBJ.
+       Currently, a test for DDBJ BLAST web API is disabled because
+       it takes relatively long time.
+     * Tests to retrieve remote BLAST database information for GenomeNet
+       and DDBJ servers are also added.
+
+ test/functional/bio/appl/blast/test_remote.rb |   93 +++++++++++++++++++++++++
+ test/functional/bio/appl/test_blast.rb        |   61 ++++++++++++++++
+ 2 files changed, 154 insertions(+), 0 deletions(-)
+ create mode 100644 test/functional/bio/appl/blast/test_remote.rb
+ create mode 100644 test/functional/bio/appl/test_blast.rb
+
+commit 67314f1f1a248954c030f7ffe048faf862bf07d2
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Feb 3 20:19:11 2011 +0900
+
+    Updated _parse_databases following the changes in the DDBJ server
+    
+     * Updated _parse_databases following the changes in the DDBJ server.
+       Changed to use (NT) or (AA) in the tail of each description.
+       Thanks to DDBJ to improve their web service API.
+
+ lib/bio/appl/blast/ddbj.rb |   29 ++++++++++++++++++++---------
+ 1 files changed, 20 insertions(+), 9 deletions(-)
+
+commit d6aad2f4cc53c1227c86b6b573644cca15c9ed82
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Wed Feb 2 00:02:32 2011 +0900
+
+    Release notes for the next release is added.
+
+ RELEASE_NOTES.rdoc |   38 ++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 38 insertions(+), 0 deletions(-)
+ create mode 100644 RELEASE_NOTES.rdoc
+
+commit b4a30cc8ac9472b9e1c2a298afc624d0229c64c9
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 1 23:33:18 2011 +0900
+
+    Bug fix: Execution failure due to the changes of DDBJ BLAST server
+
+ lib/bio/appl/blast/ddbj.rb |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+commit d30cb5975febd8b526088612c4fb9689a6cc46ba
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 1 23:01:34 2011 +0900
+
+    Support for database "mine-aa" and "mine-nt" with KEGG organism codes
+    
+     * Added support for database "mine-aa" and "mine-nt" combined with
+       KEGG organism codes. When database name starts with mine-aa or
+       mine-nt, space-separated list of KEGG organism codes can be given.
+       For example, "mine-aa eco bsu hsa".
+
+ lib/bio/appl/blast/genomenet.rb |   11 +++++++++++
+ 1 files changed, 11 insertions(+), 0 deletions(-)
+
+commit abcba798ccf57894dcd570a6578ef78db30a3e25
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 1 22:20:02 2011 +0900
+
+    RELEASE_NOTES.rdoc is renamed to doc/RELEASE_NOTES-1.4.1.rdoc
+
+ RELEASE_NOTES.rdoc           |  104 ------------------------------------------
+ doc/RELEASE_NOTES-1.4.1.rdoc |  104 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 104 insertions(+), 104 deletions(-)
+ delete mode 100644 RELEASE_NOTES.rdoc
+ create mode 100644 doc/RELEASE_NOTES-1.4.1.rdoc
+
+commit 8719cf4e06fc8a8cd0564aeb0b95372a7a0bcefb
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 1 22:07:32 2011 +0900
+
+    Bug: Options "-v" and "-b" should be used for the limit of hits.
+    
+     * Bug: Options "-v" and "-b" should be used for the limit of hits,
+       and "-V" and "-B" should not be used for the purpose.
+
+ lib/bio/appl/blast/genomenet.rb |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 974b640badae9837fe9fc173d690b27c9b045454
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Tue Feb 1 20:34:50 2011 +0900
+
+    Bug fix: Workaround for a change in the GenomeNet BLAST site.
+    
+    * Bug fix: Workaround for a change in the GenomeNet BLAST site.
+      Thanks to the anonymous reporter. The patch was originally made
+      by Toshiaki Katyama.
+
+ lib/bio/appl/blast/genomenet.rb |    7 +++----
+ 1 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 001d3e3570c77185cece4aed1be5be2ed6f94f7e
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jan 6 23:39:19 2011 +0900
+
+    Added tests to check the previous Bio::Reference#endnote fix.
+
+ test/unit/bio/test_reference.rb |   30 ++++++++++++++++++++++++++++++
+ 1 files changed, 30 insertions(+), 0 deletions(-)
+
+commit e1cd766abe24dbcc08a42103127c75ad0ab929aa
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jan 6 23:07:35 2011 +0900
+
+    Bio::Reference#pubmed_url is updated to follow recent NCBI changes.
+
+ lib/bio/reference.rb            |    5 ++---
+ test/unit/bio/test_reference.rb |    5 +++++
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit 48024313a7568a38f4291618708541ae1dac312c
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jan 6 22:56:37 2011 +0900
+
+    Bug fix: Bio::Reference#endnote fails when url is not set
+    
+     * Bug fix: Bio::Reference#endnote fails when url is not set.
+       Thanks to Warren Kibbe who reports the bug.
+       (https://github.com/bioruby/bioruby/issues#issue/15)
+
+ lib/bio/reference.rb |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit 577278a95340abfa32d3e67415d3a10bc74b82c0
+Author: Pjotr Prins <pjotr.public01 at thebird.nl>
+Date:   Fri Dec 17 12:16:31 2010 +0100
+
+    Bug fix: In Bio::MEDLINE#reference, doi field should be filled.
+    
+     * Bug fix: In Bio::MEDLINE#reference, doi field should be filled.
+       (https://github.com/bioruby/bioruby/issues#issue/29)
+
+ lib/bio/db/medline.rb            |    1 +
+ test/unit/bio/db/test_medline.rb |    1 +
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+
+commit daa20c85681576d3bfbdc8f87580a4b6227b122c
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jan 6 20:25:03 2011 +0900
+
+    Bug fix: Bio::Newick#reparse failure
+    
+     * Bug fix: Bio::Newick#reparse failure.
+       Thanks to jdudley who reports the bug.
+       (https://github.com/bioruby/bioruby/issues#issue/28)
+     * Tests are added to confirm the bug fix.
+
+ lib/bio/db/newick.rb            |    4 +++-
+ test/unit/bio/db/test_newick.rb |   12 ++++++++++++
+ 2 files changed, 15 insertions(+), 1 deletions(-)
+
+commit 16117aefdf57ac3ae16b5568f462f7b919ef005f
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Thu Jan 6 20:14:18 2011 +0900
+
+    Use setup for the preparation of adding more test methods.
+
+ test/unit/bio/db/test_newick.rb |   14 ++++++++++----
+ 1 files changed, 10 insertions(+), 4 deletions(-)
+
+commit e5dc5896a5c6249e2a6cb03d63a3c2ade36b67e7
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 21:07:13 2010 +0900
+
+    Ruby 1.9 support: suppressed warning "mismatched indentations"
+
+ test/unit/bio/db/pdb/test_pdb.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 1bce41c7ebed46ac6cf433b047fe6a4c3a538089
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 21:05:06 2010 +0900
+
+    Ruby 1.9 support: Suppressed warning "shadowing outer local variable"
+
+ lib/bio/db/pdb/residue.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 0f31727769833ccf9d6891ae192da1bc180223e0
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 21:04:07 2010 +0900
+
+    Ruby 1.9 support: Suppressed warning "shadowing outer local variable"
+
+ lib/bio/location.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 70c1135b171fcf47dd9dc1bc396d15d1c3acfa62
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 21:02:57 2010 +0900
+
+    Ruby 1.9 support: Suppressed warning "shadowing outer local variable"
+
+ lib/bio/db/pdb/pdb.rb |   14 +++++++-------
+ 1 files changed, 7 insertions(+), 7 deletions(-)
+
+commit a77e4ab78211a85aa052ca6645a2051a4f3b76d8
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 20:42:22 2010 +0900
+
+    Ruby 1.9 support: use Array#join instead of Array#to_s
+
+ lib/bio/db/pdb/pdb.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 734c2e54613e3ed5efd95e1212feab8f014d5f19
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 20:38:11 2010 +0900
+
+    Changed to use assert_instance_of
+    
+     * Changed to use assert_instance_of(klass, obj) instead of
+       assert_equal(klass, obj.class).
+
+ test/unit/bio/db/pdb/test_pdb.rb |   16 ++++++++--------
+ 1 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 490286018c8ce314da441c646ea9c5fb3f765c95
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 20:24:36 2010 +0900
+
+    Float::EPSILON was too small for the delta tolerance.
+
+ test/unit/bio/db/pdb/test_pdb.rb |   20 ++++++++++----------
+ 1 files changed, 10 insertions(+), 10 deletions(-)
+
+commit e92d225cadabe63fe23c7c32a4d1d50a371366cc
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 20:16:30 2010 +0900
+
+    Ruby 1.9 support: use assert_in_delta
+
+ test/unit/bio/db/pdb/test_pdb.rb |   24 +++++++++++++++---------
+ 1 files changed, 15 insertions(+), 9 deletions(-)
+
+commit 41452971a132ef55de3486022962fa2c333b4c85
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 19 13:19:39 2010 +0900
+
+    Fixed Object#id problem and suppressed warning messages.
+    
+     * Changed not to call nil.id (==4) invoked from chain.id.
+     * Suppressed warning message about useless use of a variable.
+     * Suppressed waring about conflict of IDs when testing
+       addResidue, addLigand and addChain methods.
+
+ test/unit/bio/db/pdb/test_pdb.rb |  119 +++++++++++++++++++-------------------
+ 1 files changed, 59 insertions(+), 60 deletions(-)
+
+commit b4af5826f77002933de9d3c2ddfcc5a7cb5629db
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Wed Nov 17 22:26:26 2010 +0900
+
+    Adjusted copyright line
+
+ test/unit/bio/db/pdb/test_pdb.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 06fd989072b2287a3accbb60684b8a029bfc0ac3
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Wed Nov 17 21:54:05 2010 +0900
+
+    A module name is changed to avoid potential name conflict.
+    
+     * A module name is changed to avoid potential name conflict.
+     * Removed a Shift_JIS character (Zenkaku space) in a comment line.
+
+ test/unit/bio/db/pdb/test_pdb.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 09007f93abe8c9c5e7561f082b55ca307a7d4a1e
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Thu Jul 15 21:06:28 2010 +0900
+
+    Added more unit tests for Bio::PDB
+    
+     * Added more unit tests for Bio::PDB.
+     * This is part of combinations of the 13 commits:
+       * 555f7b49a43e7c35c82cd48b199af96ca93d4179
+       * 2b5c87a9ada248597e0517e22191bb4c88be2a42
+       * a16e24fa35debdcacd11cf36fdf0e60fe82b3684
+       * e3607c0f7154a4156fd53ed17470aa3628cd2586
+       * 4e74c9107f09c5eb3fc7fc9ec38d9d773fe89367
+       * 605fb0a222f70eeaa1e576d31af484a9a6a2ac27
+       * 2c8b2b5496fee04b886bfcbd11fb99948816cc28
+       * 202cf2b1b57fbcac215aa135cf6343af6a49d2ef
+       * f13c070c763c9035451c3639e6e29c9a156947cd
+       * 843378e608bd1ef27a713d9be2d50f0f56915b0b
+       * a9078b8a586b66d8026af612d9a5999c6c77de33
+       * f0174a8ca3ee136271c51047fce12597d3fbb58c
+       * 6675fd930718e41ad009f469b8167f81c9b2ad52
+
+ test/unit/bio/db/pdb/test_pdb.rb | 3281 +++++++++++++++++++++++++++++++++++++-
+ 1 files changed, 3276 insertions(+), 5 deletions(-)
+
+commit 2f6a1d29b14d89ac39b408582c9865ad06560ae1
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Sat Nov 6 00:41:21 2010 +0900
+
+    Adjusted test data file path, required files and header descriptions.
+
+ test/unit/bio/db/test_litdb.rb |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+commit d3394e69c98b3be63c8287af84dc530830fb977a
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Fri Jun 18 17:11:25 2010 +0900
+
+    added unit test for Bio::LITDB with a sample file
+
+ test/data/litdb/1717226.litdb  |   13 +++++
+ test/unit/bio/db/test_litdb.rb |   95 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 108 insertions(+), 0 deletions(-)
+ create mode 100644 test/data/litdb/1717226.litdb
+ create mode 100644 test/unit/bio/db/test_litdb.rb
+
+commit cef1d2c824f138fe268d20eaa9ffd85223c85ef9
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 5 23:54:31 2010 +0900
+
+    Adjusted test data file path, required files and header descriptions.
+
+ test/unit/bio/db/test_nbrf.rb |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+commit e892e7f9b9b4daadeff44c9e479e6f51f02e383e
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Fri Jun 25 13:20:46 2010 +0900
+
+    Added unit tests for Bio::NBRF with test data.
+    
+     * Added unit tests for Bio::NBRF with test data.
+     * This is part of combinations of the two commits:
+       * 53873a82182e072e738da20381dcb2bfd8bc9e96
+         (Modified the unit test for Bio::NBRF)
+       * 4675cf85aa9c0b4de9f527f9c6bb80804fdaaaa9
+         (Modified Bio::TestNBRF and Bio::TestTRANSFAC.)
+
+ test/data/pir/CRAB_ANAPL.pir  |    6 +++
+ test/unit/bio/db/test_nbrf.rb |   82 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 88 insertions(+), 0 deletions(-)
+ create mode 100644 test/data/pir/CRAB_ANAPL.pir
+ create mode 100644 test/unit/bio/db/test_nbrf.rb
+
+commit 4922d5151138312d5a09ac60a06419c23978ba3c
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 5 23:07:13 2010 +0900
+
+    Mock class for testing is moved under the test class
+    
+     * Mock class for testing is moved under the test class, to avoid
+       potential name conflicts.
+
+ test/unit/bio/db/genbank/test_common.rb |   25 ++++++++++++-------------
+ 1 files changed, 12 insertions(+), 13 deletions(-)
+
+commit 8f630700bc6dd8c183d08291c66c665394873586
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 5 23:01:32 2010 +0900
+
+    Adjusted header descriptions.
+
+ test/unit/bio/db/genbank/test_common.rb |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit ab3d6384ca721fb6004efb5988461eecefad4d6b
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 5 22:58:21 2010 +0900
+
+    Adjusted test data file path and header descriptions.
+
+ test/unit/bio/db/genbank/test_genpept.rb |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 1d24aecfac9dbc190cdc3eef0956451cc88cfe4f
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Nov 5 22:54:19 2010 +0900
+
+    Adjusted test data file path, required files and header descriptions.
+
+ test/unit/bio/db/genbank/test_genbank.rb |   12 ++++++++----
+ 1 files changed, 8 insertions(+), 4 deletions(-)
+
+commit 09275d8661f3d49a7e40be59a086ba33659b2448
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Thu Jun 17 22:08:15 2010 +0900
+
+    Added unit tests for Bio::GenPept newly.
+    
+     * Added unit tests for Bio::GenPept newly.
+     * This is part of the commit 8e46ff42b627791f259033d5a20c1610e32cfa62
+       (Added unit tests for NBRF and GenPept newly.)
+
+ test/data/genbank/CAA35997.gp            |   48 ++++++++++++++++++
+ test/unit/bio/db/genbank/test_genpept.rb |   81 ++++++++++++++++++++++++++++++
+ 2 files changed, 129 insertions(+), 0 deletions(-)
+ create mode 100644 test/data/genbank/CAA35997.gp
+ create mode 100644 test/unit/bio/db/genbank/test_genpept.rb
+
+commit 2cde22cb358a2b7ec8197866fe35a0b46ebf9b00
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Thu Jun 24 18:52:37 2010 +0900
+
+    Added unit tests for Bio::NCBIDB::Common
+    
+     * Added unit tests for Bio::NCBIDB::Common.
+     * This is part of combination of the 4 commits:
+       * 7da8d557e8ee53da9d93c6fadfd0d8f493977c81
+         (added test/unit/bio/db/genbank/test_common.rb newly)
+       * 2b5c87a9ada248597e0517e22191bb4c88be2a42
+         (Modified a few lines of Bio::NCBIDB::TestCommon,
+          Bio::TestPDBRecord and Bio::TestPDB)
+       * 10c043535dd7bf5b9682b4060183f494742c53df
+         (Modified unit test for Bio::GenBank::Common)
+       * 0af08fb988e08948a54e33273861b5460b7f6b2d
+         (Modified the unit test for Bio::GenBank)
+
+ test/unit/bio/db/genbank/test_common.rb |  275 +++++++++++++++++++++++++++++++
+ 1 files changed, 275 insertions(+), 0 deletions(-)
+ create mode 100644 test/unit/bio/db/genbank/test_common.rb
+
+commit f775d9b7f7deda2e30d4196d4cf507b59936a654
+Author: Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+Date:   Sat Jun 26 17:54:32 2010 +0900
+
+    Added unit tests for Bio::GenBank with test data.
+    
+     * Added unit tests for Bio::GenBank with test data.
+     * This is part of combination of the two commits:
+       * 555f7b49a43e7c35c82cd48b199af96ca93d4179
+         (added test_genbank.rb and test_go.rb with the test files.
+         modified test_pdb.rb)
+       * a46f895bf378ce08143ff031ddda302f970c270a
+         (Modified Bio::GenBank and Bio::Nexus)
+
+ test/data/genbank/SCU49845.gb            |  167 +++++++++++++
+ test/unit/bio/db/genbank/test_genbank.rb |  397 ++++++++++++++++++++++++++++++
+ 2 files changed, 564 insertions(+), 0 deletions(-)
+ create mode 100644 test/data/genbank/SCU49845.gb
+ create mode 100644 test/unit/bio/db/genbank/test_genbank.rb
+
+commit 33621c1f4c16173efd05861759f577b2c4733a53
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Oct 29 16:45:22 2010 +0900
+
+    Bio::BIORUBY_EXTRA_VERSION is changed to ".5000".
+
+ bioruby.gemspec    |    2 +-
+ lib/bio/version.rb |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit cfb2c744f3762689077f5bf2092f715d25e066ed
+Author: Naohisa Goto <ng at bioruby.org>
+Date:   Fri Oct 22 13:02:03 2010 +0900
+
+    BioRuby 1.4.1 is released.
+
+ ChangeLog |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 55 insertions(+), 0 deletions(-)
+
 commit 92cfda14c08b270ed1beca33153125141f88510e
 Author: Naohisa Goto <ng at bioruby.org>
 Date:   Fri Oct 22 13:00:09 2010 +0900
diff --git a/KNOWN_ISSUES.rdoc b/KNOWN_ISSUES.rdoc
index fdbd311..f85c630 100644
--- a/KNOWN_ISSUES.rdoc
+++ b/KNOWN_ISSUES.rdoc
@@ -23,19 +23,24 @@ Currently, BioRuby do not care string encodings. In some cases,
 Encoding::CompatibilityError or "ArgumentError: invalid byte sequence in
 (encoding name)" may be raised.
 
-=== Ruby 1.9.0
+=== End-of-life Ruby versions
+
+==== Ruby 1.9.0
 
 (WONT_FIX) Ruby 1.9.0 is NOT supported because it isn't a stable release.
 Use Ruby 1.9.1 or later.
 
-=== Ruby 1.8.2 or earlier
+==== Ruby 1.8.5 or earlier
+
+(WONT_FIX) Problems observed only with Ruby 1.8.5 or earlier will not be
+fixed. Note that Ruby 1.8.5 or earlier is no longer supported, as described
+in README.rdoc.
+
+==== Ruby 1.8.2 or earlier
 
 (WONT_FIX) In some cases, temporary files and directories may not be
 removed because of the lack of FileUtils.remove_entry_secure.
 
-(WONT_FIX) We will soon end support for Ruby 1.8.2. Note that Ruby
-1.8.1 or earlier is no longer supported, as described in README.rdoc.
-
 === Issues about SOAP/WSDL
 
 SOAP4R (SOAP and WSDL implementation) is no longer bundled with Ruby 1.9.
@@ -52,6 +57,15 @@ fixed and new patch is available on the above URL. Note that some Linux
 distributions would have incorporated the patch in their manners, and may
 have the same problem.
 
+=== RubyGems 0.8.11 or earlier
+
+(WONT_FIX) With very old version of RubyGems, use 'require_gem' which was
+deprecated in RubyGems 0.9.0 and removed in RubyGems 1.0.1.
+
+  #!/usr/bin/env ruby
+  require 'rubygems'
+  require_gem 'bio'
+
 == 2. OS and/or architecture-dependent issues
 
 === Microsoft Windows
@@ -116,6 +130,11 @@ correctly, even running on Ruby 1.8.x. Instead, use Bio::NCBI::REST.
 Bio::KEGG::Taxonomy fails to parse current KEGG taxonomy data file probably
 because of the growth of the data size.
 
+=== Bio::SPTR
+
+Bio::SPTR should be updated to follow UniProtKB format changes described
+in http://www.uniprot.org/docs/sp_news.htm .
+
 == 4. Compatibility issues with other libraries/extensions
 
 === ActiveRecord
@@ -128,3 +147,19 @@ know which version is suitable.
 BioRuby Shell on Web uses Ruby on Rails, but the author of the document does
 not know which version is suitable.
 
+== 5. Historical descriptions
+
+=== CVS
+
+For historical purposes: the anonymous CVS was provided at 
+
+* http://cvs.bioruby.org/
+
+and could be obtained by the following procedure.
+
+  % cvs -d :pserver:cvs at code.open-bio.org:/home/repository/bioruby login
+  CVS password: cvs (login with a password 'cvs' for the first time)
+  % cvs -d :pserver:cvs at code.open-bio.org:/home/repository/bioruby co bioruby
+
+These may be closed without any prior notice.
+
diff --git a/README.rdoc b/README.rdoc
index 5fc7a6f..6c5e674 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -9,7 +9,7 @@ License::   The Ruby License
 
 = BioRuby
 
-Copyright (C) 2001-2010 Toshiaki Katayama <k at bioruby.org>
+Copyright (C) 2001-2011 Toshiaki Katayama <k at bioruby.org>
 
 BioRuby is an open source Ruby library for developing bioinformatics
 software.  Object oriented scripting language Ruby has many features
@@ -42,6 +42,7 @@ services including KEGG API can be easily utilized by BioRuby.
 README.rdoc:: This file. General information and installation procedure.
 RELEASE_NOTES.rdoc:: News and important changes in this release.
 KNOWN_ISSUES.rdoc:: Known issues and bugs in BioRuby.
+doc/RELEASE_NOTES-1.4.1.rdoc:: News and incompatible changes from 1.4.0 to 1.4.1.
 doc/RELEASE_NOTES-1.4.0.rdoc:: News and incompatible changes from 1.3.1 to 1.4.0.
 doc/Changes-1.3.rdoc:: News and incompatible changes from 1.2.1 to 1.3.0.
 doc/Changes-0.7.rd:: News and incompatible changes from 0.6.4 to 1.2.1.
@@ -55,6 +56,7 @@ doc/KEGG_API.rd:: Documents about KEGG API, including usage of Bio::KEGG::API.
 ==== BioRuby development
 
 ChangeLog:: History of changes.
+doc/ChangeLog-before-1.3.1:: changes before 1.3.1.
 README_DEV.rdoc:: Describes ways to contribute to the BioRuby project, including coding styles and documentation guidelines.
 
 ==== Documents written in Japanese
@@ -72,6 +74,9 @@ mailing lists, Wiki documentation etc. in the top page.
 
 * http://bioruby.org/
 
+Mirror site is available, hosted on Open Bioinformatics Foundation (OBF).
+
+* http://bioruby.open-bio.org/
 
 == WHERE TO OBTAIN
 
@@ -83,7 +88,7 @@ The stable release is freely available from the BioRuby website.
 
 === RubyGems
 
-RubyGems[URL:http://rubyforge.org/projects/rubygems/] version of
+{RubyGems (packaging system for Ruby)}[http://rubygems.org/] version of
 the BioRuby package is also available for easy installation.
 
 * http://rubyforge.org/projects/bioruby/
@@ -98,27 +103,15 @@ and can be obtained by the following procedure:
 
   % git clone git://github.com/bioruby/bioruby.git
 
-==== CVS
-
-CVS is now deprecated as source control has moved to github. Please use git 
-instead of CVS. For historical purposes: the anonymous CVS was provided at 
-
-* http://cvs.bioruby.org/
-
-and could be obtained by the following procedure.
-
-  % cvs -d :pserver:cvs at code.open-bio.org:/home/repository/bioruby login
-  CVS password: cvs (login with a password 'cvs' for the first time)
-  % cvs -d :pserver:cvs at code.open-bio.org:/home/repository/bioruby co bioruby
-
 
 == REQUIREMENTS
 
-* Ruby 1.8.2 or later (except Ruby 1.9.0) -- http://www.ruby-lang.org/
-  * Ruby 1.8.7-p174 or later, or Ruby 1.8.6-p383 or later is recommended.
+* Ruby 1.8.6 or later (except Ruby 1.9.0) -- http://www.ruby-lang.org/
+  * Ruby 1.8.7-p352 or later is recommended.
   * Not yet fully ready with Ruby 1.9, although many components can now work
     in Ruby 1.9.1 and Ruby 1.9.2.
 
+
 == OPTIONAL REQUIREMENTS
 
 Some optional libraries can be utilized to extend BioRuby's functionality.
@@ -141,11 +134,6 @@ Accessing BioSQL database created by other Open Bio* libraries:
   {RubyForge:MySQL/Ruby}[http://rubyforge.org/projects/mysql-ruby/],
   {RubyForge:postgres-pr}[http://rubyforge.org/projects/postgres-pr], or
   {RubyForge:ActiveRecord Oracle enhanced adapter}[http://rubyforge.org/projects/oracle-enhanced/].
-* For BioRuby 1.2.1 or older version,
-  {RubyForge:Ruby/DBI}[http://rubyforge.org/projects/ruby-dbi] and
-  at least one driver from MySQL/Ruby, postgres-pr, or
-  {RubyForge:ruby-oci8}[http://ruby-oci8.rubyforge.org/]
-  (note that ruby-oci8 can only work with ruby-dbi 0.2.2).
 
 For parsing PhyloXML format files:
 
@@ -155,6 +143,20 @@ For parsing PhyloXML format files:
 
 == INSTALL
 
+=== INSTALL by using RubyGems (recommended)
+
+If you are using RubyGems, just type
+
+  % gems install bio
+
+Alternatively, manually download bio-X.X.X.gem from 
+http://rubyforge.org/projects/bioruby/ and install it by using gems command.
+
+RubyGems is bundled with Ruby 1.9.1 or later. For Ruby 1.8.7 or earlier,
+download and install RubyGems from http://rubygems.org/ .
+
+=== INSTALL without RubyGems
+
 In the bioruby source directory (such as bioruby-x.x.x/), run setup.rb
 as follows:
 
@@ -188,12 +190,6 @@ and run
 
 for more details.
 
-=== RubyGems
-
-If you are using RubyGems, just type
-
-  % gems install bio
-
 
 == SETUP
 
@@ -227,21 +223,26 @@ You can also read other documentation in the 'doc' directory.
 
   bioruby-x.x.x/doc/
 
-=== RubyGems
+=== RubyGems on Ruby 1.8.x
 
-With RubyGems, you need to load 'rubygems' library before using 'bio'.
+With RubyGems on Ruby 1.8.x, you may need to load 'rubygems' library before
+using 'bio'. This may not be needed, depending on settings of Ruby.
 
   #!/usr/bin/env ruby
   require 'rubygems'
   require 'bio'
 
-With old version of RubyGems, use 'require_gem' which was deprecated in
-RubyGems 0.9.0 and removed in RubyGems 1.0.1.
 
-  #!/usr/bin/env ruby
-  require 'rubygems'
-  require_gem 'bio'
+== PLUGIN (Biogem)
+
+Many plugins (called Biogem) are now available. See http://biogems.info/
+for list of plugins and related software utilizing BioRuby.
+
+* http://biogems.info/
+
+To develop your own plugin, see "Plugins" pages of BioRuby Wiki.
 
+* http://bioruby.open-bio.org/wiki/Plugins
 
 == LICENSE
 
diff --git a/RELEASE_NOTES.rdoc b/RELEASE_NOTES.rdoc
index a90a62f..7db9643 100644
--- a/RELEASE_NOTES.rdoc
+++ b/RELEASE_NOTES.rdoc
@@ -1,104 +1,132 @@
-= BioRuby 1.4.1 RELEASE NOTES
+= BioRuby 1.4.2 RELEASE NOTES
 
-A lot of changes have been made to the BioRuby 1.4.1 after the version 1.4.0
+A lot of changes have been made to the BioRuby 1.4.2 after the version 1.4.1
 is released. This document describes important and/or incompatible changes
-since the BioRuby 1.4.0 release.
+since the BioRuby 1.4.1 release.
 
 For known problems, see KNOWN_ISSUES.rdoc.
 
 == New features
 
-=== PAML Codeml support is significantly improved
+=== Speed-up of Bio::RestrictionEnzyme::Analysis.cut
 
-PAML Codeml result parser is completely rewritten and is significantly
-improved. The code is developed by Pjotr Prins.
+The running speed of Bio::RestrictionEnzyme::Analysis.cut is significantly
+increased. The new code is 50 to 80 fold faster than the previous code
+when cutting 1Mbp sequence running on Ruby 1.9.2p180. The code is written
+by Tomoaki NISHIYAMA and Naohisa Goto.
 
-=== KEGG PATHWAY and KEGG MODULE parser
+=== New classes Bio::DDBJ::REST, REST interface for DDBJ web service
 
-Parsers for KEGG PATHWAY and KEGG MODULE data are added. The code is developed
-by Kozo Nishida and Toshiaki Katayama.
+For DDBJ Web API for Biology (WABI) web service, in additon to SOAP, REST
+(REpresentational State Transfer) interface is added as Bio::DDBJ::REST.
+Currently, only selected APIs are implemented.
 
-=== Bio::KEGG improvements
+=== Bio::Blast with remote DDBJ server uses REST instead of SOAP
 
-Following new methods are added.
+Bio::Blast with remote DDBJ server uses REST instead of SOAP, because
+Soap4r (SOAP library for Ruby) does not work well with Ruby 1.9.
+We can now use remote DDBJ BLAST server with Ruby 1.9.
 
-* Bio::KEGG::GENES#keggclass, keggclasses, names_as_array, names,
-  motifs_as_strings, motifs_as_hash, motifs
-* Bio::KEGG::GENOME#original_databases
+=== Tutorial is updated
 
-=== Test codes are added and improved.
+The Tutorial.rd is updated by Pjotr Prins and Michael O'Keefe.
 
-Test codes are added and improved. Tney are developed by Kazuhiro Hayashi,
-Kozo Nishida, John Prince, and Naohisa Goto.
+=== Many unit tests are added
 
-=== Other new methods
+Added many unit tests for Bio::GenBank, Bio::GenPept, Bio::NBRF, Bio::PDB
+and so on. Most of them are developed by Kazuhiro Hayashi during the
+Google Summer of Code 2010.
 
-* Bio::Fastq#mask
-* Bio::Sequence#output_fasta
-* Bio::ClustalW::Report#get_sequence
-* Bio::Reference#==
-* Bio::Location#==
-* Bio::Locations#==
-* Bio::FastaNumericFormat#to_biosequence
+=== Other new features
 
-== Bug fixes
+* New method Bio::Fastq#to_s for convenience. Note that the use of the method
+  may cause loss of performance. To get each input sequence entry as-is,
+  consider using Bio::FlatFile#entry_raw. To output fastq format data,
+  consider using Bio::Sequence#output(:fastq).
+* New methods Bio::NCBI::REST::EFetch.nucleotide and protein,
+  to get data from "nucleotide" and "protein" database respectively.
+  Because NCBI changed not to accept "gb" format for the database
+  "sequence", the two new methods are added for convenience.
+* In BioRuby Shell, efetch method uses the above new methods.
+* In GenomeNet remote BLAST execution, database "mine-aa" and "mine-nt"
+  with KEGG organism codes are now supported.
+* Support for Ruby 1.9.2 / 1.9.3 is improved.
 
-=== Bio::Tree
+== Bug fixes
 
-Following methods did not work correctly.
+=== Bio::Blast
 
-* Bio::Tree#collect_edge!
-* Bio::Tree#remove_edge_if
+* Failure of remote BLAST execution is fixed, due to the changes in GenomeNet
+  and DDBJ.
+* When executing remote BLAST with "genomenet" server, options "-b" and "-v"
+  are now correctly used to limit the number of hits to be reported.
 
-=== Bio::KEGG::GENES and Bio::KEGG::GENOME
+=== Bio::SPTR (Bio::UniProt)
 
-* Fixed bugs in Bio::KEGG::GENES#pathway.
-* Fixed parser errors due to the format changes of KEGG GENES and KEGG GENOME.
+* Due to the UniProtKB format changes, ID, DE, and WEB RESOURCE of CC lines
+  were not correctly parsed. See also below about incompatible change of
+  the fix.
 
 === Other bug fixes
 
-* In Bio::Command, changed not to call fork(2) on platforms that do not
-  support it.
-* Bio::MEDLINE#initialize should handle continuation of lines.
-* Typo and a missing field in Bio::GO::GeneAssociation#to_str.
-* Bug fix of Bio::FastaNumericFormat#to_biosequence.
-* Fixed UniProt GN parsing issue in Bio::SPTR.
+* Bio::Reference#pubmed_url is updated to follow recent NCBI changes.
+* Fixed: Bio::Newick#reparse failure.
+* Fixed: In Bio::MEDLINE#reference, doi field should be filled.
+* Fixed: Bio::Reference#endnote fails when url is not set.
+* Fixed: Bio::FastaFormat#query passes nil to the given factory object.
+* Fixed: In BioRuby Shell, efetch() with no additional arguments fails
+  because of the NCBI site changes.
+* Fixed: In BioRuby Shell, getent() fails when EMBOSS seqret is not found.
+* Fixed: In BioRuby Shell, demo() fails due to the above two issues.
 
 == Incompatible changes
 
-=== Bio::PAML::Codeml::Report
+=== Bio::Sequence#output(:fastq)
+
+In Fastq output formatter, default width value is changed from 70 to nil.
+The nil means "without wrapping". The new default behavior without wrapping
+is generally good with many recent applications that read fastq.
+
+=== Bio::SPTR CC line topic "WEB RESOURCE"
 
-The code is completely rewritten. See the RDoc for details.
+In the return value of Bio::SPTR#cc('WEB RESOURCE'), "NAME" and "NOTE"
+are now renamed to "Name" and "Note", respectively. The change is due to
+the UniProt format change since UniProtKB release 12.2 of 11-Sep-2007.
+(See http://www.uniprot.org/docs/sp_news.htm#rel12.2 for details.)
+Note that "Name" and "Note" are used even when parsing older format.
+The change would also affect Marshal.dump (and YAML.dump) data.
 
-=== Bio::KEGG::ORTHOLOGY
+=== Bio::Blast with the remote GenomeNet server
 
-Bio::KEGG::ORTHOLOGY#pathways is changed to return a hash. The old pathway
-method is renamed to pathways_in_keggclass for compatibility.
+When executing remote BLAST with "genomenet" server, options "-b" and "-v"
+are now correctly used to limit the number of hits to be reported.
+In 1.4.1 and before, "-B" and "-V" were mistakenly used for the purpose.
 
-=== Bio::AAindex2
+=== Bio::Blast with the remote DDBJ server
 
-Bio::AAindex2 now copies each symmetric element for lower triangular matrix
-to the upper right part, because the Matrix class in Ruby 1.9.2 no longer
-accepts any dimension mismatches. We think the previous behavior is a bug.
+Bio::Blast with remote DDBJ server uses REST instead of SOAP.
 
-=== Bio::MEDLINE
+=== Bio::RestrictionEnzyme internal data structure change
 
-Bio::MEDLINE#reference no longer puts empty values in the returned
-Bio::Reference object. We think the previous behavior is a bug.
-We also think the effect is very small.
+Due to the speedup, internal data structure of the following classes
+are changed: Bio::RestrictionEnzyme::Range::SequenceRange,
+Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts,
+Bio::RestrictionEnzyme::Range::SequenceRange::Fragment.
+This indicates that Marshal.dump (and YAML.dump) data generated by older
+versions cannot be loaded by the new version, and vice versa, although
+public APIs of the classes keep compatibility.
 
 == Known issues
 
 The following issues are added or updated. See KNOWN_ISSUES.rdoc for other
 already known issues.
 
-=== String escaping of command-line arguments in Ruby 1.9.X on Windows
+* Bio::SPTR should be updated to follow UniProtKB format changes.
+* Problems observed only with Ruby 1.8.5 or earlier will not be fixed.
+* Descriptions about very old RubyGems 0.8.11 or earlier and about CVS
+  repository are moved from README.rdoc.
 
-After BioRuby 1.4.1, in Ruby 1.9.X running on Windows, escaping of
-command-line arguments are processed by the Ruby interpreter. Before BioRuby
-1.4.0, the escaping is executed in Bio::Command#escape_shell_windows, and
-the behavior is different from the Ruby interpreter's one.
+== Other important news
 
-Curreltly, due to the change, test/functional/bio/test_command.rb may fail
-on Windows with Ruby 1.9.X.
+* Required ruby version is now Ruby 1.8.6 or later (except 1.9.0).
 
diff --git a/bioruby.gemspec b/bioruby.gemspec
index 0a18cca..70c5894 100644
--- a/bioruby.gemspec
+++ b/bioruby.gemspec
@@ -3,7 +3,7 @@
 # 
 Gem::Specification.new do |s|
   s.name = 'bio'
-  s.version = "1.4.1"
+  s.version = "1.4.2"
 
   s.author = "BioRuby project"
   s.email = "staff at bioruby.org"
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
     "doc/KEGG_API.rd",
     "doc/KEGG_API.rd.ja",
     "doc/RELEASE_NOTES-1.4.0.rdoc",
+    "doc/RELEASE_NOTES-1.4.1.rdoc",
     "doc/Tutorial.rd",
     "doc/Tutorial.rd.html",
     "doc/Tutorial.rd.ja",
@@ -186,6 +187,7 @@ Gem::Specification.new do |s|
     "lib/bio/io/biosql/config/database.yml",
     "lib/bio/io/das.rb",
     "lib/bio/io/dbget.rb",
+    "lib/bio/io/ddbjrest.rb",
     "lib/bio/io/ddbjxml.rb",
     "lib/bio/io/ebisoap.rb",
     "lib/bio/io/ensembl.rb",
@@ -279,6 +281,7 @@ Gem::Specification.new do |s|
     "lib/bio/util/restriction_enzyme/analysis.rb",
     "lib/bio/util/restriction_enzyme/analysis_basic.rb",
     "lib/bio/util/restriction_enzyme/cut_symbol.rb",
+    "lib/bio/util/restriction_enzyme/dense_int_array.rb",
     "lib/bio/util/restriction_enzyme/double_stranded.rb",
     "lib/bio/util/restriction_enzyme/double_stranded/aligned_strands.rb",
     "lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair.rb",
@@ -297,6 +300,7 @@ Gem::Specification.new do |s|
     "lib/bio/util/restriction_enzyme/single_strand.rb",
     "lib/bio/util/restriction_enzyme/single_strand/cut_locations_in_enzyme_notation.rb",
     "lib/bio/util/restriction_enzyme/single_strand_complement.rb",
+    "lib/bio/util/restriction_enzyme/sorted_num_array.rb",
     "lib/bio/util/restriction_enzyme/string_formatting.rb",
     "lib/bio/util/sirna.rb",
     "lib/bio/version.rb",
@@ -363,6 +367,7 @@ Gem::Specification.new do |s|
     "sample/ssearch2tab.rb",
     "sample/tdiary.rb",
     "sample/test_phyloxml_big.rb",
+    "sample/test_restriction_enzyme_long.rb",
     "sample/tfastx2tab.rb",
     "sample/vs-genes.rb",
     "setup.rb",
@@ -402,6 +407,7 @@ Gem::Specification.new do |s|
     "test/data/command/echoarg2.bat",
     "test/data/embl/AB090716.embl",
     "test/data/embl/AB090716.embl.rel89",
+    "test/data/fasta/EFTU_BACSU.fasta",
     "test/data/fasta/example1.txt",
     "test/data/fasta/example2.txt",
     "test/data/fastq/README.txt",
@@ -456,12 +462,15 @@ Gem::Specification.new do |s|
     "test/data/fastq/wrapping_as_solexa.fastq",
     "test/data/fastq/wrapping_original_sanger.fastq",
     "test/data/gcg/pileup-aa.msf",
+    "test/data/genbank/CAA35997.gp",
+    "test/data/genbank/SCU49845.gb",
     "test/data/genscan/sample.report",
     "test/data/go/selected_component.ontology",
     "test/data/go/selected_gene_association.sgd",
     "test/data/go/selected_wikipedia2go",
     "test/data/iprscan/merged.raw",
     "test/data/iprscan/merged.txt",
+    "test/data/litdb/1717226.litdb",
     "test/data/medline/20146148_modified.medline",
     "test/data/meme/db",
     "test/data/meme/mast",
@@ -481,6 +490,7 @@ Gem::Specification.new do |s|
     "test/data/phyloxml/made_up.xml",
     "test/data/phyloxml/ncbi_taxonomy_mollusca_short.xml",
     "test/data/phyloxml/phyloxml_examples.xml",
+    "test/data/pir/CRAB_ANAPL.pir",
     "test/data/prosite/prosite.dat",
     "test/data/refseq/nm_126355.entret",
     "test/data/rpsblast/misc.rpsblast",
@@ -493,7 +503,10 @@ Gem::Specification.new do |s|
     "test/data/soft/GDS100_partial.soft",
     "test/data/soft/GSE3457_family_partial.soft",
     "test/data/uniprot/p53_human.uniprot",
+    "test/functional/bio/appl/blast/test_remote.rb",
+    "test/functional/bio/appl/test_blast.rb",
     "test/functional/bio/appl/test_pts1.rb",
+    "test/functional/bio/io/test_ddbjrest.rb",
     "test/functional/bio/io/test_ensembl.rb",
     "test/functional/bio/io/test_pubmed.rb",
     "test/functional/bio/io/test_soapwsdl.rb",
@@ -536,9 +549,13 @@ Gem::Specification.new do |s|
     "test/unit/bio/db/embl/test_embl_to_bioseq.rb",
     "test/unit/bio/db/embl/test_sptr.rb",
     "test/unit/bio/db/embl/test_uniprot.rb",
+    "test/unit/bio/db/embl/test_uniprot_new_part.rb",
     "test/unit/bio/db/fasta/test_defline.rb",
     "test/unit/bio/db/fasta/test_defline_misc.rb",
     "test/unit/bio/db/fasta/test_format_qual.rb",
+    "test/unit/bio/db/genbank/test_common.rb",
+    "test/unit/bio/db/genbank/test_genbank.rb",
+    "test/unit/bio/db/genbank/test_genpept.rb",
     "test/unit/bio/db/kegg/test_compound.rb",
     "test/unit/bio/db/kegg/test_drug.rb",
     "test/unit/bio/db/kegg/test_enzyme.rb",
@@ -558,7 +575,9 @@ Gem::Specification.new do |s|
     "test/unit/bio/db/test_gff.rb",
     "test/unit/bio/db/test_go.rb",
     "test/unit/bio/db/test_lasergene.rb",
+    "test/unit/bio/db/test_litdb.rb",
     "test/unit/bio/db/test_medline.rb",
+    "test/unit/bio/db/test_nbrf.rb",
     "test/unit/bio/db/test_newick.rb",
     "test/unit/bio/db/test_nexus.rb",
     "test/unit/bio/db/test_phyloxml.rb",
@@ -606,9 +625,11 @@ Gem::Specification.new do |s|
     "test/unit/bio/util/restriction_enzyme/single_strand/test_cut_locations_in_enzyme_notation.rb",
     "test/unit/bio/util/restriction_enzyme/test_analysis.rb",
     "test/unit/bio/util/restriction_enzyme/test_cut_symbol.rb",
+    "test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb",
     "test/unit/bio/util/restriction_enzyme/test_double_stranded.rb",
     "test/unit/bio/util/restriction_enzyme/test_single_strand.rb",
     "test/unit/bio/util/restriction_enzyme/test_single_strand_complement.rb",
+    "test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb",
     "test/unit/bio/util/restriction_enzyme/test_string_formatting.rb",
     "test/unit/bio/util/test_color_scheme.rb",
     "test/unit/bio/util/test_contingency_table.rb",
@@ -624,7 +645,8 @@ Gem::Specification.new do |s|
     "README_DEV.rdoc",
     "RELEASE_NOTES.rdoc",
     "doc/Changes-1.3.rdoc",
-    "doc/RELEASE_NOTES-1.4.0.rdoc"
+    "doc/RELEASE_NOTES-1.4.0.rdoc",
+    "doc/RELEASE_NOTES-1.4.1.rdoc"
   ]
   s.rdoc_options << '--main' << 'README.rdoc'
   s.rdoc_options << '--title' << 'BioRuby API documentation'
diff --git a/RELEASE_NOTES.rdoc b/doc/RELEASE_NOTES-1.4.1.rdoc
similarity index 100%
copy from RELEASE_NOTES.rdoc
copy to doc/RELEASE_NOTES-1.4.1.rdoc
diff --git a/doc/Tutorial.rd b/doc/Tutorial.rd
index 5725f3f..9748f1a 100644
--- a/doc/Tutorial.rd
+++ b/doc/Tutorial.rd
@@ -30,7 +30,7 @@
 #
 #
 
-bioruby> $: << '../lib'
+bioruby> $: << '../lib'  # make sure rubydoctest finds bioruby/lib
 
 =begin
 #doctest Testing bioruby
@@ -38,19 +38,19 @@ bioruby> $: << '../lib'
 = BioRuby Tutorial
 
 * Copyright (C) 2001-2003 KATAYAMA Toshiaki <k .at. bioruby.org>
-* Copyright (C) 2005-2010 Pjotr Prins, Naohisa Goto and others
+* Copyright (C) 2005-2011 Pjotr Prins, Naohisa Goto and others
 
-This document was last modified: 2010/01/08
-Current editor: Pjotr Prins <p .at. bioruby.org>
+This document was last modified: 2011/03/24
+Current editor: Michael O'Keefe <okeefm (at) rpi (dot) edu>
 
-The latest version resides in the GIT source code repository:  ./doc/((<Tutorial.rd|URL:http://github.com/pjotrp/bioruby/raw/documentation/doc/Tutorial.rd>)).
+The latest version resides in the GIT source code repository:  ./doc/((<Tutorial.rd|URL:https://github.com/bioruby/bioruby/blob/master/doc/Tutorial.rd>)).
 
 == Introduction
 
 This is a tutorial for using Bioruby. A basic knowledge of Ruby is required.
-If you want to know more about the programming langauge Ruby we recommend the
+If you want to know more about the programming language, we recommend the
 latest Ruby book ((<Programming Ruby|URL:http://www.pragprog.com/titles/ruby>))
-by Dave Thomas and Andy Hunt - the first edition is online
+by Dave Thomas and Andy Hunt - the first edition can be read online
 ((<here|URL:http://www.ruby-doc.org/docs/ProgrammingRuby/>)).
 
 For BioRuby you need to install Ruby and the BioRuby package on your computer
@@ -60,7 +60,7 @@ version it has with the
 
   % ruby -v
 
-command. Showing something like:
+command. You should see something like:
 
   ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
 
@@ -70,7 +70,7 @@ manager. For more information see the
 
 With Ruby download and install Bioruby using the links on the
 ((<Bioruby|URL:http://bioruby.org/>)) website. The recommended installation is via 
-Ruby gems:
+RubyGems:
 
   gem install bio
 
@@ -83,10 +83,13 @@ documentation can be viewed online at
 
 == Trying Bioruby
 
-Bioruby comes with its own shell. After unpacking the sources run the
-following command
+Bioruby comes with its own shell. After unpacking the sources run one of the following commands:
 
-  ./bin/bioruby  or
+  bioruby
+
+or, from the source tree
+
+  cd bioruby
   ruby -I lib bin/bioruby
 
 and you should see a prompt
@@ -110,11 +113,11 @@ question to the mailing list. BioRuby developers usually try to help.
 
 The Bio::Sequence class allows the usual sequence transformations and
 translations.  In the example below the DNA sequence "atgcatgcaaaa" is
-converted into the complemental strand, spliced into a subsequence,
-next the nucleic acid composition is calculated and the sequence is
+converted into the complemental strand and spliced into a subsequence; 
+next, the nucleic acid composition is calculated and the sequence is
 translated into the amino acid sequence, the molecular weight
-calculated, and so on. When translating into amino acid sequences the
-frame can be specified and optionally the condon table selected (as
+calculated, and so on. When translating into amino acid sequences, the
+frame can be specified and optionally the codon table selected (as
 defined in codontable.rb).
 
   bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa")
@@ -124,7 +127,7 @@ defined in codontable.rb).
   bioruby> seq.complement
   ==> "ttttgcatgcat"
 
-  bioruby> seq.subseq(3,8) # gets subsequence of positions 3 to 8
+  bioruby> seq.subseq(3,8) # gets subsequence of positions 3 to 8 (starting from 1)
   ==> "gcatgc"
   bioruby> seq.gc_percent 
   ==> 33
@@ -169,11 +172,11 @@ Windows). For example
   % ri p
   % ri File.open
 
-Nucleic acid sequence is an object of Bio::Sequence::NA class, and
-amino acid sequence is an object of Bio::Sequence::AA class.  Shared
+Nucleic acid sequence are members of the Bio::Sequence::NA class, and
+amino acid sequence are members of the Bio::Sequence::AA class.  Shared
 methods are in the parent Bio::Sequence class.
 
-As Bio::Sequence class inherits Ruby's String class, you can use
+As Bio::Sequence inherits Ruby's String class, you can use
 String class methods. For example, to get a subsequence, you can
 not only use subseq(from, to) but also String#[].
 
@@ -189,15 +192,14 @@ has index 0, for example:
 
 So when using String methods, you should subtract 1 from positions
 conventionally used in biology.  (subseq method will throw an exception if you
-specify positions smaller than or equal to 0 for either one of the "from" or
-"to".)
+specify positions smaller than or equal to 0 for either one of the "from" or "to".)
 
 The window_search(window_size, step_size) method shows a typical Ruby
 way of writing concise and clear code using 'closures'. Each sliding
 window creates a subsequence which is supplied to the enclosed block
 through a variable named +s+.
 
-* Show average percentage of GC content for 20 bases (stepping the default one base at a time)
+* Show average percentage of GC content for 20 bases (stepping the default one base at a time):
 
    bioruby> seq = Bio::Sequence::NA.new("atgcatgcaattaagctaatcccaattagatcatcccgatcatcaaaaaaaaaa")
    ==> "atgcatgcaattaagctaatcccaattagatcatcccgatcatcaaaaaaaaaa"
@@ -268,8 +270,8 @@ For example:
 
     puts my_aaseq
 
-Save the program as na2aa.rb. Prepare a nucleic acid sequence
-described below and saves it as my_naseq.txt:
+Save the program above as na2aa.rb. Prepare a nucleic acid sequence
+described below and save it as my_naseq.txt:
 
       gtggcgatctttccgaaagcgatgactggagcgaagaaccaaagcagtgacatttgtctg
       atgccgcacgtaggcctgataagacgcggacagcgtcgcatcaggcatcttgtgcaaatg
@@ -288,7 +290,7 @@ Outputs
 
     VAIFPKAMTGAKNQSSDICLMPHVGLIRRGQRRIRHLVQMSDAA*
 
-You can also write this, a bit fanciful, as a one-liner script.
+You can also write this, a bit fancifully, as a one-liner script.
 
     % ruby -r bio -e 'p Bio::Sequence::NA.new($<.read).translate' my_naseq.txt
 
@@ -301,7 +303,7 @@ sequence files. One generic example of the above can be found in
 We assume that you already have some GenBank data files. (If you don't,
 download some .seq files from ftp://ftp.ncbi.nih.gov/genbank/)
 
-As an example we fetch the ID, definition and sequence of each entry
+As an example we will fetch the ID, definition and sequence of each entry
 from the GenBank format and convert it to FASTA. This is also an example
 script in the BioRuby distribution.
 
@@ -349,7 +351,7 @@ For example, in turn, reading FASTA format files:
       puts "naseq      : " + f.naseq
     end
 
-In above two scripts, the first arguments of Bio::FlatFile.new are
+In the above two scripts, the first arguments of Bio::FlatFile.new are
 database classes of BioRuby. This is expanded on in a later section.
 
 Again another option is to use the Bio::DB.open class:
@@ -408,12 +410,9 @@ very complicated:
 
 * Note: In this example Feature#assoc method makes a Hash from a
   feature object. It is useful because you can get data from the hash
-  by using qualifiers as keys.
-  (But there is a risk some information is lost when two or more
-  qualifiers are the same. Therefore an Array is returned by
-  Feature#feature)
+  by using qualifiers as keys. But there is a risk some information is lost  when two or more qualifiers are the same. Therefore an Array is returned by  Feature#feature.
 
-Bio::Sequence#splicing splices subsequence from nucleic acid sequence
+Bio::Sequence#splicing splices subsequences from nucleic acid sequences
 according to location information used in GenBank, EMBL and DDBJ.
 
 When the specified translation table is different from the default
@@ -434,7 +433,7 @@ bio/location.rb.
     locs = Bio::Locations.new('join((8298.8300)..10206,1..855)')
     naseq.splicing(locs)
 
-You can also use the splicing method for amino acid sequences
+You can also use this splicing method for amino acid sequences
 (Bio::Sequence::AA objects).
 
 * Splicing peptide from a protein (e.g. signal peptide)
@@ -450,11 +449,7 @@ the ./lib/bio/db directory of the BioRuby source tree.
 
 In many cases the Bio::DatabaseClass acts as a factory pattern
 and recognises the database type automatically - returning a
-parsed object. For example using Bio::FlatFile
-
-Bio::FlatFile class as described above. The first argument of the
-Bio::FlatFile.new is database class name in BioRuby (such as Bio::GenBank,
-Bio::KEGG::GENES and so on).
+parsed object. For example using Bio::FlatFile class as described above. The first argument of the Bio::FlatFile.new is database class name in BioRuby (such as Bio::GenBank, Bio::KEGG::GENES and so on).
 
     ff = Bio::FlatFile.new(Bio::DatabaseClass, ARGF)
 
@@ -472,19 +467,18 @@ database class?
       p entry.seq               # sequence data of the entry
     end
 
-An example that can take any input, filter using a regular expression to output
+An example that can take any input, filter using a regular expression and output
 to a FASTA file can be found in sample/any2fasta.rb. With this technique it is
 possible to write a Unix type grep/sort pipe for sequence information. One
 example using scripts in the BIORUBY sample folder:
 
  fastagrep.rb '/At|Dm/' database.seq | fastasort.rb
 
-greps the database for Arabidopsis and Drosophila entries and sorts the output
-to FASTA.
+greps the database for Arabidopsis and Drosophila entries and sorts the output to FASTA.
 
 Other methods to extract specific data from database objects can be
 different between databases, though some methods are common (see the
-guidelines for common methods as described in bio/db.rb).
+guidelines for common methods in bio/db.rb).
 
   * entry_id --> gets ID of the entry
   * definition --> gets definition of the entry
@@ -495,16 +489,15 @@ guidelines for common methods as described in bio/db.rb).
 Refer to the documents of each database to find the exact naming
 of the included methods.
 
-In principal BioRuby uses the following conventions: when a method
-name is plural the method returns some object as an Array. For
+In general, BioRuby uses the following conventions: when a method
+name is plural, the method returns some object as an Array. For
 example, some classes have a "references" method which returns
 multiple Bio::Reference objects as an Array. And some classes have a
 "reference" method which returns a single Bio::Reference object.
 
 === Alignments (Bio::Alignment)
 
-Bio::Alignment class in bio/alignment.rb is a container class like Ruby's Hash,
-Array and BioPerl's Bio::SimpleAlign.  A very simple example is:
+The Bio::Alignment class in bio/alignment.rb is a container class like Ruby's Hash and Array classes and BioPerl's Bio::SimpleAlign.  A very simple example is:
 
   bioruby> seqs = [ 'atgca', 'aagca', 'acgca', 'acgcg' ]
   bioruby> seqs = seqs.collect{ |x| Bio::Sequence::NA.new(x) }
@@ -536,18 +529,45 @@ Array and BioPerl's Bio::SimpleAlign.  A very simple example is:
   factory = Bio::ClustalW.new
   a2 = a.do_align(factory)
 
+Read a ClustalW or Muscle 'ALN' alignment file:
+ 
+  bioruby> aln = Bio::ClustalW::Report.new(File.read('../test/data/clustalw/example1.aln'))
+  bioruby> aln.header
+  ==> "CLUSTAL 2.0.9 multiple sequence alignment"
+
+Fetch a sequence:
+
+  bioruby> seq = aln.get_sequence(1)
+  bioruby> seq.definition
+  ==> "gi|115023|sp|P10425|"
+
+Get a partial sequence:
+  
+  bioruby> seq.to_s[60..120]
+  ==> "LGYFNG-EAVPSNGLVLNTSKGLVLVDSSWDNKLTKELIEMVEKKFQKRVTDVIITHAHAD"
+
+Show the full alignment residue match information for the sequences in the set:
+
+  bioruby> aln.match_line[60..120]
+  ==> "     .     **. .   ..   ::*:       . * : : .        .: .* * *"
+
+Return a Bio::Alignment object:
+
+  bioruby> aln.alignment.consensus[60..120]
+  ==> "???????????SN?????????????D??????????L??????????????????H?H?D"
+
 == Restriction Enzymes (Bio::RE)
 
 BioRuby has extensive support for restriction enzymes (REs). It contains a full
 library of commonly used REs (from REBASE) which can be used to cut single
-stranded RNA or dubbel stranded DNA into fragments. To list all enzymes:
+stranded RNA or double stranded DNA into fragments. To list all enzymes:
 
   rebase = Bio::RestrictionEnzyme.rebase
   rebase.each do |enzyme_name, info|
     p enzyme_name
   end
 
-and cut a sequence with an enzyme follow up with:
+and to cut a sequence with an enzyme follow up with:
 
    res = seq.cut_with_enzyme('EcoRII', {:max_permutations => 0}, 
      {:view_ranges => true})
@@ -577,13 +597,14 @@ and cut a sequence with an enzyme follow up with:
 Let's start with a query.pep file which contains a sequence in FASTA
 format.  In this example we are going to execute a homology search
 from a remote internet site or on your local machine. Note that you
-can use the ssearch program instead of fasta when you use them in your
+can use the ssearch program instead of fasta when you use it in your
 local machine.
 
 === using FASTA in local machine
 
 Install the fasta program on your machine (the command name looks like
 fasta34. FASTA can be downloaded from ftp://ftp.virginia.edu/pub/fasta/).
+
 First, you must prepare your FASTA-formatted database sequence file
 target.pep and FASTA-formatted query.pep. 
 
@@ -619,7 +640,7 @@ target.pep and FASTA-formatted query.pep.
       end
     end
 
-We named above script as f_search.rb. You can execute as follows:
+We named above script f_search.rb. You can execute it as follows:
 
     % ./f_search.rb query.pep target.pep > f_search.out
 
@@ -630,14 +651,13 @@ Bio::Sequence#fasta method can be used.
     seq = ">test seq\nYQVLEEIGRGSFGSVRKVIHIPTKKLLVRKDIKYGHMNSKE"
     seq.fasta(factory)
 
-When you want to add options to FASTA command, you can set the
-third argument of Bio::Fasta.local method. For example, setting ktup to 1
-and getting top-10 hits:
+When you want to add options to FASTA commands, you can set the
+third argument of the Bio::Fasta.local method. For example, the following sets ktup to 1 and gets a list of the top 10 hits:
 
     factory = Bio::Fasta.local('fasta34', 'target.pep', '-b 10')
     factory.ktup = 1
 
-Bio::Fasta#query returns Bio::Fasta::Report object.
+Bio::Fasta#query returns a Bio::Fasta::Report object.
 We can get almost all information described in FASTA report text
 with the Report object. For example, getting information for hits:
 
@@ -665,12 +685,11 @@ with the Report object. For example, getting information for hits:
       puts hit.lap_at           # array of above four numbers
     end
 
-Most of above methods are common with the Bio::Blast::Report described
-below. Please refer to document of Bio::Fasta::Report class for
+Most of above methods are common to the Bio::Blast::Report described
+below. Please refer to the documentation of the Bio::Fasta::Report class for
 FASTA-specific details.
 
-If you need original output text of FASTA program you can use the "output"
-method of the factory object after the "query" method.
+If you need the original output text of FASTA program you can use the "output" method of the factory object after the "query" method.
 
     report = factory.query(entry)
     puts factory.output
@@ -698,15 +717,15 @@ Available databases in GenomeNet:
 Select the databases you require.  Next, give the search program from
 the type of query sequence and database.
 
-  * When query is a amino acid sequence
+  * When query is an amino acid sequence
     * When protein database, program is "fasta".
     * When nucleic database, program is "tfasta".
 
   * When query is a nucleic acid sequence
     * When nucleic database, program is "fasta".
-    * (When protein database, you would fail to search.)
+    * (When protein database, the search would fail.)
 
-For example:
+For example, run:
 
     program = 'fasta'
     database = 'genes'
@@ -741,7 +760,7 @@ The parameter "program" is different from FASTA - as you can expect:
 Bio::BLAST uses "-m 7" XML output of BLAST by default when either
 XMLParser or REXML (both of them are XML parser libraries for Ruby -
 of the two XMLParser is the fastest) is installed on your computer. In
-Ruby version 1.8.0, or later, REXML is bundled with Ruby's
+Ruby version 1.8.0 or later, REXML is bundled with Ruby's
 distribution.
 
 When no XML parser library is present, Bio::BLAST uses "-m 8" tabular
@@ -776,10 +795,10 @@ midline.
     end
 
 For simplicity and API compatibility, some information such as score
-are extracted from the first Hsp (High-scoring Segment Pair).
+is extracted from the first Hsp (High-scoring Segment Pair).
 
 Check the documentation for Bio::Blast::Report to see what can be
-retrieved. For now suffice to state that Bio::Blast::Report has a
+retrieved. For now suffice to say that Bio::Blast::Report has a
 hierarchical structure mirroring the general BLAST output stream:
 
   * In a Bio::Blast::Report object, @iterations is an array of
@@ -854,65 +873,12 @@ Bio::Blast::Report.new(or Bio::Blast::Default::Report.new):
 
     factory = Bio::Blast.remote(program, db, option, 'MYSITE')
 
-When you write above routines, please send to the BioRuby project and
-they may be included.
+When you write above routines, please send them to the BioRuby project, and they may be included in future releases.
 
 == Generate a reference list using PubMed (Bio::PubMed)
-=end
-(EDITORs NOTE: examples in this section do not work and should be rewritten.)
-
-Below script is an example which seaches PubMed and creates a reference list.
-
-    ARGV.each do |id|
-      entry = Bio::PubMed.query(id)     # searches PubMed and get entry
-      medline = Bio::MEDLINE.new(entry) # creates Bio::MEDLINE object from entry text
-      reference = medline.reference     # converts into Bio::Reference object
-      puts reference.bibtex             # shows BibTeX formatted text
-    end
-
-We named the script pmfetch.rb.
-
-    % ./pmfetch.rb 11024183 10592278 10592173
-
-To give some PubMed ID (PMID) in arguments, the script retrieves informations
-from NCBI, parses MEDLINE format text, converts into BibTeX format and
-shows them.
-
-A keyword search is also available.
-
-    #!/usr/bin/env ruby
-
-    require 'bio'
-
-    # Concatinates argument keyword list to a string
-    keywords = ARGV.join(' ')
-
-    # PubMed keyword search
-    entries = Bio::PubMed.search(keywords)
-
-    entries.each do |entry|
-      medline = Bio::MEDLINE.new(entry) # creates Bio::MEDLINE object from text
-      reference = medline.reference     # converts into Bio::Reference object
-      puts reference.bibtex             # shows BibTeX format text
-    end
-
-We named the script pmsearch.rb.
-
-    % ./pmsearch.rb genome bioinformatics
-
-To give keywords in arguments, the script searches PubMed by given
-keywords and shows bibliography informations in a BibTex format. Other
-output formats are also avaialble like the bibitem method described
-below. Some journal formats like nature and nar can be used, but lack
-bold and italic font output.
-
-(EDITORs NOTE: do we have some simple object that can be queried for
-author, title etc.?)
-=begin
 
 Nowadays using NCBI E-Utils is recommended. Use Bio::PubMed.esearch
-and Bio::PubMed.efetch instead of above methods.
-
+and Bio::PubMed.efetch.
 
     #!/usr/bin/env ruby
 
@@ -959,7 +925,7 @@ BibTeX format bibliography data to a file named genoinfo.bib.
 
 The BibTeX can be used with Tex or LaTeX to form bibliography
 information with your journal article. For more information
-on BibTex see (EDITORS NOTE: insert URL). A quick example:
+on using BibTex see ((<BibTex HowTo site|URL:http://www.bibtex.org/Using/>)). A quick example:
 
 Save this to hoge.tex:
 
@@ -977,14 +943,13 @@ Then,
     % latex hoge  # creates bibliography list
     % latex hoge  # inserts correct bibliography reference
 
-Now, you get hoge.dvi and hoge.ps - the latter you can view any
-Postscript viewer.
+Now, you get hoge.dvi and hoge.ps - the latter of which can be viewed with any Postscript viewer.
 
 === Bio::Reference#bibitem
 
 When you don't want to create a bib file, you can use
 Bio::Reference#bibitem method instead of Bio::Reference#bibtex.
-In above pmfetch.rb and pmsearch.rb scripts, change
+In the above pmfetch.rb and pmsearch.rb scripts, change
 
     puts reference.bibtex
 to
@@ -1031,11 +996,11 @@ BioRuby and other projects' members (2002).
   * Server-client model for getting entry from database via http.
 
 * BioSQL
-  * Schemas to store sequence data to relational database such as
+  * Schemas to store sequence data to relational databases such as
     MySQL and PostgreSQL, and methods to retrieve entries from the database.
 
-Here we give a quick overview. Check out
-((<URL:http://obda.open-bio.org/>)) for more extensive details.
+This tutorial only gives a quick overview of OBDA. Check out
+((<the OBDA site|URL:http://obda.open-bio.org>)) for more extensive details.
 
 == BioRegistry
 
@@ -1053,17 +1018,17 @@ when all local configulation files are not available.
 In the current BioRuby implementation all local configulation files
 are read. For databases with the same name settings encountered first
 are used. This means that if you don't like some settings of a
-database in system global configuration file
-(/etc/bioinformatics/seqdatabase.ini), you can easily override it by
+database in the system's global configuration file
+(/etc/bioinformatics/seqdatabase.ini), you can easily override them by
 writing settings to ~/.bioinformatics/seqdatabase.ini.
 
 The syntax of the configuration file is called a stanza format. For example
 
     [DatabaseName]
     protocol=ProtocolName
-    location=ServeName
+    location=ServerName
 
-You can write a description like above entry for every database.
+You can write a description like the above entry for every database.
 
 The database name is a local label for yourself, so you can name it
 freely and it can differ from the name of the actual databases. In the
@@ -1073,8 +1038,8 @@ connection to the database is tried sequentially with the order
 written in configuration files. However, this has not (yet) been
 implemented in BioRuby.
 
-In addition, for some protocol, you must set additional options
-other than locations (e.g. user name of MySQL). In the BioRegistory
+In addition, for some protocols, you must set additional options
+other than locations (e.g. user name for MySQL). In the BioRegistory
 specification, current available protocols are:
 
   * index-flat
@@ -1088,8 +1053,7 @@ In BioRuby, you can use index-flat, index-berkleydb, biofetch and biosql.
 Note that the BioRegistry specification sometimes gets updated and BioRuby
 does not always follow quickly.
 
-Here an example. Create a Bio::Registry object. It reads the configuration
-files:
+Here is an example. It creates a Bio::Registry object and reads the configuration files:
 
     reg = Bio::Registry.new
 
@@ -1100,41 +1064,38 @@ files:
     entry = serv.get_by_id('AA2CG')
 
 
-The variable "serv" is a server object corresponding to the setting
-written in configuration files. The class of the object is one of
+The variable "serv" is a server object corresponding to the settings
+written in the configuration files. The class of the object is one of
 Bio::SQL, Bio::Fetch, and so on. Note that Bio::Registry#get_database("name")
 returns nil if no database is found.
 
-After that, you can use get_by_id method and some specific methods.
-Please refer to below documents.
+After that, you can use the get_by_id method and some specific methods.
+Please refer to the sections below for more information.
 
 == BioFlat
 
 BioFlat is a mechanism to create index files of flat files and to retrieve
 these entries fast. There are two index types. index-flat is a simple index
-performing binary search without using an external library of Ruby. index-berkeleydb
+performing binary search without using any external libraries of Ruby. index-berkeleydb
 uses Berkeley DB for indexing - but requires installing bdb on your computer,
-as well as the BDB Ruby package. For creating the index itself, you can use
-br_bioflat.rb command bundled with BioRuby.
+as well as the BDB Ruby package. To create the index itself, you can use br_bioflat.rb command bundled with BioRuby.
 
     % br_bioflat.rb --makeindex database_name [--format data_format] filename...
 
 The format can be omitted because BioRuby has autodetection.  If that
-does not work you can try specifying data format as a name of BioRuby
-database class.
+doesn't work, you can try specifying the data format as the name of a BioRuby database class.
 
 Search and retrieve data from database:
 
     % br_bioflat.rb database_name identifier
 
-For example, to create index of GenBank files gbbct*.seq and get entry
-from the database:
+For example, to create an index of GenBank files gbbct*.seq and get the entry from the database:
 
     % br_bioflat.rb --makeindex my_bctdb --format GenBank gbbct*.seq
     % br_bioflat.rb my_bctdb A16STM262
 
 If you have Berkeley DB on your system and installed the bdb extension
-module of Ruby (see http://raa.ruby-lang.org/project/bdb/), you can
+module of Ruby (see ((<the BDB project page|URL:http://raa.ruby-lang.org/project/bdb/>)) ), you can
 create and search indexes with Berkeley DB - a very fast alternative
 that uses little computer memory. When creating the index, use the
 "--makeindex-bdb" option instead of "--makeindex".
@@ -1145,12 +1106,12 @@ that uses little computer memory. When creating the index, use the
 
   Note: this section is an advanced topic
 
-BioFetch is a database retrieval mechanism via CGI.  CGI Parameters,
-options and error codes are standardized.  There client access via
+BioFetch is a database retrieval mechanism via CGI. CGI Parameters,
+options and error codes are standardized. Client access via
 http is possible giving the database name, identifiers and format to
 retrieve entries.
 
-The BioRuby project has a BioFetch server in bioruby.org. It uses
+The BioRuby project has a BioFetch server at bioruby.org. It uses
 GenomeNet's DBGET system as a backend. The source code of the
 server is in sample/ directory. Currently, there are only two
 BioFetch servers in the world: bioruby.org and EBI.
@@ -1176,8 +1137,8 @@ Here are some methods to retrieve entries from our BioFetch server.
       serv = reg.get_database('genbank')
       entry = serv.get_by_id('AA2CG')
 
-If you want to use (4), you, obviously, have to include some settings
-in seqdatabase.ini. E.g.
+If you want to use (4), you have to include some settings
+in seqdatabase.ini. For example:
 
     [genbank]
     protocol=biofetch
@@ -1186,11 +1147,11 @@ in seqdatabase.ini. E.g.
 
 === The combination of BioFetch, Bio::KEGG::GENES and Bio::AAindex1
 
-Bioinformatics is often about glueing things together. Here we give an
-example to get the bacteriorhodopsin gene (VNG1467G) of the archaea
-Halobacterium from KEGG GENES database and to get alpha-helix index
+Bioinformatics is often about gluing things together. Here is an
+example that gets the bacteriorhodopsin gene (VNG1467G) of the archaea
+Halobacterium from KEGG GENES database and gets alpha-helix index
 data (BURA740101) from the AAindex (Amino acid indices and similarity
-matrices) database, and show the helix score for each 15-aa length
+matrices) database, and shows the helix score for each 15-aa length
 overlapping window.
 
     #!/usr/bin/env ruby
@@ -1212,16 +1173,16 @@ overlapping window.
       position += 1
     end
 
-The special method Bio::Fetch.query uses preset BioFetch server
-in bioruby.org. (The server internally get data from GenomeNet.
+The special method Bio::Fetch.query uses the preset BioFetch server
+at bioruby.org. (The server internally gets data from GenomeNet.
 Because the KEGG/GENES database and AAindex database are not available
-from other BioFetch servers, we used bioruby.org server with
+from other BioFetch servers, we used the bioruby.org server with
 Bio::Fetch.query method.)
 
 == BioSQL
 
-BioSQL is a well known schema to store and retrive biological sequences using a RDBMS like PostgreSQL or MySQL; note that SQLite is not supported.
-First of all, you must install a database engine or have access to a remote one. Then create the schema and populate with the taxonomy. You can follow the ((<Official Guide|URL:http://code.open-bio.org/svnweb/index.cgi/biosql/view/biosql-schema/trunk/INSTALL>)) .
+BioSQL is a well known schema to store and retrive biological sequences using a RDBMS like PostgreSQL or MySQL: note that SQLite is not supported.
+First of all, you must install a database engine or have access to a remote one. Then create the schema and populate with the taxonomy. You can follow the ((<Official Guide|URL:http://code.open-bio.org/svnweb/index.cgi/biosql/view/biosql-schema/trunk/INSTALL>)) to accomplish these steps.
 Next step is to install these gems:
 * ActiveRecord
 * CompositePrimaryKeys (Rails doesn't handle by default composite primary keys)
@@ -1230,22 +1191,23 @@ Next step is to install these gems:
 
 You can find ActiveRecord's models in /bioruby/lib/bio/io/biosql
 
-When you have your database up and running, you can connect to it in this way:
+When you have your database up and running, you can connect to it like this:
 
     #!/usr/bin/env ruby
     
     require 'bio'
 
     connection = Bio::SQL.establish_connection({'development'=>{'hostname'=>"YourHostname",
-                                                   'database'=>"CoolBioSeqDB",
-                                                   'adapter'=>"jdbcmysql", 
-                                                   'username'=>"YourUser",
-                                                   'password'=>"YouPassword"
-                                                  }
-                                  },
-                                  'development')
-
-    #The first parameter is the hash contaning the description of the configuration similar to database.yml in Rails application, you can declare different environment. The second parameter is the environment to use: 'development', 'test', 'production'.
+    'database'=>"CoolBioSeqDB",
+    'adapter'=>"jdbcmysql",
+    'username'=>"YourUser",
+    'password'=>"YouPassword"
+          }
+      },
+    'development')
+
+    #The first parameter is the hash contaning the description of the configuration; similar to database.yml in Rails applications, you can declare different environment. 
+    #The second parameter is the environment to use: 'development', 'test', or 'production'.
     
     #To store a sequence into the database you simply need a biosequence object.
     biosql_database = Bio::SQL::Biodatabase.find(:first)
@@ -1264,35 +1226,35 @@ When you have your database up and running, you can connect to it in this way:
     #retriving a generic accession
     bioseq = Bio::SQL.fetch_accession("YouAccession")
 
-    #If you use biosequence objects, you will find all its method mapped to BioSQL sequences. But you can also access to the models directly:
+    #If you use biosequence objects, you will find all its method mapped to BioSQL sequences. 
+    #But you can also access to the models directly:
 
-    #get the raw sequence associated with you accession
+    #get the raw sequence associated with your accession
     bioseq.entry.biosequence 
    
-    #get the length of your sequence, this is the explicit form of bioseq.length
+    #get the length of your sequence; this is the explicit form of bioseq.length
     bioseq.entry.biosequence.length
 
-    #convert the sequence in GenBank format
+    #convert the sequence into GenBank format
     bioseq.to_biosequence.output(:genbank)
 
-BioSQL' ((<schema|URL:http://www.biosql.org/wiki/Schema_Overview>)) is not so intuitive at the beginning, spend some time on understanding it, in the end if you know a little bit of rails everything will go smootly. You can find information to Annotation ((<here|URL:http://www.biosql.org/wiki/Annotation_Mapping>))
+BioSQL's ((<schema|URL:http://www.biosql.org/wiki/Schema_Overview>)) is not very intuitive for beginners, so spend some time on understanding it. In the end if you know a little bit of Ruby on Rails, everything will go smoothly. You can find information on Annotation ((<here|URL:http://www.biosql.org/wiki/Annotation_Mapping>)).
 ToDo: add exemaples from George. I remember he did some cool post on BioSQL and Rails.
 
-
 = PhyloXML
 
 PhyloXML is an XML language for saving, analyzing and exchanging data of 
-annotated phylogenetic trees. PhyloXML parser in BioRuby is implemented in 
-Bio::PhyloXML::Parser and writer in Bio::PhyloXML::Writer. 
-More information at www.phyloxml.org
+annotated phylogenetic trees. PhyloXML's parser in BioRuby is implemented in 
+Bio::PhyloXML::Parser, and its writer in Bio::PhyloXML::Writer. 
+More information can be found at ((<www.phyloxml.org|URL:http://www.phyloxml.org>)).
 
 == Requirements
 
-In addition to BioRuby library you need a libxml ruby bindings. To install:
+In addition to BioRuby, you need the libxml Ruby bindings. To install, execute:
 
   % gem install -r libxml-ruby
 
-For more information see ((<URL:http://libxml.rubyforge.org/install.xml>))
+For more information see the ((<libxml installer page|URL:http://libxml.rubyforge.org/install.xml>))
 
 == Parsing a file
 
@@ -1306,11 +1268,11 @@ For more information see ((<URL:http://libxml.rubyforge.org/install.xml>))
       puts tree.name
     end
 
-If there are several trees in the file, you can access the one you wish by an index
+If there are several trees in the file, you can access the one you wish by specifying its index:
 
     tree = phyloxml[3]
 
-You can use all Bio::Tree methods on the tree, since PhyloXML::Tree inherits from Bio::Tree. For example,
+You can use all Bio::Tree methods on the tree, since PhyloXML::Tree inherits from Bio::Tree. For example, 
 
    tree.leaves.each do |node|
      puts node.name
@@ -1338,7 +1300,7 @@ PhyloXML files can hold additional information besides phylogenies at the end of
 
 == Retrieving data
 
-Here is an example of how to retrieve the scientific name of the clades.
+Here is an example of how to retrieve the scientific name of the clades included in each tree.
 
     require 'bio'
     
@@ -1385,7 +1347,7 @@ Here is an example of how to retrieve the scientific name of the clades.
 
 == The BioRuby example programs
 
-Some sample programs are stored in ./samples/ directory. Run for example:
+Some sample programs are stored in ./samples/ directory. For example, the n2aa.rb program (transforms a nucleic acid sequence into an amino acid sequence) can be run using:
 
   ./sample/na2aa.rb test/data/fasta/example1.txt 
 
@@ -1404,21 +1366,21 @@ in this tutorial to doctest - more info upcoming.
 
 See the BioRuby in anger Wiki.  A lot of BioRuby's documentation exists in the
 source code and unit tests. To really dive in you will need the latest source
-code tree. The embedded rdoc documentation can be viewed online at
+code tree. The embedded rdoc documentation for the BioRuby source code can be viewed online at
 ((<URL:http://bioruby.org/rdoc/>)).
 
 == BioRuby Shell
 
-The BioRuby shell implementation you find in ./lib/bio/shell. It is very interesting
+The BioRuby shell implementation is located in ./lib/bio/shell. It is very interesting
 as it uses IRB (the Ruby intepreter) which is a powerful environment described in
-((<Programming Ruby's irb chapter|URL:http://ruby-doc.org/docs/ProgrammingRuby/html/irb.html>)). IRB commands can directly be typed in the shell, e.g.
+((<Programming Ruby's IRB chapter|URL:http://ruby-doc.org/docs/ProgrammingRuby/html/irb.html>)). IRB commands can be typed directly into the shell, e.g.
 
   bioruby!> IRB.conf[:PROMPT_MODE]
   ==!> :PROMPT_C
 
-optionally you also may want to install the optional Ruby readline support -
+Additionally, you also may want to install the optional Ruby readline support -
 with Debian libreadline-ruby. To edit a previous line you may have to press
-line down (arrow down) first.
+line down (down arrow) first.
 
 = Helpful tools
 
@@ -1428,7 +1390,7 @@ source code by clicking on class and method names.
   cd bioruby/lib
   rtags -R --vi
 
-For a tutorial see ((<URL:http://rtags.rubyforge.org/>))
+For a tutorial see ((<here|URL:http://rtags.rubyforge.org/>))
 
 = APPENDIX
 
@@ -1440,9 +1402,9 @@ Please refer to KEGG_API.rd.ja (English version: ((<URL:http://www.genome.jp/keg
 
 == Ruby Ensembl API
 
-Ruby Ensembl API is a ruby API to the Ensembl database. It is NOT currently
+The Ruby Ensembl API is a Ruby API to the Ensembl database. It is NOT currently
 included in the BioRuby archives. To install it, see
-((<URL:http://wiki.github.com/jandot/ruby-ensembl-api>))
+((<the Ruby-Ensembl Github|URL:http://wiki.github.com/jandot/ruby-ensembl-api>))
 for more information.
 
 === Gene Ontology (GO) through the Ruby Ensembl API
@@ -1455,7 +1417,7 @@ Gene Ontologies can be fetched through the Ruby Ensembl API package:
    infile.each do |line|
      accs = line.split(",")          # Split the comma-sep.entries into an array
      drosphila_acc = accs.shift      # the first entry is the Drosophila acc
-     mosq_acc = accs.shift           # the second entry is you Mosq. acc
+     mosq_acc = accs.shift           # the second entry is your Mosq. acc
      gene = Ensembl::Core::Gene.find_by_stable_id(drosophila_acc)
      print "#{mosq_acc}"
      gene.go_terms.each do |go|
@@ -1470,10 +1432,10 @@ homologues.
 
 At the moment there is no easy way of accessing BioPerl from Ruby. The best way, perhaps, is to create a Perl server that gets accessed through XML/RPC or SOAP.
 
-== Installing required external library
+== Installing required external libraries
 
 At this point for using BioRuby no additional libraries are needed, except if
-you are using Bio::PhyloXML module. Then you have to install libxml-ruby.
+you are using the Bio::PhyloXML module; then you have to install libxml-ruby.
 
 This may change, so keep an eye on the Bioruby website. Also when
 a package is missing BioRuby should show an informative message.
@@ -1485,7 +1447,7 @@ carefully that come with each package.
 
 === Installing libxml-ruby
 
-The simplest way is to use gem packaging system.
+The simplest way is to use the RubyGems packaging system:
 
   gem install -r libxml-ruby
 
@@ -1493,13 +1455,13 @@ If you get `require': no such file to load - mkmf (LoadError) error then do
 
   sudo apt-get install ruby-dev
 
-If you have other problems with installation, then see ((<URL:http://libxml.rubyforge.org/install.xml>))  
+If you have other problems with installation, then see ((<URL:http://libxml.rubyforge.org/install.xml>)).
 
 == Trouble shooting
 
 * Error: in `require': no such file to load -- bio (LoadError)
 
-Ruby fails to find the BioRuby libraries - add it to the RUBYLIB path, or pass
+Ruby is failing to find the BioRuby libraries - add it to the RUBYLIB path, or pass
 it to the interpeter. For example:
 
   ruby -I$BIORUBYPATH/lib yourprogram.rb
diff --git a/doc/Tutorial.rd.html b/doc/Tutorial.rd.html
index c970590..3eb2c95 100644
--- a/doc/Tutorial.rd.html
+++ b/doc/Tutorial.rd.html
@@ -11,29 +11,29 @@
 <h1><a name="label-0" id="label-0">BioRuby Tutorial</a></h1><!-- RDLabel: "BioRuby Tutorial" -->
 <ul>
 <li>Copyright (C) 2001-2003 KATAYAMA Toshiaki <k .at. bioruby.org></li>
-<li>Copyright (C) 2005-2010 Pjotr Prins, Naohisa Goto and others</li>
+<li>Copyright (C) 2005-2011 Pjotr Prins, Naohisa Goto and others</li>
 </ul>
-<p>This document was last modified: 2010/01/08
-Current editor: Pjotr Prins <p .at. bioruby.org></p>
-<p>The latest version resides in the GIT source code repository:  ./doc/<a href="http://github.com/pjotrp/bioruby/raw/documentation/doc/Tutorial.rd">Tutorial.rd</a>.</p>
+<p>This document was last modified: 2011/03/24
+Current editor: Michael O'Keefe <okeefm (at) rpi (dot) edu></p>
+<p>The latest version resides in the GIT source code repository:  ./doc/<a href="https://github.com/bioruby/bioruby/blob/master/doc/Tutorial.rd">Tutorial.rd</a>.</p>
 <h2><a name="label-1" id="label-1">Introduction</a></h2><!-- RDLabel: "Introduction" -->
 <p>This is a tutorial for using Bioruby. A basic knowledge of Ruby is required.
-If you want to know more about the programming langauge Ruby we recommend the
+If you want to know more about the programming language, we recommend the
 latest Ruby book <a href="http://www.pragprog.com/titles/ruby">Programming Ruby</a>
-by Dave Thomas and Andy Hunt - the first edition is online
+by Dave Thomas and Andy Hunt - the first edition can be read online
 <a href="http://www.ruby-doc.org/docs/ProgrammingRuby/">here</a>.</p>
 <p>For BioRuby you need to install Ruby and the BioRuby package on your computer</p>
 <p>You can check whether Ruby is installed on your computer and what
 version it has with the</p>
 <pre>% ruby -v</pre>
-<p>command. Showing something like:</p>
+<p>command. You should see something like:</p>
 <pre>ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]</pre>
 <p>If you see no such thing you'll have to install Ruby using your installation
 manager. For more information see the
 <a href="http://www.ruby-lang.org/en/">Ruby</a> website.</p>
 <p>With Ruby download and install Bioruby using the links on the
 <a href="http://bioruby.org/">Bioruby</a> website. The recommended installation is via 
-Ruby gems:</p>
+RubyGems:</p>
 <pre>gem install bio</pre>
 <p>See also the Bioruby <a href="http://bioruby.open-bio.org/wiki/Installation">wiki</a>.</p>
 <p>A lot of BioRuby's documentation exists in the source code and unit tests. To
@@ -41,9 +41,10 @@ really dive in you will need the latest source code tree. The embedded rdoc
 documentation can be viewed online at
 <a href="http://bioruby.org/rdoc/">bioruby's rdoc</a>. But first lets start!</p>
 <h2><a name="label-2" id="label-2">Trying Bioruby</a></h2><!-- RDLabel: "Trying Bioruby" -->
-<p>Bioruby comes with its own shell. After unpacking the sources run the
-following command</p>
-<pre>./bin/bioruby  or
+<p>Bioruby comes with its own shell. After unpacking the sources run one of the following commands:</p>
+<pre>bioruby</pre>
+<p>or, from the source tree</p>
+<pre>cd bioruby
 ruby -I lib bin/bioruby</pre>
 <p>and you should see a prompt</p>
 <pre>bioruby></pre>
@@ -60,11 +61,11 @@ question to the mailing list. BioRuby developers usually try to help.</p>
 <h2><a name="label-3" id="label-3">Working with nucleic / amino acid sequences (Bio::Sequence class)</a></h2><!-- RDLabel: "Working with nucleic / amino acid sequences (Bio::Sequence class)" -->
 <p>The Bio::Sequence class allows the usual sequence transformations and
 translations.  In the example below the DNA sequence "atgcatgcaaaa" is
-converted into the complemental strand, spliced into a subsequence,
-next the nucleic acid composition is calculated and the sequence is
+converted into the complemental strand and spliced into a subsequence; 
+next, the nucleic acid composition is calculated and the sequence is
 translated into the amino acid sequence, the molecular weight
-calculated, and so on. When translating into amino acid sequences the
-frame can be specified and optionally the condon table selected (as
+calculated, and so on. When translating into amino acid sequences, the
+frame can be specified and optionally the codon table selected (as
 defined in codontable.rb).</p>
 <pre>bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa")
 ==> "atgcatgcaaaa"
@@ -73,7 +74,7 @@ defined in codontable.rb).</p>
 bioruby> seq.complement
 ==> "ttttgcatgcat"
 
-bioruby> seq.subseq(3,8) # gets subsequence of positions 3 to 8
+bioruby> seq.subseq(3,8) # gets subsequence of positions 3 to 8 (starting from 1)
 ==> "gcatgc"
 bioruby> seq.gc_percent 
 ==> 33
@@ -112,10 +113,10 @@ Windows). For example</p>
 <pre>% ri puts
 % ri p
 % ri File.open</pre>
-<p>Nucleic acid sequence is an object of Bio::Sequence::NA class, and
-amino acid sequence is an object of Bio::Sequence::AA class.  Shared
+<p>Nucleic acid sequence are members of the Bio::Sequence::NA class, and
+amino acid sequence are members of the Bio::Sequence::AA class.  Shared
 methods are in the parent Bio::Sequence class.</p>
-<p>As Bio::Sequence class inherits Ruby's String class, you can use
+<p>As Bio::Sequence inherits Ruby's String class, you can use
 String class methods. For example, to get a subsequence, you can
 not only use subseq(from, to) but also String#[].</p>
 <p>Please take note that the Ruby's string's are base 0 - i.e. the first letter
@@ -128,14 +129,13 @@ bioruby> s[0..1]
 ==> "ab"</pre>
 <p>So when using String methods, you should subtract 1 from positions
 conventionally used in biology.  (subseq method will throw an exception if you
-specify positions smaller than or equal to 0 for either one of the "from" or
-"to".)</p>
+specify positions smaller than or equal to 0 for either one of the "from" or "to".)</p>
 <p>The window_search(window_size, step_size) method shows a typical Ruby
 way of writing concise and clear code using 'closures'. Each sliding
 window creates a subsequence which is supplied to the enclosed block
 through a variable named +s+.</p>
 <ul>
-<li><p>Show average percentage of GC content for 20 bases (stepping the default one base at a time)</p>
+<li><p>Show average percentage of GC content for 20 bases (stepping the default one base at a time):</p>
 <pre>bioruby> seq = Bio::Sequence::NA.new("atgcatgcaattaagctaatcccaattagatcatcccgatcatcaaaaaaaaaa")
 ==> "atgcatgcaattaagctaatcccaattagatcatcccgatcatcaaaaaaaaaa"
 
@@ -195,8 +195,8 @@ my_naseq = Bio::Sequence::NA.new(input_seq)
 my_aaseq = my_naseq.translate
 
 puts my_aaseq</pre>
-<p>Save the program as na2aa.rb. Prepare a nucleic acid sequence
-described below and saves it as my_naseq.txt:</p>
+<p>Save the program above as na2aa.rb. Prepare a nucleic acid sequence
+described below and save it as my_naseq.txt:</p>
 <pre>gtggcgatctttccgaaagcgatgactggagcgaagaaccaaagcagtgacatttgtctg
 atgccgcacgtaggcctgataagacgcggacagcgtcgcatcaggcatcttgtgcaaatg
 tcggatgcggcgtga</pre>
@@ -207,7 +207,7 @@ For example, translates my_naseq.txt:</p>
 <pre>% cat my_naseq.txt|ruby na2aa.rb</pre>
 <p>Outputs</p>
 <pre>VAIFPKAMTGAKNQSSDICLMPHVGLIRRGQRRIRHLVQMSDAA*</pre>
-<p>You can also write this, a bit fanciful, as a one-liner script.</p>
+<p>You can also write this, a bit fancifully, as a one-liner script.</p>
 <pre>% ruby -r bio -e 'p Bio::Sequence::NA.new($<.read).translate' my_naseq.txt</pre>
 <p>In the next section we will retrieve data from databases instead of using raw
 sequence files. One generic example of the above can be found in
@@ -215,7 +215,7 @@ sequence files. One generic example of the above can be found in
 <h2><a name="label-4" id="label-4">Parsing GenBank data (Bio::GenBank class)</a></h2><!-- RDLabel: "Parsing GenBank data (Bio::GenBank class)" -->
 <p>We assume that you already have some GenBank data files. (If you don't,
 download some .seq files from ftp://ftp.ncbi.nih.gov/genbank/)</p>
-<p>As an example we fetch the ID, definition and sequence of each entry
+<p>As an example we will fetch the ID, definition and sequence of each entry
 from the GenBank format and convert it to FASTA. This is also an example
 script in the BioRuby distribution.</p>
 <p>A first attempt could be to use the Bio::GenBank class for reading in
@@ -256,7 +256,7 @@ ff.each_entry do |f|
   puts "nalen      : " + f.nalen.to_s
   puts "naseq      : " + f.naseq
 end</pre>
-<p>In above two scripts, the first arguments of Bio::FlatFile.new are
+<p>In the above two scripts, the first arguments of Bio::FlatFile.new are
 database classes of BioRuby. This is expanded on in a later section.</p>
 <p>Again another option is to use the Bio::DB.open class:</p>
 <pre>#!/usr/bin/env ruby
@@ -311,12 +311,9 @@ end</pre>
 <ul>
 <li>Note: In this example Feature#assoc method makes a Hash from a
   feature object. It is useful because you can get data from the hash
-  by using qualifiers as keys.
-  (But there is a risk some information is lost when two or more
-  qualifiers are the same. Therefore an Array is returned by
-  Feature#feature)</li>
+  by using qualifiers as keys. But there is a risk some information is lost  when two or more qualifiers are the same. Therefore an Array is returned by  Feature#feature.</li>
 </ul>
-<p>Bio::Sequence#splicing splices subsequence from nucleic acid sequence
+<p>Bio::Sequence#splicing splices subsequences from nucleic acid sequences
 according to location information used in GenBank, EMBL and DDBJ.</p>
 <p>When the specified translation table is different from the default
 (universal), or when the first codon is not "atg" or the protein
@@ -332,7 +329,7 @@ bio/location.rb.</p>
 <pre>locs = Bio::Locations.new('join((8298.8300)..10206,1..855)')
 naseq.splicing(locs)</pre></li>
 </ul>
-<p>You can also use the splicing method for amino acid sequences
+<p>You can also use this splicing method for amino acid sequences
 (Bio::Sequence::AA objects).</p>
 <ul>
 <li><p>Splicing peptide from a protein (e.g. signal peptide)</p>
@@ -344,10 +341,7 @@ with classes like Bio::GenBank, Bio::KEGG::GENES. A full list can be found in
 the ./lib/bio/db directory of the BioRuby source tree.</p>
 <p>In many cases the Bio::DatabaseClass acts as a factory pattern
 and recognises the database type automatically - returning a
-parsed object. For example using Bio::FlatFile</p>
-<p>Bio::FlatFile class as described above. The first argument of the
-Bio::FlatFile.new is database class name in BioRuby (such as Bio::GenBank,
-Bio::KEGG::GENES and so on).</p>
+parsed object. For example using Bio::FlatFile class as described above. The first argument of the Bio::FlatFile.new is database class name in BioRuby (such as Bio::GenBank, Bio::KEGG::GENES and so on).</p>
 <pre>ff = Bio::FlatFile.new(Bio::DatabaseClass, ARGF)</pre>
 <p>Isn't it wonderful that Bio::FlatFile automagically recognizes each
 database class?</p>
@@ -361,16 +355,15 @@ ff.each_entry do |entry|
   p entry.definition        # definition of the entry
   p entry.seq               # sequence data of the entry
 end</pre>
-<p>An example that can take any input, filter using a regular expression to output
+<p>An example that can take any input, filter using a regular expression and output
 to a FASTA file can be found in sample/any2fasta.rb. With this technique it is
 possible to write a Unix type grep/sort pipe for sequence information. One
 example using scripts in the BIORUBY sample folder:</p>
 <pre>fastagrep.rb '/At|Dm/' database.seq | fastasort.rb</pre>
-<p>greps the database for Arabidopsis and Drosophila entries and sorts the output
-to FASTA.</p>
+<p>greps the database for Arabidopsis and Drosophila entries and sorts the output to FASTA.</p>
 <p>Other methods to extract specific data from database objects can be
 different between databases, though some methods are common (see the
-guidelines for common methods as described in bio/db.rb).</p>
+guidelines for common methods in bio/db.rb).</p>
 <ul>
 <li>entry_id --> gets ID of the entry</li>
 <li>definition --> gets definition of the entry</li>
@@ -380,14 +373,13 @@ guidelines for common methods as described in bio/db.rb).</p>
 </ul>
 <p>Refer to the documents of each database to find the exact naming
 of the included methods.</p>
-<p>In principal BioRuby uses the following conventions: when a method
-name is plural the method returns some object as an Array. For
+<p>In general, BioRuby uses the following conventions: when a method
+name is plural, the method returns some object as an Array. For
 example, some classes have a "references" method which returns
 multiple Bio::Reference objects as an Array. And some classes have a
 "reference" method which returns a single Bio::Reference object.</p>
 <h3><a name="label-6" id="label-6">Alignments (Bio::Alignment)</a></h3><!-- RDLabel: "Alignments (Bio::Alignment)" -->
-<p>Bio::Alignment class in bio/alignment.rb is a container class like Ruby's Hash,
-Array and BioPerl's Bio::SimpleAlign.  A very simple example is:</p>
+<p>The Bio::Alignment class in bio/alignment.rb is a container class like Ruby's Hash and Array classes and BioPerl's Bio::SimpleAlign.  A very simple example is:</p>
 <pre>bioruby> seqs = [ 'atgca', 'aagca', 'acgca', 'acgcg' ]
 bioruby> seqs = seqs.collect{ |x| Bio::Sequence::NA.new(x) }
 # creates alignment object
@@ -417,15 +409,32 @@ a.each_site { |x| p x }
 # clustalw command must be installed.
 factory = Bio::ClustalW.new
 a2 = a.do_align(factory)</pre>
+<p>Read a ClustalW or Muscle 'ALN' alignment file:</p>
+<pre>bioruby> aln = Bio::ClustalW::Report.new(File.read('../test/data/clustalw/example1.aln'))
+bioruby> aln.header
+==> "CLUSTAL 2.0.9 multiple sequence alignment"</pre>
+<p>Fetch a sequence:</p>
+<pre>bioruby> seq = aln.get_sequence(1)
+bioruby> seq.definition
+==> "gi|115023|sp|P10425|"</pre>
+<p>Get a partial sequence:</p>
+<pre>bioruby> seq.to_s[60..120]
+==> "LGYFNG-EAVPSNGLVLNTSKGLVLVDSSWDNKLTKELIEMVEKKFQKRVTDVIITHAHAD"</pre>
+<p>Show the full alignment residue match information for the sequences in the set:</p>
+<pre>bioruby> aln.match_line[60..120]
+==> "     .     **. .   ..   ::*:       . * : : .        .: .* * *"</pre>
+<p>Return a Bio::Alignment object:</p>
+<pre>bioruby> aln.alignment.consensus[60..120]
+==> "???????????SN?????????????D??????????L??????????????????H?H?D"</pre>
 <h2><a name="label-7" id="label-7">Restriction Enzymes (Bio::RE)</a></h2><!-- RDLabel: "Restriction Enzymes (Bio::RE)" -->
 <p>BioRuby has extensive support for restriction enzymes (REs). It contains a full
 library of commonly used REs (from REBASE) which can be used to cut single
-stranded RNA or dubbel stranded DNA into fragments. To list all enzymes:</p>
+stranded RNA or double stranded DNA into fragments. To list all enzymes:</p>
 <pre>rebase = Bio::RestrictionEnzyme.rebase
 rebase.each do |enzyme_name, info|
   p enzyme_name
 end</pre>
-<p>and cut a sequence with an enzyme follow up with:</p>
+<p>and to cut a sequence with an enzyme follow up with:</p>
 <pre>res = seq.cut_with_enzyme('EcoRII', {:max_permutations => 0}, 
   {:view_ranges => true})
 if res.kind_of? Symbol #error
@@ -451,12 +460,12 @@ res.each do |frag|
 <p>Let's start with a query.pep file which contains a sequence in FASTA
 format.  In this example we are going to execute a homology search
 from a remote internet site or on your local machine. Note that you
-can use the ssearch program instead of fasta when you use them in your
+can use the ssearch program instead of fasta when you use it in your
 local machine.</p>
 <h3><a name="label-9" id="label-9">using FASTA in local machine</a></h3><!-- RDLabel: "using FASTA in local machine" -->
 <p>Install the fasta program on your machine (the command name looks like
-fasta34. FASTA can be downloaded from ftp://ftp.virginia.edu/pub/fasta/).
-First, you must prepare your FASTA-formatted database sequence file
+fasta34. FASTA can be downloaded from ftp://ftp.virginia.edu/pub/fasta/).</p>
+<p>First, you must prepare your FASTA-formatted database sequence file
 target.pep and FASTA-formatted query.pep. </p>
 <pre>#!/usr/bin/env ruby
 
@@ -489,19 +498,18 @@ ff.each do |entry|
     end
   end
 end</pre>
-<p>We named above script as f_search.rb. You can execute as follows:</p>
+<p>We named above script f_search.rb. You can execute it as follows:</p>
 <pre>% ./f_search.rb query.pep target.pep > f_search.out</pre>
 <p>In above script, the variable "factory" is a factory object for executing
 FASTA many times easily. Instead of using Fasta#query method,
 Bio::Sequence#fasta method can be used.</p>
 <pre>seq = ">test seq\nYQVLEEIGRGSFGSVRKVIHIPTKKLLVRKDIKYGHMNSKE"
 seq.fasta(factory)</pre>
-<p>When you want to add options to FASTA command, you can set the
-third argument of Bio::Fasta.local method. For example, setting ktup to 1
-and getting top-10 hits:</p>
+<p>When you want to add options to FASTA commands, you can set the
+third argument of the Bio::Fasta.local method. For example, the following sets ktup to 1 and gets a list of the top 10 hits:</p>
 <pre>factory = Bio::Fasta.local('fasta34', 'target.pep', '-b 10')
 factory.ktup = 1</pre>
-<p>Bio::Fasta#query returns Bio::Fasta::Report object.
+<p>Bio::Fasta#query returns a Bio::Fasta::Report object.
 We can get almost all information described in FASTA report text
 with the Report object. For example, getting information for hits:</p>
 <pre>report.each do |hit|
@@ -527,11 +535,10 @@ with the Report object. For example, getting information for hits:</p>
                             # in hit(target) sequence
   puts hit.lap_at           # array of above four numbers
 end</pre>
-<p>Most of above methods are common with the Bio::Blast::Report described
-below. Please refer to document of Bio::Fasta::Report class for
+<p>Most of above methods are common to the Bio::Blast::Report described
+below. Please refer to the documentation of the Bio::Fasta::Report class for
 FASTA-specific details.</p>
-<p>If you need original output text of FASTA program you can use the "output"
-method of the factory object after the "query" method.</p>
+<p>If you need the original output text of FASTA program you can use the "output" method of the factory object after the "query" method.</p>
 <pre>report = factory.query(entry)
 puts factory.output</pre>
 <h3><a name="label-10" id="label-10">using FASTA from a remote internet site</a></h3><!-- RDLabel: "using FASTA from a remote internet site" -->
@@ -558,7 +565,7 @@ same things as with a local method.</p>
 <p>Select the databases you require.  Next, give the search program from
 the type of query sequence and database.</p>
 <ul>
-<li>When query is a amino acid sequence
+<li>When query is an amino acid sequence
 <ul>
 <li>When protein database, program is "fasta".</li>
 <li>When nucleic database, program is "tfasta".</li>
@@ -566,10 +573,10 @@ the type of query sequence and database.</p>
 <li>When query is a nucleic acid sequence
 <ul>
 <li>When nucleic database, program is "fasta".</li>
-<li>(When protein database, you would fail to search.)</li>
+<li>(When protein database, the search would fail.)</li>
 </ul></li>
 </ul>
-<p>For example:</p>
+<p>For example, run:</p>
 <pre>program = 'fasta'
 database = 'genes'
 
@@ -600,7 +607,7 @@ The parameter "program" is different from FASTA - as you can expect:</p>
 <p>Bio::BLAST uses "-m 7" XML output of BLAST by default when either
 XMLParser or REXML (both of them are XML parser libraries for Ruby -
 of the two XMLParser is the fastest) is installed on your computer. In
-Ruby version 1.8.0, or later, REXML is bundled with Ruby's
+Ruby version 1.8.0 or later, REXML is bundled with Ruby's
 distribution.</p>
 <p>When no XML parser library is present, Bio::BLAST uses "-m 8" tabular
 deliminated format. Available information is limited with the
@@ -631,9 +638,9 @@ midline.</p>
   puts hit.lap_at          
 end</pre>
 <p>For simplicity and API compatibility, some information such as score
-are extracted from the first Hsp (High-scoring Segment Pair).</p>
+is extracted from the first Hsp (High-scoring Segment Pair).</p>
 <p>Check the documentation for Bio::Blast::Report to see what can be
-retrieved. For now suffice to state that Bio::Blast::Report has a
+retrieved. For now suffice to say that Bio::Blast::Report has a
 hierarchical structure mirroring the general BLAST output stream:</p>
 <ul>
 <li>In a Bio::Blast::Report object, @iterations is an array of
@@ -699,11 +706,10 @@ want to add other sites, you must write the following:</p>
 named "exec_MYSITE" to get query sequence and to pass the result to
 Bio::Blast::Report.new(or Bio::Blast::Default::Report.new):</p>
 <pre>factory = Bio::Blast.remote(program, db, option, 'MYSITE')</pre>
-<p>When you write above routines, please send to the BioRuby project and
-they may be included.</p>
+<p>When you write above routines, please send them to the BioRuby project, and they may be included in future releases.</p>
 <h2><a name="label-14" id="label-14">Generate a reference list using PubMed (Bio::PubMed)</a></h2><!-- RDLabel: "Generate a reference list using PubMed (Bio::PubMed)" -->
 <p>Nowadays using NCBI E-Utils is recommended. Use Bio::PubMed.esearch
-and Bio::PubMed.efetch instead of above methods.</p>
+and Bio::PubMed.efetch.</p>
 <pre>#!/usr/bin/env ruby
 
 require 'bio'
@@ -741,7 +747,7 @@ BibTeX format bibliography data to a file named genoinfo.bib.</p>
 % ./pmsearch.rb genome bioinformatics >> genoinfo.bib</pre>
 <p>The BibTeX can be used with Tex or LaTeX to form bibliography
 information with your journal article. For more information
-on BibTex see (EDITORS NOTE: insert URL). A quick example:</p>
+on using BibTex see <a href="http://www.bibtex.org/Using/">BibTex HowTo site</a>. A quick example:</p>
 <p>Save this to hoge.tex:</p>
 <pre>\documentclass{jarticle}
 \begin{document}
@@ -754,12 +760,11 @@ foo bar KEGG database~\cite{PMID:10592173} baz hoge fuga.
 % bibtex hoge # processes genoinfo.bib
 % latex hoge  # creates bibliography list
 % latex hoge  # inserts correct bibliography reference</pre>
-<p>Now, you get hoge.dvi and hoge.ps - the latter you can view any
-Postscript viewer.</p>
+<p>Now, you get hoge.dvi and hoge.ps - the latter of which can be viewed with any Postscript viewer.</p>
 <h3><a name="label-16" id="label-16">Bio::Reference#bibitem</a></h3><!-- RDLabel: "Bio::Reference#bibitem" -->
 <p>When you don't want to create a bib file, you can use
 Bio::Reference#bibitem method instead of Bio::Reference#bibtex.
-In above pmfetch.rb and pmsearch.rb scripts, change</p>
+In the above pmfetch.rb and pmsearch.rb scripts, change</p>
 <pre>puts reference.bibtex</pre>
 <p>to</p>
 <pre>puts reference.bibitem</pre>
@@ -801,12 +806,12 @@ BioRuby and other projects' members (2002).</p>
 </ul></li>
 <li>BioSQL
 <ul>
-<li>Schemas to store sequence data to relational database such as
+<li>Schemas to store sequence data to relational databases such as
     MySQL and PostgreSQL, and methods to retrieve entries from the database.</li>
 </ul></li>
 </ul>
-<p>Here we give a quick overview. Check out
-<a href="http://obda.open-bio.org/"><URL:http://obda.open-bio.org/></a> for more extensive details.</p>
+<p>This tutorial only gives a quick overview of OBDA. Check out
+<a href="http://obda.open-bio.org">the OBDA site</a> for more extensive details.</p>
 <h2><a name="label-18" id="label-18">BioRegistry</a></h2><!-- RDLabel: "BioRegistry" -->
 <p>BioRegistry allows for locating retrieval methods and database
 locations through configuration files.  The priorities are</p>
@@ -821,14 +826,14 @@ when all local configulation files are not available.</p>
 <p>In the current BioRuby implementation all local configulation files
 are read. For databases with the same name settings encountered first
 are used. This means that if you don't like some settings of a
-database in system global configuration file
-(/etc/bioinformatics/seqdatabase.ini), you can easily override it by
+database in the system's global configuration file
+(/etc/bioinformatics/seqdatabase.ini), you can easily override them by
 writing settings to ~/.bioinformatics/seqdatabase.ini.</p>
 <p>The syntax of the configuration file is called a stanza format. For example</p>
 <pre>[DatabaseName]
 protocol=ProtocolName
-location=ServeName</pre>
-<p>You can write a description like above entry for every database.</p>
+location=ServerName</pre>
+<p>You can write a description like the above entry for every database.</p>
 <p>The database name is a local label for yourself, so you can name it
 freely and it can differ from the name of the actual databases. In the
 actual specification of BioRegistry where there are two or more
@@ -836,8 +841,8 @@ settings for a database of the same name, it is proposed that
 connection to the database is tried sequentially with the order
 written in configuration files. However, this has not (yet) been
 implemented in BioRuby.</p>
-<p>In addition, for some protocol, you must set additional options
-other than locations (e.g. user name of MySQL). In the BioRegistory
+<p>In addition, for some protocols, you must set additional options
+other than locations (e.g. user name for MySQL). In the BioRegistory
 specification, current available protocols are:</p>
 <ul>
 <li>index-flat</li>
@@ -850,8 +855,7 @@ specification, current available protocols are:</p>
 <p>In BioRuby, you can use index-flat, index-berkleydb, biofetch and biosql.
 Note that the BioRegistry specification sometimes gets updated and BioRuby
 does not always follow quickly.</p>
-<p>Here an example. Create a Bio::Registry object. It reads the configuration
-files:</p>
+<p>Here is an example. It creates a Bio::Registry object and reads the configuration files:</p>
 <pre>reg = Bio::Registry.new
 
 # connects to the database "genbank"
@@ -859,42 +863,39 @@ serv = reg.get_database('genbank')
 
 # gets entry of the ID
 entry = serv.get_by_id('AA2CG')</pre>
-<p>The variable "serv" is a server object corresponding to the setting
-written in configuration files. The class of the object is one of
+<p>The variable "serv" is a server object corresponding to the settings
+written in the configuration files. The class of the object is one of
 Bio::SQL, Bio::Fetch, and so on. Note that Bio::Registry#get_database("name")
 returns nil if no database is found.</p>
-<p>After that, you can use get_by_id method and some specific methods.
-Please refer to below documents.</p>
+<p>After that, you can use the get_by_id method and some specific methods.
+Please refer to the sections below for more information.</p>
 <h2><a name="label-19" id="label-19">BioFlat</a></h2><!-- RDLabel: "BioFlat" -->
 <p>BioFlat is a mechanism to create index files of flat files and to retrieve
 these entries fast. There are two index types. index-flat is a simple index
-performing binary search without using an external library of Ruby. index-berkeleydb
+performing binary search without using any external libraries of Ruby. index-berkeleydb
 uses Berkeley DB for indexing - but requires installing bdb on your computer,
-as well as the BDB Ruby package. For creating the index itself, you can use
-br_bioflat.rb command bundled with BioRuby.</p>
+as well as the BDB Ruby package. To create the index itself, you can use br_bioflat.rb command bundled with BioRuby.</p>
 <pre>% br_bioflat.rb --makeindex database_name [--format data_format] filename...</pre>
 <p>The format can be omitted because BioRuby has autodetection.  If that
-does not work you can try specifying data format as a name of BioRuby
-database class.</p>
+doesn't work, you can try specifying the data format as the name of a BioRuby database class.</p>
 <p>Search and retrieve data from database:</p>
 <pre>% br_bioflat.rb database_name identifier</pre>
-<p>For example, to create index of GenBank files gbbct*.seq and get entry
-from the database:</p>
+<p>For example, to create an index of GenBank files gbbct*.seq and get the entry from the database:</p>
 <pre>% br_bioflat.rb --makeindex my_bctdb --format GenBank gbbct*.seq
 % br_bioflat.rb my_bctdb A16STM262</pre>
 <p>If you have Berkeley DB on your system and installed the bdb extension
-module of Ruby (see http://raa.ruby-lang.org/project/bdb/), you can
+module of Ruby (see <a href="http://raa.ruby-lang.org/project/bdb/">the BDB project page</a> ), you can
 create and search indexes with Berkeley DB - a very fast alternative
 that uses little computer memory. When creating the index, use the
 "--makeindex-bdb" option instead of "--makeindex".</p>
 <pre>% br_bioflat.rb --makeindex-bdb database_name [--format data_format] filename...</pre>
 <h2><a name="label-20" id="label-20">BioFetch</a></h2><!-- RDLabel: "BioFetch" -->
 <pre>Note: this section is an advanced topic</pre>
-<p>BioFetch is a database retrieval mechanism via CGI.  CGI Parameters,
-options and error codes are standardized.  There client access via
+<p>BioFetch is a database retrieval mechanism via CGI. CGI Parameters,
+options and error codes are standardized. Client access via
 http is possible giving the database name, identifiers and format to
 retrieve entries.</p>
-<p>The BioRuby project has a BioFetch server in bioruby.org. It uses
+<p>The BioRuby project has a BioFetch server at bioruby.org. It uses
 GenomeNet's DBGET system as a backend. The source code of the
 server is in sample/ directory. Currently, there are only two
 BioFetch servers in the world: bioruby.org and EBI.</p>
@@ -912,18 +913,18 @@ entry = serv.fetch(db_name, entry_id)</pre></li>
 serv = reg.get_database('genbank')
 entry = serv.get_by_id('AA2CG')</pre></li>
 </ol>
-<p>If you want to use (4), you, obviously, have to include some settings
-in seqdatabase.ini. E.g.</p>
+<p>If you want to use (4), you have to include some settings
+in seqdatabase.ini. For example:</p>
 <pre>[genbank]
 protocol=biofetch
 location=http://bioruby.org/cgi-bin/biofetch.rb
 biodbname=genbank</pre>
 <h3><a name="label-21" id="label-21">The combination of BioFetch, Bio::KEGG::GENES and Bio::AAindex1</a></h3><!-- RDLabel: "The combination of BioFetch, Bio::KEGG::GENES and Bio::AAindex1" -->
-<p>Bioinformatics is often about glueing things together. Here we give an
-example to get the bacteriorhodopsin gene (VNG1467G) of the archaea
-Halobacterium from KEGG GENES database and to get alpha-helix index
+<p>Bioinformatics is often about gluing things together. Here is an
+example that gets the bacteriorhodopsin gene (VNG1467G) of the archaea
+Halobacterium from KEGG GENES database and gets alpha-helix index
 data (BURA740101) from the AAindex (Amino acid indices and similarity
-matrices) database, and show the helix score for each 15-aa length
+matrices) database, and shows the helix score for each 15-aa length
 overlapping window.</p>
 <pre>#!/usr/bin/env ruby
 
@@ -943,14 +944,14 @@ aaseq.window_search(win_size) do |subseq|
   puts [ position, score ].join("\t")
   position += 1
 end</pre>
-<p>The special method Bio::Fetch.query uses preset BioFetch server
-in bioruby.org. (The server internally get data from GenomeNet.
+<p>The special method Bio::Fetch.query uses the preset BioFetch server
+at bioruby.org. (The server internally gets data from GenomeNet.
 Because the KEGG/GENES database and AAindex database are not available
-from other BioFetch servers, we used bioruby.org server with
+from other BioFetch servers, we used the bioruby.org server with
 Bio::Fetch.query method.)</p>
 <h2><a name="label-22" id="label-22">BioSQL</a></h2><!-- RDLabel: "BioSQL" -->
-<p>BioSQL is a well known schema to store and retrive biological sequences using a RDBMS like PostgreSQL or MySQL; note that SQLite is not supported.
-First of all, you must install a database engine or have access to a remote one. Then create the schema and populate with the taxonomy. You can follow the <a href="http://code.open-bio.org/svnweb/index.cgi/biosql/view/biosql-schema/trunk/INSTALL">Official Guide</a> .
+<p>BioSQL is a well known schema to store and retrive biological sequences using a RDBMS like PostgreSQL or MySQL: note that SQLite is not supported.
+First of all, you must install a database engine or have access to a remote one. Then create the schema and populate with the taxonomy. You can follow the <a href="http://code.open-bio.org/svnweb/index.cgi/biosql/view/biosql-schema/trunk/INSTALL">Official Guide</a> to accomplish these steps.
 Next step is to install these gems:</p>
 <ul>
 <li>ActiveRecord</li>
@@ -958,21 +959,22 @@ Next step is to install these gems:</p>
 <li>The layer to comunicate with you preferred RDBMS (postgresql, mysql, jdbcmysql in case you are running JRuby )</li>
 </ul>
 <p>You can find ActiveRecord's models in /bioruby/lib/bio/io/biosql</p>
-<p>When you have your database up and running, you can connect to it in this way:</p>
+<p>When you have your database up and running, you can connect to it like this:</p>
 <pre>#!/usr/bin/env ruby
 
 require 'bio'
 
 connection = Bio::SQL.establish_connection({'development'=>{'hostname'=>"YourHostname",
-                                               'database'=>"CoolBioSeqDB",
-                                               'adapter'=>"jdbcmysql", 
-                                               'username'=>"YourUser",
-                                               'password'=>"YouPassword"
-                                              }
-                              },
-                              'development')
+'database'=>"CoolBioSeqDB",
+'adapter'=>"jdbcmysql",
+'username'=>"YourUser",
+'password'=>"YouPassword"
+      }
+  },
+'development')
 
-#The first parameter is the hash contaning the description of the configuration similar to database.yml in Rails application, you can declare different environment. The second parameter is the environment to use: 'development', 'test', 'production'.
+#The first parameter is the hash contaning the description of the configuration; similar to database.yml in Rails applications, you can declare different environment. 
+#The second parameter is the environment to use: 'development', 'test', or 'production'.
 
 #To store a sequence into the database you simply need a biosequence object.
 biosql_database = Bio::SQL::Biodatabase.find(:first)
@@ -991,27 +993,28 @@ Bio::SQL.list_databases
 #retriving a generic accession
 bioseq = Bio::SQL.fetch_accession("YouAccession")
 
-#If you use biosequence objects, you will find all its method mapped to BioSQL sequences. But you can also access to the models directly:
+#If you use biosequence objects, you will find all its method mapped to BioSQL sequences. 
+#But you can also access to the models directly:
 
-#get the raw sequence associated with you accession
+#get the raw sequence associated with your accession
 bioseq.entry.biosequence 
 
-#get the length of your sequence, this is the explicit form of bioseq.length
+#get the length of your sequence; this is the explicit form of bioseq.length
 bioseq.entry.biosequence.length
 
-#convert the sequence in GenBank format
+#convert the sequence into GenBank format
 bioseq.to_biosequence.output(:genbank)</pre>
-<p>BioSQL' <a href="http://www.biosql.org/wiki/Schema_Overview">schema</a> is not so intuitive at the beginning, spend some time on understanding it, in the end if you know a little bit of rails everything will go smootly. You can find information to Annotation <a href="http://www.biosql.org/wiki/Annotation_Mapping">here</a>
+<p>BioSQL's <a href="http://www.biosql.org/wiki/Schema_Overview">schema</a> is not very intuitive for beginners, so spend some time on understanding it. In the end if you know a little bit of Ruby on Rails, everything will go smoothly. You can find information on Annotation <a href="http://www.biosql.org/wiki/Annotation_Mapping">here</a>.
 ToDo: add exemaples from George. I remember he did some cool post on BioSQL and Rails.</p>
 <h1><a name="label-23" id="label-23">PhyloXML</a></h1><!-- RDLabel: "PhyloXML" -->
 <p>PhyloXML is an XML language for saving, analyzing and exchanging data of 
-annotated phylogenetic trees. PhyloXML parser in BioRuby is implemented in 
-Bio::PhyloXML::Parser and writer in Bio::PhyloXML::Writer. 
-More information at www.phyloxml.org</p>
+annotated phylogenetic trees. PhyloXML's parser in BioRuby is implemented in 
+Bio::PhyloXML::Parser, and its writer in Bio::PhyloXML::Writer. 
+More information can be found at <a href="http://www.phyloxml.org">www.phyloxml.org</a>.</p>
 <h2><a name="label-24" id="label-24">Requirements</a></h2><!-- RDLabel: "Requirements" -->
-<p>In addition to BioRuby library you need a libxml ruby bindings. To install:</p>
+<p>In addition to BioRuby, you need the libxml Ruby bindings. To install, execute:</p>
 <pre>% gem install -r libxml-ruby</pre>
-<p>For more information see <a href="http://libxml.rubyforge.org/install.xml"><URL:http://libxml.rubyforge.org/install.xml></a></p>
+<p>For more information see the <a href="http://libxml.rubyforge.org/install.xml">libxml installer page</a></p>
 <h2><a name="label-25" id="label-25">Parsing a file</a></h2><!-- RDLabel: "Parsing a file" -->
 <pre>require 'bio'
 
@@ -1022,9 +1025,9 @@ phyloxml = Bio::PhyloXML::Parser.open('example.xml')
 phyloxml.each do |tree|
   puts tree.name
 end</pre>
-<p>If there are several trees in the file, you can access the one you wish by an index</p>
+<p>If there are several trees in the file, you can access the one you wish by specifying its index:</p>
 <pre>tree = phyloxml[3]</pre>
-<p>You can use all Bio::Tree methods on the tree, since PhyloXML::Tree inherits from Bio::Tree. For example,</p>
+<p>You can use all Bio::Tree methods on the tree, since PhyloXML::Tree inherits from Bio::Tree. For example, </p>
 <pre>tree.leaves.each do |node|
   puts node.name
 end</pre>
@@ -1045,7 +1048,7 @@ writer.write(tree1)
 # Add another tree to the file
 writer.write(tree2)</pre>
 <h2><a name="label-27" id="label-27">Retrieving data</a></h2><!-- RDLabel: "Retrieving data" -->
-<p>Here is an example of how to retrieve the scientific name of the clades.</p>
+<p>Here is an example of how to retrieve the scientific name of the clades included in each tree.</p>
 <pre>require 'bio'
 
 phyloxml = Bio::PhyloXML::Parser.open('ncbi_taxonomy_mollusca.xml')
@@ -1086,7 +1089,7 @@ end
 #aggtcgcggcctgtggaagtcctctcct
 #taaatcgc--cccgtgg-agtccc-cct</pre>
 <h2><a name="label-29" id="label-29">The BioRuby example programs</a></h2><!-- RDLabel: "The BioRuby example programs" -->
-<p>Some sample programs are stored in ./samples/ directory. Run for example:</p>
+<p>Some sample programs are stored in ./samples/ directory. For example, the n2aa.rb program (transforms a nucleic acid sequence into an amino acid sequence) can be run using:</p>
 <pre>./sample/na2aa.rb test/data/fasta/example1.txt </pre>
 <h2><a name="label-30" id="label-30">Unit testing and doctests</a></h2><!-- RDLabel: "Unit testing and doctests" -->
 <p>BioRuby comes with an extensive testing framework with over 1300 tests and 2700
@@ -1098,23 +1101,23 @@ in this tutorial to doctest - more info upcoming.</p>
 <h2><a name="label-31" id="label-31">Further reading</a></h2><!-- RDLabel: "Further reading" -->
 <p>See the BioRuby in anger Wiki.  A lot of BioRuby's documentation exists in the
 source code and unit tests. To really dive in you will need the latest source
-code tree. The embedded rdoc documentation can be viewed online at
+code tree. The embedded rdoc documentation for the BioRuby source code can be viewed online at
 <a href="http://bioruby.org/rdoc/"><URL:http://bioruby.org/rdoc/></a>.</p>
 <h2><a name="label-32" id="label-32">BioRuby Shell</a></h2><!-- RDLabel: "BioRuby Shell" -->
-<p>The BioRuby shell implementation you find in ./lib/bio/shell. It is very interesting
+<p>The BioRuby shell implementation is located in ./lib/bio/shell. It is very interesting
 as it uses IRB (the Ruby intepreter) which is a powerful environment described in
-<a href="http://ruby-doc.org/docs/ProgrammingRuby/html/irb.html">Programming Ruby's irb chapter</a>. IRB commands can directly be typed in the shell, e.g.</p>
+<a href="http://ruby-doc.org/docs/ProgrammingRuby/html/irb.html">Programming Ruby's IRB chapter</a>. IRB commands can be typed directly into the shell, e.g.</p>
 <pre>bioruby!> IRB.conf[:PROMPT_MODE]
 ==!> :PROMPT_C</pre>
-<p>optionally you also may want to install the optional Ruby readline support -
+<p>Additionally, you also may want to install the optional Ruby readline support -
 with Debian libreadline-ruby. To edit a previous line you may have to press
-line down (arrow down) first.</p>
+line down (down arrow) first.</p>
 <h1><a name="label-33" id="label-33">Helpful tools</a></h1><!-- RDLabel: "Helpful tools" -->
 <p>Apart from rdoc you may also want to use rtags - which allows jumping around
 source code by clicking on class and method names. </p>
 <pre>cd bioruby/lib
 rtags -R --vi</pre>
-<p>For a tutorial see <a href="http://rtags.rubyforge.org/"><URL:http://rtags.rubyforge.org/></a></p>
+<p>For a tutorial see <a href="http://rtags.rubyforge.org/">here</a></p>
 <h1><a name="label-34" id="label-34">APPENDIX</a></h1><!-- RDLabel: "APPENDIX" -->
 <h2><a name="label-35" id="label-35">KEGG API</a></h2><!-- RDLabel: "KEGG API" -->
 <p>Please refer to KEGG_API.rd.ja (English version: <a href="http://www.genome.jp/kegg/soap/doc/keggapi_manual.html"><URL:http://www.genome.jp/kegg/soap/doc/keggapi_manual.html></a> ) and</p>
@@ -1122,9 +1125,9 @@ rtags -R --vi</pre>
 <li><a href="http://www.genome.jp/kegg/soap/"><URL:http://www.genome.jp/kegg/soap/></a></li>
 </ul>
 <h2><a name="label-36" id="label-36">Ruby Ensembl API</a></h2><!-- RDLabel: "Ruby Ensembl API" -->
-<p>Ruby Ensembl API is a ruby API to the Ensembl database. It is NOT currently
+<p>The Ruby Ensembl API is a Ruby API to the Ensembl database. It is NOT currently
 included in the BioRuby archives. To install it, see
-<a href="http://wiki.github.com/jandot/ruby-ensembl-api"><URL:http://wiki.github.com/jandot/ruby-ensembl-api></a>
+<a href="http://wiki.github.com/jandot/ruby-ensembl-api">the Ruby-Ensembl Github</a>
 for more information.</p>
 <h3><a name="label-37" id="label-37">Gene Ontology (GO) through the Ruby Ensembl API</a></h3><!-- RDLabel: "Gene Ontology (GO) through the Ruby Ensembl API" -->
 <p>Gene Ontologies can be fetched through the Ruby Ensembl API package:</p>
@@ -1134,7 +1137,7 @@ infile = IO.readlines(ARGV.shift) # reading your comma-separated accession mappi
 infile.each do |line|
   accs = line.split(",")          # Split the comma-sep.entries into an array
   drosphila_acc = accs.shift      # the first entry is the Drosophila acc
-  mosq_acc = accs.shift           # the second entry is you Mosq. acc
+  mosq_acc = accs.shift           # the second entry is your Mosq. acc
   gene = Ensembl::Core::Gene.find_by_stable_id(drosophila_acc)
   print "#{mosq_acc}"
   gene.go_terms.each do |go|
@@ -1145,9 +1148,9 @@ end</pre>
 homologues.</p>
 <h2><a name="label-38" id="label-38">Using BioPerl or BioPython from Ruby</a></h2><!-- RDLabel: "Using BioPerl or BioPython from Ruby" -->
 <p>At the moment there is no easy way of accessing BioPerl from Ruby. The best way, perhaps, is to create a Perl server that gets accessed through XML/RPC or SOAP.</p>
-<h2><a name="label-39" id="label-39">Installing required external library</a></h2><!-- RDLabel: "Installing required external library" -->
+<h2><a name="label-39" id="label-39">Installing required external libraries</a></h2><!-- RDLabel: "Installing required external libraries" -->
 <p>At this point for using BioRuby no additional libraries are needed, except if
-you are using Bio::PhyloXML module. Then you have to install libxml-ruby.</p>
+you are using the Bio::PhyloXML module; then you have to install libxml-ruby.</p>
 <p>This may change, so keep an eye on the Bioruby website. Also when
 a package is missing BioRuby should show an informative message.</p>
 <p>At this point installing third party Ruby packages can be a bit
@@ -1155,16 +1158,16 @@ painful, as the gem standard for packages evolved late and some still
 force you to copy things by hand. Therefore read the README's
 carefully that come with each package.</p>
 <h3><a name="label-40" id="label-40">Installing libxml-ruby</a></h3><!-- RDLabel: "Installing libxml-ruby" -->
-<p>The simplest way is to use gem packaging system.</p>
+<p>The simplest way is to use the RubyGems packaging system:</p>
 <pre>gem install -r libxml-ruby</pre>
 <p>If you get `require': no such file to load - mkmf (LoadError) error then do</p>
 <pre>sudo apt-get install ruby-dev</pre>
-<p>If you have other problems with installation, then see <a href="http://libxml.rubyforge.org/install.xml"><URL:http://libxml.rubyforge.org/install.xml></a>  </p>
+<p>If you have other problems with installation, then see <a href="http://libxml.rubyforge.org/install.xml"><URL:http://libxml.rubyforge.org/install.xml></a>.</p>
 <h2><a name="label-41" id="label-41">Trouble shooting</a></h2><!-- RDLabel: "Trouble shooting" -->
 <ul>
 <li>Error: in `require': no such file to load -- bio (LoadError)</li>
 </ul>
-<p>Ruby fails to find the BioRuby libraries - add it to the RUBYLIB path, or pass
+<p>Ruby is failing to find the BioRuby libraries - add it to the RUBYLIB path, or pass
 it to the interpeter. For example:</p>
 <pre>ruby -I$BIORUBYPATH/lib yourprogram.rb</pre>
 <h2><a name="label-42" id="label-42">Modifying this page</a></h2><!-- RDLabel: "Modifying this page" -->
diff --git a/lib/bio.rb b/lib/bio.rb
index 81b8093..0ee0196 100644
--- a/lib/bio.rb
+++ b/lib/bio.rb
@@ -82,6 +82,7 @@ module Bio
   ## below are described in bio/db/genbank/ddbj.rb
   #class DDBJ
   #  autoload :XML,          'bio/io/ddbjxml'
+  #  autoload :REST,         'bio/io/ddbjrest'
   #end
 
   ## EMBL/TrEMBL/Swiss-Prot/SPTR
diff --git a/lib/bio/appl/blast.rb b/lib/bio/appl/blast.rb
index a65d016..bb1915d 100644
--- a/lib/bio/appl/blast.rb
+++ b/lib/bio/appl/blast.rb
@@ -30,7 +30,7 @@ module Bio
   #   
   #   # To run an actual BLAST analysis:
   #   #   1. create a BLAST factory
-  #   remote_blast_factory = Bio::Blast.remote('blastp', 'SWISS',
+  #   remote_blast_factory = Bio::Blast.remote('blastp', 'swissprot',
   #                                            '-e 0.0001', 'genomenet')
   #   #or:
   #   local_blast_factory = Bio::Blast.local('blastn','/path/to/db')
diff --git a/lib/bio/appl/blast/ddbj.rb b/lib/bio/appl/blast/ddbj.rb
index f938082..286abcb 100644
--- a/lib/bio/appl/blast/ddbj.rb
+++ b/lib/bio/appl/blast/ddbj.rb
@@ -8,7 +8,7 @@
 #
 
 require 'bio/appl/blast/remote'
-require 'bio/io/ddbjxml'
+require 'bio/io/ddbjrest'
 
 module Bio::Blast::Remote
 
@@ -37,32 +37,43 @@ module Bio::Blast::Remote
         if defined? @parse_databases
           return nil if @parse_databases
         end
-        drv = Bio::DDBJ::XML::Blast.new
+        drv = Bio::DDBJ::REST::Blast.new
         str = drv.getSupportDatabaseList
 
         databases = {}
         dbdescs = {}
-        key = 'blastn'
+        keys = [ 'blastn', 'blastp' ]
+        keys.each do |key|
+          databases[key] ||= []
+          dbdescs[key] ||= {}
+        end
         prefix = ''
-        databases[key] ||= []
-        dbdescs[key] ||= {}
+        prefix_count = 0
         str.each_line do |line|
           a = line.strip.split(/\s*\-\s*/, 2)
           case a.size
           when 1
             prefix = a[0].to_s.strip
             prefix += ': ' unless prefix.empty?
-            key = 'blastn'
+            prefix_count = 0
             next #each_line
           when 0
-            prefix = ''
-            key = 'blastp'
-            databases[key] ||= []
-            dbdescs[key] ||= {}
+            prefix = '' if prefix_count > 0
             next #each_line
           end
           name = a[0].to_s.strip.freeze
-          desc = (prefix + a[1].to_s.strip).freeze
+          desc = a[1].to_s.strip
+          key = case desc
+                when /\(NT\)\s*$/
+                  'blastn'
+                when /\(AA\)\s*$/
+                  'blastp'
+                else
+                  warn "DDBJ BLAST: could not determine the database is NT or AA: #{line.chomp}" if $VERBOSE
+                  next #each_line
+                end
+          desc = (prefix + desc).freeze
+          prefix_count += 1
           databases[key].push name
           dbdescs[key][name] = desc
         end
@@ -96,11 +107,9 @@ module Bio::Blast::Remote
       options = make_command_line_options
       opt = Bio::Blast::NCBIOptions.new(options)
 
-      # SOAP objects are cached
-      @ddbj_remote_blast ||= Bio::DDBJ::XML::Blast.new
-      #@ddbj_request_manager ||= Bio::DDBJ::XML::RequestManager.new
-      # always use REST version to prevent warning messages
-      @ddbj_request_manager ||= Bio::DDBJ::XML::RequestManager::REST.new
+      # REST objects are cached
+      @ddbj_remote_blast ||= Bio::DDBJ::REST::Blast.new
+      @ddbj_request_manager ||= Bio::DDBJ::REST::RequestManager.new
 
       program = opt.delete('-p')
       db = opt.delete('-d')
@@ -110,24 +119,7 @@ module Bio::Blast::Remote
       qid = @ddbj_remote_blast.searchParamAsync(program, db, query, optstr)
       @output = qid
 
-      sleeptime = 2
-      flag = true
-      while flag
-        if $VERBOSE then
-          $stderr.puts "DDBJ BLAST: ID: #{qid} -- waitng #{sleeptime} sec."
-        end
-        sleep(sleeptime)
-
-        result = @ddbj_request_manager.getAsyncResult(qid)
-        case result.to_s
-        when /The search and analysis service by WWW is very busy now/
-          raise result.to_s.strip + '(Alternatively, wrong options may be given.)'
-        when /Your job has not completed yet/
-          sleeptime = 5
-        else
-          flag = false
-        end
-      end while flag
+      result = @ddbj_request_manager.wait_getAsyncResult(qid)
 
       @output = result
       return @output
diff --git a/lib/bio/appl/blast/genomenet.rb b/lib/bio/appl/blast/genomenet.rb
index b8dc884..b27efb5 100644
--- a/lib/bio/appl/blast/genomenet.rb
+++ b/lib/bio/appl/blast/genomenet.rb
@@ -69,11 +69,11 @@ module Bio::Blast::Remote
   # 
   # * http://www.ncbi.nlm.nih.gov/blast/
   # * http://www.ncbi.nlm.nih.gov/Education/BLASTinfo/similarity.html
-  # * http://blast.genome.jp/ideas/ideas.html#blast
+  # * http://www.genome.jp/tools/blast/
   #
   module GenomeNet
 
-    Host = "blast.genome.jp".freeze
+    Host = "www.genome.jp".freeze
 
     # Creates a remote BLAST factory using GenomeNet.
     # Returns Bio::Blast object.
@@ -100,7 +100,7 @@ module Bio::Blast::Remote
         key = nil
         host = Bio::Blast::Remote::Genomenet::Host
         http = Bio::Command.new_http(host)
-        result = http.get('/')
+        result = http.get('/tools/blast/')
         #p result.body
         result.body.each_line do |line|
           case line
@@ -166,11 +166,20 @@ module Bio::Blast::Remote
       program = opt.delete('-p')
       db = opt.delete('-d')
 
+      # When database name starts with mine-aa or mine-nt,
+      # space-separated list of KEGG organism codes can be given.
+      # For example, "mine-aa eco bsu hsa".
+      if /\A(mine-(aa|nt))\s+/ =~ db.to_s then
+        db = $1
+        myspecies = {}
+        myspecies["myspecies-#{$2}"] = $'
+      end
+
       matrix = opt.delete('-M') || 'blosum62'
       filter = opt.delete('-F') || 'T'
 
-      opt_V = opt.delete('-V') || 500 # default value for GenomeNet
-      opt_B = opt.delete('-B') || 250 # default value for GenomeNet
+      opt_v = opt.delete('-v') || 500 # default value for GenomeNet
+      opt_b = opt.delete('-b') || 250 # default value for GenomeNet
 
       # format, not for form parameters, but included in option string
       opt_m = opt.get('-m') || '7' # default of BioRuby GenomeNet factory
@@ -186,11 +195,13 @@ module Bio::Blast::Remote
         'other_param'    => optstr,
         'matrix'         => matrix,
         'filter'         => filter,
-        'V_value'        => opt_V, 
-        'B_value'        => opt_B, 
+        'V_value'        => opt_v, 
+        'B_value'        => opt_b, 
         'alignment_view' => 0,
       }
 
+      form.merge!(myspecies) if myspecies
+
       form.keys.each do |k|
         form.delete(k) unless form[k]
       end
@@ -227,10 +238,9 @@ module Bio::Blast::Remote
           end
         end
 
-        # workaround 2005.08.12
-        if /\<A +HREF=\"(http\:\/\/blast\.genome\.jp(\/tmp\/[^\"]+))\"\>Show all result\<\/A\>/i =~ @output.to_s then
-          result = http.get($2)
-          @output = result.body
+        # workaround 2005.08.12 + 2011.01.27
+        if /\<A +HREF=\"(http\:\/\/[\-\.a-z0-9]+\.genome\.jp(\/tmp\/[^\"]+))\"\>Show all result\<\/A\>/i =~ @output.to_s then
+          @output = Bio::Command.read_uri($1)
           txt = @output.to_s.split(/\<pre\>/)[1]
           raise 'cannot understand response' unless txt
           txt.sub!(/\<\/pre\>.*\z/m, '')
diff --git a/lib/bio/db/embl/sptr.rb b/lib/bio/db/embl/sptr.rb
index 1a2e729..5109740 100644
--- a/lib/bio/db/embl/sptr.rb
+++ b/lib/bio/db/embl/sptr.rb
@@ -50,7 +50,18 @@ class SPTR < EMBLDB
   # returns a content (Int or String) of the ID line by a given key.
   # Hash keys: ['ENTRY_NAME', 'DATA_CLASS', 'MODECULE_TYPE', 'SEQUENCE_LENGTH']
   #
-  # === ID Line
+  # === ID Line (since UniProtKB release 9.0 of 31-Oct-2006)
+  #   ID   P53_HUMAN               Reviewed;         393 AA.
+  #   #"ID  #{ENTRY_NAME} #{DATA_CLASS}; #{SEQUENCE_LENGTH}."
+  #
+  # === Examples
+  #   obj.id_line  #=> {"ENTRY_NAME"=>"P53_HUMAN", "DATA_CLASS"=>"Reviewed", 
+  #                     "SEQUENCE_LENGTH"=>393, "MOLECULE_TYPE"=>nil}
+  #
+  #   obj.id_line('ENTRY_NAME') #=> "P53_HUMAN"
+  #
+  # 
+  # === ID Line (older style)
   #   ID   P53_HUMAN      STANDARD;      PRT;   393 AA.
   #   #"ID  #{ENTRY_NAME} #{DATA_CLASS}; #{MOLECULE_TYPE}; #{SEQUENCE_LENGTH}."
   #
@@ -65,11 +76,20 @@ class SPTR < EMBLDB
     return @data['ID'] if @data['ID']
 
     part = @orig['ID'].split(/ +/)         
+    if part[4].to_s.chomp == 'AA.' then
+      # after UniProtKB release 9.0 of 31-Oct-2006
+      # (http://www.uniprot.org/docs/sp_news.htm)
+      molecule_type   = nil
+      sequence_length = part[3].to_i
+    else
+      molecule_type   = part[3].sub(/;/,'')
+      sequence_length = part[4].to_i
+    end
     @data['ID'] = {
       'ENTRY_NAME'      => part[1],
       'DATA_CLASS'      => part[2].sub(/;/,''),
-      'MOLECULE_TYPE'   => part[3].sub(/;/,''),
-      'SEQUENCE_LENGTH' => part[4].to_i 
+      'MOLECULE_TYPE'   => molecule_type,
+      'SEQUENCE_LENGTH' => sequence_length
     }
   end
 
@@ -111,12 +131,27 @@ class SPTR < EMBLDB
   # returns a Hash of information in the DT lines.
   #  hash keys: 
   #    ['created', 'sequence', 'annotation']
+  #--
   #  also Symbols acceptable (ASAP):
   #    [:created, :sequence, :annotation]
+  #++
   #
-  # returns a String of information in the DT lines by a given key..
+  # Since UniProtKB release 7.0 of 07-Feb-2006, the DT line format is
+  # changed, and the word "annotation" is no longer used in DT lines.
+  # Despite the change, the word "annotation" is still used for keeping
+  # compatibility.
+  #
+  # returns a String of information in the DT lines by a given key.
   #
   # === DT Line; date (3/entry)
+  #   DT DD-MMM-YYY (integrated into UniProtKB/XXXXX.)
+  #   DT DD-MMM-YYY (sequence version NN)
+  #   DT DD-MMM-YYY (entry version NN)
+  #
+  # The format have been changed in UniProtKB release 7.0 of 07-Feb-2006.
+  # Below is the older format.
+  #
+  # === Old format of DT Line; date (3/entry)
   #   DT DD-MMM-YYY (rel. NN, Created)
   #   DT DD-MMM-YYY (rel. NN, Last sequence update)
   #   DT DD-MMM-YYY (rel. NN, Last annotation update)
@@ -133,7 +168,79 @@ class SPTR < EMBLDB
   end
 
 
+  # (private) parses DE line (description lines)
+  # since UniProtKB release 14.0 of 22-Jul-2008
+  #
+  # Return array containing array.
+  #
+  # http://www.uniprot.org/docs/sp_news.htm
+  def parse_DE_line_rel14(str)
+    # Retruns if it is not the new format since Rel.14
+    return nil unless /^DE   (RecName|AltName|SubName)\: / =~ str
+    ret = []
+    cur = nil
+    str.each_line do |line|
+      case line
+      when /^DE   (Includes|Contains)\: *$/
+        cur = [ $1 ]
+        ret.push cur
+        cur = nil
+        #subcat_and_desc = nil
+        next
+      when /^DE   *(RecName|AltName|SubName)\: +(.*)/
+        category = $1
+        subcat_and_desc = $2
+        cur = [ category ]
+        ret.push cur
+      when /^DE   *(Flags)\: +(.*)/
+        category = $1
+        desc = $2
+        flags = desc.strip.split(/\s*\;\s*/) || []
+        cur = [ category, flags ]
+        ret.push cur
+        cur = nil
+        #subcat_and_desc = nil
+        next
+      when /^DE   *(.*)/
+        subcat_and_desc = $1
+      else
+        warn "Warning: skipped DE line in unknown format: #{line.inspect}"
+        #subcat_and_desc = nil
+        next
+      end
+      case subcat_and_desc
+      when nil
+        # does nothing
+      when /\A([^\=]+)\=(.*)/
+        subcat = $1
+        desc = $2
+        desc.sub!(/\;\s*\z/, '')
+        unless cur
+          warn "Warning: unknown category in DE line: #{line.inspect}"
+          cur = [ '' ]
+          ret.push cur
+        end
+        cur.push [ subcat, desc ]
+      else
+        warn "Warning: skipped DE line description in unknown format: #{line.inspect}"
+      end
+    end
+    ret
+  end
+  private :parse_DE_line_rel14
+
   # returns the proposed official name of the protein.
+  # Returns a String.
+  #
+  # Since UniProtKB release 14.0 of 22-Jul-2008, the DE line format have
+  # been changed. The method returns the full name which is taken from
+  # "RecName: Full=" or "SubName: Full=" line normally in the beginning of
+  # the DE lines. 
+  # Unlike parser for old format, no special treatments for fragment or
+  # precursor.
+  #
+  # For old format, the method parses the DE lines and returns the protein
+  # name as a String.
   # 
   # === DE Line; description (>=1)
   #  "DE #{OFFICIAL_NAME} (#{SYNONYM})"
@@ -142,27 +249,83 @@ class SPTR < EMBLDB
   #  SYNONYM        >=0
   #  CONTEINS       >=0
   def protein_name
-    name = ""
-    if de_line = fetch('DE') then
-      str = de_line[/^[^\[]*/] # everything preceding the first [ (the "contains" part)
-      name = str[/^[^(]*/].strip
-      name << ' (Fragment)' if str =~ /fragment/i
+    @data['DE'] ||= parse_DE_line_rel14(get('DE'))
+    parsed_de_line = @data['DE']
+    if parsed_de_line then
+      # since UniProtKB release 14.0 of 22-Jul-2008
+      name = nil
+      parsed_de_line.each do |a|
+        case a[0]
+        when 'RecName', 'SubName'
+          if name_pair = a[1..-1].find { |b| b[0] == 'Full' } then
+            name = name_pair[1]
+            break
+          end
+        end
+      end
+      name = name.to_s
+    else
+      # old format (before Rel. 13.x)
+      name = ""
+      if de_line = fetch('DE') then
+        str = de_line[/^[^\[]*/] # everything preceding the first [ (the "contains" part)
+        name = str[/^[^(]*/].strip
+        name << ' (Fragment)' if str =~ /fragment/i
+      end
     end
     return name
   end
 
 
-  # returns an array of synonyms (unofficial names).
+  # returns synonyms (unofficial and/or alternative names).
+  # Returns an Array containing String objects.
+  #
+  # Since UniProtKB release 14.0 of 22-Jul-2008, the DE line format have
+  # been changed. The method returns the full or short names which are
+  # taken from "RecName: Short=", "RecName: EC=", and AltName lines,
+  # except after "Contains:" or "Includes:".
+  # For keeping compatibility with old format parser, "RecName: EC=N.N.N.N"
+  # is reported as "EC N.N.N.N".
+  # In addition, to prevent confusion, "Allergen=" and "CD_antigen=" 
+  # prefixes are added for the corresponding fields.
   #
+  # For old format, the method parses the DE lines and returns synonyms.
   # synonyms are each placed in () following the official name on the DE line.
   def synonyms
     ary = Array.new
-    if de_line = fetch('DE') then
-      line = de_line.sub(/\[.*\]/,'') # ignore stuff between [ and ].  That's the "contains" part
+    @data['DE'] ||= parse_DE_line_rel14(get('DE'))
+    parsed_de_line = @data['DE']
+    if parsed_de_line then
+      # since UniProtKB release 14.0 of 22-Jul-2008
+      parsed_de_line.each do |a|
+        case a[0]
+        when 'Includes', 'Contains'
+          break #the each loop
+        when 'RecName', 'SubName', 'AltName'
+          a[1..-1].each do |b|
+            if name = b[1] and b[1] != self.protein_name then
+              case b[0]
+              when 'EC'
+                name = "EC " + b[1]
+              when 'Allergen', 'CD_antigen'
+                name = b[0] + '=' + b[1]
+              else
+                name = b[1]
+              end
+              ary.push name
+            end
+          end
+        end #case a[0]
+      end #parsed_de_line.each
+    else
+      # old format (before Rel. 13.x)
+      if de_line = fetch('DE') then
+        line = de_line.sub(/\[.*\]/,'') # ignore stuff between [ and ].  That's the "contains" part
       line.scan(/\([^)]+/) do |synonym| 
         unless synonym =~ /fragment/i then 
           ary << synonym[1..-1].strip # index to remove the leading (  
         end
+        end
       end
     end
     return ary
@@ -919,25 +1082,34 @@ class SPTR < EMBLDB
   end
   private :cc_subcellular_location
 
-  
-  # CC   -!- WEB RESOURCE: NAME=ResourceName[; NOTE=FreeText][; URL=WWWAddress].  
+
+  #--
+  # Since UniProtKB release 12.2 of 11-Sep-2007:
+  # CC   -!- WEB RESOURCE: Name=ResourceName[; Note=FreeText][; URL=WWWAddress].  # Old format:
+  # CC   -!- WEB RESOURCE: NAME=ResourceName[; NOTE=FreeText][; URL=WWWAddress].
+  #++
+
   def cc_web_resource(data)
     data.map {|x|
-      entry = {'NAME' => nil, 'NOTE' => nil, 'URL' => nil}
+      entry = {'Name' => nil, 'Note' => nil, 'URL' => nil}
       x.split(';').each do |y|
         case y
-        when /NAME=(.+)/
-          entry['NAME'] = $1.strip
-        when /NOTE=(.+)/
-          entry['NOTE'] = $1.strip
-        when /URL="(.+)"/
+        when /(Name|Note)\=(.+)/
+          key = $1
+          val = $2.strip
+          entry[key] = val
+        when /(NAME|NOTE)\=(.+)/
+          key = $1.downcase.capitalize
+          val = $2.strip
+          entry[key] = val
+        when /URL\=\"(.+)\"/
           entry['URL'] = $1.strip
         end
       end
       entry
     }
   end
-  
+  private :cc_web_resource
 
   # returns databases cross-references in the DR lines.
   # * Bio::SPTR#dr  -> Hash w/in Array
diff --git a/lib/bio/db/fasta.rb b/lib/bio/db/fasta.rb
index 7ea668e..2f9befe 100644
--- a/lib/bio/db/fasta.rb
+++ b/lib/bio/db/fasta.rb
@@ -148,7 +148,7 @@ module Bio
     #   end
     #
     def query(factory)
-      factory.query(@entry)
+      factory.query(entry)
     end
     alias fasta query
     alias blast query
diff --git a/lib/bio/db/fastq.rb b/lib/bio/db/fastq.rb
index f913e6d..5f453c2 100644
--- a/lib/bio/db/fastq.rb
+++ b/lib/bio/db/fastq.rb
@@ -407,6 +407,20 @@ class Fastq
   # raw sequence data as a String object
   attr_reader :sequence_string
 
+  # Returns Fastq formatted string constructed from instance variables.
+  # The string will always be consisted of four lines without wrapping of
+  # the sequence and quality string, and the third-line is always only
+  # contains "+". This may be different from initial entry.
+  #
+  # Note that use of the method may be inefficient and may lose performance
+  # because new string object is created every time it is called.
+  # For showing an entry as-is, consider using Bio::FlatFile#entry_raw.
+  # For output with various options, use Bio::Sequence#output(:fastq).
+  #
+  def to_s
+    "@#{@definition}\n#{@sequence_string}\n+\n#{@quality_string}\n"
+  end
+
   # returns Bio::Sequence::NA
   def naseq
     unless defined? @naseq then
diff --git a/lib/bio/db/fastq/format_fastq.rb b/lib/bio/db/fastq/format_fastq.rb
index 520b37a..10bf235 100644
--- a/lib/bio/db/fastq/format_fastq.rb
+++ b/lib/bio/db/fastq/format_fastq.rb
@@ -26,7 +26,7 @@ module Bio::Sequence::Format::Formatter
     # *Arguments*:
     # * _sequence_: Bio::Sequence object
     # * (optional) :repeat_title => (true or false) if true, repeating title in the "+" line; if not true, "+" only (default false)
-    # * (optional) :width => _width_: (Fixnum) width to wrap sequence and quality lines;  nil to prevent wrapping (default 70)
+    # * (optional) :width => _width_: (Fixnum) width to wrap sequence and quality lines;  nil to prevent wrapping (default nil)
     # * (optional) :title => _title_: (String) completely replaces title line with the _title_ (default nil)
     # * (optional) :default_score => _score_: (Integer) default score for bases that have no valid quality scores or error probabilities; false or nil means the lowest score, true means the highest score (default nil)
     def initialize; end if false # dummy for RDoc
@@ -43,7 +43,7 @@ module Bio::Sequence::Format::Formatter
     # *Returns*:: String object
     def output
       title = @options[:title]
-      width = @options.has_key?(:width) ? @options[:width] : 70
+      width = @options.has_key?(:width) ? @options[:width] : nil
       seq = @sequence.seq.to_s
       entry_id = @sequence.entry_id || 
         "#{@sequence.primary_accession}.#{@sequence.sequence_version}"
diff --git a/lib/bio/db/genbank/ddbj.rb b/lib/bio/db/genbank/ddbj.rb
index 84fa703..2db0502 100644
--- a/lib/bio/db/genbank/ddbj.rb
+++ b/lib/bio/db/genbank/ddbj.rb
@@ -4,8 +4,6 @@
 # Copyright::  Copyright (C) 2000-2004 Toshiaki Katayama <k at bioruby.org>
 # License::    The Ruby License
 #
-# $Id: ddbj.rb,v 1.9 2007/04/05 23:35:40 trevor Exp $
-#
 
 require 'bio/db/genbank/genbank'
 
@@ -14,6 +12,7 @@ module Bio
 class DDBJ < GenBank
 
   autoload :XML,          'bio/io/ddbjxml'
+  autoload :REST,         'bio/io/ddbjrest'
 
   # Nothing to do (DDBJ database format is completely same as GenBank)
 
diff --git a/lib/bio/db/genbank/format_genbank.rb b/lib/bio/db/genbank/format_genbank.rb
index 80bed74..1fc6cb5 100644
--- a/lib/bio/db/genbank/format_genbank.rb
+++ b/lib/bio/db/genbank/format_genbank.rb
@@ -125,7 +125,7 @@ __END_OF_REFERENCE__
 
     # formats date
     def date_format_genbank
-      date_modified || date_created || null_date
+      format_date(date_modified || date_created || null_date)
     end
 
     # moleculue type
diff --git a/lib/bio/db/medline.rb b/lib/bio/db/medline.rb
index 09235ac..3ee9008 100644
--- a/lib/bio/db/medline.rb
+++ b/lib/bio/db/medline.rb
@@ -58,6 +58,7 @@ class MEDLINE < NCBIDB
     hash['medline']  	= ui
     hash['abstract']	= abstract
     hash['mesh']	= mesh
+    hash['doi']	= doi
     hash['affiliations'] = affiliations
 
     hash.delete_if { |k, v| v.nil? or v.empty? }
diff --git a/lib/bio/db/newick.rb b/lib/bio/db/newick.rb
index c30c668..9b3a142 100644
--- a/lib/bio/db/newick.rb
+++ b/lib/bio/db/newick.rb
@@ -343,7 +343,9 @@ module Bio
     # Returns self.
     # This method is useful after changing parser options.
     def reparse
-      remove_instance_variable(:tree)
+      if defined?(@tree)
+        remove_instance_variable(:@tree)
+      end
       self.tree
       self
     end
diff --git a/lib/bio/db/pdb/pdb.rb b/lib/bio/db/pdb/pdb.rb
index 1b69adc..b05f208 100644
--- a/lib/bio/db/pdb/pdb.rb
+++ b/lib/bio/db/pdb/pdb.rb
@@ -6,7 +6,7 @@
 #             Alex Gutteridge <alexg at ebi.ac.uk>
 # License::   The Ruby License
 #
-#  $Id: pdb.rb,v 1.28 2008/04/01 10:36:44 ngoto Exp $
+#  $Id:$
 #
 # = About Bio::PDB
 #
@@ -339,18 +339,18 @@ module Bio
       #
       def do_parse
         return self if @parsed or !@str
-        str = @str
+        str0 = @str
         each_symbol do |key, klass, ranges|
           #If we only have one range then pull that out
           #and store it in the hash
           if ranges.size <= 1 then
-            self[key] = klass.new(str[ranges.first])
+            self[key] = klass.new(str0[ranges.first])
           else
             #Go through each range and add the string to an array
             #set the hash key to point to that array
             ary = []
             ranges.each do |r|
-              ary << klass.new(str[r]) unless str[r].to_s.strip.empty?
+              ary << klass.new(str0[r]) unless str0[r].to_s.strip.empty?
             end
             self[key] = ary
           end
@@ -362,10 +362,10 @@ module Bio
             each_symbol do |key, klass, ranges|
               #If there's one range then grab that range
               if ranges.size <= 1 then
-                r = ranges.first
-                unless str[r].to_s.strip.empty?
+                r1 = ranges.first
+                unless str[r1].to_s.strip.empty?
                   #and concatenate the new data onto the old
-                  v = klass.new(str[r])
+                  v = klass.new(str[r1])
                   self[key].concat(v) if self[key] != v
                 end
               else
@@ -1820,14 +1820,14 @@ module Bio
                  nil
                end || 'X')
             end
-            seq = Bio::Sequence::AA.new(a.to_s)
+            seq = Bio::Sequence::AA.new(a.join(''))
           else
             # nucleic acid sequence
             a.collect! do |na|
               na = na.delete('^a-zA-Z')
               na.size == 1 ? na : 'n'
             end
-            seq = Bio::Sequence::NA.new(a.to_s)
+            seq = Bio::Sequence::NA.new(a.join(''))
           end
           newHash[k] = seq
         end
diff --git a/lib/bio/db/pdb/residue.rb b/lib/bio/db/pdb/residue.rb
index 9f428b6..e8b7b37 100644
--- a/lib/bio/db/pdb/residue.rb
+++ b/lib/bio/db/pdb/residue.rb
@@ -6,7 +6,7 @@
 #              Naohisa Goto <ng at bioruby.org>
 # License::    The Ruby License
 #
-# $Id: residue.rb,v 1.14 2007/12/18 13:48:42 ngoto Exp $
+# $Id:$
 #
 # = Bio::PDB::Residue
 #
@@ -67,7 +67,7 @@ module Bio
 
       #Keyed access to atoms based on atom name e.g. ["CA"]
       def [](key)
-        atom = @atoms.find{ |atom| key == atom.name }
+        @atoms.find{ |atom| key == atom.name }
       end
 
       # Updates residue id. This is a private method.
diff --git a/lib/bio/io/ddbjrest.rb b/lib/bio/io/ddbjrest.rb
new file mode 100644
index 0000000..b413d64
--- /dev/null
+++ b/lib/bio/io/ddbjrest.rb
@@ -0,0 +1,344 @@
+#
+# = bio/io/ddbjrest.rb - DDBJ Web API for Biology (WABI) access class via REST
+#
+# Copyright::	Copyright (C) 2011
+#		Naohisa Goto <ng at bioruby.org>
+# License::	The Ruby License
+#
+# == Description
+# 
+# This file contains Bio::DDBJ::REST, DDBJ Web API for Biology (WABI) access
+# classes via REST (Representational State Transfer) protocol.
+#
+# == References
+#
+# * http://xml.nig.ac.jp/
+#
+
+require 'bio/command'
+require 'bio/db/genbank/ddbj'
+
+module Bio
+class DDBJ
+
+  # == Description
+  #
+  # The module Bio::DDBJ::REST is the namespace for the DDBJ Web API for
+  # Biology (WABI) via REST protocol. Under the Bio::DDBJ::REST,
+  # following classes are available.
+  #
+  # * Bio::DDBJ::REST::DDBJ
+  # * Bio::DDBJ::REST::Blast
+  # * Bio::DDBJ::REST::ClustalW
+  # * Bio::DDBJ::REST::Mafft
+  # * Bio::DDBJ::REST::RequestManager
+  #
+  # Following classes are NOT available, but will be written in the future.
+  #
+  # * Bio::DDBJ::REST::GetEntry
+  # * Bio::DDBJ::REST::ARSA
+  # * Bio::DDBJ::REST::VecScreen
+  # * Bio::DDBJ::REST::PhylogeneticTree
+  # * Bio::DDBJ::REST::Gib
+  # * Bio::DDBJ::REST::Gtop
+  # * Bio::DDBJ::REST::GTPS
+  # * Bio::DDBJ::REST::GIBV
+  # * Bio::DDBJ::REST::GIBIS
+  # * Bio::DDBJ::REST::SPS
+  # * Bio::DDBJ::REST::TxSearch
+  # * Bio::DDBJ::REST::Ensembl
+  # * Bio::DDBJ::REST::NCBIGenomeAnnotation
+  #
+  # Read the document of each class for details.
+  #
+  # In addition, there is a private class Bio::DDBJ::REST::WABItemplate,
+  # basic class for the above classes. Normal users should not use the
+  # WABItemplate class directly.
+  #
+  module REST
+
+    # Bio::DDBJ::REST::WABItemplate is a private class to provide common
+    # methods to access DDBJ Web API for Biology (WABI) services by using
+    # REST protocol.
+    #
+    # Normal users should not use the class directly.
+    #
+    class WABItemplate
+
+      # hostname for the WABI service
+      WABI_HOST = 'xml.nig.ac.jp'
+
+      # path for the WABI service
+      WABI_PATH = '/rest/Invoke'
+
+      private
+
+      # Creates a new object.
+      def initialize
+        @http = Bio::Command.new_http(WABI_HOST)
+        @service = self.class.to_s.split(/\:\:/)[-1]
+      end
+
+      # (private) query to the service by using POST method
+      def _wabi_post(method_name, param)
+        parameters = {
+          'service' => @service,
+          'method' => method_name
+        }
+        parameters.update(param)
+        #$stderr.puts parameters.inspect
+        r = Bio::Command.http_post_form(@http, WABI_PATH, parameters)
+        #$stderr.puts r.inspect
+        #$stderr.puts "-"*78
+        #$stderr.puts r.body
+        #$stderr.puts "-"*78
+        r.body
+      end
+
+      def self.define_wabi_method(array,
+                                  ruby_method_name = nil,
+                                  public_method_name = nil)
+        wabi_method_name = array[0]
+        ruby_method_name ||= wabi_method_name
+        public_method_name ||= wabi_method_name
+        arg = array[1..-1]
+        arguments = arg.join(', ')
+        parameters = "{" +
+          arg.collect { |x| "#{x.dump} => #{x}" }.join(", ") + "}"
+        module_eval "def #{ruby_method_name}(#{arguments})
+                       param = #{parameters}
+                       _wabi_post(#{wabi_method_name.dump}, param)
+                     end
+                     def self.#{public_method_name}(#{arguments})
+                       self.new.#{public_method_name}(#{arguments})
+                     end"
+        self
+      end
+      private_class_method :define_wabi_method
+
+      def self.def_wabi(array)
+        define_wabi_method(array)
+      end
+      private_class_method :def_wabi
+
+      def self.def_wabi_custom(array)
+        ruby_method_name = '_' + array[0]
+        define_wabi_method(array, ruby_method_name)
+        module_eval "private :#{ruby_method_name}"
+        self
+      end
+      private_class_method :def_wabi_custom
+
+      def self.def_wabi_async(array)
+        m = array[0]
+        def_wabi_custom(array)
+        module_eval "def #{m}(*arg)
+            ret = _#{m}(*arg)
+            if /Your +requestId +is\s*\:\s*(.+)\s*/i =~ ret.to_s then
+              return $1
+            else
+              raise \"unknown return value: \#\{ret.inspect\}\"
+            end
+          end"
+        self
+      end
+      private_class_method :def_wabi_async
+    end #class WABItemplate
+
+    # === Description
+    #
+    # DDBJ (DNA DataBank of Japan) entry retrieval functions.
+    #
+    # * http://xml.nig.ac.jp/wabi/Method?serviceName=DDBJ&mode=methodList&lang=en
+    #
+    # === Examples
+    #
+    # see http://xml.nig.ac.jp/wabi/Method?serviceName=DDBJ&mode=methodList&lang=en
+    #
+    class DDBJ < WABItemplate
+
+      # Number and ratio of each base such as A,T,G,C.
+      #
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=countBasePair&mode=methodDetail
+      # ---
+      # *Arguments*:
+      # * (required) _accession_: (String) accession
+      # *Returns*:: (String) tab-deliminated text
+      def countBasePair(accession); end if false #dummy
+      def_wabi %w( countBasePair accession )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=get&mode=methodDetail
+      def get(accessionList, paramList); end if false #dummy
+      def_wabi %w( get accessionList paramList )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=getAllFeatures&mode=methodDetail
+      def getAllFeatures(accession); end if false #dummy
+      def_wabi %w( getAllFeatures accession )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=getFFEntry&mode=methodDetail
+      def getFFEntry(accession); end if false #dummy
+      def_wabi %w( getFFEntry accession )
+
+      # http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=getRelatedFeatures&mode=methodDetail
+      def getRelatedFeatures(accession, start, stop); end if false #dummy
+      def_wabi %w( getRelatedFeatures accession start stop )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=DDBJ&methodName=getRelatedFeaturesSeq&mode=methodDetail
+      def getRelatedFeaturesSeq(accession, start, stop); end if false #dummy
+      def_wabi %w( getRelatedFeaturesSeq accession start stop )
+    end #class DDBJ
+
+    # === Description
+    #
+    # DDBJ (DNA DataBank of Japan) BLAST web service.
+    # See below for details and examples.
+    #
+    # Users normally would want to use searchParamAsync or
+    # searchParallelAsync with RequestManager.
+    #
+    # * http://xml.nig.ac.jp/wabi/Method?serviceName=Blast&mode=methodList&lang=en
+    class Blast < WABItemplate
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=extractPosition&mode=methodDetail
+      def extractPosition(result); end if false #dummy
+      def_wabi %w( extractPosition result )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=getSupportDatabaseList&mode=methodDetail
+      def getSupportDatabaseList(); end if false #dummy
+      def_wabi %w( getSupportDatabaseList )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchParallel&mode=methodDetail
+      def searchParallel(program, database, query, param); end if false #dummy
+      def_wabi %w( searchParallel program database query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchParallelAsync&mode=methodDetail
+      def searchParallelAsync(program, database,
+                              query, param); end if false #dummy
+      def_wabi_async %w( searchParallelAsync program database query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchParam&mode=methodDetail
+      def searchParam(program, database, query, param); end if false #dummy
+      def_wabi %w( searchParam program database query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchParamAsync&mode=methodDetail
+      def searchParamAsync(program, database,
+                           query, param); end if false #dummy
+      def_wabi_async %w( searchParamAsync program database query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchSimple&mode=methodDetail
+      def searchSimple(program, database, query); end if false #dummy
+      def_wabi %w( searchSimple program database query )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Blast&methodName=searchSimpleAsync&mode=methodDetail
+      def searchSimpleAsync(program, database, query); end if false #dummy
+      def_wabi_async %w( searchSimpleAsync program database query )
+
+    end #class Blast
+
+    # === Description
+    #
+    # DDBJ (DNA DataBank of Japan) web service of ClustalW multiple sequence
+    # alignment software.
+    # See below for details and examples.
+    #
+    # * http://xml.nig.ac.jp/wabi/Method?serviceName=ClustalW&mode=methodList&lang=en
+    class ClustalW < WABItemplate
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=ClustalW&methodName=analyzeParam&mode=methodDetail
+      def analyzeParam(query, param); end if false #dummy
+      def_wabi %w( analyzeParam query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=ClustalW&methodName=analyzeParamAsync&mode=methodDetail
+      def analyzeParamAsync(query, param); end if false #dummy
+      def_wabi_async %w( analyzeParamAsync query param )
+
+      # http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=ClustalW&methodName=analyzeSimple&mode=methodDetail
+      def analyzeSimple(query); end if false #dummy
+      def_wabi %w( analyzeSimple query )
+
+      # http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=ClustalW&methodName=analyzeSimpleAsync&mode=methodDetail
+      def analyzeSimpleAsync(query); end if false #dummy
+      def_wabi_async %w( analyzeSimpleAsync query )
+    end #lcass ClustalW
+
+    # === Description
+    #
+    # DDBJ (DNA DataBank of Japan) web service of MAFFT multiple sequence
+    # alignment software.
+    # See below for details and examples.
+    #
+    # * http://xml.nig.ac.jp/wabi/Method?serviceName=Mafft&mode=methodList&lang=en
+    class Mafft < WABItemplate
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Mafft&methodName=analyzeParam&mode=methodDetail
+      def analyzeParam(query, param); end if false #dummy
+      def_wabi %w( analyzeParam query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Mafft&methodName=analyzeParamAsync&mode=methodDetail
+      def analyzeParamAsync(query, param); end if false #dummy
+      def_wabi_async %w( analyzeParamAsync query param )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Mafft&methodName=analyzeSimple&mode=methodDetail
+      def analyzeSimple(query); end if false #dummy
+      def_wabi %w( analyzeSimple query )
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=Mafft&methodName=analyzeSimpleAsync&mode=methodDetail
+      def analyzeSimpleAsync(query); end if false #dummy
+      def_wabi_async %w( analyzeSimpleAsync query )
+    end #lcass Mafft
+
+
+    # === Description
+    #
+    # DDBJ (DNA DataBank of Japan) special web service to get result of
+    # asynchronous web service.
+    # See below for details and examples.
+    #
+    # * http://xml.nig.ac.jp/wabi/Method?serviceName=RequestManager&mode=methodList&lang=en
+    class RequestManager < WABItemplate
+
+      # see http://xml.nig.ac.jp/wabi/Method?&lang=en&serviceName=RequestManager&methodName=getAsyncResult&mode=methodDetail
+      def getAsyncResult(requestId); end if false #dummy
+      def_wabi %w( getAsyncResult requestId )
+
+      # Waits until the query is finished and the result is returnd,
+      # with calling getAsyncResult.
+      # 
+      # This is BioRuby original method.
+      # ---
+      # *Arguments*:
+      # * (required) _requestID_: (String) requestId
+      # *Returns*:: (String) result
+      def wait_getAsyncResult(requestId)
+        sleeptime = 2
+        while true
+          result = getAsyncResult(requestId)
+          case result.to_s
+          when /The search and analysis service by WWW is very busy now/
+            raise result.to_s.strip + '(Alternatively, wrong options may be given.)'
+          when /\AYour job has not (?:been )?completed yet/
+            sleeptime = 2 + rand(4)
+          when /\AERROR:/
+            raise result.to_s.strip
+          else
+            return result
+          end #case
+          if $VERBOSE then
+            $stderr.puts "DDBJ REST: requestId: #{requestId} -- waitng #{sleeptime} sec."
+          end
+          sleep(sleeptime)
+        end
+        # will never be reached here
+        raise "Bug?"
+      end
+
+      # the same as Bio::DDBJ::REST::RequestManager#wait_getAsyncResult
+      def self.wait_getAsyncResult(requestId)
+        self.new.wait_getAsyncResult(requestId)
+      end
+
+    end #class RequestManager
+
+  end #module REST
+end #class DDBJ
+end #module Bio
+
+
diff --git a/lib/bio/io/ncbirest.rb b/lib/bio/io/ncbirest.rb
index fa6103f..35443bd 100644
--- a/lib/bio/io/ncbirest.rb
+++ b/lib/bio/io/ncbirest.rb
@@ -127,6 +127,7 @@ class REST
   def ncbi_post_form(serv, opts)
     ncbi_check_parameters(opts)
     ncbi_access_wait
+    #$stderr.puts opts.inspect
     response = Bio::Command.post_form(serv, opts)
     response
   end
@@ -485,7 +486,7 @@ class REST
       #  nucleotide = nuccore + nucest + nucgss
       #
       # format (rettype):
-      # * native       all but Gene    Default format for viewing sequences
+      # * native       all but Gene    ASN Default format for viewing sequences
       # * fasta        all sequence    FASTA view of a sequence
       # * gb           NA sequence     GenBank view for sequences
       # * gbc          NA sequence     INSDSeq structured flat file
@@ -540,6 +541,125 @@ class REST
         Bio::NCBI::REST.efetch(ids, opts)
       end
 
+      # Retrieve nucleotide sequence entries by given IDs using E-Utils
+      # (efetch).
+      #
+      # * http://eutils.ncbi.nlm.nih.gov/entrez/query/static/efetchseq_help.html
+      #  nucleotide = nuccore + nucest + nucgss
+      #
+      # format (rettype):
+      # * native       all but Gene    ASN Default format for viewing sequences
+      # * fasta        all sequence    FASTA view of a sequence
+      # * gb           NA sequence     GenBank view for sequences
+      # * gbc          NA sequence     INSDSeq structured flat file
+      # * gbwithparts  NA sequence     GenBank CON division with sequences
+      # * est          dbEST sequence  EST Report
+      # * gss          dbGSS sequence  GSS Report
+      # * gp           AA sequence     GenPept view
+      # * gpc          AA sequence     INSDSeq structured flat file
+      # * seqid        all sequence    Convert GIs into seqids
+      # * acc          all sequence    Convert GIs into accessions
+      # * chr          dbSNP only      SNP Chromosome Report
+      # * flt          dbSNP only      SNP Flat File report
+      # * rsr          dbSNP only      SNP RS Cluster report
+      # * brief        dbSNP only      SNP ID list
+      # * docset       dbSNP only      SNP RS summary
+      #
+      # == Usage
+      #
+      #  Bio::NCBI::REST::EFetch.nucleotide("123,U12345,U12345.1,gb|U12345|")
+      #
+      #  list = [123, "U12345.1", "gb|U12345|"]
+      #  Bio::NCBI::REST::EFetch.nucleotide(list)
+      #  Bio::NCBI::REST::EFetch.nucleotide(list, "fasta")
+      #  Bio::NCBI::REST::EFetch.nucleotide(list, "acc")
+      #  Bio::NCBI::REST::EFetch.nucleotide(list, "xml")
+      #
+      #  Bio::NCBI::REST::EFetch.nucleotide("AE009950")
+      #  Bio::NCBI::REST::EFetch.nucleotide("AE009950", "gbwithparts")
+      #
+      #  ncbi = Bio::NCBI::REST::EFetch.new
+      #  ncbi.nucleotide("123,U12345,U12345.1,gb|U12345|")
+      #  ncbi.nucleotide(list)
+      #  ncbi.nucleotide(list, "fasta")
+      #  ncbi.nucleotide(list, "acc")
+      #  ncbi.nucleotide(list, "xml")
+      #  ncbi.nucleotide("AE009950")
+      #  ncbi.nucleotide("AE009950", "gbwithparts")
+      #
+      # ---
+      #
+      # *Arguments*:
+      # * _ids_: list of NCBI entry IDs (required)
+      # * _format_: "gb", "gbc", "fasta", "acc", "xml" etc.
+      # *Returns*:: String
+      def nucleotide(ids, format = "gb", hash = {})
+        case format
+        when "xml"
+          format = "gbc"
+        end
+        opts = { "db" => "nucleotide", "rettype" => format }
+        opts.update(hash)
+        Bio::NCBI::REST.efetch(ids, opts)
+      end
+
+      # Retrieve protein sequence entries by given IDs using E-Utils
+      # (efetch).
+      #
+      # * http://eutils.ncbi.nlm.nih.gov/entrez/query/static/efetchseq_help.html
+      #  protein
+      #
+      # format (rettype):
+      # * native       all but Gene    ASN Default format for viewing sequences
+      # * fasta        all sequence    FASTA view of a sequence
+      # * gb           NA sequence     GenBank view for sequences
+      # * gbc          NA sequence     INSDSeq structured flat file
+      # * gbwithparts  NA sequence     GenBank CON division with sequences
+      # * est          dbEST sequence  EST Report
+      # * gss          dbGSS sequence  GSS Report
+      # * gp           AA sequence     GenPept view
+      # * gpc          AA sequence     INSDSeq structured flat file
+      # * seqid        all sequence    Convert GIs into seqids
+      # * acc          all sequence    Convert GIs into accessions
+      # * chr          dbSNP only      SNP Chromosome Report
+      # * flt          dbSNP only      SNP Flat File report
+      # * rsr          dbSNP only      SNP RS Cluster report
+      # * brief        dbSNP only      SNP ID list
+      # * docset       dbSNP only      SNP RS summary
+      #
+      # == Usage
+      #
+      #  Bio::NCBI::REST::EFetch.protein("7527480,AAF63163.1,AAF63163")
+      #
+      #  list = [ 7527480, "AAF63163.1", "AAF63163"]
+      #  Bio::NCBI::REST::EFetch.protein(list)
+      #  Bio::NCBI::REST::EFetch.protein(list, "fasta")
+      #  Bio::NCBI::REST::EFetch.protein(list, "acc")
+      #  Bio::NCBI::REST::EFetch.protein(list, "xml")
+      #
+      #  ncbi = Bio::NCBI::REST::EFetch.new
+      #  ncbi.protein("7527480,AAF63163.1,AAF63163")
+      #  ncbi.protein(list)
+      #  ncbi.protein(list, "fasta")
+      #  ncbi.protein(list, "acc")
+      #  ncbi.protein(list, "xml")
+      #
+      # ---
+      #
+      # *Arguments*:
+      # * _ids_: list of NCBI entry IDs (required)
+      # * _format_: "gp", "gpc", "fasta", "acc", "xml" etc.
+      # *Returns*:: String
+      def protein(ids, format = "gp", hash = {})
+        case format
+        when "xml"
+          format = "gpc"
+        end
+        opts = { "db" => "protein", "rettype" => format }
+        opts.update(hash)
+        Bio::NCBI::REST.efetch(ids, opts)
+      end
+
       # Retrieve PubMed entries by given IDs using E-Utils (efetch).
       #
       # * http://eutils.ncbi.nlm.nih.gov/entrez/query/static/efetchlit_help.html
diff --git a/lib/bio/location.rb b/lib/bio/location.rb
index 772b531..d7aadc2 100644
--- a/lib/bio/location.rb
+++ b/lib/bio/location.rb
@@ -632,8 +632,8 @@ class Locations
         end
       end
 
-      join_list.each do |position|
-        ary << gbl_pos2loc(position)
+      join_list.each do |pos|
+        ary << gbl_pos2loc(pos)
       end
 
     when /^complement\((.*)\)$/				# (J) complement()
diff --git a/lib/bio/reference.rb b/lib/bio/reference.rb
index 69cf53f..973f07e 100644
--- a/lib/bio/reference.rb
+++ b/lib/bio/reference.rb
@@ -272,7 +272,7 @@ module Bio
       lines << "%N #{@issue}" unless @issue.to_s.empty?
       lines << "%P #{@pages}" unless @pages.empty?
       lines << "%M #{@pubmed}" unless @pubmed.to_s.empty?
-      u = @url.empty? ? pubmed_url : @url
+      u = @url.to_s.empty? ? pubmed_url : @url
       lines << "%U #{u}" unless u.empty?
       lines << "%X #{@abstract}" unless @abstract.empty?
       @mesh.each do |term|
@@ -587,9 +587,8 @@ module Bio
     # *Returns*:: String
     def pubmed_url
       unless @pubmed.to_s.empty?
-        cgi = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi"
-        opts = "cmd=Retrieve&db=PubMed&dopt=Citation&list_uids"
-        return "#{cgi}?#{opts}=#{@pubmed}"
+        head = "http://www.ncbi.nlm.nih.gov/pubmed"
+        return "#{head}/#{@pubmed}"
       end
       ''
     end
diff --git a/lib/bio/shell/plugin/entry.rb b/lib/bio/shell/plugin/entry.rb
index 1d05121..8f20ef7 100644
--- a/lib/bio/shell/plugin/entry.rb
+++ b/lib/bio/shell/plugin/entry.rb
@@ -62,7 +62,7 @@ module Bio::Shell
   #   * "db:entry"  -- local BioFlat, OBDA, EMBOSS, KEGG API
   def getent(arg)
     entry = ""
-    db, entry_id = arg.to_s.strip.split(/:/)
+    db, entry_id = arg.to_s.strip.split(/\:/, 2)
 
     # local file
     if arg.respond_to?(:gets) or File.exists?(arg)
@@ -81,8 +81,12 @@ module Bio::Shell
 
     else
       # EMBOSS USA in ~/.embossrc
-      str = entret(arg)
-      if $?.exitstatus == 0 and str.length != 0
+      begin
+        str = entret(arg)
+      rescue SystemCallError
+        str = ''
+      end
+      if $? and $?.exitstatus == 0 and str.length != 0
         puts "Retrieving entry from EMBOSS (#{arg})"
         entry = str
 
diff --git a/lib/bio/shell/plugin/ncbirest.rb b/lib/bio/shell/plugin/ncbirest.rb
index 5393a6b..beb7dc1 100644
--- a/lib/bio/shell/plugin/ncbirest.rb
+++ b/lib/bio/shell/plugin/ncbirest.rb
@@ -31,7 +31,11 @@ module Bio::Shell
   # Otherwise, it acts the same as Bio::NCBI::REST.efetch.
   def efetch(ids, *arg)
     if arg.empty? then
-      Bio::NCBI::REST::EFetch.sequence(ids)
+      ret = Bio::NCBI::REST::EFetch.nucleotide(ids)
+      unless /^LOCUS       / =~ ret.to_s then
+        ret = Bio::NCBI::REST::EFetch.protein(ids)
+      end
+      ret
     elsif arg[0].kind_of?(Symbol)
       meth = arg[0]
       case meth.to_s
diff --git a/lib/bio/util/restriction_enzyme.rb b/lib/bio/util/restriction_enzyme.rb
index e7ba263..66ff7e2 100644
--- a/lib/bio/util/restriction_enzyme.rb
+++ b/lib/bio/util/restriction_enzyme.rb
@@ -125,6 +125,9 @@ class RestrictionEnzyme
   autoload :Analysis,                'bio/util/restriction_enzyme/analysis'
   autoload :Range,                   'bio/util/restriction_enzyme/range/sequence_range'
 
+  autoload :SortedNumArray,          'bio/util/restriction_enzyme/sorted_num_array'
+  autoload :DenseIntArray,          'bio/util/restriction_enzyme/dense_int_array'
+
   include CutSymbol
   extend CutSymbol
 
diff --git a/lib/bio/util/restriction_enzyme/dense_int_array.rb b/lib/bio/util/restriction_enzyme/dense_int_array.rb
new file mode 100644
index 0000000..ad97341
--- /dev/null
+++ b/lib/bio/util/restriction_enzyme/dense_int_array.rb
@@ -0,0 +1,195 @@
+#
+# bio/util/restriction_enzyme/dense_int_array.rb - Internal data storage for Bio::RestrictionEnzyme::Range::SequenceRange
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+#               Tomoaki NISHIYAMA
+# License::     The Ruby License
+#
+
+module Bio
+class RestrictionEnzyme
+
+  # a class to store integer numbers, containing many contiguous
+  # integral numbers.
+  #
+  # Bio::RestrictionEnzyme internal use only.
+  # Please do not create the instance outside Bio::RestrictionEnzyme.
+  class DenseIntArray
+    MutableRange = Struct.new(:first, :last)
+
+    include Enumerable
+
+    # Same usage as Array.[]
+    def self.[](*args)
+      a = self.new
+      args.each do |elem|
+        a.push elem
+      end
+      a
+    end
+
+    # creates a new object
+    def initialize
+      @data = []
+    end
+
+    # initialize copy
+    def initialize_copy(other)
+      super(other)
+      @data = @data.collect { |elem| elem.dup }
+    end
+
+    # sets internal data object
+    def internal_data=(a)
+      #clear_cache
+      @data = a
+      self
+    end
+    protected :internal_data=
+
+    # gets internal data object
+    def internal_data
+      @data
+    end
+    protected :internal_data
+
+    # Same usage as Array#[]
+    def [](*arg)
+      #$stderr.puts "SortedIntArray#[]"
+      to_a[*arg]
+    end
+
+    # Not implemented
+    def []=(*arg)
+      raise NotImplementedError, 'DenseIntArray#[]= is not implemented.'
+    end
+
+    # Same usage as Array#each
+    def each
+      @data.each do |elem|
+        elem.first.upto(elem.last) { |num| yield num }
+      end
+      self
+    end
+
+    # Same usage as Array#reverse_each
+    def reverse_each
+      @data.reverse_each do |elem|
+        elem.last.downto(elem.first) { |num| yield num }
+      end
+      self
+    end
+
+    # Same usage as Array#+, but accepts only the same classes instance.
+    def +(other)
+      unless other.is_a?(self.class) then
+        raise TypeError, 'unsupported data type'
+      end
+      tmpdata = @data + other.internal_data
+      tmpdata.sort! { |a,b| a.first <=> b.first }
+      result = self.class.new
+      return result if tmpdata.empty?
+      newdata = result.internal_data
+      newdata.push tmpdata[0].dup
+      (1...(tmpdata.size)).each do |i|
+        if (x = newdata[-1].last) >= tmpdata[i].first then
+          newdata[-1].last = tmpdata[i].last if tmpdata[i].last > x
+        else
+          newdata.push tmpdata[i].dup
+        end
+      end
+      result
+    end
+
+    # Same usage as Array#==
+    def ==(other)
+      if r = super(other) then
+        r
+      elsif other.is_a?(self.class) then
+        other.internal_data == @data
+      else
+        false
+      end
+    end
+
+    # Same usage as Array#concat
+    def concat(ary)
+      ary.each { |elem| self.<<(elem) }
+      self
+    end
+
+    # Same usage as Array#push
+    def push(*args)
+      args.each do |elem|
+        self.<<(elem)
+      end
+      self
+    end
+
+    # Same usage as Array#unshift
+    def unshift(*arg)
+      raise NotImplementedError, 'DenseIntArray#unshift is not implemented.'
+    end
+
+    # Same usage as Array#<<
+    def <<(elem)
+      if !@data.empty? and
+          @data[-1].last + 1 == elem then
+        @data[-1].last = elem
+      else
+        @data << MutableRange.new(elem, elem)
+      end
+      self
+    end
+
+    # Same usage as Array#include?
+    def include?(elem)
+      return false if @data.empty? or elem < self.first or self.last < elem
+      @data.any? do |range|
+        range.first <= elem && elem <= range.last
+      end
+    end
+
+    # Same usage as Array#first
+    def first
+      elem = @data.first
+      elem ? elem.first : nil
+    end
+
+    # Same usage as Array#last
+    def last
+      elem = @data.last
+      elem ? elem.last : nil
+    end
+
+    # Same usage as Array#size
+    def size
+      sum = 0
+      @data.each do |range|
+        sum += (range.last - range.first + 1)
+      end
+      sum
+    end
+    alias length size
+
+    # Same usage as Array#delete
+    def delete(elem)
+      raise NotImplementedError, 'DenseIntArray#delete is not implemented.'
+    end
+
+    # Does nothing
+    def sort!(&block)
+      # does nothing
+      self
+    end
+
+    # Does nothing
+    def uniq!
+      # does nothing
+      self
+    end
+  end #class DenseIntArray
+
+end #class RestrictionEnzyme
+end #module Bio
diff --git a/lib/bio/util/restriction_enzyme/range/sequence_range.rb b/lib/bio/util/restriction_enzyme/range/sequence_range.rb
index 1ccd246..e1ef127 100644
--- a/lib/bio/util/restriction_enzyme/range/sequence_range.rb
+++ b/lib/bio/util/restriction_enzyme/range/sequence_range.rb
@@ -5,7 +5,7 @@
 # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com)
 # License::   The Ruby License
 #
-#  $Id: sequence_range.rb,v 1.9 2007/07/16 19:28:48 k Exp $
+#  $Id:$
 #
 
 require 'bio/util/restriction_enzyme'
@@ -160,7 +160,7 @@ class SequenceRange
     @__fragments_current = true
     
     num_txt = '0123456789'
-    num_txt_repeat = (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1]
+    num_txt_repeat = (num_txt * ( @size.div(num_txt.size) + 1))[0.. at size-1]
     fragments = Fragments.new(num_txt_repeat, num_txt_repeat)
 
     cc = Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts.new(@size)
@@ -193,9 +193,9 @@ class SequenceRange
   # * +cc+: Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts
   # *Returns*:: +Hash+ Keys are unique, values are Bio::RestrictionEnzyme::Range::SequenceRange::Bin objects filled with indexes of the sequence locations they represent.
   def create_bins(cc)
-    p_cut = cc.vc_primary
-    c_cut = cc.vc_complement
-    h_cut = cc.hc_between_strands
+    p_cut = cc.vc_primary_as_original_class
+    c_cut = cc.vc_complement_as_original_class
+    h_cut = cc.hc_between_strands_as_original_class
     
     if @circular
       # NOTE
@@ -247,8 +247,8 @@ class SequenceRange
   # initializing the bin.
   def setup_new_bin(bins, bin_id)
     bins[ bin_id ] = Bin.new
-    bins[ bin_id ].p = []
-    bins[ bin_id ].c = []
+    bins[ bin_id ].p = DenseIntArray[] #could be replaced by SortedNumArray[]
+    bins[ bin_id ].c = DenseIntArray[] #could be replaced by SortedNumArray[] 
   end
   
 end # SequenceRange
diff --git a/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb b/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb
index 331c3cd..fb0e75c 100644
--- a/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb
+++ b/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb
@@ -34,13 +34,40 @@ class CalculatedCuts
   include StringFormatting
 
   # +Array+ of vertical cuts on the primary strand in 0-based index notation
-  attr_reader :vc_primary
+  def vc_primary
+    #$stderr.puts caller[0].inspect ###DEBUG
+    @vc_primary.to_a
+  end
+
+  # Returns the same contents as vc_primary, but returns original data
+  # structure used in the class.
+  def vc_primary_as_original_class
+    @vc_primary
+  end
   
   # +Array+ of vertical cuts on the complementary strand in 0-based index notation
-  attr_reader :vc_complement
+  def vc_complement
+    #$stderr.puts caller[0].inspect ###DEBUG
+    @vc_complement.to_a
+  end
+
+  # Returns the same contents as vc_complement, but returns original data
+  # structure used in the class.
+  def vc_complement_as_original_class
+    @vc_complement
+  end
 
   # +Array+ of horizontal cuts between strands in 0-based index notation
-  attr_reader :hc_between_strands
+  def hc_between_strands
+    #$stderr.puts caller[0].inspect ###DEBUG
+    @hc_between_strands.to_a
+  end
+
+  # Returns the same contents as hc_between_strands, but returns original data
+  # structure used in the class.
+  def hc_between_strands_as_original_class
+    @hc_between_strands
+  end
 
   # Set to +true+ if the fragment CalculatedCuts is working on is circular
   attr_accessor :circular
@@ -60,9 +87,9 @@ class CalculatedCuts
   def initialize(size=nil, circular=false)
     @size = size
     @circular = circular
-    @vc_primary = []
-    @vc_complement = []
-    @hc_between_strands = []
+    @vc_primary = SortedNumArray[]
+    @vc_complement = SortedNumArray[]
+    @hc_between_strands = SortedNumArray[]
   end
 
   # Accepts an +Array+ of CutRange type objects and applies them to 
@@ -75,9 +102,12 @@ class CalculatedCuts
   def add_cuts_from_cut_ranges(cut_ranges)
     @strands_for_display_current = false
 
+    @vc_primary = @vc_primary.dup
+    @vc_complement = @vc_complement.dup
+
     cut_ranges.each do |cut_range|
-      @vc_primary += [cut_range.p_cut_left, cut_range.p_cut_right]
-      @vc_complement += [cut_range.c_cut_left, cut_range.c_cut_right]
+      @vc_primary.concat [cut_range.p_cut_left, cut_range.p_cut_right]
+      @vc_complement.concat [cut_range.c_cut_left, cut_range.c_cut_right]
 
       # Add horizontal cut ranges.  This may happen from cuts made inbetween a
       # VerticalCutRange or may be specifically defined by a HorizontalCutRange.
@@ -124,10 +154,10 @@ class CalculatedCuts
     @size = size if size
     raise IndexError, "Size of the strand must be provided here or during initalization." if !@size.kind_of?(Fixnum) and not @circular
 
-    vcuts = (@vc_primary + @vc_complement).uniq.sort
+    vcuts = @vc_primary + @vc_complement
     hcuts = @hc_between_strands
     last_index = @size - 1
-    good_hcuts = []
+    good_hcuts = SortedNumArray[]
     potential_hcuts = []
 
     if @circular
@@ -146,13 +176,14 @@ class CalculatedCuts
 
       if potential_hcuts.empty?
         if vcuts.include?( hcut ) and vcuts.include?( hcut - 1 )
-          good_hcuts += [hcut]
+          good_hcuts << hcut
         elsif vcuts.include?( hcut - 1 )
           potential_hcuts << hcut
         end
       else
         if vcuts.include?( hcut )
-          good_hcuts += potential_hcuts + [hcut]
+          good_hcuts.concat(potential_hcuts)
+          good_hcuts << hcut
           potential_hcuts.clear
         else
           potential_hcuts << hcut
@@ -163,7 +194,7 @@ class CalculatedCuts
     check_vc = lambda do |vertical_cuts, opposing_vcuts|
       # opposing_vcuts is here only to check for blunt cuts, so there shouldn't
       # be any out-of-order problems with this
-      good_vc = []
+      good_vc = SortedNumArray[]
       vertical_cuts.each { |vc| good_vc << vc if good_hcuts.include?( vc ) or good_hcuts.include?( vc + 1 ) or opposing_vcuts.include?( vc ) }
       good_vc
     end
@@ -192,18 +223,26 @@ class CalculatedCuts
     hcs = '-'   # Horizontal cut symbol
     vhcs = '+'  # Intersection of vertical and horizontal cut symbol
       
-    num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1] }
+    num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * (@size.div(num_txt.size) + 1))[0.. at size-1] }
     (str1 == nil) ? a = num_txt_repeat.call : a = str1.dup
     (str2 == nil) ? b = num_txt_repeat.call : b = str2.dup
 
+    if vcp and !vcp.is_a?(SortedNumArray) then
+      vcp = SortedNumArray.new.concat(vcp)
+    end
+    if vcc and !vcc.is_a?(SortedNumArray) then
+      vcc = SortedNumArray.new.concat(vcc)
+    end
+    if hc and !hc.is_a?(SortedNumArray) then
+      hc = SortedNumArray.new.concat(hc)
+    end
+
     vcp = @vc_primary if vcp==nil
     vcc = @vc_complement if vcc==nil
     hc = @hc_between_strands if hc==nil
 
-    vcuts = (vcp + vcc).uniq.sort
-
-    vcp.reverse.each { |c| a.insert(c+1, vcs) }
-    vcc.reverse.each { |c| b.insert(c+1, vcs) }
+    vcp.reverse_each { |c| a.insert(c+1, vcs) }
+    vcc.reverse_each { |c| b.insert(c+1, vcs) }
 
     between = ' ' * @size
     hc.each {|hcut| between[hcut,1] = hcs }
diff --git a/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb b/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb
index 95bbfd6..7490a96 100644
--- a/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb
+++ b/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb
@@ -5,7 +5,7 @@
 # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com)
 # License::   The Ruby License
 #
-#  $Id: fragment.rb,v 1.6 2007/07/16 19:28:48 k Exp $
+#  $Id:$
 #
 
 require 'bio/util/restriction_enzyme'
@@ -31,7 +31,7 @@ class Fragment
     df.primary = ''
     df.complement = ''
 
-    both_bins = (@primary_bin + @complement_bin).sort.uniq
+    both_bins = @primary_bin + @complement_bin
     both_bins.each do |item|
       @primary_bin.include?(item) ? df.primary << p_str[item] : df.primary << ' '
       @complement_bin.include?(item) ? df.complement << c_str[item] : df.complement << ' '
diff --git a/lib/bio/util/restriction_enzyme/sorted_num_array.rb b/lib/bio/util/restriction_enzyme/sorted_num_array.rb
new file mode 100644
index 0000000..b6b7bd1
--- /dev/null
+++ b/lib/bio/util/restriction_enzyme/sorted_num_array.rb
@@ -0,0 +1,219 @@
+#
+# bio/util/restriction_enzyme/sorted_num_array.rb - Internal data storage for Bio::RestrictionEnzyme::Range::SequenceRange
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+module Bio
+class RestrictionEnzyme
+
+  # a class to store sorted numerics.
+  #
+  # Bio::RestrictionEnzyme internal use only.
+  # Please do not create the instance outside Bio::RestrictionEnzyme.
+  class SortedNumArray
+
+    # Same usage as Array.[]
+    def self.[](*args)
+      a = self.new
+      args.each do |elem|
+        a.push elem
+      end
+      a
+    end
+
+    # Creates a new object
+    def initialize
+      @hash = {}
+      #clear_cache
+    end
+
+    # initialize copy
+    def initialize_copy(other)
+      super(other)
+      @hash = @hash.dup
+    end
+
+    # sets internal hash object
+    def internal_data_hash=(h)
+      #clear_cache
+      @hash = h
+      self
+    end
+    protected :internal_data_hash=
+
+    # gets internal hash object
+    def internal_data_hash
+      @hash
+    end
+    protected :internal_data_hash
+
+    #---
+    ## clear the internal cache
+    #def clear_cache
+    #  @sorted_keys = nil
+    #end
+    #protected :clear_cache
+    #+++
+
+    # sorted keys
+    def sorted_keys
+      #@sorted_keys ||= @hash.keys.sort
+      #@sorted_keys
+      @hash.keys.sort
+    end
+    private :sorted_keys
+
+    # adds a new element
+    def push_element(n)
+      #return if @hash.has_key?(n) #already existed; do nothing
+      @hash.store(n, true)
+      #if @sorted_keys then
+      #  if thelast = @sorted_keys[-1] and n > thelast then
+      #    @sorted_keys.push n
+      #  else
+      #    clear_cache
+      #  end
+      #end
+      nil
+    end
+    private :push_element
+
+    # adds a new element in the beginning of the array 
+    def unshift_element(n)
+      #return if @hash.has_key?(n) #already existed; do nothing
+      @hash.store(n, true)
+      #if @sorted_keys then
+      #  if thefirst = @sorted_keys[0] and n < thefirst then
+      #    @sorted_keys.unshift n
+      #  else
+      #    clear_cache
+      #  end
+      #end
+      nil
+    end
+    private :unshift_element
+
+    # Same usage as Array#[]
+    def [](*arg)
+      #$stderr.puts "SortedNumArray#[]"
+      sorted_keys[*arg]
+    end
+
+    # Not implemented
+    def []=(*arg)
+      raise NotImplementedError, 'SortedNumArray#[]= is not implemented.'
+    end
+
+    # Same usage as Array#each
+    def each(&block)
+      sorted_keys.each(&block)
+    end
+
+    # Same usage as Array#reverse_each
+    def reverse_each(&block)
+      sorted_keys.reverse_each(&block)
+    end
+
+    # Same usage as Array#+, but accepts only the same classes instance.
+    def +(other)
+      unless other.is_a?(self.class) then
+        raise TypeError, 'unsupported data type'
+      end
+      new_hash = @hash.merge(other.internal_data_hash)
+      result = self.class.new
+      result.internal_data_hash = new_hash
+      result
+    end
+
+    # Same usage as Array#==
+    def ==(other)
+      if r = super(other) then
+        r
+      elsif other.is_a?(self.class) then
+        other.internal_data_hash == @hash
+      else
+        false
+      end
+    end
+
+    # Same usage as Array#concat
+    def concat(ary)
+      ary.each { |elem| push_element(elem) }
+      self
+    end
+
+    # Same usage as Array#push
+    def push(*args)
+      args.each do |elem|
+        push_element(elem)
+      end
+      self
+    end
+
+    # Same usage as Array#unshift
+    def unshift(*arg)
+      arg.reverse_each do |elem|
+        unshift_element(elem)
+      end
+      self
+    end
+
+    # Same usage as Array#<<
+    def <<(elem)
+      push_element(elem)
+      self
+    end
+
+    # Same usage as Array#include?
+    def include?(elem)
+      @hash.has_key?(elem)
+    end
+
+    # Same usage as Array#first
+    def first
+      sorted_keys.first
+    end
+
+    # Same usage as Array#last
+    def last
+      sorted_keys.last
+    end
+
+    # Same usage as Array#size
+    def size
+      @hash.size
+    end
+    alias length size
+
+    # Same usage as Array#delete
+    def delete(elem)
+      #clear_cache
+      @hash.delete(elem) ? elem : nil
+    end
+
+    # Does nothing
+    def sort!(&block)
+      # does nothing
+      self
+    end
+
+    # Does nothing
+    def uniq!
+      # does nothing
+      self
+    end
+
+    # Converts to an array
+    def to_a
+      #sorted_keys.dup
+      sorted_keys
+    end
+  end #class SortedNumArray
+
+end #class RestrictionEnzyme
+end #module Bio
+
+
diff --git a/lib/bio/version.rb b/lib/bio/version.rb
index 89544dc..379277b 100644
--- a/lib/bio/version.rb
+++ b/lib/bio/version.rb
@@ -10,7 +10,7 @@
 module Bio
 
   # BioRuby version (Array containing Integer)
-  BIORUBY_VERSION = [1, 4, 1].extend(Comparable).freeze
+  BIORUBY_VERSION = [1, 4, 2].extend(Comparable).freeze
 
   # Extra version specifier (String or nil).
   # Existance of the value indicates pre-release version or modified version.
diff --git a/metadata.yml b/metadata.yml
index 383a382..a349f8d 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,34 +1,26 @@
---- !ruby/object:Gem::Specification 
+--- !ruby/object:Gem::Specification
 name: bio
-version: !ruby/object:Gem::Version 
-  prerelease: false
-  segments: 
-  - 1
-  - 4
-  - 1
-  version: 1.4.1
+version: !ruby/object:Gem::Version
+  version: 1.4.2
+  prerelease: 
 platform: ruby
-authors: 
+authors:
 - BioRuby project
 autorequire: bio
 bindir: bin
 cert_chain: []
-
-date: 2010-10-22 00:00:00 +09:00
-default_executable: bioruby
+date: 2011-08-26 00:00:00.000000000 Z
 dependencies: []
-
 description: BioRuby is a library for bioinformatics (biology + information science).
 email: staff at bioruby.org
-executables: 
+executables:
 - bioruby
 - br_biofetch.rb
 - br_bioflat.rb
 - br_biogetseq.rb
 - br_pmfetch.rb
 extensions: []
-
-extra_rdoc_files: 
+extra_rdoc_files:
 - ChangeLog
 - KNOWN_ISSUES.rdoc
 - README.rdoc
@@ -36,7 +28,8 @@ extra_rdoc_files:
 - RELEASE_NOTES.rdoc
 - doc/Changes-1.3.rdoc
 - doc/RELEASE_NOTES-1.4.0.rdoc
-files: 
+- doc/RELEASE_NOTES-1.4.1.rdoc
+files:
 - COPYING
 - COPYING.ja
 - ChangeLog
@@ -61,6 +54,7 @@ files:
 - doc/KEGG_API.rd
 - doc/KEGG_API.rd.ja
 - doc/RELEASE_NOTES-1.4.0.rdoc
+- doc/RELEASE_NOTES-1.4.1.rdoc
 - doc/Tutorial.rd
 - doc/Tutorial.rd.html
 - doc/Tutorial.rd.ja
@@ -209,6 +203,7 @@ files:
 - lib/bio/io/biosql/config/database.yml
 - lib/bio/io/das.rb
 - lib/bio/io/dbget.rb
+- lib/bio/io/ddbjrest.rb
 - lib/bio/io/ddbjxml.rb
 - lib/bio/io/ebisoap.rb
 - lib/bio/io/ensembl.rb
@@ -302,6 +297,7 @@ files:
 - lib/bio/util/restriction_enzyme/analysis.rb
 - lib/bio/util/restriction_enzyme/analysis_basic.rb
 - lib/bio/util/restriction_enzyme/cut_symbol.rb
+- lib/bio/util/restriction_enzyme/dense_int_array.rb
 - lib/bio/util/restriction_enzyme/double_stranded.rb
 - lib/bio/util/restriction_enzyme/double_stranded/aligned_strands.rb
 - lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair.rb
@@ -320,6 +316,7 @@ files:
 - lib/bio/util/restriction_enzyme/single_strand.rb
 - lib/bio/util/restriction_enzyme/single_strand/cut_locations_in_enzyme_notation.rb
 - lib/bio/util/restriction_enzyme/single_strand_complement.rb
+- lib/bio/util/restriction_enzyme/sorted_num_array.rb
 - lib/bio/util/restriction_enzyme/string_formatting.rb
 - lib/bio/util/sirna.rb
 - lib/bio/version.rb
@@ -386,6 +383,7 @@ files:
 - sample/ssearch2tab.rb
 - sample/tdiary.rb
 - sample/test_phyloxml_big.rb
+- sample/test_restriction_enzyme_long.rb
 - sample/tfastx2tab.rb
 - sample/vs-genes.rb
 - setup.rb
@@ -425,6 +423,7 @@ files:
 - test/data/command/echoarg2.bat
 - test/data/embl/AB090716.embl
 - test/data/embl/AB090716.embl.rel89
+- test/data/fasta/EFTU_BACSU.fasta
 - test/data/fasta/example1.txt
 - test/data/fasta/example2.txt
 - test/data/fastq/README.txt
@@ -479,12 +478,15 @@ files:
 - test/data/fastq/wrapping_as_solexa.fastq
 - test/data/fastq/wrapping_original_sanger.fastq
 - test/data/gcg/pileup-aa.msf
+- test/data/genbank/CAA35997.gp
+- test/data/genbank/SCU49845.gb
 - test/data/genscan/sample.report
 - test/data/go/selected_component.ontology
 - test/data/go/selected_gene_association.sgd
 - test/data/go/selected_wikipedia2go
 - test/data/iprscan/merged.raw
 - test/data/iprscan/merged.txt
+- test/data/litdb/1717226.litdb
 - test/data/medline/20146148_modified.medline
 - test/data/meme/db
 - test/data/meme/mast
@@ -504,6 +506,7 @@ files:
 - test/data/phyloxml/made_up.xml
 - test/data/phyloxml/ncbi_taxonomy_mollusca_short.xml
 - test/data/phyloxml/phyloxml_examples.xml
+- test/data/pir/CRAB_ANAPL.pir
 - test/data/prosite/prosite.dat
 - test/data/refseq/nm_126355.entret
 - test/data/rpsblast/misc.rpsblast
@@ -516,7 +519,10 @@ files:
 - test/data/soft/GDS100_partial.soft
 - test/data/soft/GSE3457_family_partial.soft
 - test/data/uniprot/p53_human.uniprot
+- test/functional/bio/appl/blast/test_remote.rb
+- test/functional/bio/appl/test_blast.rb
 - test/functional/bio/appl/test_pts1.rb
+- test/functional/bio/io/test_ddbjrest.rb
 - test/functional/bio/io/test_ensembl.rb
 - test/functional/bio/io/test_pubmed.rb
 - test/functional/bio/io/test_soapwsdl.rb
@@ -559,9 +565,13 @@ files:
 - test/unit/bio/db/embl/test_embl_to_bioseq.rb
 - test/unit/bio/db/embl/test_sptr.rb
 - test/unit/bio/db/embl/test_uniprot.rb
+- test/unit/bio/db/embl/test_uniprot_new_part.rb
 - test/unit/bio/db/fasta/test_defline.rb
 - test/unit/bio/db/fasta/test_defline_misc.rb
 - test/unit/bio/db/fasta/test_format_qual.rb
+- test/unit/bio/db/genbank/test_common.rb
+- test/unit/bio/db/genbank/test_genbank.rb
+- test/unit/bio/db/genbank/test_genpept.rb
 - test/unit/bio/db/kegg/test_compound.rb
 - test/unit/bio/db/kegg/test_drug.rb
 - test/unit/bio/db/kegg/test_enzyme.rb
@@ -581,7 +591,9 @@ files:
 - test/unit/bio/db/test_gff.rb
 - test/unit/bio/db/test_go.rb
 - test/unit/bio/db/test_lasergene.rb
+- test/unit/bio/db/test_litdb.rb
 - test/unit/bio/db/test_medline.rb
+- test/unit/bio/db/test_nbrf.rb
 - test/unit/bio/db/test_newick.rb
 - test/unit/bio/db/test_nexus.rb
 - test/unit/bio/db/test_phyloxml.rb
@@ -629,20 +641,20 @@ files:
 - test/unit/bio/util/restriction_enzyme/single_strand/test_cut_locations_in_enzyme_notation.rb
 - test/unit/bio/util/restriction_enzyme/test_analysis.rb
 - test/unit/bio/util/restriction_enzyme/test_cut_symbol.rb
+- test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb
 - test/unit/bio/util/restriction_enzyme/test_double_stranded.rb
 - test/unit/bio/util/restriction_enzyme/test_single_strand.rb
 - test/unit/bio/util/restriction_enzyme/test_single_strand_complement.rb
+- test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb
 - test/unit/bio/util/restriction_enzyme/test_string_formatting.rb
 - test/unit/bio/util/test_color_scheme.rb
 - test/unit/bio/util/test_contingency_table.rb
 - test/unit/bio/util/test_restriction_enzyme.rb
 - test/unit/bio/util/test_sirna.rb
-has_rdoc: true
 homepage: http://bioruby.org/
 licenses: []
-
 post_install_message: 
-rdoc_options: 
+rdoc_options:
 - --main
 - README.rdoc
 - --title
@@ -651,30 +663,24 @@ rdoc_options:
 - \.yaml\z
 - --line-numbers
 - --inline-source
-require_paths: 
+require_paths:
 - lib
-required_ruby_version: !ruby/object:Gem::Requirement 
+required_ruby_version: !ruby/object:Gem::Requirement
   none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      segments: 
-      - 0
-      version: "0"
-required_rubygems_version: !ruby/object:Gem::Requirement 
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
   none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      segments: 
-      - 0
-      version: "0"
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
 requirements: []
-
 rubyforge_project: bioruby
-rubygems_version: 1.3.7
+rubygems_version: 1.8.10
 signing_key: 
 specification_version: 3
 summary: Bioinformatics library
 test_files: []
-
diff --git a/sample/test_restriction_enzyme_long.rb b/sample/test_restriction_enzyme_long.rb
new file mode 100644
index 0000000..d99aa5b
--- /dev/null
+++ b/sample/test_restriction_enzyme_long.rb
@@ -0,0 +1,4403 @@
+#
+# = sample/test_restriction_enzyme_long.rb - Benchmark tests for Bio::RestrictionEnzyme::Analysis.cut for long sequences
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+# Acknowledgements: The idea of the test is based on the issue report
+# https://github.com/bioruby/bioruby/issues/10
+# posted by ray1729 (https://github.com/ray1729).
+#
+
+require 'test/unit'
+require 'benchmark'
+require 'bio'
+
+entry = Bio::TogoWS::REST.entry('genbank', 'BA000007.2')
+EcoliO157H7Seq = Bio::GenBank.new(entry).naseq.freeze
+
+module TestRestrictionEnzymeAnalysisCutLong
+
+  # dummy benchmarch class
+  class DummyBench
+    def report(str); yield; end
+  end
+
+  module HelperMethods
+    def _truncate_cut_ranges(cut_ranges, len)
+      limit = len - 1
+      ret = cut_ranges.collect do |a|
+        if a[0] > limit || a[2] > limit then
+          nil
+        else
+          a.collect { |pos| pos > limit ? limit : pos }
+        end
+      end
+      ret.compact!
+      if last_a = ret[-1] then
+        last_a[1] = limit
+        last_a[3] = limit
+      end
+      ret
+    end
+
+    def _collect_cut_ranges(cuts)
+      cuts.collect do |f|
+                [ f.p_left, f.p_right, f.c_left, f.c_right ]
+      end
+    end
+
+    def _test_by_size(len, bench = DummyBench.new)
+      cuts = nil
+      bench.report("#{self.class::TestLabel} #{len}") {
+        cuts = _cut(self.class::SampleSequence[0, len])
+      }
+      cut_ranges = _collect_cut_ranges(cuts)
+      expected = _truncate_cut_ranges(self.class::SampleCutRanges, len)
+      assert_equal(expected, cut_ranges)
+    end
+
+    def test_10k_to_100k
+      $stderr.print "\n"
+      Benchmark.bm(26) do |bench|
+        10_000.step(100_000, 10_000) do |len|
+          _test_by_size(len, bench)
+        end
+      end
+    end
+
+    def test_100k_to_1M
+      $stderr.print "\n"
+      Benchmark.bm(26) do |bench|
+        100_000.step(1_000_000, 100_000) do |len|
+          _test_by_size(len, bench)
+        end
+      end
+    end
+
+    def test_1M_to_5M_and_whole
+      $stderr.print "\n"
+      Benchmark.bm(26) do |bench|
+        1_000_000.step(5_000_000, 1_000_000) do |len|
+          _test_by_size(len, bench)
+        end
+        _test_by_size(self.class::SampleSequence.length, bench)
+      end
+    end if defined? Bio::RestrictionEnzyme::SortedNumArray
+
+    def disabled_test_whole
+      cuts = _cut(self.class::SampleSequence)
+      cut_ranges = _collect_cut_ranges(cuts)
+      cut_ranges.each do |a|
+        $stderr.print "        [ ", a.join(", "), " ], \n"
+      end
+      assert_equal(self.class::SampleCutRanges, cut_ranges)
+    end
+  end #module HelperMethods
+
+
+  class TestEcoliO157H7_BstEII < Test::Unit::TestCase
+
+    include HelperMethods
+
+    TestLabel = 'BstEII'
+
+    SampleSequence = EcoliO157H7Seq
+
+    SampleCutRanges = BstEII_WHOLE =
+      [ [ 0, 79, 0, 84 ], 
+        [ 80, 4612, 85, 4617 ], 
+        [ 4613, 13483, 4618, 13488 ], 
+        [ 13484, 15984, 13489, 15989 ], 
+        [ 15985, 21462, 15990, 21467 ], 
+        [ 21463, 27326, 21468, 27331 ], 
+        [ 27327, 30943, 27332, 30948 ], 
+        [ 30944, 34888, 30949, 34893 ], 
+        [ 34889, 35077, 34894, 35082 ], 
+        [ 35078, 35310, 35083, 35315 ], 
+        [ 35311, 36254, 35316, 36259 ], 
+        [ 36255, 41885, 36260, 41890 ], 
+        [ 41886, 43070, 41891, 43075 ], 
+        [ 43071, 45689, 43076, 45694 ], 
+        [ 45690, 52325, 45695, 52330 ], 
+        [ 52326, 55703, 52331, 55708 ], 
+        [ 55704, 58828, 55709, 58833 ], 
+        [ 58829, 59178, 58834, 59183 ], 
+        [ 59179, 72610, 59184, 72615 ], 
+        [ 72611, 72739, 72616, 72744 ], 
+        [ 72740, 73099, 72745, 73104 ], 
+        [ 73100, 75123, 73105, 75128 ], 
+        [ 75124, 77366, 75129, 77371 ], 
+        [ 77367, 77810, 77372, 77815 ], 
+        [ 77811, 78740, 77816, 78745 ], 
+        [ 78741, 79717, 78746, 79722 ], 
+        [ 79718, 82250, 79723, 82255 ], 
+        [ 82251, 84604, 82256, 84609 ], 
+        [ 84605, 95491, 84610, 95496 ], 
+        [ 95492, 95785, 95497, 95790 ], 
+        [ 95786, 95794, 95791, 95799 ], 
+        [ 95795, 96335, 95800, 96340 ], 
+        [ 96336, 102044, 96341, 102049 ], 
+        [ 102045, 102541, 102050, 102546 ], 
+        [ 102542, 103192, 102547, 103197 ], 
+        [ 103193, 104722, 103198, 104727 ], 
+        [ 104723, 110883, 104728, 110888 ], 
+        [ 110884, 120090, 110889, 120095 ], 
+        [ 120091, 120657, 120096, 120662 ], 
+        [ 120658, 128308, 120663, 128313 ], 
+        [ 128309, 138305, 128314, 138310 ], 
+        [ 138306, 141147, 138311, 141152 ], 
+        [ 141148, 143724, 141153, 143729 ], 
+        [ 143725, 143838, 143730, 143843 ], 
+        [ 143839, 144303, 143844, 144308 ], 
+        [ 144304, 148199, 144309, 148204 ], 
+        [ 148200, 149577, 148205, 149582 ], 
+        [ 149578, 149731, 149583, 149736 ], 
+        [ 149732, 156115, 149737, 156120 ], 
+        [ 156116, 161126, 156121, 161131 ], 
+        [ 161127, 162856, 161132, 162861 ], 
+        [ 162857, 170693, 162862, 170698 ], 
+        [ 170694, 170944, 170699, 170949 ], 
+        [ 170945, 171201, 170950, 171206 ], 
+        [ 171202, 173241, 171207, 173246 ], 
+        [ 173242, 177283, 173247, 177288 ], 
+        [ 177284, 178177, 177289, 178182 ], 
+        [ 178178, 178781, 178183, 178786 ], 
+        [ 178782, 181610, 178787, 181615 ], 
+        [ 181611, 181706, 181616, 181711 ], 
+        [ 181707, 185661, 181712, 185666 ], 
+        [ 185662, 193407, 185667, 193412 ], 
+        [ 193408, 195511, 193413, 195516 ], 
+        [ 195512, 195754, 195517, 195759 ], 
+        [ 195755, 197247, 195760, 197252 ], 
+        [ 197248, 200659, 197253, 200664 ], 
+        [ 200660, 201820, 200665, 201825 ], 
+        [ 201821, 202300, 201826, 202305 ], 
+        [ 202301, 202686, 202306, 202691 ], 
+        [ 202687, 206289, 202692, 206294 ], 
+        [ 206290, 206466, 206295, 206471 ], 
+        [ 206467, 207011, 206472, 207016 ], 
+        [ 207012, 208159, 207017, 208164 ], 
+        [ 208160, 209976, 208165, 209981 ], 
+        [ 209977, 210078, 209982, 210083 ], 
+        [ 210079, 211485, 210084, 211490 ], 
+        [ 211486, 212377, 211491, 212382 ], 
+        [ 212378, 213569, 212383, 213574 ], 
+        [ 213570, 216005, 213575, 216010 ], 
+        [ 216006, 220098, 216011, 220103 ], 
+        [ 220099, 224063, 220104, 224068 ], 
+        [ 224064, 228604, 224069, 228609 ], 
+        [ 228605, 239993, 228610, 239998 ], 
+        [ 239994, 247914, 239999, 247919 ], 
+        [ 247915, 251579, 247920, 251584 ], 
+        [ 251580, 257092, 251585, 257097 ], 
+        [ 257093, 261621, 257098, 261626 ], 
+        [ 261622, 263030, 261627, 263035 ], 
+        [ 263031, 265084, 263036, 265089 ], 
+        [ 265085, 265243, 265090, 265248 ], 
+        [ 265244, 265534, 265249, 265539 ], 
+        [ 265535, 266117, 265540, 266122 ], 
+        [ 266118, 274428, 266123, 274433 ], 
+        [ 274429, 282285, 274434, 282290 ], 
+        [ 282286, 286948, 282291, 286953 ], 
+        [ 286949, 292547, 286954, 292552 ], 
+        [ 292548, 297678, 292553, 297683 ], 
+        [ 297679, 308161, 297684, 308166 ], 
+        [ 308162, 308706, 308167, 308711 ], 
+        [ 308707, 313482, 308712, 313487 ], 
+        [ 313483, 337118, 313488, 337123 ], 
+        [ 337119, 337935, 337124, 337940 ], 
+        [ 337936, 338781, 337941, 338786 ], 
+        [ 338782, 339493, 338787, 339498 ], 
+        [ 339494, 341025, 339499, 341030 ], 
+        [ 341026, 344424, 341031, 344429 ], 
+        [ 344425, 348384, 344430, 348389 ], 
+        [ 348385, 354781, 348390, 354786 ], 
+        [ 354782, 356692, 354787, 356697 ], 
+        [ 356693, 357008, 356698, 357013 ], 
+        [ 357009, 357305, 357014, 357310 ], 
+        [ 357306, 357328, 357311, 357333 ], 
+        [ 357329, 358126, 357334, 358131 ], 
+        [ 358127, 359472, 358132, 359477 ], 
+        [ 359473, 362160, 359478, 362165 ], 
+        [ 362161, 365395, 362166, 365400 ], 
+        [ 365396, 365704, 365401, 365709 ], 
+        [ 365705, 381746, 365710, 381751 ], 
+        [ 381747, 381994, 381752, 381999 ], 
+        [ 381995, 383335, 382000, 383340 ], 
+        [ 383336, 385141, 383341, 385146 ], 
+        [ 385142, 390171, 385147, 390176 ], 
+        [ 390172, 392764, 390177, 392769 ], 
+        [ 392765, 394338, 392770, 394343 ], 
+        [ 394339, 394686, 394344, 394691 ], 
+        [ 394687, 398703, 394692, 398708 ], 
+        [ 398704, 404095, 398709, 404100 ], 
+        [ 404096, 408361, 404101, 408366 ], 
+        [ 408362, 413032, 408367, 413037 ], 
+        [ 413033, 414563, 413038, 414568 ], 
+        [ 414564, 416901, 414569, 416906 ], 
+        [ 416902, 417419, 416907, 417424 ], 
+        [ 417420, 421777, 417425, 421782 ], 
+        [ 421778, 423748, 421783, 423753 ], 
+        [ 423749, 431903, 423754, 431908 ], 
+        [ 431904, 440000, 431909, 440005 ], 
+        [ 440001, 448040, 440006, 448045 ], 
+        [ 448041, 452994, 448046, 452999 ], 
+        [ 452995, 453075, 453000, 453080 ], 
+        [ 453076, 454950, 453081, 454955 ], 
+        [ 454951, 455888, 454956, 455893 ], 
+        [ 455889, 460160, 455894, 460165 ], 
+        [ 460161, 463076, 460166, 463081 ], 
+        [ 463077, 465003, 463082, 465008 ], 
+        [ 465004, 466828, 465009, 466833 ], 
+        [ 466829, 467686, 466834, 467691 ], 
+        [ 467687, 468596, 467692, 468601 ], 
+        [ 468597, 479953, 468602, 479958 ], 
+        [ 479954, 480538, 479959, 480543 ], 
+        [ 480539, 482869, 480544, 482874 ], 
+        [ 482870, 489378, 482875, 489383 ], 
+        [ 489379, 492241, 489384, 492246 ], 
+        [ 492242, 495406, 492247, 495411 ], 
+        [ 495407, 495712, 495412, 495717 ], 
+        [ 495713, 497829, 495718, 497834 ], 
+        [ 497830, 501698, 497835, 501703 ], 
+        [ 501699, 504565, 501704, 504570 ], 
+        [ 504566, 505105, 504571, 505110 ], 
+        [ 505106, 508452, 505111, 508457 ], 
+        [ 508453, 515947, 508458, 515952 ], 
+        [ 515948, 519141, 515953, 519146 ], 
+        [ 519142, 519398, 519147, 519403 ], 
+        [ 519399, 521386, 519404, 521391 ], 
+        [ 521387, 526115, 521392, 526120 ], 
+        [ 526116, 526729, 526121, 526734 ], 
+        [ 526730, 527018, 526735, 527023 ], 
+        [ 527019, 528059, 527024, 528064 ], 
+        [ 528060, 532689, 528065, 532694 ], 
+        [ 532690, 534702, 532695, 534707 ], 
+        [ 534703, 535272, 534708, 535277 ], 
+        [ 535273, 538668, 535278, 538673 ], 
+        [ 538669, 543939, 538674, 543944 ], 
+        [ 543940, 547429, 543945, 547434 ], 
+        [ 547430, 553890, 547435, 553895 ], 
+        [ 553891, 554678, 553896, 554683 ], 
+        [ 554679, 555452, 554684, 555457 ], 
+        [ 555453, 556296, 555458, 556301 ], 
+        [ 556297, 559341, 556302, 559346 ], 
+        [ 559342, 559991, 559347, 559996 ], 
+        [ 559992, 563242, 559997, 563247 ], 
+        [ 563243, 576432, 563248, 576437 ], 
+        [ 576433, 582431, 576438, 582436 ], 
+        [ 582432, 582959, 582437, 582964 ], 
+        [ 582960, 583475, 582965, 583480 ], 
+        [ 583476, 583589, 583481, 583594 ], 
+        [ 583590, 583670, 583595, 583675 ], 
+        [ 583671, 583901, 583676, 583906 ], 
+        [ 583902, 584198, 583907, 584203 ], 
+        [ 584199, 584633, 584204, 584638 ], 
+        [ 584634, 585704, 584639, 585709 ], 
+        [ 585705, 585746, 585710, 585751 ], 
+        [ 585747, 586175, 585752, 586180 ], 
+        [ 586176, 586301, 586181, 586306 ], 
+        [ 586302, 586643, 586307, 586648 ], 
+        [ 586644, 586775, 586649, 586780 ], 
+        [ 586776, 587072, 586781, 587077 ], 
+        [ 587073, 587214, 587078, 587219 ], 
+        [ 587215, 587540, 587220, 587545 ], 
+        [ 587541, 587969, 587546, 587974 ], 
+        [ 587970, 588095, 587975, 588100 ], 
+        [ 588096, 588437, 588101, 588442 ], 
+        [ 588438, 588569, 588443, 588574 ], 
+        [ 588570, 589008, 588575, 589013 ], 
+        [ 589009, 589166, 589014, 589171 ], 
+        [ 589167, 590366, 589172, 590371 ], 
+        [ 590367, 590792, 590372, 590797 ], 
+        [ 590793, 591077, 590798, 591082 ], 
+        [ 591078, 591263, 591083, 591268 ], 
+        [ 591264, 591863, 591269, 591868 ], 
+        [ 591864, 592058, 591869, 592063 ], 
+        [ 592059, 592160, 592064, 592165 ], 
+        [ 592161, 592568, 592166, 592573 ], 
+        [ 592569, 592760, 592574, 592765 ], 
+        [ 592761, 593060, 592766, 593065 ], 
+        [ 593061, 593186, 593066, 593191 ], 
+        [ 593187, 593366, 593192, 593371 ], 
+        [ 593367, 593957, 593372, 593962 ], 
+        [ 593958, 594827, 593963, 594832 ], 
+        [ 594828, 594980, 594833, 594985 ], 
+        [ 594981, 595649, 594986, 595654 ], 
+        [ 595650, 595893, 595655, 595898 ], 
+        [ 595894, 596057, 595899, 596062 ], 
+        [ 596058, 596159, 596063, 596164 ], 
+        [ 596160, 596351, 596165, 596356 ], 
+        [ 596352, 596660, 596357, 596665 ], 
+        [ 596661, 596960, 596666, 596965 ], 
+        [ 596961, 597102, 596966, 597107 ], 
+        [ 597103, 597155, 597108, 597160 ], 
+        [ 597156, 597257, 597161, 597262 ], 
+        [ 597258, 599957, 597263, 599962 ], 
+        [ 599958, 611038, 599963, 611043 ], 
+        [ 611039, 612202, 611044, 612207 ], 
+        [ 612203, 614051, 612208, 614056 ], 
+        [ 614052, 614134, 614057, 614139 ], 
+        [ 614135, 614787, 614140, 614792 ], 
+        [ 614788, 616272, 614793, 616277 ], 
+        [ 616273, 617737, 616278, 617742 ], 
+        [ 617738, 627339, 617743, 627344 ], 
+        [ 627340, 628902, 627345, 628907 ], 
+        [ 628903, 636523, 628908, 636528 ], 
+        [ 636524, 637529, 636529, 637534 ], 
+        [ 637530, 647713, 637535, 647718 ], 
+        [ 647714, 648684, 647719, 648689 ], 
+        [ 648685, 653543, 648690, 653548 ], 
+        [ 653544, 659030, 653549, 659035 ], 
+        [ 659031, 662241, 659036, 662246 ], 
+        [ 662242, 671781, 662247, 671786 ], 
+        [ 671782, 672048, 671787, 672053 ], 
+        [ 672049, 673788, 672054, 673793 ], 
+        [ 673789, 674707, 673794, 674712 ], 
+        [ 674708, 674998, 674713, 675003 ], 
+        [ 674999, 675157, 675004, 675162 ], 
+        [ 675158, 688595, 675163, 688600 ], 
+        [ 688596, 693309, 688601, 693314 ], 
+        [ 693310, 697406, 693315, 697411 ], 
+        [ 697407, 702676, 697412, 702681 ], 
+        [ 702677, 707382, 702682, 707387 ], 
+        [ 707383, 708604, 707388, 708609 ], 
+        [ 708605, 710046, 708610, 710051 ], 
+        [ 710047, 711630, 710052, 711635 ], 
+        [ 711631, 711696, 711636, 711701 ], 
+        [ 711697, 712329, 711702, 712334 ], 
+        [ 712330, 716461, 712335, 716466 ], 
+        [ 716462, 720238, 716467, 720243 ], 
+        [ 720239, 720374, 720244, 720379 ], 
+        [ 720375, 724200, 720380, 724205 ], 
+        [ 724201, 725687, 724206, 725692 ], 
+        [ 725688, 730067, 725693, 730072 ], 
+        [ 730068, 730574, 730073, 730579 ], 
+        [ 730575, 730699, 730580, 730704 ], 
+        [ 730700, 732726, 730705, 732731 ], 
+        [ 732727, 738597, 732732, 738602 ], 
+        [ 738598, 743326, 738603, 743331 ], 
+        [ 743327, 744992, 743332, 744997 ], 
+        [ 744993, 745843, 744998, 745848 ], 
+        [ 745844, 751518, 745849, 751523 ], 
+        [ 751519, 752431, 751524, 752436 ], 
+        [ 752432, 752549, 752437, 752554 ], 
+        [ 752550, 766036, 752555, 766041 ], 
+        [ 766037, 768968, 766042, 768973 ], 
+        [ 768969, 770151, 768974, 770156 ], 
+        [ 770152, 771158, 770157, 771163 ], 
+        [ 771159, 771405, 771164, 771410 ], 
+        [ 771406, 781958, 771411, 781963 ], 
+        [ 781959, 784226, 781964, 784231 ], 
+        [ 784227, 786945, 784232, 786950 ], 
+        [ 786946, 787203, 786951, 787208 ], 
+        [ 787204, 789251, 787209, 789256 ], 
+        [ 789252, 791218, 789257, 791223 ], 
+        [ 791219, 793716, 791224, 793721 ], 
+        [ 793717, 795003, 793722, 795008 ], 
+        [ 795004, 795521, 795009, 795526 ], 
+        [ 795522, 804514, 795527, 804519 ], 
+        [ 804515, 805238, 804520, 805243 ], 
+        [ 805239, 805887, 805244, 805892 ], 
+        [ 805888, 808461, 805893, 808466 ], 
+        [ 808462, 809805, 808467, 809810 ], 
+        [ 809806, 810086, 809811, 810091 ], 
+        [ 810087, 810726, 810092, 810731 ], 
+        [ 810727, 820111, 810732, 820116 ], 
+        [ 820112, 821326, 820117, 821331 ], 
+        [ 821327, 821647, 821332, 821652 ], 
+        [ 821648, 824277, 821653, 824282 ], 
+        [ 824278, 825750, 824283, 825755 ], 
+        [ 825751, 828770, 825756, 828775 ], 
+        [ 828771, 828924, 828776, 828929 ], 
+        [ 828925, 830194, 828930, 830199 ], 
+        [ 830195, 830786, 830200, 830791 ], 
+        [ 830787, 832788, 830792, 832793 ], 
+        [ 832789, 833306, 832794, 833311 ], 
+        [ 833307, 835656, 833312, 835661 ], 
+        [ 835657, 841180, 835662, 841185 ], 
+        [ 841181, 842112, 841186, 842117 ], 
+        [ 842113, 843973, 842118, 843978 ], 
+        [ 843974, 843990, 843979, 843995 ], 
+        [ 843991, 852882, 843996, 852887 ], 
+        [ 852883, 854392, 852888, 854397 ], 
+        [ 854393, 857721, 854398, 857726 ], 
+        [ 857722, 857961, 857727, 857966 ], 
+        [ 857962, 862783, 857967, 862788 ], 
+        [ 862784, 878953, 862789, 878958 ], 
+        [ 878954, 885194, 878959, 885199 ], 
+        [ 885195, 886313, 885200, 886318 ], 
+        [ 886314, 886460, 886319, 886465 ], 
+        [ 886461, 890233, 886466, 890238 ], 
+        [ 890234, 890346, 890239, 890351 ], 
+        [ 890347, 890379, 890352, 890384 ], 
+        [ 890380, 899676, 890385, 899681 ], 
+        [ 899677, 903962, 899682, 903967 ], 
+        [ 903963, 904236, 903968, 904241 ], 
+        [ 904237, 908130, 904242, 908135 ], 
+        [ 908131, 916611, 908136, 916616 ], 
+        [ 916612, 916803, 916617, 916808 ], 
+        [ 916804, 920531, 916809, 920536 ], 
+        [ 920532, 928505, 920537, 928510 ], 
+        [ 928506, 936947, 928511, 936952 ], 
+        [ 936948, 937240, 936953, 937245 ], 
+        [ 937241, 939698, 937246, 939703 ], 
+        [ 939699, 939711, 939704, 939716 ], 
+        [ 939712, 941642, 939717, 941647 ], 
+        [ 941643, 949052, 941648, 949057 ], 
+        [ 949053, 949800, 949058, 949805 ], 
+        [ 949801, 951412, 949806, 951417 ], 
+        [ 951413, 951810, 951418, 951815 ], 
+        [ 951811, 952386, 951816, 952391 ], 
+        [ 952387, 953295, 952392, 953300 ], 
+        [ 953296, 953894, 953301, 953899 ], 
+        [ 953895, 958753, 953900, 958758 ], 
+        [ 958754, 964476, 958759, 964481 ], 
+        [ 964477, 967468, 964482, 967473 ], 
+        [ 967469, 969631, 967474, 969636 ], 
+        [ 969632, 970966, 969637, 970971 ], 
+        [ 970967, 971138, 970972, 971143 ], 
+        [ 971139, 974185, 971144, 974190 ], 
+        [ 974186, 974365, 974191, 974370 ], 
+        [ 974366, 975256, 974371, 975261 ], 
+        [ 975257, 976794, 975262, 976799 ], 
+        [ 976795, 987406, 976800, 987411 ], 
+        [ 987407, 988132, 987412, 988137 ], 
+        [ 988133, 992809, 988138, 992814 ], 
+        [ 992810, 1000225, 992815, 1000230 ], 
+        [ 1000226, 1001626, 1000231, 1001631 ], 
+        [ 1001627, 1007354, 1001632, 1007359 ], 
+        [ 1007355, 1011910, 1007360, 1011915 ], 
+        [ 1011911, 1012377, 1011916, 1012382 ], 
+        [ 1012378, 1017328, 1012383, 1017333 ], 
+        [ 1017329, 1020891, 1017334, 1020896 ], 
+        [ 1020892, 1021340, 1020897, 1021345 ], 
+        [ 1021341, 1024845, 1021346, 1024850 ], 
+        [ 1024846, 1025853, 1024851, 1025858 ], 
+        [ 1025854, 1030691, 1025859, 1030696 ], 
+        [ 1030692, 1032676, 1030697, 1032681 ], 
+        [ 1032677, 1037847, 1032682, 1037852 ], 
+        [ 1037848, 1039473, 1037853, 1039478 ], 
+        [ 1039474, 1044241, 1039479, 1044246 ], 
+        [ 1044242, 1045920, 1044247, 1045925 ], 
+        [ 1045921, 1053286, 1045926, 1053291 ], 
+        [ 1053287, 1053309, 1053292, 1053314 ], 
+        [ 1053310, 1054643, 1053315, 1054648 ], 
+        [ 1054644, 1056527, 1054649, 1056532 ], 
+        [ 1056528, 1058682, 1056533, 1058687 ], 
+        [ 1058683, 1059297, 1058688, 1059302 ], 
+        [ 1059298, 1060416, 1059303, 1060421 ], 
+        [ 1060417, 1064234, 1060422, 1064239 ], 
+        [ 1064235, 1064848, 1064240, 1064853 ], 
+        [ 1064849, 1065434, 1064854, 1065439 ], 
+        [ 1065435, 1075642, 1065440, 1075647 ], 
+        [ 1075643, 1076325, 1075648, 1076330 ], 
+        [ 1076326, 1076534, 1076331, 1076539 ], 
+        [ 1076535, 1078866, 1076540, 1078871 ], 
+        [ 1078867, 1080537, 1078872, 1080542 ], 
+        [ 1080538, 1082144, 1080543, 1082149 ], 
+        [ 1082145, 1085746, 1082150, 1085751 ], 
+        [ 1085747, 1087087, 1085752, 1087092 ], 
+        [ 1087088, 1088273, 1087093, 1088278 ], 
+        [ 1088274, 1093062, 1088279, 1093067 ], 
+        [ 1093063, 1096867, 1093068, 1096872 ], 
+        [ 1096868, 1102488, 1096873, 1102493 ], 
+        [ 1102489, 1106371, 1102494, 1106376 ], 
+        [ 1106372, 1108123, 1106377, 1108128 ], 
+        [ 1108124, 1113311, 1108129, 1113316 ], 
+        [ 1113312, 1114557, 1113317, 1114562 ], 
+        [ 1114558, 1120566, 1114563, 1120571 ], 
+        [ 1120567, 1121004, 1120572, 1121009 ], 
+        [ 1121005, 1122501, 1121010, 1122506 ], 
+        [ 1122502, 1130582, 1122507, 1130587 ], 
+        [ 1130583, 1132170, 1130588, 1132175 ], 
+        [ 1132171, 1140126, 1132176, 1140131 ], 
+        [ 1140127, 1143361, 1140132, 1143366 ], 
+        [ 1143362, 1149205, 1143367, 1149210 ], 
+        [ 1149206, 1149331, 1149211, 1149336 ], 
+        [ 1149332, 1156272, 1149337, 1156277 ], 
+        [ 1156273, 1161624, 1156278, 1161629 ], 
+        [ 1161625, 1171353, 1161630, 1171358 ], 
+        [ 1171354, 1171934, 1171359, 1171939 ], 
+        [ 1171935, 1172114, 1171940, 1172119 ], 
+        [ 1172115, 1185368, 1172120, 1185373 ], 
+        [ 1185369, 1193993, 1185374, 1193998 ], 
+        [ 1193994, 1194272, 1193999, 1194277 ], 
+        [ 1194273, 1197920, 1194278, 1197925 ], 
+        [ 1197921, 1200373, 1197926, 1200378 ], 
+        [ 1200374, 1200597, 1200379, 1200602 ], 
+        [ 1200598, 1200714, 1200603, 1200719 ], 
+        [ 1200715, 1203674, 1200720, 1203679 ], 
+        [ 1203675, 1204865, 1203680, 1204870 ], 
+        [ 1204866, 1205330, 1204871, 1205335 ], 
+        [ 1205331, 1210727, 1205336, 1210732 ], 
+        [ 1210728, 1211881, 1210733, 1211886 ], 
+        [ 1211882, 1214283, 1211887, 1214288 ], 
+        [ 1214284, 1216981, 1214289, 1216986 ], 
+        [ 1216982, 1223522, 1216987, 1223527 ], 
+        [ 1223523, 1228205, 1223528, 1228210 ], 
+        [ 1228206, 1236067, 1228211, 1236072 ], 
+        [ 1236068, 1236265, 1236073, 1236270 ], 
+        [ 1236266, 1239969, 1236271, 1239974 ], 
+        [ 1239970, 1240641, 1239975, 1240646 ], 
+        [ 1240642, 1244738, 1240647, 1244743 ], 
+        [ 1244739, 1244821, 1244744, 1244826 ], 
+        [ 1244822, 1272971, 1244827, 1272976 ], 
+        [ 1272972, 1276524, 1272977, 1276529 ], 
+        [ 1276525, 1290344, 1276530, 1290349 ], 
+        [ 1290345, 1292253, 1290350, 1292258 ], 
+        [ 1292254, 1293482, 1292259, 1293487 ], 
+        [ 1293483, 1295919, 1293488, 1295924 ], 
+        [ 1295920, 1302834, 1295925, 1302839 ], 
+        [ 1302835, 1303464, 1302840, 1303469 ], 
+        [ 1303465, 1309308, 1303470, 1309313 ], 
+        [ 1309309, 1311482, 1309314, 1311487 ], 
+        [ 1311483, 1312493, 1311488, 1312498 ], 
+        [ 1312494, 1316488, 1312499, 1316493 ], 
+        [ 1316489, 1318127, 1316494, 1318132 ], 
+        [ 1318128, 1325643, 1318133, 1325648 ], 
+        [ 1325644, 1328313, 1325649, 1328318 ], 
+        [ 1328314, 1345348, 1328319, 1345353 ], 
+        [ 1345349, 1347480, 1345354, 1347485 ], 
+        [ 1347481, 1348458, 1347486, 1348463 ], 
+        [ 1348459, 1350595, 1348464, 1350600 ], 
+        [ 1350596, 1350770, 1350601, 1350775 ], 
+        [ 1350771, 1351954, 1350776, 1351959 ], 
+        [ 1351955, 1356474, 1351960, 1356479 ], 
+        [ 1356475, 1362756, 1356480, 1362761 ], 
+        [ 1362757, 1368544, 1362762, 1368549 ], 
+        [ 1368545, 1377993, 1368550, 1377998 ], 
+        [ 1377994, 1379610, 1377999, 1379615 ], 
+        [ 1379611, 1391551, 1379616, 1391556 ], 
+        [ 1391552, 1395841, 1391557, 1395846 ], 
+        [ 1395842, 1401721, 1395847, 1401726 ], 
+        [ 1401722, 1406871, 1401727, 1406876 ], 
+        [ 1406872, 1411041, 1406877, 1411046 ], 
+        [ 1411042, 1417851, 1411047, 1417856 ], 
+        [ 1417852, 1419058, 1417857, 1419063 ], 
+        [ 1419059, 1428120, 1419064, 1428125 ], 
+        [ 1428121, 1428584, 1428126, 1428589 ], 
+        [ 1428585, 1430700, 1428590, 1430705 ], 
+        [ 1430701, 1438278, 1430706, 1438283 ], 
+        [ 1438279, 1443084, 1438284, 1443089 ], 
+        [ 1443085, 1444668, 1443090, 1444673 ], 
+        [ 1444669, 1444866, 1444674, 1444871 ], 
+        [ 1444867, 1444914, 1444872, 1444919 ], 
+        [ 1444915, 1445093, 1444920, 1445098 ], 
+        [ 1445094, 1446216, 1445099, 1446221 ], 
+        [ 1446217, 1448518, 1446222, 1448523 ], 
+        [ 1448519, 1452860, 1448524, 1452865 ], 
+        [ 1452861, 1454246, 1452866, 1454251 ], 
+        [ 1454247, 1455414, 1454252, 1455419 ], 
+        [ 1455415, 1460976, 1455420, 1460981 ], 
+        [ 1460977, 1461164, 1460982, 1461169 ], 
+        [ 1461165, 1463675, 1461170, 1463680 ], 
+        [ 1463676, 1465339, 1463681, 1465344 ], 
+        [ 1465340, 1469872, 1465345, 1469877 ], 
+        [ 1469873, 1471479, 1469878, 1471484 ], 
+        [ 1471480, 1472745, 1471485, 1472750 ], 
+        [ 1472746, 1479208, 1472751, 1479213 ], 
+        [ 1479209, 1480831, 1479214, 1480836 ], 
+        [ 1480832, 1485359, 1480837, 1485364 ], 
+        [ 1485360, 1485530, 1485365, 1485535 ], 
+        [ 1485531, 1486004, 1485536, 1486009 ], 
+        [ 1486005, 1487314, 1486010, 1487319 ], 
+        [ 1487315, 1491008, 1487320, 1491013 ], 
+        [ 1491009, 1492068, 1491014, 1492073 ], 
+        [ 1492069, 1493001, 1492074, 1493006 ], 
+        [ 1493002, 1495524, 1493007, 1495529 ], 
+        [ 1495525, 1498599, 1495530, 1498604 ], 
+        [ 1498600, 1499384, 1498605, 1499389 ], 
+        [ 1499385, 1500494, 1499390, 1500499 ], 
+        [ 1500495, 1504828, 1500500, 1504833 ], 
+        [ 1504829, 1509790, 1504834, 1509795 ], 
+        [ 1509791, 1512050, 1509796, 1512055 ], 
+        [ 1512051, 1514922, 1512056, 1514927 ], 
+        [ 1514923, 1515140, 1514928, 1515145 ], 
+        [ 1515141, 1515194, 1515146, 1515199 ], 
+        [ 1515195, 1515647, 1515200, 1515652 ], 
+        [ 1515648, 1516602, 1515653, 1516607 ], 
+        [ 1516603, 1517689, 1516608, 1517694 ], 
+        [ 1517690, 1519324, 1517695, 1519329 ], 
+        [ 1519325, 1524288, 1519330, 1524293 ], 
+        [ 1524289, 1524809, 1524294, 1524814 ], 
+        [ 1524810, 1525934, 1524815, 1525939 ], 
+        [ 1525935, 1526325, 1525940, 1526330 ], 
+        [ 1526326, 1527046, 1526331, 1527051 ], 
+        [ 1527047, 1528800, 1527052, 1528805 ], 
+        [ 1528801, 1529067, 1528806, 1529072 ], 
+        [ 1529068, 1529127, 1529073, 1529132 ], 
+        [ 1529128, 1536262, 1529133, 1536267 ], 
+        [ 1536263, 1543858, 1536268, 1543863 ], 
+        [ 1543859, 1554015, 1543864, 1554020 ], 
+        [ 1554016, 1555315, 1554021, 1555320 ], 
+        [ 1555316, 1558476, 1555321, 1558481 ], 
+        [ 1558477, 1560403, 1558482, 1560408 ], 
+        [ 1560404, 1564152, 1560409, 1564157 ], 
+        [ 1564153, 1565868, 1564158, 1565873 ], 
+        [ 1565869, 1566075, 1565874, 1566080 ], 
+        [ 1566076, 1572715, 1566081, 1572720 ], 
+        [ 1572716, 1575566, 1572721, 1575571 ], 
+        [ 1575567, 1575840, 1575572, 1575845 ], 
+        [ 1575841, 1575957, 1575846, 1575962 ], 
+        [ 1575958, 1578588, 1575963, 1578593 ], 
+        [ 1578589, 1587557, 1578594, 1587562 ], 
+        [ 1587558, 1588891, 1587563, 1588896 ], 
+        [ 1588892, 1597227, 1588897, 1597232 ], 
+        [ 1597228, 1597262, 1597233, 1597267 ], 
+        [ 1597263, 1606974, 1597268, 1606979 ], 
+        [ 1606975, 1613512, 1606980, 1613517 ], 
+        [ 1613513, 1613900, 1613518, 1613905 ], 
+        [ 1613901, 1614931, 1613906, 1614936 ], 
+        [ 1614932, 1620971, 1614937, 1620976 ], 
+        [ 1620972, 1625931, 1620977, 1625936 ], 
+        [ 1625932, 1635578, 1625937, 1635583 ], 
+        [ 1635579, 1636949, 1635584, 1636954 ], 
+        [ 1636950, 1642076, 1636955, 1642081 ], 
+        [ 1642077, 1643227, 1642082, 1643232 ], 
+        [ 1643228, 1643451, 1643233, 1643456 ], 
+        [ 1643452, 1643568, 1643457, 1643573 ], 
+        [ 1643569, 1651406, 1643574, 1651411 ], 
+        [ 1651407, 1651474, 1651412, 1651479 ], 
+        [ 1651475, 1660688, 1651480, 1660693 ], 
+        [ 1660689, 1665846, 1660694, 1665851 ], 
+        [ 1665847, 1667026, 1665852, 1667031 ], 
+        [ 1667027, 1675465, 1667032, 1675470 ], 
+        [ 1675466, 1679164, 1675471, 1679169 ], 
+        [ 1679165, 1681962, 1679170, 1681967 ], 
+        [ 1681963, 1688016, 1681968, 1688021 ], 
+        [ 1688017, 1690659, 1688022, 1690664 ], 
+        [ 1690660, 1692872, 1690665, 1692877 ], 
+        [ 1692873, 1697102, 1692878, 1697107 ], 
+        [ 1697103, 1698132, 1697108, 1698137 ], 
+        [ 1698133, 1703429, 1698138, 1703434 ], 
+        [ 1703430, 1706057, 1703435, 1706062 ], 
+        [ 1706058, 1708683, 1706063, 1708688 ], 
+        [ 1708684, 1720884, 1708689, 1720889 ], 
+        [ 1720885, 1721218, 1720890, 1721223 ], 
+        [ 1721219, 1725289, 1721224, 1725294 ], 
+        [ 1725290, 1726495, 1725295, 1726500 ], 
+        [ 1726496, 1728646, 1726501, 1728651 ], 
+        [ 1728647, 1729060, 1728652, 1729065 ], 
+        [ 1729061, 1732801, 1729066, 1732806 ], 
+        [ 1732802, 1733308, 1732807, 1733313 ], 
+        [ 1733309, 1734471, 1733314, 1734476 ], 
+        [ 1734472, 1740942, 1734477, 1740947 ], 
+        [ 1740943, 1744762, 1740948, 1744767 ], 
+        [ 1744763, 1746379, 1744768, 1746384 ], 
+        [ 1746380, 1747144, 1746385, 1747149 ], 
+        [ 1747145, 1753062, 1747150, 1753067 ], 
+        [ 1753063, 1754367, 1753068, 1754372 ], 
+        [ 1754368, 1763444, 1754373, 1763449 ], 
+        [ 1763445, 1777420, 1763450, 1777425 ], 
+        [ 1777421, 1782626, 1777426, 1782631 ], 
+        [ 1782627, 1784342, 1782632, 1784347 ], 
+        [ 1784343, 1784549, 1784348, 1784554 ], 
+        [ 1784550, 1791189, 1784555, 1791194 ], 
+        [ 1791190, 1793878, 1791195, 1793883 ], 
+        [ 1793879, 1794152, 1793884, 1794157 ], 
+        [ 1794153, 1794269, 1794158, 1794274 ], 
+        [ 1794270, 1794972, 1794275, 1794977 ], 
+        [ 1794973, 1796163, 1794978, 1796168 ], 
+        [ 1796164, 1802296, 1796169, 1802301 ], 
+        [ 1802297, 1805729, 1802302, 1805734 ], 
+        [ 1805730, 1806305, 1805735, 1806310 ], 
+        [ 1806306, 1810512, 1806311, 1810517 ], 
+        [ 1810513, 1816402, 1810518, 1816407 ], 
+        [ 1816403, 1826227, 1816408, 1826232 ], 
+        [ 1826228, 1826701, 1826233, 1826706 ], 
+        [ 1826702, 1827720, 1826707, 1827725 ], 
+        [ 1827721, 1836707, 1827726, 1836712 ], 
+        [ 1836708, 1836926, 1836713, 1836931 ], 
+        [ 1836927, 1838667, 1836932, 1838672 ], 
+        [ 1838668, 1843220, 1838673, 1843225 ], 
+        [ 1843221, 1843829, 1843226, 1843834 ], 
+        [ 1843830, 1846577, 1843835, 1846582 ], 
+        [ 1846578, 1849125, 1846583, 1849130 ], 
+        [ 1849126, 1850237, 1849131, 1850242 ], 
+        [ 1850238, 1851708, 1850243, 1851713 ], 
+        [ 1851709, 1853436, 1851714, 1853441 ], 
+        [ 1853437, 1853475, 1853442, 1853480 ], 
+        [ 1853476, 1853493, 1853481, 1853498 ], 
+        [ 1853494, 1854900, 1853499, 1854905 ], 
+        [ 1854901, 1861797, 1854906, 1861802 ], 
+        [ 1861798, 1862267, 1861803, 1862272 ], 
+        [ 1862268, 1866445, 1862273, 1866450 ], 
+        [ 1866446, 1866700, 1866451, 1866705 ], 
+        [ 1866701, 1870143, 1866706, 1870148 ], 
+        [ 1870144, 1870675, 1870149, 1870680 ], 
+        [ 1870676, 1881704, 1870681, 1881709 ], 
+        [ 1881705, 1882659, 1881710, 1882664 ], 
+        [ 1882660, 1884008, 1882665, 1884013 ], 
+        [ 1884009, 1885076, 1884014, 1885081 ], 
+        [ 1885077, 1897857, 1885082, 1897862 ], 
+        [ 1897858, 1931549, 1897863, 1931554 ], 
+        [ 1931550, 1931660, 1931555, 1931665 ], 
+        [ 1931661, 1936680, 1931666, 1936685 ], 
+        [ 1936681, 1938835, 1936686, 1938840 ], 
+        [ 1938836, 1939367, 1938841, 1939372 ], 
+        [ 1939368, 1944718, 1939373, 1944723 ], 
+        [ 1944719, 1949924, 1944724, 1949929 ], 
+        [ 1949925, 1951640, 1949930, 1951645 ], 
+        [ 1951641, 1951847, 1951646, 1951852 ], 
+        [ 1951848, 1958495, 1951853, 1958500 ], 
+        [ 1958496, 1961184, 1958501, 1961189 ], 
+        [ 1961185, 1961458, 1961190, 1961463 ], 
+        [ 1961459, 1963223, 1961464, 1963228 ], 
+        [ 1963224, 1964535, 1963229, 1964540 ], 
+        [ 1964536, 1964578, 1964541, 1964583 ], 
+        [ 1964579, 1965726, 1964584, 1965731 ], 
+        [ 1965727, 1975723, 1965732, 1975728 ], 
+        [ 1975724, 1983495, 1975729, 1983500 ], 
+        [ 1983496, 1989041, 1983501, 1989046 ], 
+        [ 1989042, 1991939, 1989047, 1991944 ], 
+        [ 1991940, 1994134, 1991945, 1994139 ], 
+        [ 1994135, 2006390, 1994140, 2006395 ], 
+        [ 2006391, 2006681, 2006396, 2006686 ], 
+        [ 2006682, 2012753, 2006687, 2012758 ], 
+        [ 2012754, 2020299, 2012759, 2020304 ], 
+        [ 2020300, 2021594, 2020305, 2021599 ], 
+        [ 2021595, 2035653, 2021600, 2035658 ], 
+        [ 2035654, 2043961, 2035659, 2043966 ], 
+        [ 2043962, 2044411, 2043967, 2044416 ], 
+        [ 2044412, 2045320, 2044417, 2045325 ], 
+        [ 2045321, 2046593, 2045326, 2046598 ], 
+        [ 2046594, 2058014, 2046599, 2058019 ], 
+        [ 2058015, 2058262, 2058020, 2058267 ], 
+        [ 2058263, 2061616, 2058268, 2061621 ], 
+        [ 2061617, 2067334, 2061622, 2067339 ], 
+        [ 2067335, 2069059, 2067340, 2069064 ], 
+        [ 2069060, 2073142, 2069065, 2073147 ], 
+        [ 2073143, 2074555, 2073148, 2074560 ], 
+        [ 2074556, 2074634, 2074561, 2074639 ], 
+        [ 2074635, 2076422, 2074640, 2076427 ], 
+        [ 2076423, 2081937, 2076428, 2081942 ], 
+        [ 2081938, 2082042, 2081943, 2082047 ], 
+        [ 2082043, 2082408, 2082048, 2082413 ], 
+        [ 2082409, 2094661, 2082414, 2094666 ], 
+        [ 2094662, 2105556, 2094667, 2105561 ], 
+        [ 2105557, 2106153, 2105562, 2106158 ], 
+        [ 2106154, 2113282, 2106159, 2113287 ], 
+        [ 2113283, 2114197, 2113288, 2114202 ], 
+        [ 2114198, 2124245, 2114203, 2124250 ], 
+        [ 2124246, 2126629, 2124251, 2126634 ], 
+        [ 2126630, 2127367, 2126635, 2127372 ], 
+        [ 2127368, 2131854, 2127373, 2131859 ], 
+        [ 2131855, 2138481, 2131860, 2138486 ], 
+        [ 2138482, 2140084, 2138487, 2140089 ], 
+        [ 2140085, 2151397, 2140090, 2151402 ], 
+        [ 2151398, 2154116, 2151403, 2154121 ], 
+        [ 2154117, 2164531, 2154122, 2164536 ], 
+        [ 2164532, 2164999, 2164537, 2165004 ], 
+        [ 2165000, 2166190, 2165005, 2166195 ], 
+        [ 2166191, 2168535, 2166196, 2168540 ], 
+        [ 2168536, 2168652, 2168541, 2168657 ], 
+        [ 2168653, 2168876, 2168658, 2168881 ], 
+        [ 2168877, 2175197, 2168882, 2175202 ], 
+        [ 2175198, 2176568, 2175203, 2176573 ], 
+        [ 2176569, 2185419, 2176574, 2185424 ], 
+        [ 2185420, 2198074, 2185425, 2198079 ], 
+        [ 2198075, 2205716, 2198080, 2205721 ], 
+        [ 2205717, 2206482, 2205722, 2206487 ], 
+        [ 2206483, 2214819, 2206488, 2214824 ], 
+        [ 2214820, 2215255, 2214825, 2215260 ], 
+        [ 2215256, 2216910, 2215261, 2216915 ], 
+        [ 2216911, 2219477, 2216916, 2219482 ], 
+        [ 2219478, 2219751, 2219483, 2219756 ], 
+        [ 2219752, 2222602, 2219757, 2222607 ], 
+        [ 2222603, 2224016, 2222608, 2224021 ], 
+        [ 2224017, 2229253, 2224022, 2229258 ], 
+        [ 2229254, 2229460, 2229259, 2229465 ], 
+        [ 2229461, 2231176, 2229466, 2231181 ], 
+        [ 2231177, 2236382, 2231182, 2236387 ], 
+        [ 2236383, 2245581, 2236388, 2245586 ], 
+        [ 2245582, 2245719, 2245587, 2245724 ], 
+        [ 2245720, 2245761, 2245725, 2245766 ], 
+        [ 2245762, 2249902, 2245767, 2249907 ], 
+        [ 2249903, 2254722, 2249908, 2254727 ], 
+        [ 2254723, 2262668, 2254728, 2262673 ], 
+        [ 2262669, 2276333, 2262674, 2276338 ], 
+        [ 2276334, 2278349, 2276339, 2278354 ], 
+        [ 2278350, 2278595, 2278355, 2278600 ], 
+        [ 2278596, 2282039, 2278601, 2282044 ], 
+        [ 2282040, 2309292, 2282045, 2309297 ], 
+        [ 2309293, 2309737, 2309298, 2309742 ], 
+        [ 2309738, 2314845, 2309743, 2314850 ], 
+        [ 2314846, 2315016, 2314851, 2315021 ], 
+        [ 2315017, 2320047, 2315022, 2320052 ], 
+        [ 2320048, 2320645, 2320053, 2320650 ], 
+        [ 2320646, 2330437, 2320651, 2330442 ], 
+        [ 2330438, 2338082, 2330443, 2338087 ], 
+        [ 2338083, 2345465, 2338088, 2345470 ], 
+        [ 2345466, 2347233, 2345471, 2347238 ], 
+        [ 2347234, 2348720, 2347239, 2348725 ], 
+        [ 2348721, 2351324, 2348726, 2351329 ], 
+        [ 2351325, 2352448, 2351330, 2352453 ], 
+        [ 2352449, 2353999, 2352454, 2354004 ], 
+        [ 2354000, 2359046, 2354005, 2359051 ], 
+        [ 2359047, 2361149, 2359052, 2361154 ], 
+        [ 2361150, 2374039, 2361155, 2374044 ], 
+        [ 2374040, 2385349, 2374045, 2385354 ], 
+        [ 2385350, 2388585, 2385355, 2388590 ], 
+        [ 2388586, 2391734, 2388591, 2391739 ], 
+        [ 2391735, 2392141, 2391740, 2392146 ], 
+        [ 2392142, 2393939, 2392147, 2393944 ], 
+        [ 2393940, 2395026, 2393945, 2395031 ], 
+        [ 2395027, 2395860, 2395032, 2395865 ], 
+        [ 2395861, 2398211, 2395866, 2398216 ], 
+        [ 2398212, 2398326, 2398217, 2398331 ], 
+        [ 2398327, 2402303, 2398332, 2402308 ], 
+        [ 2402304, 2408154, 2402309, 2408159 ], 
+        [ 2408155, 2409936, 2408160, 2409941 ], 
+        [ 2409937, 2410353, 2409942, 2410358 ], 
+        [ 2410354, 2411021, 2410359, 2411026 ], 
+        [ 2411022, 2419571, 2411027, 2419576 ], 
+        [ 2419572, 2424488, 2419577, 2424493 ], 
+        [ 2424489, 2427895, 2424494, 2427900 ], 
+        [ 2427896, 2433794, 2427901, 2433799 ], 
+        [ 2433795, 2434280, 2433800, 2434285 ], 
+        [ 2434281, 2436129, 2434286, 2436134 ], 
+        [ 2436130, 2446339, 2436135, 2446344 ], 
+        [ 2446340, 2446355, 2446345, 2446360 ], 
+        [ 2446356, 2447550, 2446361, 2447555 ], 
+        [ 2447551, 2456375, 2447556, 2456380 ], 
+        [ 2456376, 2459685, 2456381, 2459690 ], 
+        [ 2459686, 2467707, 2459691, 2467712 ], 
+        [ 2467708, 2489626, 2467713, 2489631 ], 
+        [ 2489627, 2490030, 2489632, 2490035 ], 
+        [ 2490031, 2494181, 2490036, 2494186 ], 
+        [ 2494182, 2494578, 2494187, 2494583 ], 
+        [ 2494579, 2498330, 2494584, 2498335 ], 
+        [ 2498331, 2501619, 2498336, 2501624 ], 
+        [ 2501620, 2502774, 2501625, 2502779 ], 
+        [ 2502775, 2505440, 2502780, 2505445 ], 
+        [ 2505441, 2507840, 2505446, 2507845 ], 
+        [ 2507841, 2513953, 2507846, 2513958 ], 
+        [ 2513954, 2518482, 2513959, 2518487 ], 
+        [ 2518483, 2518510, 2518488, 2518515 ], 
+        [ 2518511, 2519154, 2518516, 2519159 ], 
+        [ 2519155, 2521663, 2519160, 2521668 ], 
+        [ 2521664, 2522690, 2521669, 2522695 ], 
+        [ 2522691, 2535156, 2522696, 2535161 ], 
+        [ 2535157, 2536302, 2535162, 2536307 ], 
+        [ 2536303, 2539683, 2536308, 2539688 ], 
+        [ 2539684, 2540838, 2539689, 2540843 ], 
+        [ 2540839, 2542542, 2540844, 2542547 ], 
+        [ 2542543, 2549711, 2542548, 2549716 ], 
+        [ 2549712, 2549979, 2549717, 2549984 ], 
+        [ 2549980, 2550376, 2549985, 2550381 ], 
+        [ 2550377, 2550442, 2550382, 2550447 ], 
+        [ 2550443, 2552498, 2550448, 2552503 ], 
+        [ 2552499, 2556237, 2552504, 2556242 ], 
+        [ 2556238, 2561281, 2556243, 2561286 ], 
+        [ 2561282, 2562381, 2561287, 2562386 ], 
+        [ 2562382, 2571576, 2562387, 2571581 ], 
+        [ 2571577, 2573918, 2571582, 2573923 ], 
+        [ 2573919, 2575854, 2573924, 2575859 ], 
+        [ 2575855, 2579045, 2575860, 2579050 ], 
+        [ 2579046, 2588728, 2579051, 2588733 ], 
+        [ 2588729, 2591930, 2588734, 2591935 ], 
+        [ 2591931, 2601304, 2591936, 2601309 ], 
+        [ 2601305, 2614812, 2601310, 2614817 ], 
+        [ 2614813, 2614839, 2614818, 2614844 ], 
+        [ 2614840, 2622328, 2614845, 2622333 ], 
+        [ 2622329, 2627903, 2622334, 2627908 ], 
+        [ 2627904, 2648431, 2627909, 2648436 ], 
+        [ 2648432, 2651846, 2648437, 2651851 ], 
+        [ 2651847, 2660586, 2651852, 2660591 ], 
+        [ 2660587, 2663434, 2660592, 2663439 ], 
+        [ 2663435, 2674481, 2663440, 2674486 ], 
+        [ 2674482, 2674949, 2674487, 2674954 ], 
+        [ 2674950, 2676096, 2674955, 2676101 ], 
+        [ 2676097, 2676139, 2676102, 2676144 ], 
+        [ 2676140, 2678485, 2676145, 2678490 ], 
+        [ 2678486, 2678602, 2678491, 2678607 ], 
+        [ 2678603, 2678826, 2678608, 2678831 ], 
+        [ 2678827, 2681278, 2678832, 2681283 ], 
+        [ 2681279, 2684926, 2681284, 2684931 ], 
+        [ 2684927, 2685205, 2684932, 2685210 ], 
+        [ 2685206, 2692493, 2685211, 2692498 ], 
+        [ 2692494, 2714956, 2692499, 2714961 ], 
+        [ 2714957, 2716135, 2714962, 2716140 ], 
+        [ 2716136, 2716930, 2716141, 2716935 ], 
+        [ 2716931, 2717350, 2716936, 2717355 ], 
+        [ 2717351, 2717774, 2717356, 2717779 ], 
+        [ 2717775, 2718590, 2717780, 2718595 ], 
+        [ 2718591, 2720379, 2718596, 2720384 ], 
+        [ 2720380, 2723960, 2720385, 2723965 ], 
+        [ 2723961, 2725658, 2723966, 2725663 ], 
+        [ 2725659, 2731980, 2725664, 2731985 ], 
+        [ 2731981, 2738172, 2731986, 2738177 ], 
+        [ 2738173, 2748433, 2738178, 2748438 ], 
+        [ 2748434, 2748596, 2748439, 2748601 ], 
+        [ 2748597, 2749729, 2748602, 2749734 ], 
+        [ 2749730, 2752944, 2749735, 2752949 ], 
+        [ 2752945, 2753953, 2752950, 2753958 ], 
+        [ 2753954, 2760599, 2753959, 2760604 ], 
+        [ 2760600, 2761236, 2760605, 2761241 ], 
+        [ 2761237, 2763346, 2761242, 2763351 ], 
+        [ 2763347, 2764218, 2763352, 2764223 ], 
+        [ 2764219, 2773348, 2764224, 2773353 ], 
+        [ 2773349, 2779707, 2773354, 2779712 ], 
+        [ 2779708, 2792111, 2779713, 2792116 ], 
+        [ 2792112, 2794418, 2792117, 2794423 ], 
+        [ 2794419, 2795818, 2794424, 2795823 ], 
+        [ 2795819, 2796261, 2795824, 2796266 ], 
+        [ 2796262, 2798929, 2796267, 2798934 ], 
+        [ 2798930, 2799454, 2798935, 2799459 ], 
+        [ 2799455, 2813416, 2799460, 2813421 ], 
+        [ 2813417, 2813479, 2813422, 2813484 ], 
+        [ 2813480, 2814107, 2813485, 2814112 ], 
+        [ 2814108, 2825357, 2814113, 2825362 ], 
+        [ 2825358, 2826820, 2825363, 2826825 ], 
+        [ 2826821, 2828096, 2826826, 2828101 ], 
+        [ 2828097, 2830088, 2828102, 2830093 ], 
+        [ 2830089, 2834601, 2830094, 2834606 ], 
+        [ 2834602, 2836621, 2834607, 2836626 ], 
+        [ 2836622, 2836884, 2836627, 2836889 ], 
+        [ 2836885, 2837913, 2836890, 2837918 ], 
+        [ 2837914, 2840393, 2837919, 2840398 ], 
+        [ 2840394, 2843391, 2840399, 2843396 ], 
+        [ 2843392, 2843629, 2843397, 2843634 ], 
+        [ 2843630, 2844665, 2843635, 2844670 ], 
+        [ 2844666, 2847821, 2844671, 2847826 ], 
+        [ 2847822, 2849601, 2847827, 2849606 ], 
+        [ 2849602, 2853189, 2849607, 2853194 ], 
+        [ 2853190, 2860428, 2853195, 2860433 ], 
+        [ 2860429, 2862152, 2860434, 2862157 ], 
+        [ 2862153, 2862729, 2862158, 2862734 ], 
+        [ 2862730, 2869033, 2862735, 2869038 ], 
+        [ 2869034, 2869157, 2869039, 2869162 ], 
+        [ 2869158, 2882082, 2869163, 2882087 ], 
+        [ 2882083, 2894091, 2882088, 2894096 ], 
+        [ 2894092, 2895090, 2894097, 2895095 ], 
+        [ 2895091, 2900119, 2895096, 2900124 ], 
+        [ 2900120, 2900555, 2900125, 2900560 ], 
+        [ 2900556, 2902167, 2900561, 2902172 ], 
+        [ 2902168, 2902210, 2902173, 2902215 ], 
+        [ 2902211, 2904556, 2902216, 2904561 ], 
+        [ 2904557, 2904673, 2904562, 2904678 ], 
+        [ 2904674, 2904897, 2904679, 2904902 ], 
+        [ 2904898, 2907797, 2904903, 2907802 ], 
+        [ 2907798, 2910456, 2907803, 2910461 ], 
+        [ 2910457, 2911608, 2910462, 2911613 ], 
+        [ 2911609, 2914744, 2911614, 2914749 ], 
+        [ 2914745, 2914779, 2914750, 2914784 ], 
+        [ 2914780, 2918124, 2914785, 2918129 ], 
+        [ 2918125, 2921020, 2918130, 2921025 ], 
+        [ 2921021, 2921458, 2921026, 2921463 ], 
+        [ 2921459, 2926580, 2921464, 2926585 ], 
+        [ 2926581, 2930570, 2926586, 2930575 ], 
+        [ 2930571, 2934873, 2930576, 2934878 ], 
+        [ 2934874, 2942883, 2934879, 2942888 ], 
+        [ 2942884, 2950823, 2942889, 2950828 ], 
+        [ 2950824, 2952204, 2950829, 2952209 ], 
+        [ 2952205, 2954108, 2952210, 2954113 ], 
+        [ 2954109, 2958788, 2954114, 2958793 ], 
+        [ 2958789, 2962338, 2958794, 2962343 ], 
+        [ 2962339, 2962634, 2962344, 2962639 ], 
+        [ 2962635, 2963567, 2962640, 2963572 ], 
+        [ 2963568, 2965512, 2963573, 2965517 ], 
+        [ 2965513, 2965715, 2965518, 2965720 ], 
+        [ 2965716, 2969537, 2965721, 2969542 ], 
+        [ 2969538, 2969667, 2969543, 2969672 ], 
+        [ 2969668, 2971097, 2969673, 2971102 ], 
+        [ 2971098, 2971329, 2971103, 2971334 ], 
+        [ 2971330, 2971874, 2971335, 2971879 ], 
+        [ 2971875, 2972098, 2971880, 2972103 ], 
+        [ 2972099, 2978342, 2972104, 2978347 ], 
+        [ 2978343, 2984060, 2978348, 2984065 ], 
+        [ 2984061, 2988924, 2984066, 2988929 ], 
+        [ 2988925, 2994739, 2988930, 2994744 ], 
+        [ 2994740, 3002088, 2994745, 3002093 ], 
+        [ 3002089, 3009887, 3002094, 3009892 ], 
+        [ 3009888, 3014827, 3009893, 3014832 ], 
+        [ 3014828, 3020885, 3014833, 3020890 ], 
+        [ 3020886, 3022261, 3020891, 3022266 ], 
+        [ 3022262, 3029543, 3022267, 3029548 ], 
+        [ 3029544, 3030265, 3029549, 3030270 ], 
+        [ 3030266, 3032363, 3030271, 3032368 ], 
+        [ 3032364, 3033161, 3032369, 3033166 ], 
+        [ 3033162, 3042175, 3033167, 3042180 ], 
+        [ 3042176, 3042389, 3042181, 3042394 ], 
+        [ 3042390, 3049663, 3042395, 3049668 ], 
+        [ 3049664, 3050210, 3049669, 3050215 ], 
+        [ 3050211, 3051389, 3050216, 3051394 ], 
+        [ 3051390, 3052128, 3051395, 3052133 ], 
+        [ 3052129, 3052883, 3052134, 3052888 ], 
+        [ 3052884, 3054679, 3052889, 3054684 ], 
+        [ 3054680, 3055955, 3054685, 3055960 ], 
+        [ 3055956, 3056024, 3055961, 3056029 ], 
+        [ 3056025, 3062859, 3056030, 3062864 ], 
+        [ 3062860, 3063276, 3062865, 3063281 ], 
+        [ 3063277, 3064101, 3063282, 3064106 ], 
+        [ 3064102, 3065575, 3064107, 3065580 ], 
+        [ 3065576, 3065710, 3065581, 3065715 ], 
+        [ 3065711, 3066590, 3065716, 3066595 ], 
+        [ 3066591, 3075292, 3066596, 3075297 ], 
+        [ 3075293, 3076853, 3075298, 3076858 ], 
+        [ 3076854, 3080566, 3076859, 3080571 ], 
+        [ 3080567, 3080707, 3080572, 3080712 ], 
+        [ 3080708, 3080747, 3080713, 3080752 ], 
+        [ 3080748, 3080916, 3080753, 3080921 ], 
+        [ 3080917, 3082200, 3080922, 3082205 ], 
+        [ 3082201, 3085986, 3082206, 3085991 ], 
+        [ 3085987, 3086111, 3085992, 3086116 ], 
+        [ 3086112, 3088509, 3086117, 3088514 ], 
+        [ 3088510, 3091108, 3088515, 3091113 ], 
+        [ 3091109, 3094298, 3091114, 3094303 ], 
+        [ 3094299, 3098254, 3094304, 3098259 ], 
+        [ 3098255, 3100958, 3098260, 3100963 ], 
+        [ 3100959, 3101111, 3100964, 3101116 ], 
+        [ 3101112, 3101710, 3101117, 3101715 ], 
+        [ 3101711, 3107070, 3101716, 3107075 ], 
+        [ 3107071, 3108550, 3107076, 3108555 ], 
+        [ 3108551, 3116752, 3108556, 3116757 ], 
+        [ 3116753, 3119656, 3116758, 3119661 ], 
+        [ 3119657, 3120436, 3119662, 3120441 ], 
+        [ 3120437, 3122936, 3120442, 3122941 ], 
+        [ 3122937, 3125746, 3122942, 3125751 ], 
+        [ 3125747, 3126385, 3125752, 3126390 ], 
+        [ 3126386, 3129525, 3126391, 3129530 ], 
+        [ 3129526, 3129570, 3129531, 3129575 ], 
+        [ 3129571, 3129752, 3129576, 3129757 ], 
+        [ 3129753, 3132349, 3129758, 3132354 ], 
+        [ 3132350, 3139904, 3132355, 3139909 ], 
+        [ 3139905, 3143832, 3139910, 3143837 ], 
+        [ 3143833, 3144573, 3143838, 3144578 ], 
+        [ 3144574, 3148252, 3144579, 3148257 ], 
+        [ 3148253, 3150053, 3148258, 3150058 ], 
+        [ 3150054, 3152136, 3150059, 3152141 ], 
+        [ 3152137, 3161578, 3152142, 3161583 ], 
+        [ 3161579, 3164826, 3161584, 3164831 ], 
+        [ 3164827, 3164943, 3164832, 3164948 ], 
+        [ 3164944, 3167563, 3164949, 3167568 ], 
+        [ 3167564, 3168258, 3167569, 3168263 ], 
+        [ 3168259, 3170295, 3168264, 3170300 ], 
+        [ 3170296, 3172533, 3170301, 3172538 ], 
+        [ 3172534, 3176792, 3172539, 3176797 ], 
+        [ 3176793, 3177637, 3176798, 3177642 ], 
+        [ 3177638, 3178306, 3177643, 3178311 ], 
+        [ 3178307, 3186857, 3178312, 3186862 ], 
+        [ 3186858, 3196386, 3186863, 3196391 ], 
+        [ 3196387, 3197840, 3196392, 3197845 ], 
+        [ 3197841, 3210828, 3197846, 3210833 ], 
+        [ 3210829, 3212953, 3210834, 3212958 ], 
+        [ 3212954, 3226292, 3212959, 3226297 ], 
+        [ 3226293, 3226762, 3226298, 3226767 ], 
+        [ 3226763, 3230485, 3226768, 3230490 ], 
+        [ 3230486, 3233743, 3230491, 3233748 ], 
+        [ 3233744, 3234567, 3233749, 3234572 ], 
+        [ 3234568, 3235194, 3234573, 3235199 ], 
+        [ 3235195, 3235499, 3235200, 3235504 ], 
+        [ 3235500, 3243889, 3235505, 3243894 ], 
+        [ 3243890, 3259251, 3243895, 3259256 ], 
+        [ 3259252, 3262432, 3259257, 3262437 ], 
+        [ 3262433, 3262672, 3262438, 3262677 ], 
+        [ 3262673, 3266686, 3262678, 3266691 ], 
+        [ 3266687, 3269046, 3266692, 3269051 ], 
+        [ 3269047, 3269620, 3269052, 3269625 ], 
+        [ 3269621, 3272036, 3269626, 3272041 ], 
+        [ 3272037, 3272516, 3272042, 3272521 ], 
+        [ 3272517, 3272796, 3272522, 3272801 ], 
+        [ 3272797, 3278978, 3272802, 3278983 ], 
+        [ 3278979, 3279467, 3278984, 3279472 ], 
+        [ 3279468, 3280283, 3279473, 3280288 ], 
+        [ 3280284, 3282531, 3280289, 3282536 ], 
+        [ 3282532, 3286305, 3282537, 3286310 ], 
+        [ 3286306, 3286606, 3286311, 3286611 ], 
+        [ 3286607, 3287302, 3286612, 3287307 ], 
+        [ 3287303, 3290776, 3287308, 3290781 ], 
+        [ 3290777, 3294305, 3290782, 3294310 ], 
+        [ 3294306, 3298010, 3294311, 3298015 ], 
+        [ 3298011, 3298799, 3298016, 3298804 ], 
+        [ 3298800, 3299744, 3298805, 3299749 ], 
+        [ 3299745, 3302402, 3299750, 3302407 ], 
+        [ 3302403, 3314750, 3302408, 3314755 ], 
+        [ 3314751, 3314777, 3314756, 3314782 ], 
+        [ 3314778, 3315543, 3314783, 3315548 ], 
+        [ 3315544, 3319495, 3315549, 3319500 ], 
+        [ 3319496, 3321744, 3319501, 3321749 ], 
+        [ 3321745, 3324685, 3321750, 3324690 ], 
+        [ 3324686, 3331241, 3324691, 3331246 ], 
+        [ 3331242, 3345624, 3331247, 3345629 ], 
+        [ 3345625, 3349729, 3345630, 3349734 ], 
+        [ 3349730, 3350579, 3349735, 3350584 ], 
+        [ 3350580, 3353994, 3350585, 3353999 ], 
+        [ 3353995, 3355238, 3354000, 3355243 ], 
+        [ 3355239, 3360120, 3355244, 3360125 ], 
+        [ 3360121, 3368828, 3360126, 3368833 ], 
+        [ 3368829, 3376335, 3368834, 3376340 ], 
+        [ 3376336, 3380722, 3376341, 3380727 ], 
+        [ 3380723, 3381309, 3380728, 3381314 ], 
+        [ 3381310, 3382080, 3381315, 3382085 ], 
+        [ 3382081, 3384674, 3382086, 3384679 ], 
+        [ 3384675, 3385188, 3384680, 3385193 ], 
+        [ 3385189, 3388713, 3385194, 3388718 ], 
+        [ 3388714, 3392079, 3388719, 3392084 ], 
+        [ 3392080, 3394131, 3392085, 3394136 ], 
+        [ 3394132, 3394381, 3394137, 3394386 ], 
+        [ 3394382, 3395362, 3394387, 3395367 ], 
+        [ 3395363, 3396615, 3395368, 3396620 ], 
+        [ 3396616, 3399453, 3396621, 3399458 ], 
+        [ 3399454, 3400585, 3399459, 3400590 ], 
+        [ 3400586, 3405494, 3400591, 3405499 ], 
+        [ 3405495, 3413040, 3405500, 3413045 ], 
+        [ 3413041, 3413955, 3413046, 3413960 ], 
+        [ 3413956, 3413965, 3413961, 3413970 ], 
+        [ 3413966, 3415450, 3413971, 3415455 ], 
+        [ 3415451, 3415543, 3415456, 3415548 ], 
+        [ 3415544, 3415693, 3415549, 3415698 ], 
+        [ 3415694, 3416866, 3415699, 3416871 ], 
+        [ 3416867, 3421885, 3416872, 3421890 ], 
+        [ 3421886, 3425142, 3421891, 3425147 ], 
+        [ 3425143, 3437815, 3425148, 3437820 ], 
+        [ 3437816, 3440231, 3437821, 3440236 ], 
+        [ 3440232, 3442385, 3440237, 3442390 ], 
+        [ 3442386, 3449766, 3442391, 3449771 ], 
+        [ 3449767, 3455799, 3449772, 3455804 ], 
+        [ 3455800, 3473047, 3455805, 3473052 ], 
+        [ 3473048, 3483375, 3473053, 3483380 ], 
+        [ 3483376, 3505500, 3483381, 3505505 ], 
+        [ 3505501, 3514082, 3505506, 3514087 ], 
+        [ 3514083, 3522092, 3514088, 3522097 ], 
+        [ 3522093, 3522111, 3522098, 3522116 ], 
+        [ 3522112, 3522767, 3522117, 3522772 ], 
+        [ 3522768, 3531627, 3522773, 3531632 ], 
+        [ 3531628, 3537780, 3531633, 3537785 ], 
+        [ 3537781, 3540644, 3537786, 3540649 ], 
+        [ 3540645, 3543017, 3540650, 3543022 ], 
+        [ 3543018, 3543842, 3543023, 3543847 ], 
+        [ 3543843, 3545546, 3543848, 3545551 ], 
+        [ 3545547, 3547077, 3545552, 3547082 ], 
+        [ 3547078, 3547149, 3547083, 3547154 ], 
+        [ 3547150, 3548533, 3547155, 3548538 ], 
+        [ 3548534, 3549829, 3548539, 3549834 ], 
+        [ 3549830, 3549935, 3549835, 3549940 ], 
+        [ 3549936, 3550203, 3549941, 3550208 ], 
+        [ 3550204, 3550227, 3550209, 3550232 ], 
+        [ 3550228, 3551480, 3550233, 3551485 ], 
+        [ 3551481, 3552210, 3551486, 3552215 ], 
+        [ 3552211, 3562847, 3552216, 3562852 ], 
+        [ 3562848, 3563068, 3562853, 3563073 ], 
+        [ 3563069, 3563973, 3563074, 3563978 ], 
+        [ 3563974, 3565130, 3563979, 3565135 ], 
+        [ 3565131, 3565565, 3565136, 3565570 ], 
+        [ 3565566, 3566132, 3565571, 3566137 ], 
+        [ 3566133, 3567018, 3566138, 3567023 ], 
+        [ 3567019, 3567627, 3567024, 3567632 ], 
+        [ 3567628, 3570838, 3567633, 3570843 ], 
+        [ 3570839, 3574124, 3570844, 3574129 ], 
+        [ 3574125, 3575098, 3574130, 3575103 ], 
+        [ 3575099, 3575586, 3575104, 3575591 ], 
+        [ 3575587, 3576602, 3575592, 3576607 ], 
+        [ 3576603, 3590383, 3576608, 3590388 ], 
+        [ 3590384, 3594697, 3590389, 3594702 ], 
+        [ 3594698, 3597307, 3594703, 3597312 ], 
+        [ 3597308, 3598837, 3597313, 3598842 ], 
+        [ 3598838, 3599839, 3598843, 3599844 ], 
+        [ 3599840, 3603578, 3599845, 3603583 ], 
+        [ 3603579, 3609322, 3603584, 3609327 ], 
+        [ 3609323, 3614549, 3609328, 3614554 ], 
+        [ 3614550, 3618664, 3614555, 3618669 ], 
+        [ 3618665, 3619899, 3618670, 3619904 ], 
+        [ 3619900, 3624824, 3619905, 3624829 ], 
+        [ 3624825, 3628159, 3624830, 3628164 ], 
+        [ 3628160, 3628423, 3628165, 3628428 ], 
+        [ 3628424, 3630285, 3628429, 3630290 ], 
+        [ 3630286, 3630486, 3630291, 3630491 ], 
+        [ 3630487, 3634237, 3630492, 3634242 ], 
+        [ 3634238, 3639209, 3634243, 3639214 ], 
+        [ 3639210, 3652188, 3639215, 3652193 ], 
+        [ 3652189, 3659027, 3652194, 3659032 ], 
+        [ 3659028, 3659079, 3659033, 3659084 ], 
+        [ 3659080, 3659207, 3659085, 3659212 ], 
+        [ 3659208, 3667507, 3659213, 3667512 ], 
+        [ 3667508, 3667741, 3667513, 3667746 ], 
+        [ 3667742, 3668429, 3667747, 3668434 ], 
+        [ 3668430, 3670470, 3668435, 3670475 ], 
+        [ 3670471, 3673148, 3670476, 3673153 ], 
+        [ 3673149, 3674083, 3673154, 3674088 ], 
+        [ 3674084, 3678214, 3674089, 3678219 ], 
+        [ 3678215, 3680677, 3678220, 3680682 ], 
+        [ 3680678, 3684205, 3680683, 3684210 ], 
+        [ 3684206, 3690753, 3684211, 3690758 ], 
+        [ 3690754, 3698350, 3690759, 3698355 ], 
+        [ 3698351, 3699287, 3698356, 3699292 ], 
+        [ 3699288, 3702298, 3699293, 3702303 ], 
+        [ 3702299, 3706224, 3702304, 3706229 ], 
+        [ 3706225, 3706948, 3706230, 3706953 ], 
+        [ 3706949, 3709050, 3706954, 3709055 ], 
+        [ 3709051, 3725109, 3709056, 3725114 ], 
+        [ 3725110, 3731514, 3725115, 3731519 ], 
+        [ 3731515, 3736239, 3731520, 3736244 ], 
+        [ 3736240, 3736361, 3736245, 3736366 ], 
+        [ 3736362, 3738698, 3736367, 3738703 ], 
+        [ 3738699, 3745350, 3738704, 3745355 ], 
+        [ 3745351, 3747516, 3745356, 3747521 ], 
+        [ 3747517, 3748248, 3747522, 3748253 ], 
+        [ 3748249, 3750382, 3748254, 3750387 ], 
+        [ 3750383, 3761090, 3750388, 3761095 ], 
+        [ 3761091, 3762084, 3761096, 3762089 ], 
+        [ 3762085, 3762616, 3762090, 3762621 ], 
+        [ 3762617, 3769672, 3762622, 3769677 ], 
+        [ 3769673, 3769809, 3769678, 3769814 ], 
+        [ 3769810, 3769962, 3769815, 3769967 ], 
+        [ 3769963, 3774893, 3769968, 3774898 ], 
+        [ 3774894, 3776322, 3774899, 3776327 ], 
+        [ 3776323, 3778089, 3776328, 3778094 ], 
+        [ 3778090, 3784214, 3778095, 3784219 ], 
+        [ 3784215, 3799015, 3784220, 3799020 ], 
+        [ 3799016, 3806065, 3799021, 3806070 ], 
+        [ 3806066, 3807768, 3806071, 3807773 ], 
+        [ 3807769, 3816682, 3807774, 3816687 ], 
+        [ 3816683, 3817044, 3816688, 3817049 ], 
+        [ 3817045, 3817768, 3817050, 3817773 ], 
+        [ 3817769, 3822167, 3817774, 3822172 ], 
+        [ 3822168, 3824032, 3822173, 3824037 ], 
+        [ 3824033, 3828542, 3824038, 3828547 ], 
+        [ 3828543, 3832118, 3828548, 3832123 ], 
+        [ 3832119, 3832453, 3832124, 3832458 ], 
+        [ 3832454, 3837573, 3832459, 3837578 ], 
+        [ 3837574, 3842658, 3837579, 3842663 ], 
+        [ 3842659, 3844599, 3842664, 3844604 ], 
+        [ 3844600, 3844788, 3844605, 3844793 ], 
+        [ 3844789, 3850826, 3844794, 3850831 ], 
+        [ 3850827, 3855395, 3850832, 3855400 ], 
+        [ 3855396, 3860530, 3855401, 3860535 ], 
+        [ 3860531, 3873056, 3860536, 3873061 ], 
+        [ 3873057, 3880197, 3873062, 3880202 ], 
+        [ 3880198, 3882820, 3880203, 3882825 ], 
+        [ 3882821, 3883310, 3882826, 3883315 ], 
+        [ 3883311, 3885744, 3883316, 3885749 ], 
+        [ 3885745, 3891218, 3885750, 3891223 ], 
+        [ 3891219, 3891354, 3891224, 3891359 ], 
+        [ 3891355, 3894419, 3891360, 3894424 ], 
+        [ 3894420, 3900500, 3894425, 3900505 ], 
+        [ 3900501, 3907313, 3900506, 3907318 ], 
+        [ 3907314, 3908919, 3907319, 3908924 ], 
+        [ 3908920, 3909807, 3908925, 3909812 ], 
+        [ 3909808, 3909977, 3909813, 3909982 ], 
+        [ 3909978, 3930585, 3909983, 3930590 ], 
+        [ 3930586, 3933363, 3930591, 3933368 ], 
+        [ 3933364, 3935176, 3933369, 3935181 ], 
+        [ 3935177, 3936871, 3935182, 3936876 ], 
+        [ 3936872, 3945198, 3936877, 3945203 ], 
+        [ 3945199, 3946390, 3945204, 3946395 ], 
+        [ 3946391, 3946986, 3946396, 3946991 ], 
+        [ 3946987, 3956408, 3946992, 3956413 ], 
+        [ 3956409, 3958333, 3956414, 3958338 ], 
+        [ 3958334, 3959031, 3958339, 3959036 ], 
+        [ 3959032, 3960932, 3959037, 3960937 ], 
+        [ 3960933, 3964190, 3960938, 3964195 ], 
+        [ 3964191, 3969413, 3964196, 3969418 ], 
+        [ 3969414, 3972146, 3969419, 3972151 ], 
+        [ 3972147, 3972344, 3972152, 3972349 ], 
+        [ 3972345, 3978065, 3972350, 3978070 ], 
+        [ 3978066, 3981977, 3978071, 3981982 ], 
+        [ 3981978, 3984768, 3981983, 3984773 ], 
+        [ 3984769, 3984918, 3984774, 3984923 ], 
+        [ 3984919, 3985704, 3984924, 3985709 ], 
+        [ 3985705, 3995454, 3985710, 3995459 ], 
+        [ 3995455, 3997410, 3995460, 3997415 ], 
+        [ 3997411, 4000982, 3997416, 4000987 ], 
+        [ 4000983, 4002514, 4000988, 4002519 ], 
+        [ 4002515, 4005689, 4002520, 4005694 ], 
+        [ 4005690, 4016078, 4005695, 4016083 ], 
+        [ 4016079, 4017237, 4016084, 4017242 ], 
+        [ 4017238, 4018412, 4017243, 4018417 ], 
+        [ 4018413, 4018717, 4018418, 4018722 ], 
+        [ 4018718, 4023281, 4018723, 4023286 ], 
+        [ 4023282, 4032076, 4023287, 4032081 ], 
+        [ 4032077, 4041164, 4032082, 4041169 ], 
+        [ 4041165, 4041295, 4041170, 4041300 ], 
+        [ 4041296, 4041920, 4041301, 4041925 ], 
+        [ 4041921, 4046747, 4041926, 4046752 ], 
+        [ 4046748, 4052606, 4046753, 4052611 ], 
+        [ 4052607, 4054469, 4052612, 4054474 ], 
+        [ 4054470, 4054629, 4054475, 4054634 ], 
+        [ 4054630, 4054968, 4054635, 4054973 ], 
+        [ 4054969, 4055333, 4054974, 4055338 ], 
+        [ 4055334, 4056058, 4055339, 4056063 ], 
+        [ 4056059, 4059084, 4056064, 4059089 ], 
+        [ 4059085, 4062508, 4059090, 4062513 ], 
+        [ 4062509, 4065383, 4062514, 4065388 ], 
+        [ 4065384, 4065643, 4065389, 4065648 ], 
+        [ 4065644, 4069949, 4065649, 4069954 ], 
+        [ 4069950, 4078343, 4069955, 4078348 ], 
+        [ 4078344, 4083896, 4078349, 4083901 ], 
+        [ 4083897, 4085884, 4083902, 4085889 ], 
+        [ 4085885, 4090152, 4085890, 4090157 ], 
+        [ 4090153, 4093908, 4090158, 4093913 ], 
+        [ 4093909, 4094118, 4093914, 4094123 ], 
+        [ 4094119, 4095249, 4094124, 4095254 ], 
+        [ 4095250, 4097811, 4095255, 4097816 ], 
+        [ 4097812, 4101896, 4097817, 4101901 ], 
+        [ 4101897, 4107088, 4101902, 4107093 ], 
+        [ 4107089, 4107551, 4107094, 4107556 ], 
+        [ 4107552, 4107580, 4107557, 4107585 ], 
+        [ 4107581, 4109180, 4107586, 4109185 ], 
+        [ 4109181, 4110537, 4109186, 4110542 ], 
+        [ 4110538, 4116491, 4110543, 4116496 ], 
+        [ 4116492, 4117909, 4116497, 4117914 ], 
+        [ 4117910, 4118469, 4117915, 4118474 ], 
+        [ 4118470, 4123661, 4118475, 4123666 ], 
+        [ 4123662, 4123865, 4123667, 4123870 ], 
+        [ 4123866, 4125127, 4123871, 4125132 ], 
+        [ 4125128, 4129187, 4125133, 4129192 ], 
+        [ 4129188, 4132972, 4129193, 4132977 ], 
+        [ 4132973, 4134272, 4132978, 4134277 ], 
+        [ 4134273, 4135470, 4134278, 4135475 ], 
+        [ 4135471, 4136837, 4135476, 4136842 ], 
+        [ 4136838, 4146292, 4136843, 4146297 ], 
+        [ 4146293, 4146443, 4146298, 4146448 ], 
+        [ 4146444, 4148935, 4146449, 4148940 ], 
+        [ 4148936, 4162265, 4148941, 4162270 ], 
+        [ 4162266, 4164781, 4162271, 4164786 ], 
+        [ 4164782, 4170898, 4164787, 4170903 ], 
+        [ 4170899, 4175870, 4170904, 4175875 ], 
+        [ 4175871, 4175960, 4175876, 4175965 ], 
+        [ 4175961, 4180869, 4175966, 4180874 ], 
+        [ 4180870, 4181479, 4180875, 4181484 ], 
+        [ 4181480, 4187785, 4181485, 4187790 ], 
+        [ 4187786, 4192423, 4187791, 4192428 ], 
+        [ 4192424, 4192625, 4192429, 4192630 ], 
+        [ 4192626, 4194747, 4192631, 4194752 ], 
+        [ 4194748, 4195600, 4194753, 4195605 ], 
+        [ 4195601, 4195842, 4195606, 4195847 ], 
+        [ 4195843, 4197634, 4195848, 4197639 ], 
+        [ 4197635, 4198036, 4197640, 4198041 ], 
+        [ 4198037, 4205660, 4198042, 4205665 ], 
+        [ 4205661, 4213510, 4205666, 4213515 ], 
+        [ 4213511, 4217238, 4213516, 4217243 ], 
+        [ 4217239, 4221217, 4217244, 4221222 ], 
+        [ 4221218, 4225159, 4221223, 4225164 ], 
+        [ 4225160, 4226183, 4225165, 4226188 ], 
+        [ 4226184, 4228901, 4226189, 4228906 ], 
+        [ 4228902, 4229774, 4228907, 4229779 ], 
+        [ 4229775, 4230559, 4229780, 4230564 ], 
+        [ 4230560, 4235572, 4230565, 4235577 ], 
+        [ 4235573, 4242029, 4235578, 4242034 ], 
+        [ 4242030, 4242765, 4242035, 4242770 ], 
+        [ 4242766, 4244054, 4242771, 4244059 ], 
+        [ 4244055, 4245334, 4244060, 4245339 ], 
+        [ 4245335, 4249019, 4245340, 4249024 ], 
+        [ 4249020, 4249100, 4249025, 4249105 ], 
+        [ 4249101, 4256705, 4249106, 4256710 ], 
+        [ 4256706, 4259509, 4256711, 4259514 ], 
+        [ 4259510, 4261410, 4259515, 4261415 ], 
+        [ 4261411, 4270525, 4261416, 4270530 ], 
+        [ 4270526, 4274109, 4270531, 4274114 ], 
+        [ 4274110, 4281849, 4274115, 4281854 ], 
+        [ 4281850, 4284762, 4281855, 4284767 ], 
+        [ 4284763, 4303042, 4284768, 4303047 ], 
+        [ 4303043, 4303258, 4303048, 4303263 ], 
+        [ 4303259, 4306632, 4303264, 4306637 ], 
+        [ 4306633, 4312216, 4306638, 4312221 ], 
+        [ 4312217, 4314890, 4312222, 4314895 ], 
+        [ 4314891, 4316460, 4314896, 4316465 ], 
+        [ 4316461, 4316626, 4316466, 4316631 ], 
+        [ 4316627, 4318092, 4316632, 4318097 ], 
+        [ 4318093, 4318604, 4318098, 4318609 ], 
+        [ 4318605, 4318772, 4318610, 4318777 ], 
+        [ 4318773, 4321424, 4318778, 4321429 ], 
+        [ 4321425, 4321489, 4321430, 4321494 ], 
+        [ 4321490, 4327535, 4321495, 4327540 ], 
+        [ 4327536, 4329548, 4327541, 4329553 ], 
+        [ 4329549, 4331509, 4329554, 4331514 ], 
+        [ 4331510, 4332147, 4331515, 4332152 ], 
+        [ 4332148, 4334445, 4332153, 4334450 ], 
+        [ 4334446, 4338820, 4334451, 4338825 ], 
+        [ 4338821, 4339739, 4338826, 4339744 ], 
+        [ 4339740, 4343682, 4339745, 4343687 ], 
+        [ 4343683, 4348264, 4343688, 4348269 ], 
+        [ 4348265, 4352206, 4348270, 4352211 ], 
+        [ 4352207, 4356621, 4352212, 4356626 ], 
+        [ 4356622, 4366184, 4356627, 4366189 ], 
+        [ 4366185, 4374134, 4366190, 4374139 ], 
+        [ 4374135, 4374749, 4374140, 4374754 ], 
+        [ 4374750, 4388049, 4374755, 4388054 ], 
+        [ 4388050, 4388548, 4388055, 4388553 ], 
+        [ 4388549, 4395214, 4388554, 4395219 ], 
+        [ 4395215, 4397725, 4395220, 4397730 ], 
+        [ 4397726, 4401917, 4397731, 4401922 ], 
+        [ 4401918, 4401962, 4401923, 4401967 ], 
+        [ 4401963, 4404470, 4401968, 4404475 ], 
+        [ 4404471, 4404603, 4404476, 4404608 ], 
+        [ 4404604, 4404677, 4404609, 4404682 ], 
+        [ 4404678, 4407845, 4404683, 4407850 ], 
+        [ 4407846, 4415693, 4407851, 4415698 ], 
+        [ 4415694, 4415957, 4415699, 4415962 ], 
+        [ 4415958, 4426334, 4415963, 4426339 ], 
+        [ 4426335, 4427143, 4426340, 4427148 ], 
+        [ 4427144, 4432989, 4427149, 4432994 ], 
+        [ 4432990, 4433640, 4432995, 4433645 ], 
+        [ 4433641, 4435236, 4433646, 4435241 ], 
+        [ 4435237, 4450981, 4435242, 4450986 ], 
+        [ 4450982, 4452121, 4450987, 4452126 ], 
+        [ 4452122, 4454417, 4452127, 4454422 ], 
+        [ 4454418, 4455164, 4454423, 4455169 ], 
+        [ 4455165, 4459226, 4455170, 4459231 ], 
+        [ 4459227, 4462863, 4459232, 4462868 ], 
+        [ 4462864, 4469714, 4462869, 4469719 ], 
+        [ 4469715, 4471008, 4469720, 4471013 ], 
+        [ 4471009, 4473114, 4471014, 4473119 ], 
+        [ 4473115, 4477852, 4473120, 4477857 ], 
+        [ 4477853, 4477874, 4477858, 4477879 ], 
+        [ 4477875, 4482921, 4477880, 4482926 ], 
+        [ 4482922, 4489809, 4482927, 4489814 ], 
+        [ 4489810, 4490912, 4489815, 4490917 ], 
+        [ 4490913, 4491974, 4490918, 4491979 ], 
+        [ 4491975, 4492157, 4491980, 4492162 ], 
+        [ 4492158, 4493614, 4492163, 4493619 ], 
+        [ 4493615, 4496829, 4493620, 4496834 ], 
+        [ 4496830, 4497697, 4496835, 4497702 ], 
+        [ 4497698, 4499157, 4497703, 4499162 ], 
+        [ 4499158, 4502248, 4499163, 4502253 ], 
+        [ 4502249, 4504493, 4502254, 4504498 ], 
+        [ 4504494, 4505336, 4504499, 4505341 ], 
+        [ 4505337, 4506680, 4505342, 4506685 ], 
+        [ 4506681, 4506961, 4506686, 4506966 ], 
+        [ 4506962, 4507601, 4506967, 4507606 ], 
+        [ 4507602, 4513351, 4507607, 4513356 ], 
+        [ 4513352, 4516356, 4513357, 4516361 ], 
+        [ 4516357, 4520650, 4516362, 4520655 ], 
+        [ 4520651, 4528820, 4520656, 4528825 ], 
+        [ 4528821, 4535971, 4528826, 4535976 ], 
+        [ 4535972, 4540172, 4535977, 4540177 ], 
+        [ 4540173, 4551230, 4540178, 4551235 ], 
+        [ 4551231, 4552997, 4551236, 4553002 ], 
+        [ 4552998, 4555491, 4553003, 4555496 ], 
+        [ 4555492, 4558033, 4555497, 4558038 ], 
+        [ 4558034, 4562123, 4558039, 4562128 ], 
+        [ 4562124, 4563100, 4562129, 4563105 ], 
+        [ 4563101, 4564639, 4563106, 4564644 ], 
+        [ 4564640, 4566006, 4564645, 4566011 ], 
+        [ 4566007, 4575457, 4566012, 4575462 ], 
+        [ 4575458, 4575809, 4575463, 4575814 ], 
+        [ 4575810, 4576253, 4575815, 4576258 ], 
+        [ 4576254, 4579647, 4576259, 4579652 ], 
+        [ 4579648, 4588823, 4579653, 4588828 ], 
+        [ 4588824, 4589254, 4588829, 4589259 ], 
+        [ 4589255, 4598670, 4589260, 4598675 ], 
+        [ 4598671, 4601105, 4598676, 4601110 ], 
+        [ 4601106, 4602566, 4601111, 4602571 ], 
+        [ 4602567, 4612068, 4602572, 4612073 ], 
+        [ 4612069, 4615603, 4612074, 4615608 ], 
+        [ 4615604, 4627887, 4615609, 4627892 ], 
+        [ 4627888, 4631394, 4627893, 4631399 ], 
+        [ 4631395, 4631631, 4631400, 4631636 ], 
+        [ 4631632, 4635963, 4631637, 4635968 ], 
+        [ 4635964, 4641129, 4635969, 4641134 ], 
+        [ 4641130, 4642980, 4641135, 4642985 ], 
+        [ 4642981, 4643635, 4642986, 4643640 ], 
+        [ 4643636, 4644147, 4643641, 4644152 ], 
+        [ 4644148, 4649332, 4644153, 4649337 ], 
+        [ 4649333, 4649464, 4649338, 4649469 ], 
+        [ 4649465, 4656366, 4649470, 4656371 ], 
+        [ 4656367, 4656864, 4656372, 4656869 ], 
+        [ 4656865, 4656933, 4656870, 4656938 ], 
+        [ 4656934, 4660056, 4656939, 4660061 ], 
+        [ 4660057, 4665881, 4660062, 4665886 ], 
+        [ 4665882, 4668837, 4665887, 4668842 ], 
+        [ 4668838, 4672873, 4668843, 4672878 ], 
+        [ 4672874, 4681462, 4672879, 4681467 ], 
+        [ 4681463, 4696368, 4681468, 4696373 ], 
+        [ 4696369, 4699474, 4696374, 4699479 ], 
+        [ 4699475, 4704523, 4699480, 4704528 ], 
+        [ 4704524, 4706008, 4704529, 4706013 ], 
+        [ 4706009, 4706510, 4706014, 4706515 ], 
+        [ 4706511, 4711295, 4706516, 4711300 ], 
+        [ 4711296, 4711543, 4711301, 4711548 ], 
+        [ 4711544, 4711935, 4711549, 4711940 ], 
+        [ 4711936, 4712790, 4711941, 4712795 ], 
+        [ 4712791, 4713126, 4712796, 4713131 ], 
+        [ 4713127, 4713730, 4713132, 4713735 ], 
+        [ 4713731, 4717619, 4713736, 4717624 ], 
+        [ 4717620, 4724224, 4717625, 4724229 ], 
+        [ 4724225, 4725868, 4724230, 4725873 ], 
+        [ 4725869, 4727653, 4725874, 4727658 ], 
+        [ 4727654, 4729069, 4727659, 4729074 ], 
+        [ 4729070, 4730833, 4729075, 4730838 ], 
+        [ 4730834, 4733099, 4730839, 4733104 ], 
+        [ 4733100, 4733576, 4733105, 4733581 ], 
+        [ 4733577, 4736754, 4733582, 4736759 ], 
+        [ 4736755, 4741684, 4736760, 4741689 ], 
+        [ 4741685, 4744830, 4741690, 4744835 ], 
+        [ 4744831, 4746768, 4744836, 4746773 ], 
+        [ 4746769, 4749037, 4746774, 4749042 ], 
+        [ 4749038, 4749801, 4749043, 4749806 ], 
+        [ 4749802, 4749864, 4749807, 4749869 ], 
+        [ 4749865, 4750966, 4749870, 4750971 ], 
+        [ 4750967, 4752965, 4750972, 4752970 ], 
+        [ 4752966, 4754237, 4752971, 4754242 ], 
+        [ 4754238, 4757191, 4754243, 4757196 ], 
+        [ 4757192, 4762052, 4757197, 4762057 ], 
+        [ 4762053, 4764164, 4762058, 4764169 ], 
+        [ 4764165, 4766341, 4764170, 4766346 ], 
+        [ 4766342, 4767519, 4766347, 4767524 ], 
+        [ 4767520, 4769451, 4767525, 4769456 ], 
+        [ 4769452, 4770366, 4769457, 4770371 ], 
+        [ 4770367, 4774504, 4770372, 4774509 ], 
+        [ 4774505, 4779310, 4774510, 4779315 ], 
+        [ 4779311, 4784713, 4779316, 4784718 ], 
+        [ 4784714, 4784960, 4784719, 4784965 ], 
+        [ 4784961, 4789181, 4784966, 4789186 ], 
+        [ 4789182, 4792894, 4789187, 4792899 ], 
+        [ 4792895, 4804321, 4792900, 4804326 ], 
+        [ 4804322, 4807780, 4804327, 4807785 ], 
+        [ 4807781, 4808367, 4807786, 4808372 ], 
+        [ 4808368, 4811025, 4808373, 4811030 ], 
+        [ 4811026, 4813062, 4811031, 4813067 ], 
+        [ 4813063, 4822160, 4813068, 4822165 ], 
+        [ 4822161, 4833156, 4822166, 4833161 ], 
+        [ 4833157, 4839621, 4833162, 4839626 ], 
+        [ 4839622, 4853316, 4839627, 4853321 ], 
+        [ 4853317, 4862268, 4853322, 4862273 ], 
+        [ 4862269, 4862689, 4862274, 4862694 ], 
+        [ 4862690, 4863453, 4862695, 4863458 ], 
+        [ 4863454, 4863657, 4863459, 4863662 ], 
+        [ 4863658, 4867215, 4863663, 4867220 ], 
+        [ 4867216, 4867943, 4867221, 4867948 ], 
+        [ 4867944, 4870367, 4867949, 4870372 ], 
+        [ 4870368, 4871260, 4870373, 4871265 ], 
+        [ 4871261, 4871925, 4871266, 4871930 ], 
+        [ 4871926, 4872824, 4871931, 4872829 ], 
+        [ 4872825, 4879935, 4872830, 4879940 ], 
+        [ 4879936, 4881593, 4879941, 4881598 ], 
+        [ 4881594, 4882087, 4881599, 4882092 ], 
+        [ 4882088, 4889351, 4882093, 4889356 ], 
+        [ 4889352, 4890443, 4889357, 4890448 ], 
+        [ 4890444, 4898485, 4890449, 4898490 ], 
+        [ 4898486, 4901057, 4898491, 4901062 ], 
+        [ 4901058, 4904245, 4901063, 4904250 ], 
+        [ 4904246, 4904668, 4904251, 4904673 ], 
+        [ 4904669, 4904984, 4904674, 4904989 ], 
+        [ 4904985, 4914224, 4904990, 4914229 ], 
+        [ 4914225, 4916537, 4914230, 4916542 ], 
+        [ 4916538, 4919908, 4916543, 4919913 ], 
+        [ 4919909, 4926663, 4919914, 4926668 ], 
+        [ 4926664, 4929329, 4926669, 4929334 ], 
+        [ 4929330, 4930673, 4929335, 4930678 ], 
+        [ 4930674, 4930954, 4930679, 4930959 ], 
+        [ 4930955, 4931594, 4930960, 4931599 ], 
+        [ 4931595, 4937282, 4931600, 4937287 ], 
+        [ 4937283, 4939667, 4937288, 4939672 ], 
+        [ 4939668, 4941837, 4939673, 4941842 ], 
+        [ 4941838, 4947030, 4941843, 4947035 ], 
+        [ 4947031, 4951071, 4947036, 4951076 ], 
+        [ 4951072, 4953999, 4951077, 4954004 ], 
+        [ 4954000, 4955481, 4954005, 4955486 ], 
+        [ 4955482, 4959224, 4955487, 4959229 ], 
+        [ 4959225, 4974624, 4959230, 4974629 ], 
+        [ 4974625, 4977429, 4974630, 4977434 ], 
+        [ 4977430, 4984448, 4977435, 4984453 ], 
+        [ 4984449, 4986670, 4984454, 4986675 ], 
+        [ 4986671, 4992038, 4986676, 4992043 ], 
+        [ 4992039, 4993811, 4992044, 4993816 ], 
+        [ 4993812, 4995631, 4993817, 4995636 ], 
+        [ 4995632, 4996624, 4995637, 4996629 ], 
+        [ 4996625, 4996668, 4996630, 4996673 ], 
+        [ 4996669, 4998818, 4996674, 4998823 ], 
+        [ 4998819, 5004186, 4998824, 5004191 ], 
+        [ 5004187, 5013598, 5004192, 5013603 ], 
+        [ 5013599, 5016180, 5013604, 5016185 ], 
+        [ 5016181, 5018455, 5016186, 5018460 ], 
+        [ 5018456, 5026770, 5018461, 5026775 ], 
+        [ 5026771, 5028841, 5026776, 5028846 ], 
+        [ 5028842, 5031862, 5028847, 5031867 ], 
+        [ 5031863, 5036331, 5031868, 5036336 ], 
+        [ 5036332, 5037861, 5036337, 5037866 ], 
+        [ 5037862, 5038887, 5037867, 5038892 ], 
+        [ 5038888, 5040440, 5038893, 5040445 ], 
+        [ 5040441, 5042902, 5040446, 5042907 ], 
+        [ 5042903, 5044827, 5042908, 5044832 ], 
+        [ 5044828, 5050524, 5044833, 5050529 ], 
+        [ 5050525, 5053866, 5050530, 5053871 ], 
+        [ 5053867, 5054707, 5053872, 5054712 ], 
+        [ 5054708, 5055021, 5054713, 5055026 ], 
+        [ 5055022, 5057873, 5055027, 5057878 ], 
+        [ 5057874, 5059734, 5057879, 5059739 ], 
+        [ 5059735, 5061548, 5059740, 5061553 ], 
+        [ 5061549, 5063342, 5061554, 5063347 ], 
+        [ 5063343, 5064119, 5063348, 5064124 ], 
+        [ 5064120, 5064638, 5064125, 5064643 ], 
+        [ 5064639, 5068774, 5064644, 5068779 ], 
+        [ 5068775, 5069157, 5068780, 5069162 ], 
+        [ 5069158, 5069375, 5069163, 5069380 ], 
+        [ 5069376, 5071533, 5069381, 5071538 ], 
+        [ 5071534, 5072259, 5071539, 5072264 ], 
+        [ 5072260, 5072332, 5072265, 5072337 ], 
+        [ 5072333, 5074288, 5072338, 5074293 ], 
+        [ 5074289, 5087508, 5074294, 5087513 ], 
+        [ 5087509, 5088409, 5087514, 5088414 ], 
+        [ 5088410, 5093963, 5088415, 5093968 ], 
+        [ 5093964, 5098261, 5093969, 5098266 ], 
+        [ 5098262, 5116037, 5098267, 5116042 ], 
+        [ 5116038, 5116647, 5116043, 5116652 ], 
+        [ 5116648, 5119282, 5116653, 5119287 ], 
+        [ 5119283, 5132940, 5119288, 5132945 ], 
+        [ 5132941, 5133405, 5132946, 5133410 ], 
+        [ 5133406, 5134558, 5133411, 5134563 ], 
+        [ 5134559, 5138432, 5134564, 5138437 ], 
+        [ 5138433, 5138944, 5138438, 5138949 ], 
+        [ 5138945, 5139157, 5138950, 5139162 ], 
+        [ 5139158, 5139587, 5139163, 5139592 ], 
+        [ 5139588, 5142617, 5139593, 5142622 ], 
+        [ 5142618, 5148183, 5142623, 5148188 ], 
+        [ 5148184, 5148672, 5148189, 5148677 ], 
+        [ 5148673, 5150053, 5148678, 5150058 ], 
+        [ 5150054, 5151087, 5150059, 5151092 ], 
+        [ 5151088, 5153217, 5151093, 5153222 ], 
+        [ 5153218, 5154383, 5153223, 5154388 ], 
+        [ 5154384, 5155016, 5154389, 5155021 ], 
+        [ 5155017, 5156599, 5155022, 5156604 ], 
+        [ 5156600, 5157802, 5156605, 5157807 ], 
+        [ 5157803, 5157970, 5157808, 5157975 ], 
+        [ 5157971, 5160625, 5157976, 5160630 ], 
+        [ 5160626, 5162852, 5160631, 5162857 ], 
+        [ 5162853, 5164824, 5162858, 5164829 ], 
+        [ 5164825, 5171077, 5164830, 5171082 ], 
+        [ 5171078, 5180591, 5171083, 5180596 ], 
+        [ 5180592, 5188235, 5180597, 5188240 ], 
+        [ 5188236, 5194013, 5188241, 5194018 ], 
+        [ 5194014, 5200363, 5194019, 5200368 ], 
+        [ 5200364, 5200380, 5200369, 5200385 ], 
+        [ 5200381, 5212416, 5200386, 5212421 ], 
+        [ 5212417, 5214189, 5212422, 5214194 ], 
+        [ 5214190, 5218448, 5214195, 5218453 ], 
+        [ 5218449, 5221514, 5218454, 5221519 ], 
+        [ 5221515, 5222405, 5221520, 5222410 ], 
+        [ 5222406, 5223121, 5222411, 5223126 ], 
+        [ 5223122, 5225062, 5223127, 5225067 ], 
+        [ 5225063, 5227034, 5225068, 5227039 ], 
+        [ 5227035, 5237062, 5227040, 5237067 ], 
+        [ 5237063, 5238549, 5237068, 5238554 ], 
+        [ 5238550, 5239941, 5238555, 5239946 ], 
+        [ 5239942, 5241160, 5239947, 5241165 ], 
+        [ 5241161, 5245009, 5241166, 5245014 ], 
+        [ 5245010, 5245420, 5245015, 5245425 ], 
+        [ 5245421, 5246665, 5245426, 5246670 ], 
+        [ 5246666, 5246882, 5246671, 5246887 ], 
+        [ 5246883, 5252321, 5246888, 5252326 ], 
+        [ 5252322, 5261182, 5252327, 5261187 ], 
+        [ 5261183, 5273111, 5261188, 5273116 ], 
+        [ 5273112, 5273132, 5273117, 5273137 ], 
+        [ 5273133, 5273680, 5273138, 5273685 ], 
+        [ 5273681, 5274282, 5273686, 5274287 ], 
+        [ 5274283, 5277485, 5274288, 5277490 ], 
+        [ 5277486, 5278602, 5277491, 5278607 ], 
+        [ 5278603, 5286668, 5278608, 5286673 ], 
+        [ 5286669, 5288844, 5286674, 5288849 ], 
+        [ 5288845, 5295426, 5288850, 5295431 ], 
+        [ 5295427, 5299331, 5295432, 5299336 ], 
+        [ 5299332, 5299740, 5299337, 5299745 ], 
+        [ 5299741, 5302074, 5299746, 5302079 ], 
+        [ 5302075, 5304927, 5302080, 5304932 ], 
+        [ 5304928, 5316196, 5304933, 5316201 ], 
+        [ 5316197, 5321884, 5316202, 5321889 ], 
+        [ 5321885, 5327443, 5321890, 5327448 ], 
+        [ 5327444, 5333009, 5327449, 5333014 ], 
+        [ 5333010, 5335558, 5333015, 5335563 ], 
+        [ 5335559, 5337934, 5335564, 5337939 ], 
+        [ 5337935, 5340296, 5337940, 5340301 ], 
+        [ 5340297, 5342510, 5340302, 5342515 ], 
+        [ 5342511, 5343834, 5342516, 5343839 ], 
+        [ 5343835, 5359283, 5343840, 5359288 ], 
+        [ 5359284, 5362544, 5359289, 5362549 ], 
+        [ 5362545, 5375729, 5362550, 5375734 ], 
+        [ 5375730, 5375790, 5375735, 5375795 ], 
+        [ 5375791, 5377253, 5375796, 5377258 ], 
+        [ 5377254, 5378696, 5377259, 5378701 ], 
+        [ 5378697, 5382060, 5378702, 5382065 ], 
+        [ 5382061, 5388224, 5382066, 5388229 ], 
+        [ 5388225, 5391633, 5388230, 5391638 ], 
+        [ 5391634, 5401417, 5391639, 5401422 ], 
+        [ 5401418, 5406537, 5401423, 5406542 ], 
+        [ 5406538, 5408637, 5406543, 5408642 ], 
+        [ 5408638, 5417270, 5408643, 5417275 ], 
+        [ 5417271, 5419353, 5417276, 5419358 ], 
+        [ 5419354, 5420144, 5419359, 5420149 ], 
+        [ 5420145, 5420216, 5420150, 5420221 ], 
+        [ 5420217, 5420740, 5420222, 5420745 ], 
+        [ 5420741, 5427477, 5420746, 5427482 ], 
+        [ 5427478, 5429323, 5427483, 5429328 ], 
+        [ 5429324, 5441634, 5429329, 5441639 ], 
+        [ 5441635, 5448663, 5441640, 5448668 ], 
+        [ 5448664, 5452231, 5448669, 5452236 ], 
+        [ 5452232, 5458274, 5452237, 5458279 ], 
+        [ 5458275, 5459524, 5458280, 5459529 ], 
+        [ 5459525, 5468509, 5459530, 5468514 ], 
+        [ 5468510, 5469773, 5468515, 5469778 ], 
+        [ 5469774, 5475379, 5469779, 5475384 ], 
+        [ 5475380, 5476063, 5475385, 5476068 ], 
+        [ 5476064, 5477860, 5476069, 5477865 ], 
+        [ 5477861, 5478124, 5477866, 5478129 ], 
+        [ 5478125, 5478577, 5478130, 5478582 ], 
+        [ 5478578, 5479176, 5478583, 5479181 ], 
+        [ 5479177, 5483012, 5479182, 5483017 ], 
+        [ 5483013, 5483809, 5483018, 5483814 ], 
+        [ 5483810, 5495234, 5483815, 5495239 ], 
+        [ 5495235, 5498449, 5495240, 5498449 ]
+      ]
+
+    def _cut(seq)
+      cuts = Bio::RestrictionEnzyme::Analysis.cut(seq, "BstEII",
+                                                  {:view_ranges => true})
+    end
+
+    def test_BstEII_edge_cases
+      (13481..13492).each do |len|
+        _test_by_size(len)
+      end
+    end
+
+  end # class TestEcoliO157H7_BstEII
+
+  class TestEcoliO157H7_3enzymes < Test::Unit::TestCase
+    include HelperMethods
+
+    TestLabel = 'SacI+EcoRI+BstEII'
+
+    SampleSequence = EcoliO157H7Seq
+
+    
+    SampleCutRanges = The3Enzymes_WHOLE =
+      [ [ 0, 79, 0, 84 ], 
+        [ 80, 3858, 85, 3862 ], 
+        [ 3859, 4612, 3863, 4617 ], 
+        [ 4613, 5619, 4618, 5623 ], 
+        [ 5620, 7472, 5624, 7468 ], 
+        [ 7473, 12905, 7469, 12909 ], 
+        [ 12906, 13483, 12910, 13488 ], 
+        [ 13484, 14551, 13489, 14547 ], 
+        [ 14552, 15984, 14548, 15989 ], 
+        [ 15985, 20045, 15990, 20049 ], 
+        [ 20046, 21462, 20050, 21467 ], 
+        [ 21463, 27326, 21468, 27331 ], 
+        [ 27327, 30943, 27332, 30948 ], 
+        [ 30944, 34888, 30949, 34893 ], 
+        [ 34889, 35077, 34894, 35082 ], 
+        [ 35078, 35310, 35083, 35315 ], 
+        [ 35311, 36254, 35316, 36259 ], 
+        [ 36255, 36648, 36260, 36652 ], 
+        [ 36649, 36918, 36653, 36922 ], 
+        [ 36919, 41885, 36923, 41890 ], 
+        [ 41886, 43070, 41891, 43075 ], 
+        [ 43071, 45689, 43076, 45694 ], 
+        [ 45690, 48588, 45695, 48584 ], 
+        [ 48589, 52325, 48585, 52330 ], 
+        [ 52326, 54650, 52331, 54654 ], 
+        [ 54651, 54728, 54655, 54732 ], 
+        [ 54729, 55703, 54733, 55708 ], 
+        [ 55704, 58828, 55709, 58833 ], 
+        [ 58829, 59178, 58834, 59183 ], 
+        [ 59179, 59800, 59184, 59796 ], 
+        [ 59801, 61256, 59797, 61260 ], 
+        [ 61257, 72610, 61261, 72615 ], 
+        [ 72611, 72739, 72616, 72744 ], 
+        [ 72740, 73099, 72745, 73104 ], 
+        [ 73100, 75123, 73105, 75128 ], 
+        [ 75124, 77366, 75129, 77371 ], 
+        [ 77367, 77810, 77372, 77815 ], 
+        [ 77811, 78740, 77816, 78745 ], 
+        [ 78741, 79717, 78746, 79722 ], 
+        [ 79718, 82250, 79723, 82255 ], 
+        [ 82251, 84604, 82256, 84609 ], 
+        [ 84605, 95491, 84610, 95496 ], 
+        [ 95492, 95785, 95497, 95790 ], 
+        [ 95786, 95794, 95791, 95799 ], 
+        [ 95795, 96335, 95800, 96340 ], 
+        [ 96336, 96489, 96341, 96493 ], 
+        [ 96490, 101464, 96494, 101468 ], 
+        [ 101465, 102044, 101469, 102049 ], 
+        [ 102045, 102541, 102050, 102546 ], 
+        [ 102542, 103192, 102547, 103197 ], 
+        [ 103193, 103397, 103198, 103393 ], 
+        [ 103398, 104722, 103394, 104727 ], 
+        [ 104723, 106365, 104728, 106369 ], 
+        [ 106366, 106896, 106370, 106900 ], 
+        [ 106897, 107735, 106901, 107739 ], 
+        [ 107736, 110020, 107740, 110024 ], 
+        [ 110021, 110883, 110025, 110888 ], 
+        [ 110884, 112524, 110889, 112528 ], 
+        [ 112525, 113324, 112529, 113328 ], 
+        [ 113325, 115867, 113329, 115871 ], 
+        [ 115868, 117723, 115872, 117727 ], 
+        [ 117724, 118742, 117728, 118738 ], 
+        [ 118743, 120090, 118739, 120095 ], 
+        [ 120091, 120657, 120096, 120662 ], 
+        [ 120658, 128060, 120663, 128064 ], 
+        [ 128061, 128308, 128065, 128313 ], 
+        [ 128309, 136112, 128314, 136116 ], 
+        [ 136113, 138305, 136117, 138310 ], 
+        [ 138306, 138996, 138311, 139000 ], 
+        [ 138997, 139146, 139001, 139142 ], 
+        [ 139147, 141147, 139143, 141152 ], 
+        [ 141148, 143724, 141153, 143729 ], 
+        [ 143725, 143838, 143730, 143843 ], 
+        [ 143839, 144303, 143844, 144308 ], 
+        [ 144304, 148199, 144309, 148204 ], 
+        [ 148200, 149577, 148205, 149582 ], 
+        [ 149578, 149731, 149583, 149736 ], 
+        [ 149732, 152137, 149737, 152141 ], 
+        [ 152138, 156115, 152142, 156120 ], 
+        [ 156116, 161126, 156121, 161131 ], 
+        [ 161127, 162856, 161132, 162861 ], 
+        [ 162857, 168965, 162862, 168961 ], 
+        [ 168966, 170693, 168962, 170698 ], 
+        [ 170694, 170944, 170699, 170949 ], 
+        [ 170945, 171201, 170950, 171206 ], 
+        [ 171202, 173241, 171207, 173246 ], 
+        [ 173242, 177283, 173247, 177288 ], 
+        [ 177284, 178048, 177289, 178052 ], 
+        [ 178049, 178177, 178053, 178182 ], 
+        [ 178178, 178781, 178183, 178786 ], 
+        [ 178782, 181610, 178787, 181615 ], 
+        [ 181611, 181706, 181616, 181711 ], 
+        [ 181707, 185355, 181712, 185351 ], 
+        [ 185356, 185661, 185352, 185666 ], 
+        [ 185662, 193407, 185667, 193412 ], 
+        [ 193408, 194141, 193413, 194145 ], 
+        [ 194142, 194876, 194146, 194880 ], 
+        [ 194877, 195511, 194881, 195516 ], 
+        [ 195512, 195754, 195517, 195759 ], 
+        [ 195755, 197005, 195760, 197009 ], 
+        [ 197006, 197247, 197010, 197252 ], 
+        [ 197248, 200659, 197253, 200664 ], 
+        [ 200660, 201820, 200665, 201825 ], 
+        [ 201821, 202300, 201826, 202305 ], 
+        [ 202301, 202686, 202306, 202691 ], 
+        [ 202687, 206289, 202692, 206294 ], 
+        [ 206290, 206466, 206295, 206471 ], 
+        [ 206467, 207011, 206472, 207016 ], 
+        [ 207012, 208159, 207017, 208164 ], 
+        [ 208160, 209976, 208165, 209981 ], 
+        [ 209977, 210078, 209982, 210083 ], 
+        [ 210079, 211485, 210084, 211490 ], 
+        [ 211486, 212377, 211491, 212382 ], 
+        [ 212378, 213569, 212383, 213574 ], 
+        [ 213570, 214316, 213575, 214312 ], 
+        [ 214317, 216005, 214313, 216010 ], 
+        [ 216006, 217226, 216011, 217222 ], 
+        [ 217227, 220098, 217223, 220103 ], 
+        [ 220099, 221476, 220104, 221480 ], 
+        [ 221477, 221641, 221481, 221645 ], 
+        [ 221642, 224063, 221646, 224068 ], 
+        [ 224064, 227774, 224069, 227778 ], 
+        [ 227775, 228604, 227779, 228609 ], 
+        [ 228605, 229453, 228610, 229449 ], 
+        [ 229454, 229931, 229450, 229935 ], 
+        [ 229932, 232247, 229936, 232251 ], 
+        [ 232248, 235221, 232252, 235225 ], 
+        [ 235222, 237291, 235226, 237295 ], 
+        [ 237292, 239035, 237296, 239039 ], 
+        [ 239036, 239993, 239040, 239998 ], 
+        [ 239994, 240624, 239999, 240628 ], 
+        [ 240625, 240887, 240629, 240891 ], 
+        [ 240888, 242089, 240892, 242093 ], 
+        [ 242090, 243880, 242094, 243884 ], 
+        [ 243881, 245321, 243885, 245325 ], 
+        [ 245322, 247914, 245326, 247919 ], 
+        [ 247915, 251579, 247920, 251584 ], 
+        [ 251580, 257092, 251585, 257097 ], 
+        [ 257093, 259887, 257098, 259891 ], 
+        [ 259888, 260535, 259892, 260539 ], 
+        [ 260536, 261621, 260540, 261626 ], 
+        [ 261622, 263030, 261627, 263035 ], 
+        [ 263031, 264258, 263036, 264262 ], 
+        [ 264259, 265004, 264263, 265008 ], 
+        [ 265005, 265084, 265009, 265089 ], 
+        [ 265085, 265243, 265090, 265248 ], 
+        [ 265244, 265534, 265249, 265539 ], 
+        [ 265535, 266117, 265540, 266122 ], 
+        [ 266118, 274428, 266123, 274433 ], 
+        [ 274429, 275235, 274434, 275231 ], 
+        [ 275236, 276946, 275232, 276950 ], 
+        [ 276947, 277457, 276951, 277461 ], 
+        [ 277458, 279137, 277462, 279133 ], 
+        [ 279138, 282285, 279134, 282290 ], 
+        [ 282286, 286948, 282291, 286953 ], 
+        [ 286949, 288342, 286954, 288338 ], 
+        [ 288343, 289897, 288339, 289901 ], 
+        [ 289898, 292547, 289902, 292552 ], 
+        [ 292548, 297678, 292553, 297683 ], 
+        [ 297679, 303902, 297684, 303906 ], 
+        [ 303903, 304580, 303907, 304584 ], 
+        [ 304581, 307362, 304585, 307366 ], 
+        [ 307363, 307931, 307367, 307935 ], 
+        [ 307932, 308161, 307936, 308166 ], 
+        [ 308162, 308706, 308167, 308711 ], 
+        [ 308707, 313482, 308712, 313487 ], 
+        [ 313483, 316025, 313488, 316021 ], 
+        [ 316026, 324159, 316022, 324163 ], 
+        [ 324160, 326130, 324164, 326134 ], 
+        [ 326131, 331620, 326135, 331624 ], 
+        [ 331621, 336338, 331625, 336342 ], 
+        [ 336339, 336873, 336343, 336877 ], 
+        [ 336874, 337118, 336878, 337123 ], 
+        [ 337119, 337935, 337124, 337940 ], 
+        [ 337936, 338781, 337941, 338786 ], 
+        [ 338782, 339493, 338787, 339498 ], 
+        [ 339494, 341025, 339499, 341030 ], 
+        [ 341026, 343919, 341031, 343923 ], 
+        [ 343920, 344424, 343924, 344429 ], 
+        [ 344425, 348384, 344430, 348389 ], 
+        [ 348385, 348408, 348390, 348404 ], 
+        [ 348409, 353417, 348405, 353413 ], 
+        [ 353418, 354781, 353414, 354786 ], 
+        [ 354782, 356692, 354787, 356697 ], 
+        [ 356693, 357008, 356698, 357013 ], 
+        [ 357009, 357305, 357014, 357310 ], 
+        [ 357306, 357328, 357311, 357333 ], 
+        [ 357329, 358126, 357334, 358131 ], 
+        [ 358127, 359472, 358132, 359477 ], 
+        [ 359473, 362160, 359478, 362165 ], 
+        [ 362161, 365395, 362166, 365400 ], 
+        [ 365396, 365704, 365401, 365709 ], 
+        [ 365705, 368663, 365710, 368667 ], 
+        [ 368664, 368841, 368668, 368845 ], 
+        [ 368842, 370589, 368846, 370593 ], 
+        [ 370590, 371148, 370594, 371152 ], 
+        [ 371149, 373639, 371153, 373643 ], 
+        [ 373640, 377393, 373644, 377397 ], 
+        [ 377394, 381068, 377398, 381072 ], 
+        [ 381069, 381692, 381073, 381688 ], 
+        [ 381693, 381746, 381689, 381751 ], 
+        [ 381747, 381994, 381752, 381999 ], 
+        [ 381995, 383335, 382000, 383340 ], 
+        [ 383336, 385141, 383341, 385146 ], 
+        [ 385142, 389399, 385147, 389403 ], 
+        [ 389400, 390171, 389404, 390176 ], 
+        [ 390172, 392340, 390177, 392344 ], 
+        [ 392341, 392764, 392345, 392769 ], 
+        [ 392765, 394338, 392770, 394343 ], 
+        [ 394339, 394686, 394344, 394691 ], 
+        [ 394687, 397592, 394692, 397596 ], 
+        [ 397593, 398703, 397597, 398708 ], 
+        [ 398704, 404095, 398709, 404100 ], 
+        [ 404096, 408361, 404101, 408366 ], 
+        [ 408362, 409029, 408367, 409025 ], 
+        [ 409030, 413032, 409026, 413037 ], 
+        [ 413033, 414563, 413038, 414568 ], 
+        [ 414564, 416901, 414569, 416906 ], 
+        [ 416902, 417419, 416907, 417424 ], 
+        [ 417420, 420057, 417425, 420061 ], 
+        [ 420058, 421129, 420062, 421125 ], 
+        [ 421130, 421777, 421126, 421782 ], 
+        [ 421778, 423748, 421783, 423753 ], 
+        [ 423749, 431903, 423754, 431908 ], 
+        [ 431904, 432852, 431909, 432848 ], 
+        [ 432853, 440000, 432849, 440005 ], 
+        [ 440001, 440754, 440006, 440750 ], 
+        [ 440755, 444226, 440751, 444222 ], 
+        [ 444227, 448040, 444223, 448045 ], 
+        [ 448041, 452994, 448046, 452999 ], 
+        [ 452995, 453075, 453000, 453080 ], 
+        [ 453076, 454654, 453081, 454658 ], 
+        [ 454655, 454950, 454659, 454955 ], 
+        [ 454951, 455888, 454956, 455893 ], 
+        [ 455889, 460160, 455894, 460165 ], 
+        [ 460161, 462319, 460166, 462323 ], 
+        [ 462320, 462650, 462324, 462654 ], 
+        [ 462651, 463076, 462655, 463081 ], 
+        [ 463077, 465003, 463082, 465008 ], 
+        [ 465004, 466828, 465009, 466833 ], 
+        [ 466829, 467686, 466834, 467691 ], 
+        [ 467687, 468596, 467692, 468601 ], 
+        [ 468597, 475083, 468602, 475087 ], 
+        [ 475084, 479953, 475088, 479958 ], 
+        [ 479954, 480538, 479959, 480543 ], 
+        [ 480539, 482480, 480544, 482484 ], 
+        [ 482481, 482869, 482485, 482874 ], 
+        [ 482870, 483410, 482875, 483414 ], 
+        [ 483411, 489378, 483415, 489383 ], 
+        [ 489379, 492112, 489384, 492116 ], 
+        [ 492113, 492241, 492117, 492246 ], 
+        [ 492242, 493791, 492247, 493795 ], 
+        [ 493792, 495406, 493796, 495411 ], 
+        [ 495407, 495712, 495412, 495717 ], 
+        [ 495713, 497829, 495718, 497834 ], 
+        [ 497830, 501698, 497835, 501703 ], 
+        [ 501699, 503304, 501704, 503308 ], 
+        [ 503305, 504565, 503309, 504570 ], 
+        [ 504566, 505105, 504571, 505110 ], 
+        [ 505106, 508452, 505111, 508457 ], 
+        [ 508453, 514353, 508458, 514357 ], 
+        [ 514354, 515947, 514358, 515952 ], 
+        [ 515948, 519141, 515953, 519146 ], 
+        [ 519142, 519398, 519147, 519403 ], 
+        [ 519399, 519662, 519404, 519666 ], 
+        [ 519663, 521386, 519667, 521391 ], 
+        [ 521387, 521935, 521392, 521939 ], 
+        [ 521936, 523114, 521940, 523118 ], 
+        [ 523115, 524176, 523119, 524180 ], 
+        [ 524177, 524521, 524181, 524525 ], 
+        [ 524522, 524936, 524526, 524932 ], 
+        [ 524937, 526115, 524933, 526120 ], 
+        [ 526116, 526729, 526121, 526734 ], 
+        [ 526730, 527018, 526735, 527023 ], 
+        [ 527019, 528059, 527024, 528064 ], 
+        [ 528060, 532689, 528065, 532694 ], 
+        [ 532690, 534193, 532695, 534189 ], 
+        [ 534194, 534702, 534190, 534707 ], 
+        [ 534703, 535272, 534708, 535277 ], 
+        [ 535273, 538638, 535278, 538642 ], 
+        [ 538639, 538668, 538643, 538673 ], 
+        [ 538669, 543939, 538674, 543944 ], 
+        [ 543940, 547429, 543945, 547434 ], 
+        [ 547430, 547624, 547435, 547628 ], 
+        [ 547625, 550898, 547629, 550902 ], 
+        [ 550899, 553890, 550903, 553895 ], 
+        [ 553891, 554678, 553896, 554683 ], 
+        [ 554679, 555452, 554684, 555457 ], 
+        [ 555453, 556296, 555458, 556301 ], 
+        [ 556297, 557116, 556302, 557120 ], 
+        [ 557117, 559341, 557121, 559346 ], 
+        [ 559342, 559991, 559347, 559996 ], 
+        [ 559992, 563242, 559997, 563247 ], 
+        [ 563243, 563390, 563248, 563394 ], 
+        [ 563391, 566071, 563395, 566075 ], 
+        [ 566072, 566857, 566076, 566861 ], 
+        [ 566858, 571925, 566862, 571929 ], 
+        [ 571926, 576432, 571930, 576437 ], 
+        [ 576433, 582431, 576438, 582436 ], 
+        [ 582432, 582959, 582437, 582964 ], 
+        [ 582960, 583475, 582965, 583480 ], 
+        [ 583476, 583589, 583481, 583594 ], 
+        [ 583590, 583670, 583595, 583675 ], 
+        [ 583671, 583901, 583676, 583906 ], 
+        [ 583902, 584198, 583907, 584203 ], 
+        [ 584199, 584633, 584204, 584638 ], 
+        [ 584634, 585704, 584639, 585709 ], 
+        [ 585705, 585746, 585710, 585751 ], 
+        [ 585747, 586175, 585752, 586180 ], 
+        [ 586176, 586301, 586181, 586306 ], 
+        [ 586302, 586643, 586307, 586648 ], 
+        [ 586644, 586775, 586649, 586780 ], 
+        [ 586776, 587072, 586781, 587077 ], 
+        [ 587073, 587214, 587078, 587219 ], 
+        [ 587215, 587540, 587220, 587545 ], 
+        [ 587541, 587969, 587546, 587974 ], 
+        [ 587970, 588095, 587975, 588100 ], 
+        [ 588096, 588437, 588101, 588442 ], 
+        [ 588438, 588569, 588443, 588574 ], 
+        [ 588570, 589008, 588575, 589013 ], 
+        [ 589009, 589166, 589014, 589171 ], 
+        [ 589167, 590366, 589172, 590371 ], 
+        [ 590367, 590792, 590372, 590797 ], 
+        [ 590793, 591077, 590798, 591082 ], 
+        [ 591078, 591263, 591083, 591268 ], 
+        [ 591264, 591863, 591269, 591868 ], 
+        [ 591864, 592058, 591869, 592063 ], 
+        [ 592059, 592160, 592064, 592165 ], 
+        [ 592161, 592568, 592166, 592573 ], 
+        [ 592569, 592760, 592574, 592765 ], 
+        [ 592761, 593060, 592766, 593065 ], 
+        [ 593061, 593186, 593066, 593191 ], 
+        [ 593187, 593366, 593192, 593371 ], 
+        [ 593367, 593957, 593372, 593962 ], 
+        [ 593958, 594827, 593963, 594832 ], 
+        [ 594828, 594980, 594833, 594985 ], 
+        [ 594981, 595649, 594986, 595654 ], 
+        [ 595650, 595893, 595655, 595898 ], 
+        [ 595894, 596057, 595899, 596062 ], 
+        [ 596058, 596159, 596063, 596164 ], 
+        [ 596160, 596351, 596165, 596356 ], 
+        [ 596352, 596660, 596357, 596665 ], 
+        [ 596661, 596960, 596666, 596965 ], 
+        [ 596961, 597102, 596966, 597107 ], 
+        [ 597103, 597155, 597108, 597160 ], 
+        [ 597156, 597257, 597161, 597262 ], 
+        [ 597258, 599957, 597263, 599962 ], 
+        [ 599958, 604182, 599963, 604186 ], 
+        [ 604183, 611038, 604187, 611043 ], 
+        [ 611039, 612202, 611044, 612207 ], 
+        [ 612203, 614051, 612208, 614056 ], 
+        [ 614052, 614134, 614057, 614139 ], 
+        [ 614135, 614787, 614140, 614792 ], 
+        [ 614788, 616272, 614793, 616277 ], 
+        [ 616273, 616867, 616278, 616871 ], 
+        [ 616868, 617737, 616872, 617742 ], 
+        [ 617738, 627339, 617743, 627344 ], 
+        [ 627340, 628902, 627345, 628907 ], 
+        [ 628903, 629142, 628908, 629146 ], 
+        [ 629143, 629458, 629147, 629454 ], 
+        [ 629459, 636523, 629455, 636528 ], 
+        [ 636524, 637529, 636529, 637534 ], 
+        [ 637530, 639061, 637535, 639065 ], 
+        [ 639062, 647713, 639066, 647718 ], 
+        [ 647714, 648684, 647719, 648689 ], 
+        [ 648685, 652752, 648690, 652748 ], 
+        [ 652753, 653543, 652749, 653548 ], 
+        [ 653544, 654406, 653549, 654410 ], 
+        [ 654407, 658188, 654411, 658192 ], 
+        [ 658189, 659030, 658193, 659035 ], 
+        [ 659031, 662241, 659036, 662246 ], 
+        [ 662242, 670896, 662247, 670900 ], 
+        [ 670897, 671781, 670901, 671786 ], 
+        [ 671782, 672048, 671787, 672053 ], 
+        [ 672049, 673788, 672054, 673793 ], 
+        [ 673789, 674707, 673794, 674712 ], 
+        [ 674708, 674998, 674713, 675003 ], 
+        [ 674999, 675157, 675004, 675162 ], 
+        [ 675158, 688595, 675163, 688600 ], 
+        [ 688596, 693309, 688601, 693314 ], 
+        [ 693310, 693523, 693315, 693527 ], 
+        [ 693524, 696514, 693528, 696518 ], 
+        [ 696515, 697406, 696519, 697411 ], 
+        [ 697407, 702676, 697412, 702681 ], 
+        [ 702677, 707208, 702682, 707212 ], 
+        [ 707209, 707382, 707213, 707387 ], 
+        [ 707383, 708604, 707388, 708609 ], 
+        [ 708605, 710046, 708610, 710051 ], 
+        [ 710047, 711630, 710052, 711635 ], 
+        [ 711631, 711696, 711636, 711701 ], 
+        [ 711697, 712329, 711702, 712334 ], 
+        [ 712330, 714099, 712335, 714103 ], 
+        [ 714100, 716461, 714104, 716466 ], 
+        [ 716462, 720238, 716467, 720243 ], 
+        [ 720239, 720374, 720244, 720379 ], 
+        [ 720375, 720471, 720380, 720475 ], 
+        [ 720472, 721463, 720476, 721467 ], 
+        [ 721464, 723143, 721468, 723147 ], 
+        [ 723144, 723348, 723148, 723352 ], 
+        [ 723349, 724200, 723353, 724205 ], 
+        [ 724201, 725464, 724206, 725468 ], 
+        [ 725465, 725687, 725469, 725692 ], 
+        [ 725688, 729467, 725693, 729471 ], 
+        [ 729468, 730067, 729472, 730072 ], 
+        [ 730068, 730406, 730073, 730410 ], 
+        [ 730407, 730574, 730411, 730579 ], 
+        [ 730575, 730699, 730580, 730704 ], 
+        [ 730700, 732726, 730705, 732731 ], 
+        [ 732727, 734363, 732732, 734359 ], 
+        [ 734364, 738597, 734360, 738602 ], 
+        [ 738598, 738869, 738603, 738873 ], 
+        [ 738870, 739571, 738874, 739575 ], 
+        [ 739572, 742040, 739576, 742044 ], 
+        [ 742041, 742350, 742045, 742346 ], 
+        [ 742351, 743326, 742347, 743331 ], 
+        [ 743327, 743557, 743332, 743561 ], 
+        [ 743558, 743966, 743562, 743970 ], 
+        [ 743967, 744992, 743971, 744997 ], 
+        [ 744993, 745843, 744998, 745848 ], 
+        [ 745844, 751518, 745849, 751523 ], 
+        [ 751519, 752431, 751524, 752436 ], 
+        [ 752432, 752549, 752437, 752554 ], 
+        [ 752550, 758622, 752555, 758626 ], 
+        [ 758623, 760978, 758627, 760982 ], 
+        [ 760979, 761319, 760983, 761315 ], 
+        [ 761320, 766036, 761316, 766041 ], 
+        [ 766037, 768968, 766042, 768973 ], 
+        [ 768969, 770151, 768974, 770156 ], 
+        [ 770152, 771158, 770157, 771163 ], 
+        [ 771159, 771405, 771164, 771410 ], 
+        [ 771406, 771429, 771411, 771433 ], 
+        [ 771430, 774384, 771434, 774388 ], 
+        [ 774385, 781958, 774389, 781963 ], 
+        [ 781959, 784226, 781964, 784231 ], 
+        [ 784227, 784572, 784232, 784576 ], 
+        [ 784573, 784806, 784577, 784810 ], 
+        [ 784807, 786886, 784811, 786890 ], 
+        [ 786887, 786945, 786891, 786950 ], 
+        [ 786946, 787203, 786951, 787208 ], 
+        [ 787204, 789251, 787209, 789256 ], 
+        [ 789252, 791218, 789257, 791223 ], 
+        [ 791219, 793716, 791224, 793721 ], 
+        [ 793717, 795003, 793722, 795008 ], 
+        [ 795004, 795521, 795009, 795526 ], 
+        [ 795522, 800659, 795527, 800663 ], 
+        [ 800660, 802360, 800664, 802364 ], 
+        [ 802361, 804514, 802365, 804519 ], 
+        [ 804515, 805238, 804520, 805243 ], 
+        [ 805239, 805887, 805244, 805892 ], 
+        [ 805888, 807288, 805893, 807292 ], 
+        [ 807289, 808461, 807293, 808466 ], 
+        [ 808462, 808692, 808467, 808696 ], 
+        [ 808693, 809805, 808697, 809810 ], 
+        [ 809806, 810086, 809811, 810091 ], 
+        [ 810087, 810726, 810092, 810731 ], 
+        [ 810727, 813170, 810732, 813174 ], 
+        [ 813171, 813863, 813175, 813867 ], 
+        [ 813864, 820111, 813868, 820116 ], 
+        [ 820112, 821326, 820117, 821331 ], 
+        [ 821327, 821647, 821332, 821652 ], 
+        [ 821648, 824277, 821653, 824282 ], 
+        [ 824278, 825750, 824283, 825755 ], 
+        [ 825751, 828770, 825756, 828775 ], 
+        [ 828771, 828924, 828776, 828929 ], 
+        [ 828925, 830194, 828930, 830199 ], 
+        [ 830195, 830786, 830200, 830791 ], 
+        [ 830787, 831245, 830792, 831241 ], 
+        [ 831246, 832788, 831242, 832793 ], 
+        [ 832789, 833306, 832794, 833311 ], 
+        [ 833307, 835264, 833312, 835260 ], 
+        [ 835265, 835656, 835261, 835661 ], 
+        [ 835657, 841180, 835662, 841185 ], 
+        [ 841181, 842112, 841186, 842117 ], 
+        [ 842113, 842524, 842118, 842528 ], 
+        [ 842525, 843973, 842529, 843978 ], 
+        [ 843974, 843990, 843979, 843995 ], 
+        [ 843991, 851267, 843996, 851271 ], 
+        [ 851268, 852882, 851272, 852887 ], 
+        [ 852883, 854392, 852888, 854397 ], 
+        [ 854393, 857721, 854398, 857726 ], 
+        [ 857722, 857961, 857727, 857966 ], 
+        [ 857962, 859112, 857967, 859116 ], 
+        [ 859113, 862783, 859117, 862788 ], 
+        [ 862784, 869922, 862789, 869926 ], 
+        [ 869923, 878953, 869927, 878958 ], 
+        [ 878954, 885194, 878959, 885199 ], 
+        [ 885195, 886313, 885200, 886318 ], 
+        [ 886314, 886460, 886319, 886465 ], 
+        [ 886461, 888041, 886466, 888045 ], 
+        [ 888042, 890161, 888046, 890165 ], 
+        [ 890162, 890233, 890166, 890238 ], 
+        [ 890234, 890346, 890239, 890351 ], 
+        [ 890347, 890379, 890352, 890384 ], 
+        [ 890380, 895074, 890385, 895078 ], 
+        [ 895075, 897876, 895079, 897880 ], 
+        [ 897877, 897943, 897881, 897947 ], 
+        [ 897944, 899572, 897948, 899576 ], 
+        [ 899573, 899676, 899577, 899681 ], 
+        [ 899677, 903962, 899682, 903967 ], 
+        [ 903963, 904236, 903968, 904241 ], 
+        [ 904237, 908130, 904242, 908135 ], 
+        [ 908131, 912131, 908136, 912127 ], 
+        [ 912132, 916611, 912128, 916616 ], 
+        [ 916612, 916803, 916617, 916808 ], 
+        [ 916804, 920531, 916809, 920536 ], 
+        [ 920532, 923592, 920537, 923596 ], 
+        [ 923593, 927519, 923597, 927523 ], 
+        [ 927520, 928181, 927524, 928185 ], 
+        [ 928182, 928505, 928186, 928510 ], 
+        [ 928506, 928644, 928511, 928640 ], 
+        [ 928645, 934935, 928641, 934931 ], 
+        [ 934936, 935911, 934932, 935915 ], 
+        [ 935912, 936947, 935916, 936952 ], 
+        [ 936948, 937240, 936953, 937245 ], 
+        [ 937241, 939698, 937246, 939703 ], 
+        [ 939699, 939711, 939704, 939716 ], 
+        [ 939712, 941642, 939717, 941647 ], 
+        [ 941643, 949052, 941648, 949057 ], 
+        [ 949053, 949800, 949058, 949805 ], 
+        [ 949801, 949851, 949806, 949855 ], 
+        [ 949852, 951412, 949856, 951417 ], 
+        [ 951413, 951810, 951418, 951815 ], 
+        [ 951811, 952386, 951816, 952391 ], 
+        [ 952387, 953295, 952392, 953300 ], 
+        [ 953296, 953894, 953301, 953899 ], 
+        [ 953895, 955768, 953900, 955772 ], 
+        [ 955769, 955953, 955773, 955957 ], 
+        [ 955954, 956045, 955958, 956041 ], 
+        [ 956046, 958753, 956042, 958758 ], 
+        [ 958754, 964476, 958759, 964481 ], 
+        [ 964477, 967468, 964482, 967473 ], 
+        [ 967469, 969625, 967474, 969629 ], 
+        [ 969626, 969631, 969630, 969636 ], 
+        [ 969632, 970966, 969637, 970971 ], 
+        [ 970967, 971138, 970972, 971143 ], 
+        [ 971139, 974185, 971144, 974190 ], 
+        [ 974186, 974365, 974191, 974370 ], 
+        [ 974366, 975256, 974371, 975261 ], 
+        [ 975257, 976794, 975262, 976799 ], 
+        [ 976795, 980694, 976800, 980698 ], 
+        [ 980695, 987406, 980699, 987411 ], 
+        [ 987407, 988132, 987412, 988137 ], 
+        [ 988133, 992809, 988138, 992814 ], 
+        [ 992810, 996307, 992815, 996311 ], 
+        [ 996308, 999121, 996312, 999125 ], 
+        [ 999122, 1000225, 999126, 1000230 ], 
+        [ 1000226, 1001626, 1000231, 1001631 ], 
+        [ 1001627, 1005050, 1001632, 1005054 ], 
+        [ 1005051, 1007354, 1005055, 1007359 ], 
+        [ 1007355, 1011910, 1007360, 1011915 ], 
+        [ 1011911, 1012377, 1011916, 1012382 ], 
+        [ 1012378, 1015175, 1012383, 1015179 ], 
+        [ 1015176, 1017328, 1015180, 1017333 ], 
+        [ 1017329, 1020891, 1017334, 1020896 ], 
+        [ 1020892, 1021340, 1020897, 1021345 ], 
+        [ 1021341, 1024845, 1021346, 1024850 ], 
+        [ 1024846, 1025853, 1024851, 1025858 ], 
+        [ 1025854, 1030691, 1025859, 1030696 ], 
+        [ 1030692, 1032676, 1030697, 1032681 ], 
+        [ 1032677, 1037847, 1032682, 1037852 ], 
+        [ 1037848, 1039473, 1037853, 1039478 ], 
+        [ 1039474, 1039858, 1039479, 1039854 ], 
+        [ 1039859, 1044241, 1039855, 1044246 ], 
+        [ 1044242, 1045920, 1044247, 1045925 ], 
+        [ 1045921, 1049805, 1045926, 1049809 ], 
+        [ 1049806, 1050388, 1049810, 1050392 ], 
+        [ 1050389, 1053286, 1050393, 1053291 ], 
+        [ 1053287, 1053309, 1053292, 1053314 ], 
+        [ 1053310, 1054643, 1053315, 1054648 ], 
+        [ 1054644, 1056252, 1054649, 1056256 ], 
+        [ 1056253, 1056527, 1056257, 1056532 ], 
+        [ 1056528, 1056947, 1056533, 1056943 ], 
+        [ 1056948, 1058682, 1056944, 1058687 ], 
+        [ 1058683, 1059297, 1058688, 1059302 ], 
+        [ 1059298, 1060416, 1059303, 1060421 ], 
+        [ 1060417, 1061894, 1060422, 1061898 ], 
+        [ 1061895, 1064234, 1061899, 1064239 ], 
+        [ 1064235, 1064848, 1064240, 1064853 ], 
+        [ 1064849, 1065434, 1064854, 1065439 ], 
+        [ 1065435, 1075046, 1065440, 1075042 ], 
+        [ 1075047, 1075642, 1075043, 1075647 ], 
+        [ 1075643, 1076325, 1075648, 1076330 ], 
+        [ 1076326, 1076534, 1076331, 1076539 ], 
+        [ 1076535, 1078135, 1076540, 1078139 ], 
+        [ 1078136, 1078866, 1078140, 1078871 ], 
+        [ 1078867, 1079914, 1078872, 1079910 ], 
+        [ 1079915, 1080537, 1079911, 1080542 ], 
+        [ 1080538, 1082144, 1080543, 1082149 ], 
+        [ 1082145, 1083416, 1082150, 1083420 ], 
+        [ 1083417, 1085746, 1083421, 1085751 ], 
+        [ 1085747, 1087087, 1085752, 1087092 ], 
+        [ 1087088, 1088273, 1087093, 1088278 ], 
+        [ 1088274, 1092093, 1088279, 1092097 ], 
+        [ 1092094, 1093062, 1092098, 1093067 ], 
+        [ 1093063, 1096867, 1093068, 1096872 ], 
+        [ 1096868, 1097288, 1096873, 1097292 ], 
+        [ 1097289, 1102488, 1097293, 1102493 ], 
+        [ 1102489, 1102751, 1102494, 1102747 ], 
+        [ 1102752, 1104366, 1102748, 1104362 ], 
+        [ 1104367, 1106371, 1104363, 1106376 ], 
+        [ 1106372, 1108123, 1106377, 1108128 ], 
+        [ 1108124, 1112263, 1108129, 1112259 ], 
+        [ 1112264, 1113311, 1112260, 1113316 ], 
+        [ 1113312, 1114557, 1113317, 1114562 ], 
+        [ 1114558, 1117715, 1114563, 1117719 ], 
+        [ 1117716, 1118552, 1117720, 1118556 ], 
+        [ 1118553, 1120566, 1118557, 1120571 ], 
+        [ 1120567, 1121004, 1120572, 1121009 ], 
+        [ 1121005, 1121076, 1121010, 1121080 ], 
+        [ 1121077, 1121609, 1121081, 1121613 ], 
+        [ 1121610, 1121694, 1121614, 1121698 ], 
+        [ 1121695, 1122501, 1121699, 1122506 ], 
+        [ 1122502, 1130582, 1122507, 1130587 ], 
+        [ 1130583, 1132170, 1130588, 1132175 ], 
+        [ 1132171, 1135259, 1132176, 1135263 ], 
+        [ 1135260, 1136119, 1135264, 1136123 ], 
+        [ 1136120, 1137316, 1136124, 1137320 ], 
+        [ 1137317, 1140126, 1137321, 1140131 ], 
+        [ 1140127, 1142998, 1140132, 1143002 ], 
+        [ 1142999, 1143361, 1143003, 1143366 ], 
+        [ 1143362, 1143637, 1143367, 1143633 ], 
+        [ 1143638, 1143644, 1143634, 1143648 ], 
+        [ 1143645, 1146618, 1143649, 1146622 ], 
+        [ 1146619, 1149205, 1146623, 1149210 ], 
+        [ 1149206, 1149331, 1149211, 1149336 ], 
+        [ 1149332, 1152263, 1149337, 1152259 ], 
+        [ 1152264, 1152809, 1152260, 1152805 ], 
+        [ 1152810, 1154382, 1152806, 1154386 ], 
+        [ 1154383, 1156272, 1154387, 1156277 ], 
+        [ 1156273, 1159968, 1156278, 1159972 ], 
+        [ 1159969, 1161624, 1159973, 1161629 ], 
+        [ 1161625, 1163044, 1161630, 1163048 ], 
+        [ 1163045, 1164030, 1163049, 1164026 ], 
+        [ 1164031, 1166628, 1164027, 1166632 ], 
+        [ 1166629, 1167897, 1166633, 1167901 ], 
+        [ 1167898, 1171353, 1167902, 1171358 ], 
+        [ 1171354, 1171934, 1171359, 1171939 ], 
+        [ 1171935, 1172114, 1171940, 1172119 ], 
+        [ 1172115, 1173373, 1172120, 1173369 ], 
+        [ 1173374, 1175421, 1173370, 1175417 ], 
+        [ 1175422, 1179850, 1175418, 1179854 ], 
+        [ 1179851, 1181462, 1179855, 1181466 ], 
+        [ 1181463, 1185368, 1181467, 1185373 ], 
+        [ 1185369, 1193993, 1185374, 1193998 ], 
+        [ 1193994, 1194272, 1193999, 1194277 ], 
+        [ 1194273, 1195941, 1194278, 1195945 ], 
+        [ 1195942, 1197920, 1195946, 1197925 ], 
+        [ 1197921, 1199011, 1197926, 1199007 ], 
+        [ 1199012, 1200079, 1199008, 1200075 ], 
+        [ 1200080, 1200373, 1200076, 1200378 ], 
+        [ 1200374, 1200419, 1200379, 1200423 ], 
+        [ 1200420, 1200597, 1200424, 1200602 ], 
+        [ 1200598, 1200714, 1200603, 1200719 ], 
+        [ 1200715, 1203674, 1200720, 1203679 ], 
+        [ 1203675, 1204865, 1203680, 1204870 ], 
+        [ 1204866, 1205330, 1204871, 1205335 ], 
+        [ 1205331, 1206317, 1205336, 1206321 ], 
+        [ 1206318, 1210727, 1206322, 1210732 ], 
+        [ 1210728, 1211881, 1210733, 1211886 ], 
+        [ 1211882, 1214283, 1211887, 1214288 ], 
+        [ 1214284, 1215542, 1214289, 1215546 ], 
+        [ 1215543, 1216981, 1215547, 1216986 ], 
+        [ 1216982, 1220754, 1216987, 1220750 ], 
+        [ 1220755, 1221554, 1220751, 1221550 ], 
+        [ 1221555, 1222528, 1221551, 1222532 ], 
+        [ 1222529, 1223522, 1222533, 1223527 ], 
+        [ 1223523, 1223938, 1223528, 1223942 ], 
+        [ 1223939, 1226908, 1223943, 1226912 ], 
+        [ 1226909, 1227062, 1226913, 1227066 ], 
+        [ 1227063, 1228205, 1227067, 1228210 ], 
+        [ 1228206, 1229934, 1228211, 1229938 ], 
+        [ 1229935, 1236067, 1229939, 1236072 ], 
+        [ 1236068, 1236265, 1236073, 1236270 ], 
+        [ 1236266, 1239904, 1236271, 1239908 ], 
+        [ 1239905, 1239969, 1239909, 1239974 ], 
+        [ 1239970, 1240641, 1239975, 1240646 ], 
+        [ 1240642, 1244451, 1240647, 1244447 ], 
+        [ 1244452, 1244738, 1244448, 1244743 ], 
+        [ 1244739, 1244821, 1244744, 1244826 ], 
+        [ 1244822, 1247339, 1244827, 1247343 ], 
+        [ 1247340, 1248889, 1247344, 1248885 ], 
+        [ 1248890, 1250671, 1248886, 1250675 ], 
+        [ 1250672, 1254643, 1250676, 1254647 ], 
+        [ 1254644, 1255112, 1254648, 1255108 ], 
+        [ 1255113, 1257527, 1255109, 1257523 ], 
+        [ 1257528, 1264487, 1257524, 1264491 ], 
+        [ 1264488, 1269317, 1264492, 1269321 ], 
+        [ 1269318, 1272971, 1269322, 1272976 ], 
+        [ 1272972, 1276524, 1272977, 1276529 ], 
+        [ 1276525, 1281881, 1276530, 1281877 ], 
+        [ 1281882, 1281933, 1281878, 1281937 ], 
+        [ 1281934, 1287297, 1281938, 1287301 ], 
+        [ 1287298, 1287557, 1287302, 1287561 ], 
+        [ 1287558, 1290344, 1287562, 1290349 ], 
+        [ 1290345, 1292253, 1290350, 1292258 ], 
+        [ 1292254, 1293482, 1292259, 1293487 ], 
+        [ 1293483, 1295919, 1293488, 1295924 ], 
+        [ 1295920, 1302576, 1295925, 1302580 ], 
+        [ 1302577, 1302834, 1302581, 1302839 ], 
+        [ 1302835, 1302920, 1302840, 1302924 ], 
+        [ 1302921, 1303091, 1302925, 1303095 ], 
+        [ 1303092, 1303464, 1303096, 1303469 ], 
+        [ 1303465, 1306801, 1303470, 1306805 ], 
+        [ 1306802, 1307555, 1306806, 1307559 ], 
+        [ 1307556, 1309308, 1307560, 1309313 ], 
+        [ 1309309, 1311482, 1309314, 1311487 ], 
+        [ 1311483, 1312493, 1311488, 1312498 ], 
+        [ 1312494, 1316488, 1312499, 1316493 ], 
+        [ 1316489, 1318127, 1316494, 1318132 ], 
+        [ 1318128, 1325643, 1318133, 1325648 ], 
+        [ 1325644, 1328313, 1325649, 1328318 ], 
+        [ 1328314, 1329159, 1328319, 1329155 ], 
+        [ 1329160, 1332129, 1329156, 1332133 ], 
+        [ 1332130, 1332245, 1332134, 1332249 ], 
+        [ 1332246, 1332269, 1332250, 1332265 ], 
+        [ 1332270, 1332837, 1332266, 1332841 ], 
+        [ 1332838, 1334227, 1332842, 1334223 ], 
+        [ 1334228, 1345348, 1334224, 1345353 ], 
+        [ 1345349, 1346662, 1345354, 1346666 ], 
+        [ 1346663, 1347480, 1346667, 1347485 ], 
+        [ 1347481, 1348458, 1347486, 1348463 ], 
+        [ 1348459, 1350595, 1348464, 1350600 ], 
+        [ 1350596, 1350770, 1350601, 1350775 ], 
+        [ 1350771, 1351954, 1350776, 1351959 ], 
+        [ 1351955, 1356474, 1351960, 1356479 ], 
+        [ 1356475, 1359703, 1356480, 1359699 ], 
+        [ 1359704, 1361176, 1359700, 1361180 ], 
+        [ 1361177, 1362756, 1361181, 1362761 ], 
+        [ 1362757, 1368544, 1362762, 1368549 ], 
+        [ 1368545, 1370442, 1368550, 1370438 ], 
+        [ 1370443, 1373317, 1370439, 1373321 ], 
+        [ 1373318, 1374484, 1373322, 1374488 ], 
+        [ 1374485, 1377993, 1374489, 1377998 ], 
+        [ 1377994, 1379610, 1377999, 1379615 ], 
+        [ 1379611, 1380792, 1379616, 1380796 ], 
+        [ 1380793, 1381209, 1380797, 1381205 ], 
+        [ 1381210, 1386893, 1381206, 1386897 ], 
+        [ 1386894, 1391551, 1386898, 1391556 ], 
+        [ 1391552, 1393799, 1391557, 1393803 ], 
+        [ 1393800, 1395841, 1393804, 1395846 ], 
+        [ 1395842, 1397239, 1395847, 1397243 ], 
+        [ 1397240, 1401721, 1397244, 1401726 ], 
+        [ 1401722, 1403822, 1401727, 1403818 ], 
+        [ 1403823, 1406871, 1403819, 1406876 ], 
+        [ 1406872, 1407926, 1406877, 1407922 ], 
+        [ 1407927, 1408482, 1407923, 1408486 ], 
+        [ 1408483, 1409484, 1408487, 1409480 ], 
+        [ 1409485, 1410252, 1409481, 1410256 ], 
+        [ 1410253, 1411041, 1410257, 1411046 ], 
+        [ 1411042, 1417851, 1411047, 1417856 ], 
+        [ 1417852, 1419058, 1417857, 1419063 ], 
+        [ 1419059, 1419370, 1419064, 1419366 ], 
+        [ 1419371, 1419429, 1419367, 1419433 ], 
+        [ 1419430, 1426518, 1419434, 1426522 ], 
+        [ 1426519, 1428120, 1426523, 1428125 ], 
+        [ 1428121, 1428584, 1428126, 1428589 ], 
+        [ 1428585, 1430135, 1428590, 1430139 ], 
+        [ 1430136, 1430700, 1430140, 1430705 ], 
+        [ 1430701, 1436904, 1430706, 1436908 ], 
+        [ 1436905, 1438278, 1436909, 1438283 ], 
+        [ 1438279, 1441717, 1438284, 1441721 ], 
+        [ 1441718, 1443084, 1441722, 1443089 ], 
+        [ 1443085, 1444668, 1443090, 1444673 ], 
+        [ 1444669, 1444866, 1444674, 1444871 ], 
+        [ 1444867, 1444914, 1444872, 1444919 ], 
+        [ 1444915, 1445093, 1444920, 1445098 ], 
+        [ 1445094, 1446216, 1445099, 1446221 ], 
+        [ 1446217, 1448333, 1446222, 1448329 ], 
+        [ 1448334, 1448518, 1448330, 1448523 ], 
+        [ 1448519, 1449362, 1448524, 1449358 ], 
+        [ 1449363, 1449444, 1449359, 1449440 ], 
+        [ 1449445, 1452860, 1449441, 1452865 ], 
+        [ 1452861, 1454246, 1452866, 1454251 ], 
+        [ 1454247, 1455021, 1454252, 1455017 ], 
+        [ 1455022, 1455414, 1455018, 1455419 ], 
+        [ 1455415, 1460976, 1455420, 1460981 ], 
+        [ 1460977, 1461164, 1460982, 1461169 ], 
+        [ 1461165, 1461294, 1461170, 1461298 ], 
+        [ 1461295, 1463675, 1461299, 1463680 ], 
+        [ 1463676, 1463710, 1463681, 1463714 ], 
+        [ 1463711, 1465339, 1463715, 1465344 ], 
+        [ 1465340, 1469872, 1465345, 1469877 ], 
+        [ 1469873, 1471479, 1469878, 1471484 ], 
+        [ 1471480, 1471922, 1471485, 1471926 ], 
+        [ 1471923, 1472450, 1471927, 1472454 ], 
+        [ 1472451, 1472745, 1472455, 1472750 ], 
+        [ 1472746, 1479208, 1472751, 1479213 ], 
+        [ 1479209, 1480831, 1479214, 1480836 ], 
+        [ 1480832, 1483483, 1480837, 1483479 ], 
+        [ 1483484, 1485359, 1483480, 1485364 ], 
+        [ 1485360, 1485530, 1485365, 1485535 ], 
+        [ 1485531, 1485675, 1485536, 1485679 ], 
+        [ 1485676, 1486004, 1485680, 1486009 ], 
+        [ 1486005, 1487314, 1486010, 1487319 ], 
+        [ 1487315, 1491008, 1487320, 1491013 ], 
+        [ 1491009, 1492068, 1491014, 1492073 ], 
+        [ 1492069, 1492190, 1492074, 1492194 ], 
+        [ 1492191, 1493001, 1492195, 1493006 ], 
+        [ 1493002, 1495524, 1493007, 1495529 ], 
+        [ 1495525, 1498599, 1495530, 1498604 ], 
+        [ 1498600, 1499384, 1498605, 1499389 ], 
+        [ 1499385, 1500494, 1499390, 1500499 ], 
+        [ 1500495, 1504828, 1500500, 1504833 ], 
+        [ 1504829, 1506224, 1504834, 1506228 ], 
+        [ 1506225, 1506798, 1506229, 1506802 ], 
+        [ 1506799, 1508452, 1506803, 1508456 ], 
+        [ 1508453, 1509790, 1508457, 1509795 ], 
+        [ 1509791, 1512050, 1509796, 1512055 ], 
+        [ 1512051, 1514922, 1512056, 1514927 ], 
+        [ 1514923, 1515140, 1514928, 1515145 ], 
+        [ 1515141, 1515194, 1515146, 1515199 ], 
+        [ 1515195, 1515647, 1515200, 1515652 ], 
+        [ 1515648, 1516602, 1515653, 1516607 ], 
+        [ 1516603, 1517689, 1516608, 1517694 ], 
+        [ 1517690, 1519324, 1517695, 1519329 ], 
+        [ 1519325, 1524288, 1519330, 1524293 ], 
+        [ 1524289, 1524809, 1524294, 1524814 ], 
+        [ 1524810, 1524838, 1524815, 1524842 ], 
+        [ 1524839, 1525934, 1524843, 1525939 ], 
+        [ 1525935, 1526325, 1525940, 1526330 ], 
+        [ 1526326, 1527046, 1526331, 1527051 ], 
+        [ 1527047, 1527437, 1527052, 1527441 ], 
+        [ 1527438, 1528800, 1527442, 1528805 ], 
+        [ 1528801, 1529067, 1528806, 1529072 ], 
+        [ 1529068, 1529127, 1529073, 1529132 ], 
+        [ 1529128, 1532112, 1529133, 1532108 ], 
+        [ 1532113, 1533431, 1532109, 1533435 ], 
+        [ 1533432, 1536262, 1533436, 1536267 ], 
+        [ 1536263, 1543858, 1536268, 1543863 ], 
+        [ 1543859, 1547883, 1543864, 1547887 ], 
+        [ 1547884, 1550923, 1547888, 1550927 ], 
+        [ 1550924, 1550941, 1550928, 1550945 ], 
+        [ 1550942, 1551904, 1550946, 1551900 ], 
+        [ 1551905, 1554015, 1551901, 1554020 ], 
+        [ 1554016, 1554903, 1554021, 1554907 ], 
+        [ 1554904, 1555315, 1554908, 1555320 ], 
+        [ 1555316, 1558476, 1555321, 1558481 ], 
+        [ 1558477, 1560403, 1558482, 1560408 ], 
+        [ 1560404, 1564152, 1560409, 1564157 ], 
+        [ 1564153, 1565868, 1564158, 1565873 ], 
+        [ 1565869, 1566075, 1565874, 1566080 ], 
+        [ 1566076, 1572396, 1566081, 1572392 ], 
+        [ 1572397, 1572715, 1572393, 1572720 ], 
+        [ 1572716, 1573897, 1572721, 1573901 ], 
+        [ 1573898, 1575566, 1573902, 1575571 ], 
+        [ 1575567, 1575840, 1575572, 1575845 ], 
+        [ 1575841, 1575957, 1575846, 1575962 ], 
+        [ 1575958, 1577744, 1575963, 1577748 ], 
+        [ 1577745, 1578588, 1577749, 1578593 ], 
+        [ 1578589, 1580138, 1578594, 1580134 ], 
+        [ 1580139, 1582760, 1580135, 1582764 ], 
+        [ 1582761, 1587557, 1582765, 1587562 ], 
+        [ 1587558, 1588891, 1587563, 1588896 ], 
+        [ 1588892, 1590824, 1588897, 1590828 ], 
+        [ 1590825, 1591786, 1590829, 1591790 ], 
+        [ 1591787, 1597227, 1591791, 1597232 ], 
+        [ 1597228, 1597262, 1597233, 1597267 ], 
+        [ 1597263, 1606974, 1597268, 1606979 ], 
+        [ 1606975, 1608871, 1606980, 1608875 ], 
+        [ 1608872, 1613363, 1608876, 1613367 ], 
+        [ 1613364, 1613512, 1613368, 1613517 ], 
+        [ 1613513, 1613900, 1613518, 1613905 ], 
+        [ 1613901, 1614931, 1613906, 1614936 ], 
+        [ 1614932, 1616478, 1614937, 1616482 ], 
+        [ 1616479, 1620090, 1616483, 1620094 ], 
+        [ 1620091, 1620971, 1620095, 1620976 ], 
+        [ 1620972, 1625931, 1620977, 1625936 ], 
+        [ 1625932, 1635578, 1625937, 1635583 ], 
+        [ 1635579, 1636949, 1635584, 1636954 ], 
+        [ 1636950, 1642076, 1636955, 1642081 ], 
+        [ 1642077, 1643227, 1642082, 1643232 ], 
+        [ 1643228, 1643451, 1643233, 1643456 ], 
+        [ 1643452, 1643568, 1643457, 1643573 ], 
+        [ 1643569, 1651406, 1643574, 1651411 ], 
+        [ 1651407, 1651474, 1651412, 1651479 ], 
+        [ 1651475, 1656665, 1651480, 1656669 ], 
+        [ 1656666, 1660688, 1656670, 1660693 ], 
+        [ 1660689, 1662867, 1660694, 1662871 ], 
+        [ 1662868, 1665846, 1662872, 1665851 ], 
+        [ 1665847, 1667026, 1665852, 1667031 ], 
+        [ 1667027, 1669021, 1667032, 1669025 ], 
+        [ 1669022, 1669975, 1669026, 1669979 ], 
+        [ 1669976, 1675465, 1669980, 1675470 ], 
+        [ 1675466, 1679164, 1675471, 1679169 ], 
+        [ 1679165, 1681962, 1679170, 1681967 ], 
+        [ 1681963, 1688016, 1681968, 1688021 ], 
+        [ 1688017, 1690659, 1688022, 1690664 ], 
+        [ 1690660, 1692872, 1690665, 1692877 ], 
+        [ 1692873, 1697102, 1692878, 1697107 ], 
+        [ 1697103, 1698132, 1697108, 1698137 ], 
+        [ 1698133, 1698208, 1698138, 1698212 ], 
+        [ 1698209, 1703429, 1698213, 1703434 ], 
+        [ 1703430, 1705101, 1703435, 1705105 ], 
+        [ 1705102, 1705881, 1705106, 1705885 ], 
+        [ 1705882, 1706057, 1705886, 1706062 ], 
+        [ 1706058, 1708138, 1706063, 1708142 ], 
+        [ 1708139, 1708683, 1708143, 1708688 ], 
+        [ 1708684, 1712200, 1708689, 1712204 ], 
+        [ 1712201, 1720884, 1712205, 1720889 ], 
+        [ 1720885, 1721218, 1720890, 1721223 ], 
+        [ 1721219, 1725289, 1721224, 1725294 ], 
+        [ 1725290, 1726034, 1725295, 1726038 ], 
+        [ 1726035, 1726495, 1726039, 1726500 ], 
+        [ 1726496, 1728646, 1726501, 1728651 ], 
+        [ 1728647, 1729060, 1728652, 1729065 ], 
+        [ 1729061, 1732801, 1729066, 1732806 ], 
+        [ 1732802, 1733308, 1732807, 1733313 ], 
+        [ 1733309, 1734471, 1733314, 1734476 ], 
+        [ 1734472, 1738054, 1734477, 1738058 ], 
+        [ 1738055, 1738256, 1738059, 1738260 ], 
+        [ 1738257, 1740942, 1738261, 1740947 ], 
+        [ 1740943, 1744762, 1740948, 1744767 ], 
+        [ 1744763, 1746379, 1744768, 1746384 ], 
+        [ 1746380, 1746672, 1746385, 1746668 ], 
+        [ 1746673, 1747144, 1746669, 1747149 ], 
+        [ 1747145, 1751310, 1747150, 1751306 ], 
+        [ 1751311, 1753062, 1751307, 1753067 ], 
+        [ 1753063, 1754367, 1753068, 1754372 ], 
+        [ 1754368, 1758860, 1754373, 1758864 ], 
+        [ 1758861, 1763444, 1758865, 1763449 ], 
+        [ 1763445, 1769087, 1763450, 1769091 ], 
+        [ 1769088, 1769105, 1769092, 1769109 ], 
+        [ 1769106, 1769947, 1769110, 1769951 ], 
+        [ 1769948, 1772285, 1769952, 1772289 ], 
+        [ 1772286, 1774404, 1772290, 1774408 ], 
+        [ 1774405, 1776003, 1774409, 1776007 ], 
+        [ 1776004, 1777420, 1776008, 1777425 ], 
+        [ 1777421, 1782626, 1777426, 1782631 ], 
+        [ 1782627, 1784342, 1782632, 1784347 ], 
+        [ 1784343, 1784549, 1784348, 1784554 ], 
+        [ 1784550, 1785362, 1784555, 1785366 ], 
+        [ 1785363, 1791189, 1785367, 1791194 ], 
+        [ 1791190, 1792209, 1791195, 1792213 ], 
+        [ 1792210, 1793878, 1792214, 1793883 ], 
+        [ 1793879, 1794152, 1793884, 1794157 ], 
+        [ 1794153, 1794269, 1794158, 1794274 ], 
+        [ 1794270, 1794972, 1794275, 1794977 ], 
+        [ 1794973, 1796163, 1794978, 1796168 ], 
+        [ 1796164, 1800687, 1796169, 1800683 ], 
+        [ 1800688, 1802296, 1800684, 1802301 ], 
+        [ 1802297, 1804730, 1802302, 1804734 ], 
+        [ 1804731, 1805422, 1804735, 1805426 ], 
+        [ 1805423, 1805729, 1805427, 1805734 ], 
+        [ 1805730, 1806305, 1805735, 1806310 ], 
+        [ 1806306, 1806755, 1806311, 1806759 ], 
+        [ 1806756, 1806879, 1806760, 1806875 ], 
+        [ 1806880, 1810512, 1806876, 1810517 ], 
+        [ 1810513, 1816402, 1810518, 1816407 ], 
+        [ 1816403, 1826227, 1816408, 1826232 ], 
+        [ 1826228, 1826701, 1826233, 1826706 ], 
+        [ 1826702, 1827720, 1826707, 1827725 ], 
+        [ 1827721, 1833845, 1827726, 1833849 ], 
+        [ 1833846, 1836707, 1833850, 1836712 ], 
+        [ 1836708, 1836926, 1836713, 1836931 ], 
+        [ 1836927, 1838667, 1836932, 1838672 ], 
+        [ 1838668, 1838935, 1838673, 1838939 ], 
+        [ 1838936, 1842071, 1838940, 1842075 ], 
+        [ 1842072, 1842664, 1842076, 1842668 ], 
+        [ 1842665, 1843220, 1842669, 1843225 ], 
+        [ 1843221, 1843829, 1843226, 1843834 ], 
+        [ 1843830, 1845044, 1843835, 1845048 ], 
+        [ 1845045, 1846577, 1845049, 1846582 ], 
+        [ 1846578, 1848717, 1846583, 1848721 ], 
+        [ 1848718, 1849125, 1848722, 1849130 ], 
+        [ 1849126, 1850237, 1849131, 1850242 ], 
+        [ 1850238, 1851708, 1850243, 1851713 ], 
+        [ 1851709, 1853436, 1851714, 1853441 ], 
+        [ 1853437, 1853475, 1853442, 1853480 ], 
+        [ 1853476, 1853493, 1853481, 1853498 ], 
+        [ 1853494, 1854900, 1853499, 1854905 ], 
+        [ 1854901, 1854987, 1854906, 1854991 ], 
+        [ 1854988, 1861797, 1854992, 1861802 ], 
+        [ 1861798, 1862267, 1861803, 1862272 ], 
+        [ 1862268, 1866445, 1862273, 1866450 ], 
+        [ 1866446, 1866700, 1866451, 1866705 ], 
+        [ 1866701, 1870035, 1866706, 1870039 ], 
+        [ 1870036, 1870143, 1870040, 1870148 ], 
+        [ 1870144, 1870675, 1870149, 1870680 ], 
+        [ 1870676, 1871498, 1870681, 1871502 ], 
+        [ 1871499, 1873369, 1871503, 1873373 ], 
+        [ 1873370, 1877824, 1873374, 1877828 ], 
+        [ 1877825, 1880920, 1877829, 1880916 ], 
+        [ 1880921, 1881704, 1880917, 1881709 ], 
+        [ 1881705, 1882659, 1881710, 1882664 ], 
+        [ 1882660, 1884008, 1882665, 1884013 ], 
+        [ 1884009, 1885076, 1884014, 1885081 ], 
+        [ 1885077, 1888274, 1885082, 1888270 ], 
+        [ 1888275, 1897857, 1888271, 1897862 ], 
+        [ 1897858, 1907112, 1897863, 1907116 ], 
+        [ 1907113, 1907770, 1907117, 1907774 ], 
+        [ 1907771, 1912119, 1907775, 1912123 ], 
+        [ 1912120, 1913812, 1912124, 1913816 ], 
+        [ 1913813, 1913938, 1913817, 1913942 ], 
+        [ 1913939, 1922086, 1913943, 1922090 ], 
+        [ 1922087, 1924874, 1922091, 1924878 ], 
+        [ 1924875, 1929326, 1924879, 1929322 ], 
+        [ 1929327, 1931549, 1929323, 1931554 ], 
+        [ 1931550, 1931660, 1931555, 1931665 ], 
+        [ 1931661, 1936680, 1931666, 1936685 ], 
+        [ 1936681, 1938633, 1936686, 1938637 ], 
+        [ 1938634, 1938835, 1938638, 1938840 ], 
+        [ 1938836, 1939367, 1938841, 1939372 ], 
+        [ 1939368, 1941696, 1939373, 1941700 ], 
+        [ 1941697, 1943301, 1941701, 1943305 ], 
+        [ 1943302, 1944718, 1943306, 1944723 ], 
+        [ 1944719, 1949924, 1944724, 1949929 ], 
+        [ 1949925, 1951640, 1949930, 1951645 ], 
+        [ 1951641, 1951847, 1951646, 1951852 ], 
+        [ 1951848, 1952660, 1951853, 1952664 ], 
+        [ 1952661, 1953731, 1952665, 1953735 ], 
+        [ 1953732, 1958495, 1953736, 1958500 ], 
+        [ 1958496, 1959515, 1958501, 1959519 ], 
+        [ 1959516, 1961184, 1959520, 1961189 ], 
+        [ 1961185, 1961458, 1961190, 1961463 ], 
+        [ 1961459, 1963223, 1961464, 1963228 ], 
+        [ 1963224, 1964535, 1963229, 1964540 ], 
+        [ 1964536, 1964578, 1964541, 1964583 ], 
+        [ 1964579, 1965726, 1964584, 1965731 ], 
+        [ 1965727, 1967936, 1965732, 1967940 ], 
+        [ 1967937, 1970524, 1967941, 1970528 ], 
+        [ 1970525, 1971307, 1970529, 1971303 ], 
+        [ 1971308, 1971952, 1971304, 1971956 ], 
+        [ 1971953, 1971961, 1971957, 1971965 ], 
+        [ 1971962, 1974876, 1971966, 1974880 ], 
+        [ 1974877, 1975723, 1974881, 1975728 ], 
+        [ 1975724, 1977141, 1975729, 1977137 ], 
+        [ 1977142, 1983495, 1977138, 1983500 ], 
+        [ 1983496, 1985266, 1983501, 1985270 ], 
+        [ 1985267, 1989041, 1985271, 1989046 ], 
+        [ 1989042, 1991504, 1989047, 1991508 ], 
+        [ 1991505, 1991939, 1991509, 1991944 ], 
+        [ 1991940, 1994134, 1991945, 1994139 ], 
+        [ 1994135, 1997719, 1994140, 1997723 ], 
+        [ 1997720, 1997804, 1997724, 1997800 ], 
+        [ 1997805, 2002856, 1997801, 2002860 ], 
+        [ 2002857, 2006390, 2002861, 2006395 ], 
+        [ 2006391, 2006681, 2006396, 2006686 ], 
+        [ 2006682, 2012753, 2006687, 2012758 ], 
+        [ 2012754, 2020299, 2012759, 2020304 ], 
+        [ 2020300, 2021594, 2020305, 2021599 ], 
+        [ 2021595, 2023023, 2021600, 2023027 ], 
+        [ 2023024, 2026978, 2023028, 2026974 ], 
+        [ 2026979, 2035653, 2026975, 2035658 ], 
+        [ 2035654, 2035969, 2035659, 2035973 ], 
+        [ 2035970, 2038524, 2035974, 2038528 ], 
+        [ 2038525, 2040783, 2038529, 2040787 ], 
+        [ 2040784, 2042430, 2040788, 2042434 ], 
+        [ 2042431, 2043961, 2042435, 2043966 ], 
+        [ 2043962, 2044411, 2043967, 2044416 ], 
+        [ 2044412, 2045320, 2044417, 2045325 ], 
+        [ 2045321, 2045652, 2045326, 2045648 ], 
+        [ 2045653, 2046593, 2045649, 2046598 ], 
+        [ 2046594, 2058014, 2046599, 2058019 ], 
+        [ 2058015, 2058163, 2058020, 2058167 ], 
+        [ 2058164, 2058262, 2058168, 2058267 ], 
+        [ 2058263, 2059250, 2058268, 2059246 ], 
+        [ 2059251, 2061616, 2059247, 2061621 ], 
+        [ 2061617, 2067334, 2061622, 2067339 ], 
+        [ 2067335, 2069059, 2067340, 2069064 ], 
+        [ 2069060, 2073142, 2069065, 2073147 ], 
+        [ 2073143, 2074555, 2073148, 2074560 ], 
+        [ 2074556, 2074634, 2074561, 2074639 ], 
+        [ 2074635, 2076234, 2074640, 2076238 ], 
+        [ 2076235, 2076422, 2076239, 2076427 ], 
+        [ 2076423, 2080648, 2076428, 2080652 ], 
+        [ 2080649, 2081937, 2080653, 2081942 ], 
+        [ 2081938, 2082042, 2081943, 2082047 ], 
+        [ 2082043, 2082408, 2082048, 2082413 ], 
+        [ 2082409, 2086395, 2082414, 2086399 ], 
+        [ 2086396, 2088062, 2086400, 2088066 ], 
+        [ 2088063, 2088207, 2088067, 2088211 ], 
+        [ 2088208, 2092297, 2088212, 2092301 ], 
+        [ 2092298, 2093453, 2092302, 2093449 ], 
+        [ 2093454, 2094661, 2093450, 2094666 ], 
+        [ 2094662, 2098386, 2094667, 2098390 ], 
+        [ 2098387, 2105404, 2098391, 2105408 ], 
+        [ 2105405, 2105556, 2105409, 2105561 ], 
+        [ 2105557, 2106153, 2105562, 2106158 ], 
+        [ 2106154, 2107284, 2106159, 2107288 ], 
+        [ 2107285, 2110444, 2107289, 2110448 ], 
+        [ 2110445, 2110523, 2110449, 2110527 ], 
+        [ 2110524, 2113282, 2110528, 2113287 ], 
+        [ 2113283, 2114197, 2113288, 2114202 ], 
+        [ 2114198, 2119617, 2114203, 2119621 ], 
+        [ 2119618, 2124245, 2119622, 2124250 ], 
+        [ 2124246, 2126629, 2124251, 2126634 ], 
+        [ 2126630, 2127367, 2126635, 2127372 ], 
+        [ 2127368, 2131057, 2127373, 2131061 ], 
+        [ 2131058, 2131854, 2131062, 2131859 ], 
+        [ 2131855, 2134278, 2131860, 2134282 ], 
+        [ 2134279, 2134456, 2134283, 2134460 ], 
+        [ 2134457, 2137761, 2134461, 2137765 ], 
+        [ 2137762, 2138481, 2137766, 2138486 ], 
+        [ 2138482, 2139541, 2138487, 2139545 ], 
+        [ 2139542, 2140084, 2139546, 2140089 ], 
+        [ 2140085, 2151397, 2140090, 2151402 ], 
+        [ 2151398, 2154116, 2151403, 2154121 ], 
+        [ 2154117, 2158877, 2154122, 2158881 ], 
+        [ 2158878, 2158886, 2158882, 2158890 ], 
+        [ 2158887, 2160314, 2158891, 2160318 ], 
+        [ 2160315, 2164531, 2160319, 2164536 ], 
+        [ 2164532, 2164999, 2164537, 2165004 ], 
+        [ 2165000, 2166190, 2165005, 2166195 ], 
+        [ 2166191, 2168535, 2166196, 2168540 ], 
+        [ 2168536, 2168652, 2168541, 2168657 ], 
+        [ 2168653, 2168876, 2168658, 2168881 ], 
+        [ 2168877, 2169179, 2168882, 2169175 ], 
+        [ 2169180, 2170247, 2169176, 2170243 ], 
+        [ 2170248, 2175197, 2170244, 2175202 ], 
+        [ 2175198, 2176568, 2175203, 2176573 ], 
+        [ 2176569, 2185419, 2176574, 2185424 ], 
+        [ 2185420, 2187124, 2185425, 2187128 ], 
+        [ 2187125, 2188632, 2187129, 2188636 ], 
+        [ 2188633, 2194633, 2188637, 2194637 ], 
+        [ 2194634, 2196521, 2194638, 2196525 ], 
+        [ 2196522, 2197400, 2196526, 2197396 ], 
+        [ 2197401, 2198074, 2197397, 2198079 ], 
+        [ 2198075, 2200597, 2198080, 2200601 ], 
+        [ 2200598, 2202376, 2200602, 2202380 ], 
+        [ 2202377, 2203542, 2202381, 2203546 ], 
+        [ 2203543, 2205716, 2203547, 2205721 ], 
+        [ 2205717, 2206482, 2205722, 2206487 ], 
+        [ 2206483, 2209774, 2206488, 2209778 ], 
+        [ 2209775, 2214819, 2209779, 2214824 ], 
+        [ 2214820, 2215255, 2214825, 2215260 ], 
+        [ 2215256, 2216910, 2215261, 2216915 ], 
+        [ 2216911, 2219477, 2216916, 2219482 ], 
+        [ 2219478, 2219751, 2219483, 2219756 ], 
+        [ 2219752, 2221421, 2219757, 2221425 ], 
+        [ 2221422, 2222602, 2221426, 2222607 ], 
+        [ 2222603, 2222929, 2222608, 2222925 ], 
+        [ 2222930, 2224016, 2222926, 2224021 ], 
+        [ 2224017, 2228441, 2224022, 2228445 ], 
+        [ 2228442, 2229253, 2228446, 2229258 ], 
+        [ 2229254, 2229460, 2229259, 2229465 ], 
+        [ 2229461, 2231176, 2229466, 2231181 ], 
+        [ 2231177, 2236382, 2231182, 2236387 ], 
+        [ 2236383, 2238087, 2236388, 2238091 ], 
+        [ 2238088, 2239596, 2238092, 2239600 ], 
+        [ 2239597, 2242924, 2239601, 2242920 ], 
+        [ 2242925, 2243879, 2242921, 2243883 ], 
+        [ 2243880, 2243897, 2243884, 2243901 ], 
+        [ 2243898, 2245581, 2243902, 2245586 ], 
+        [ 2245582, 2245719, 2245587, 2245724 ], 
+        [ 2245720, 2245761, 2245725, 2245766 ], 
+        [ 2245762, 2249902, 2245767, 2249907 ], 
+        [ 2249903, 2254722, 2249908, 2254727 ], 
+        [ 2254723, 2254803, 2254728, 2254807 ], 
+        [ 2254804, 2257149, 2254808, 2257153 ], 
+        [ 2257150, 2262668, 2257154, 2262673 ], 
+        [ 2262669, 2267507, 2262674, 2267503 ], 
+        [ 2267508, 2270370, 2267504, 2270366 ], 
+        [ 2270371, 2276333, 2270367, 2276338 ], 
+        [ 2276334, 2277071, 2276339, 2277075 ], 
+        [ 2277072, 2278349, 2277076, 2278354 ], 
+        [ 2278350, 2278595, 2278355, 2278600 ], 
+        [ 2278596, 2281303, 2278601, 2281307 ], 
+        [ 2281304, 2282039, 2281308, 2282044 ], 
+        [ 2282040, 2286122, 2282045, 2286126 ], 
+        [ 2286123, 2295986, 2286127, 2295990 ], 
+        [ 2295987, 2296911, 2295991, 2296907 ], 
+        [ 2296912, 2300006, 2296908, 2300010 ], 
+        [ 2300007, 2309292, 2300011, 2309297 ], 
+        [ 2309293, 2309737, 2309298, 2309742 ], 
+        [ 2309738, 2312320, 2309743, 2312324 ], 
+        [ 2312321, 2314845, 2312325, 2314850 ], 
+        [ 2314846, 2315016, 2314851, 2315021 ], 
+        [ 2315017, 2320047, 2315022, 2320052 ], 
+        [ 2320048, 2320645, 2320053, 2320650 ], 
+        [ 2320646, 2326925, 2320651, 2326921 ], 
+        [ 2326926, 2330437, 2326922, 2330442 ], 
+        [ 2330438, 2335656, 2330443, 2335660 ], 
+        [ 2335657, 2338082, 2335661, 2338087 ], 
+        [ 2338083, 2343729, 2338088, 2343725 ], 
+        [ 2343730, 2345465, 2343726, 2345470 ], 
+        [ 2345466, 2345517, 2345471, 2345521 ], 
+        [ 2345518, 2347136, 2345522, 2347140 ], 
+        [ 2347137, 2347233, 2347141, 2347238 ], 
+        [ 2347234, 2348720, 2347239, 2348725 ], 
+        [ 2348721, 2351324, 2348726, 2351329 ], 
+        [ 2351325, 2352448, 2351330, 2352453 ], 
+        [ 2352449, 2353999, 2352454, 2354004 ], 
+        [ 2354000, 2354134, 2354005, 2354138 ], 
+        [ 2354135, 2359046, 2354139, 2359051 ], 
+        [ 2359047, 2361149, 2359052, 2361154 ], 
+        [ 2361150, 2374039, 2361155, 2374044 ], 
+        [ 2374040, 2382502, 2374045, 2382506 ], 
+        [ 2382503, 2385349, 2382507, 2385354 ], 
+        [ 2385350, 2388585, 2385355, 2388590 ], 
+        [ 2388586, 2391734, 2388591, 2391739 ], 
+        [ 2391735, 2392141, 2391740, 2392146 ], 
+        [ 2392142, 2393939, 2392147, 2393944 ], 
+        [ 2393940, 2395026, 2393945, 2395031 ], 
+        [ 2395027, 2395860, 2395032, 2395865 ], 
+        [ 2395861, 2398211, 2395866, 2398216 ], 
+        [ 2398212, 2398326, 2398217, 2398331 ], 
+        [ 2398327, 2400696, 2398332, 2400700 ], 
+        [ 2400697, 2402303, 2400701, 2402308 ], 
+        [ 2402304, 2405335, 2402309, 2405339 ], 
+        [ 2405336, 2408154, 2405340, 2408159 ], 
+        [ 2408155, 2409936, 2408160, 2409941 ], 
+        [ 2409937, 2410353, 2409942, 2410358 ], 
+        [ 2410354, 2411021, 2410359, 2411026 ], 
+        [ 2411022, 2414614, 2411027, 2414618 ], 
+        [ 2414615, 2419571, 2414619, 2419576 ], 
+        [ 2419572, 2421744, 2419577, 2421748 ], 
+        [ 2421745, 2424488, 2421749, 2424493 ], 
+        [ 2424489, 2427895, 2424494, 2427900 ], 
+        [ 2427896, 2430604, 2427901, 2430600 ], 
+        [ 2430605, 2433794, 2430601, 2433799 ], 
+        [ 2433795, 2434280, 2433800, 2434285 ], 
+        [ 2434281, 2435465, 2434286, 2435461 ], 
+        [ 2435466, 2436129, 2435462, 2436134 ], 
+        [ 2436130, 2446339, 2436135, 2446344 ], 
+        [ 2446340, 2446355, 2446345, 2446360 ], 
+        [ 2446356, 2447550, 2446361, 2447555 ], 
+        [ 2447551, 2447589, 2447556, 2447593 ], 
+        [ 2447590, 2451279, 2447594, 2451283 ], 
+        [ 2451280, 2456375, 2451284, 2456380 ], 
+        [ 2456376, 2458676, 2456381, 2458672 ], 
+        [ 2458677, 2459075, 2458673, 2459079 ], 
+        [ 2459076, 2459685, 2459080, 2459690 ], 
+        [ 2459686, 2467707, 2459691, 2467712 ], 
+        [ 2467708, 2474920, 2467713, 2474924 ], 
+        [ 2474921, 2483809, 2474925, 2483813 ], 
+        [ 2483810, 2487345, 2483814, 2487349 ], 
+        [ 2487346, 2489626, 2487350, 2489631 ], 
+        [ 2489627, 2490030, 2489632, 2490035 ], 
+        [ 2490031, 2493086, 2490036, 2493090 ], 
+        [ 2493087, 2494181, 2493091, 2494186 ], 
+        [ 2494182, 2494578, 2494187, 2494583 ], 
+        [ 2494579, 2498330, 2494584, 2498335 ], 
+        [ 2498331, 2501619, 2498336, 2501624 ], 
+        [ 2501620, 2502148, 2501625, 2502152 ], 
+        [ 2502149, 2502774, 2502153, 2502779 ], 
+        [ 2502775, 2503405, 2502780, 2503409 ], 
+        [ 2503406, 2505440, 2503410, 2505445 ], 
+        [ 2505441, 2507840, 2505446, 2507845 ], 
+        [ 2507841, 2513737, 2507846, 2513741 ], 
+        [ 2513738, 2513953, 2513742, 2513958 ], 
+        [ 2513954, 2516708, 2513959, 2516712 ], 
+        [ 2516709, 2518482, 2516713, 2518487 ], 
+        [ 2518483, 2518510, 2518488, 2518515 ], 
+        [ 2518511, 2519154, 2518516, 2519159 ], 
+        [ 2519155, 2521663, 2519160, 2521668 ], 
+        [ 2521664, 2522690, 2521669, 2522695 ], 
+        [ 2522691, 2533188, 2522696, 2533184 ], 
+        [ 2533189, 2535156, 2533185, 2535161 ], 
+        [ 2535157, 2536302, 2535162, 2536307 ], 
+        [ 2536303, 2536525, 2536308, 2536521 ], 
+        [ 2536526, 2539683, 2536522, 2539688 ], 
+        [ 2539684, 2540838, 2539689, 2540843 ], 
+        [ 2540839, 2542188, 2540844, 2542192 ], 
+        [ 2542189, 2542542, 2542193, 2542547 ], 
+        [ 2542543, 2543529, 2542548, 2543533 ], 
+        [ 2543530, 2543833, 2543534, 2543829 ], 
+        [ 2543834, 2549711, 2543830, 2549716 ], 
+        [ 2549712, 2549979, 2549717, 2549984 ], 
+        [ 2549980, 2550376, 2549985, 2550381 ], 
+        [ 2550377, 2550442, 2550382, 2550447 ], 
+        [ 2550443, 2552498, 2550448, 2552503 ], 
+        [ 2552499, 2556237, 2552504, 2556242 ], 
+        [ 2556238, 2557871, 2556243, 2557875 ], 
+        [ 2557872, 2561281, 2557876, 2561286 ], 
+        [ 2561282, 2562381, 2561287, 2562386 ], 
+        [ 2562382, 2571576, 2562387, 2571581 ], 
+        [ 2571577, 2573918, 2571582, 2573923 ], 
+        [ 2573919, 2575854, 2573924, 2575859 ], 
+        [ 2575855, 2575961, 2575860, 2575965 ], 
+        [ 2575962, 2576170, 2575966, 2576166 ], 
+        [ 2576171, 2579045, 2576167, 2579050 ], 
+        [ 2579046, 2587793, 2579051, 2587797 ], 
+        [ 2587794, 2588693, 2587798, 2588689 ], 
+        [ 2588694, 2588728, 2588690, 2588733 ], 
+        [ 2588729, 2589643, 2588734, 2589647 ], 
+        [ 2589644, 2591930, 2589648, 2591935 ], 
+        [ 2591931, 2592492, 2591936, 2592496 ], 
+        [ 2592493, 2595383, 2592497, 2595387 ], 
+        [ 2595384, 2601304, 2595388, 2601309 ], 
+        [ 2601305, 2610396, 2601310, 2610400 ], 
+        [ 2610397, 2613914, 2610401, 2613918 ], 
+        [ 2613915, 2614812, 2613919, 2614817 ], 
+        [ 2614813, 2614839, 2614818, 2614844 ], 
+        [ 2614840, 2622328, 2614845, 2622333 ], 
+        [ 2622329, 2624051, 2622334, 2624055 ], 
+        [ 2624052, 2627903, 2624056, 2627908 ], 
+        [ 2627904, 2633758, 2627909, 2633762 ], 
+        [ 2633759, 2640020, 2633763, 2640024 ], 
+        [ 2640021, 2648431, 2640025, 2648436 ], 
+        [ 2648432, 2651846, 2648437, 2651851 ], 
+        [ 2651847, 2658412, 2651852, 2658416 ], 
+        [ 2658413, 2660586, 2658417, 2660591 ], 
+        [ 2660587, 2660643, 2660592, 2660647 ], 
+        [ 2660644, 2662994, 2660648, 2662998 ], 
+        [ 2662995, 2663434, 2662999, 2663439 ], 
+        [ 2663435, 2664288, 2663440, 2664292 ], 
+        [ 2664289, 2666257, 2664293, 2666261 ], 
+        [ 2666258, 2668305, 2666262, 2668301 ], 
+        [ 2668306, 2668367, 2668302, 2668363 ], 
+        [ 2668368, 2669373, 2668364, 2669377 ], 
+        [ 2669374, 2674481, 2669378, 2674486 ], 
+        [ 2674482, 2674949, 2674487, 2674954 ], 
+        [ 2674950, 2676096, 2674955, 2676101 ], 
+        [ 2676097, 2676139, 2676102, 2676144 ], 
+        [ 2676140, 2678485, 2676145, 2678490 ], 
+        [ 2678486, 2678602, 2678491, 2678607 ], 
+        [ 2678603, 2678826, 2678608, 2678831 ], 
+        [ 2678827, 2679129, 2678832, 2679125 ], 
+        [ 2679130, 2680196, 2679126, 2680192 ], 
+        [ 2680197, 2681278, 2680193, 2681283 ], 
+        [ 2681279, 2683258, 2681284, 2683262 ], 
+        [ 2683259, 2684926, 2683263, 2684931 ], 
+        [ 2684927, 2685205, 2684932, 2685210 ], 
+        [ 2685206, 2691894, 2685211, 2691898 ], 
+        [ 2691895, 2692493, 2691899, 2692498 ], 
+        [ 2692494, 2695364, 2692499, 2695368 ], 
+        [ 2695365, 2696872, 2695369, 2696876 ], 
+        [ 2696873, 2701148, 2696877, 2701152 ], 
+        [ 2701149, 2701165, 2701153, 2701169 ], 
+        [ 2701166, 2703577, 2701170, 2703581 ], 
+        [ 2703578, 2709273, 2703582, 2709269 ], 
+        [ 2709274, 2710251, 2709270, 2710255 ], 
+        [ 2710252, 2714956, 2710256, 2714961 ], 
+        [ 2714957, 2716135, 2714962, 2716140 ], 
+        [ 2716136, 2716265, 2716141, 2716261 ], 
+        [ 2716266, 2716930, 2716262, 2716935 ], 
+        [ 2716931, 2717350, 2716936, 2717355 ], 
+        [ 2717351, 2717774, 2717356, 2717779 ], 
+        [ 2717775, 2718590, 2717780, 2718595 ], 
+        [ 2718591, 2720379, 2718596, 2720384 ], 
+        [ 2720380, 2721786, 2720385, 2721790 ], 
+        [ 2721787, 2723960, 2721791, 2723965 ], 
+        [ 2723961, 2725032, 2723966, 2725036 ], 
+        [ 2725033, 2725167, 2725037, 2725171 ], 
+        [ 2725168, 2725658, 2725172, 2725663 ], 
+        [ 2725659, 2731050, 2725664, 2731054 ], 
+        [ 2731051, 2731980, 2731055, 2731985 ], 
+        [ 2731981, 2738172, 2731986, 2738177 ], 
+        [ 2738173, 2738501, 2738178, 2738505 ], 
+        [ 2738502, 2741368, 2738506, 2741372 ], 
+        [ 2741369, 2741523, 2741373, 2741527 ], 
+        [ 2741524, 2743821, 2741528, 2743817 ], 
+        [ 2743822, 2743903, 2743818, 2743899 ], 
+        [ 2743904, 2746696, 2743900, 2746700 ], 
+        [ 2746697, 2748433, 2746701, 2748438 ], 
+        [ 2748434, 2748596, 2748439, 2748601 ], 
+        [ 2748597, 2749549, 2748602, 2749553 ], 
+        [ 2749550, 2749729, 2749554, 2749734 ], 
+        [ 2749730, 2750963, 2749735, 2750967 ], 
+        [ 2750964, 2751613, 2750968, 2751609 ], 
+        [ 2751614, 2752944, 2751610, 2752949 ], 
+        [ 2752945, 2753953, 2752950, 2753958 ], 
+        [ 2753954, 2754044, 2753959, 2754040 ], 
+        [ 2754045, 2755376, 2754041, 2755380 ], 
+        [ 2755377, 2760599, 2755381, 2760604 ], 
+        [ 2760600, 2761236, 2760605, 2761241 ], 
+        [ 2761237, 2763346, 2761242, 2763351 ], 
+        [ 2763347, 2764218, 2763352, 2764223 ], 
+        [ 2764219, 2767629, 2764224, 2767633 ], 
+        [ 2767630, 2771002, 2767634, 2771006 ], 
+        [ 2771003, 2773348, 2771007, 2773353 ], 
+        [ 2773349, 2778556, 2773354, 2778560 ], 
+        [ 2778557, 2779108, 2778561, 2779112 ], 
+        [ 2779109, 2779707, 2779113, 2779712 ], 
+        [ 2779708, 2780639, 2779713, 2780643 ], 
+        [ 2780640, 2781795, 2780644, 2781791 ], 
+        [ 2781796, 2782076, 2781792, 2782080 ], 
+        [ 2782077, 2788770, 2782081, 2788774 ], 
+        [ 2788771, 2792111, 2788775, 2792116 ], 
+        [ 2792112, 2794418, 2792117, 2794423 ], 
+        [ 2794419, 2795818, 2794424, 2795823 ], 
+        [ 2795819, 2796261, 2795824, 2796266 ], 
+        [ 2796262, 2798929, 2796267, 2798934 ], 
+        [ 2798930, 2799454, 2798935, 2799459 ], 
+        [ 2799455, 2811616, 2799460, 2811620 ], 
+        [ 2811617, 2813416, 2811621, 2813421 ], 
+        [ 2813417, 2813479, 2813422, 2813484 ], 
+        [ 2813480, 2814107, 2813485, 2814112 ], 
+        [ 2814108, 2818929, 2814113, 2818933 ], 
+        [ 2818930, 2825357, 2818934, 2825362 ], 
+        [ 2825358, 2826820, 2825363, 2826825 ], 
+        [ 2826821, 2828096, 2826826, 2828101 ], 
+        [ 2828097, 2828932, 2828102, 2828936 ], 
+        [ 2828933, 2830088, 2828937, 2830093 ], 
+        [ 2830089, 2830687, 2830094, 2830683 ], 
+        [ 2830688, 2834601, 2830684, 2834606 ], 
+        [ 2834602, 2836621, 2834607, 2836626 ], 
+        [ 2836622, 2836884, 2836627, 2836889 ], 
+        [ 2836885, 2837913, 2836890, 2837918 ], 
+        [ 2837914, 2840393, 2837919, 2840398 ], 
+        [ 2840394, 2841225, 2840399, 2841229 ], 
+        [ 2841226, 2843391, 2841230, 2843396 ], 
+        [ 2843392, 2843629, 2843397, 2843634 ], 
+        [ 2843630, 2844665, 2843635, 2844670 ], 
+        [ 2844666, 2845263, 2844671, 2845267 ], 
+        [ 2845264, 2847821, 2845268, 2847826 ], 
+        [ 2847822, 2848450, 2847827, 2848454 ], 
+        [ 2848451, 2849601, 2848455, 2849606 ], 
+        [ 2849602, 2853189, 2849607, 2853194 ], 
+        [ 2853190, 2853798, 2853195, 2853802 ], 
+        [ 2853799, 2860428, 2853803, 2860433 ], 
+        [ 2860429, 2862152, 2860434, 2862157 ], 
+        [ 2862153, 2862729, 2862158, 2862734 ], 
+        [ 2862730, 2869033, 2862735, 2869038 ], 
+        [ 2869034, 2869157, 2869039, 2869162 ], 
+        [ 2869158, 2872699, 2869163, 2872703 ], 
+        [ 2872700, 2882082, 2872704, 2882087 ], 
+        [ 2882083, 2888775, 2882088, 2888779 ], 
+        [ 2888776, 2894091, 2888780, 2894096 ], 
+        [ 2894092, 2895090, 2894097, 2895095 ], 
+        [ 2895091, 2895718, 2895096, 2895722 ], 
+        [ 2895719, 2896669, 2895723, 2896665 ], 
+        [ 2896670, 2900119, 2896666, 2900124 ], 
+        [ 2900120, 2900555, 2900125, 2900560 ], 
+        [ 2900556, 2902167, 2900561, 2902172 ], 
+        [ 2902168, 2902210, 2902173, 2902215 ], 
+        [ 2902211, 2904556, 2902216, 2904561 ], 
+        [ 2904557, 2904673, 2904562, 2904678 ], 
+        [ 2904674, 2904897, 2904679, 2904902 ], 
+        [ 2904898, 2905200, 2904903, 2905196 ], 
+        [ 2905201, 2906268, 2905197, 2906264 ], 
+        [ 2906269, 2907797, 2906265, 2907802 ], 
+        [ 2907798, 2910456, 2907803, 2910461 ], 
+        [ 2910457, 2911608, 2910462, 2911613 ], 
+        [ 2911609, 2914587, 2911614, 2914591 ], 
+        [ 2914588, 2914744, 2914592, 2914749 ], 
+        [ 2914745, 2914779, 2914750, 2914784 ], 
+        [ 2914780, 2918124, 2914785, 2918129 ], 
+        [ 2918125, 2921020, 2918130, 2921025 ], 
+        [ 2921021, 2921458, 2921026, 2921463 ], 
+        [ 2921459, 2923338, 2921464, 2923342 ], 
+        [ 2923339, 2926580, 2923343, 2926585 ], 
+        [ 2926581, 2930570, 2926586, 2930575 ], 
+        [ 2930571, 2931452, 2930576, 2931456 ], 
+        [ 2931453, 2934873, 2931457, 2934878 ], 
+        [ 2934874, 2940294, 2934879, 2940298 ], 
+        [ 2940295, 2942883, 2940299, 2942888 ], 
+        [ 2942884, 2943246, 2942889, 2943250 ], 
+        [ 2943247, 2946109, 2943251, 2946105 ], 
+        [ 2946110, 2950823, 2946106, 2950828 ], 
+        [ 2950824, 2952204, 2950829, 2952209 ], 
+        [ 2952205, 2952842, 2952210, 2952846 ], 
+        [ 2952843, 2954108, 2952847, 2954113 ], 
+        [ 2954109, 2958788, 2954114, 2958793 ], 
+        [ 2958789, 2959652, 2958794, 2959656 ], 
+        [ 2959653, 2962338, 2959657, 2962343 ], 
+        [ 2962339, 2962634, 2962344, 2962639 ], 
+        [ 2962635, 2963567, 2962640, 2963572 ], 
+        [ 2963568, 2965512, 2963573, 2965517 ], 
+        [ 2965513, 2965542, 2965518, 2965546 ], 
+        [ 2965543, 2965715, 2965547, 2965720 ], 
+        [ 2965716, 2969537, 2965721, 2969542 ], 
+        [ 2969538, 2969667, 2969543, 2969672 ], 
+        [ 2969668, 2971097, 2969673, 2971102 ], 
+        [ 2971098, 2971329, 2971103, 2971334 ], 
+        [ 2971330, 2971441, 2971335, 2971437 ], 
+        [ 2971442, 2971588, 2971438, 2971584 ], 
+        [ 2971589, 2971874, 2971585, 2971879 ], 
+        [ 2971875, 2972098, 2971880, 2972103 ], 
+        [ 2972099, 2974355, 2972104, 2974359 ], 
+        [ 2974356, 2978342, 2974360, 2978347 ], 
+        [ 2978343, 2984060, 2978348, 2984065 ], 
+        [ 2984061, 2985968, 2984066, 2985972 ], 
+        [ 2985969, 2987338, 2985973, 2987342 ], 
+        [ 2987339, 2988924, 2987343, 2988929 ], 
+        [ 2988925, 2991267, 2988930, 2991271 ], 
+        [ 2991268, 2994739, 2991272, 2994744 ], 
+        [ 2994740, 3002088, 2994745, 3002093 ], 
+        [ 3002089, 3009887, 3002094, 3009892 ], 
+        [ 3009888, 3014827, 3009893, 3014832 ], 
+        [ 3014828, 3017608, 3014833, 3017612 ], 
+        [ 3017609, 3020196, 3017613, 3020192 ], 
+        [ 3020197, 3020885, 3020193, 3020890 ], 
+        [ 3020886, 3022261, 3020891, 3022266 ], 
+        [ 3022262, 3029543, 3022267, 3029548 ], 
+        [ 3029544, 3030265, 3029549, 3030270 ], 
+        [ 3030266, 3032363, 3030271, 3032368 ], 
+        [ 3032364, 3033161, 3032369, 3033166 ], 
+        [ 3033162, 3042175, 3033167, 3042180 ], 
+        [ 3042176, 3042389, 3042181, 3042394 ], 
+        [ 3042390, 3043311, 3042395, 3043315 ], 
+        [ 3043312, 3045343, 3043316, 3045347 ], 
+        [ 3045344, 3049663, 3045348, 3049668 ], 
+        [ 3049664, 3050210, 3049669, 3050215 ], 
+        [ 3050211, 3051389, 3050216, 3051394 ], 
+        [ 3051390, 3052128, 3051395, 3052133 ], 
+        [ 3052129, 3052883, 3052134, 3052888 ], 
+        [ 3052884, 3054679, 3052889, 3054684 ], 
+        [ 3054680, 3055955, 3054685, 3055960 ], 
+        [ 3055956, 3056024, 3055961, 3056029 ], 
+        [ 3056025, 3062859, 3056030, 3062864 ], 
+        [ 3062860, 3063276, 3062865, 3063281 ], 
+        [ 3063277, 3064101, 3063282, 3064106 ], 
+        [ 3064102, 3065135, 3064107, 3065131 ], 
+        [ 3065136, 3065575, 3065132, 3065580 ], 
+        [ 3065576, 3065710, 3065581, 3065715 ], 
+        [ 3065711, 3066590, 3065716, 3066595 ], 
+        [ 3066591, 3070621, 3066596, 3070625 ], 
+        [ 3070622, 3075292, 3070626, 3075297 ], 
+        [ 3075293, 3076853, 3075298, 3076858 ], 
+        [ 3076854, 3078695, 3076859, 3078699 ], 
+        [ 3078696, 3080566, 3078700, 3080571 ], 
+        [ 3080567, 3080707, 3080572, 3080712 ], 
+        [ 3080708, 3080747, 3080713, 3080752 ], 
+        [ 3080748, 3080916, 3080753, 3080921 ], 
+        [ 3080917, 3082200, 3080922, 3082205 ], 
+        [ 3082201, 3085986, 3082206, 3085991 ], 
+        [ 3085987, 3086111, 3085992, 3086116 ], 
+        [ 3086112, 3088509, 3086117, 3088514 ], 
+        [ 3088510, 3090889, 3088515, 3090893 ], 
+        [ 3090890, 3091108, 3090894, 3091113 ], 
+        [ 3091109, 3094298, 3091114, 3094303 ], 
+        [ 3094299, 3095542, 3094304, 3095546 ], 
+        [ 3095543, 3098254, 3095547, 3098259 ], 
+        [ 3098255, 3100958, 3098260, 3100963 ], 
+        [ 3100959, 3101111, 3100964, 3101116 ], 
+        [ 3101112, 3101710, 3101117, 3101715 ], 
+        [ 3101711, 3102184, 3101716, 3102180 ], 
+        [ 3102185, 3107070, 3102181, 3107075 ], 
+        [ 3107071, 3108550, 3107076, 3108555 ], 
+        [ 3108551, 3109638, 3108556, 3109642 ], 
+        [ 3109639, 3110010, 3109643, 3110014 ], 
+        [ 3110011, 3110596, 3110015, 3110592 ], 
+        [ 3110597, 3114705, 3110593, 3114709 ], 
+        [ 3114706, 3116752, 3114710, 3116757 ], 
+        [ 3116753, 3118943, 3116758, 3118947 ], 
+        [ 3118944, 3118963, 3118948, 3118967 ], 
+        [ 3118964, 3119656, 3118968, 3119661 ], 
+        [ 3119657, 3120436, 3119662, 3120441 ], 
+        [ 3120437, 3122936, 3120442, 3122941 ], 
+        [ 3122937, 3125746, 3122942, 3125751 ], 
+        [ 3125747, 3126385, 3125752, 3126390 ], 
+        [ 3126386, 3126792, 3126391, 3126796 ], 
+        [ 3126793, 3129487, 3126797, 3129491 ], 
+        [ 3129488, 3129525, 3129492, 3129530 ], 
+        [ 3129526, 3129570, 3129531, 3129575 ], 
+        [ 3129571, 3129752, 3129576, 3129757 ], 
+        [ 3129753, 3132349, 3129758, 3132354 ], 
+        [ 3132350, 3133454, 3132355, 3133458 ], 
+        [ 3133455, 3135493, 3133459, 3135497 ], 
+        [ 3135494, 3139904, 3135498, 3139909 ], 
+        [ 3139905, 3143832, 3139910, 3143837 ], 
+        [ 3143833, 3144573, 3143838, 3144578 ], 
+        [ 3144574, 3146787, 3144579, 3146783 ], 
+        [ 3146788, 3148252, 3146784, 3148257 ], 
+        [ 3148253, 3149799, 3148258, 3149803 ], 
+        [ 3149800, 3150053, 3149804, 3150058 ], 
+        [ 3150054, 3152136, 3150059, 3152141 ], 
+        [ 3152137, 3159529, 3152142, 3159533 ], 
+        [ 3159530, 3161578, 3159534, 3161583 ], 
+        [ 3161579, 3162165, 3161584, 3162169 ], 
+        [ 3162166, 3162816, 3162170, 3162820 ], 
+        [ 3162817, 3164826, 3162821, 3164831 ], 
+        [ 3164827, 3164943, 3164832, 3164948 ], 
+        [ 3164944, 3167365, 3164949, 3167369 ], 
+        [ 3167366, 3167563, 3167370, 3167568 ], 
+        [ 3167564, 3168258, 3167569, 3168263 ], 
+        [ 3168259, 3170295, 3168264, 3170300 ], 
+        [ 3170296, 3172533, 3170301, 3172538 ], 
+        [ 3172534, 3176792, 3172539, 3176797 ], 
+        [ 3176793, 3177637, 3176798, 3177642 ], 
+        [ 3177638, 3178306, 3177643, 3178311 ], 
+        [ 3178307, 3180657, 3178312, 3180661 ], 
+        [ 3180658, 3181485, 3180662, 3181489 ], 
+        [ 3181486, 3182629, 3181490, 3182633 ], 
+        [ 3182630, 3186857, 3182634, 3186862 ], 
+        [ 3186858, 3190084, 3186863, 3190088 ], 
+        [ 3190085, 3194127, 3190089, 3194131 ], 
+        [ 3194128, 3196386, 3194132, 3196391 ], 
+        [ 3196387, 3196711, 3196392, 3196715 ], 
+        [ 3196712, 3197840, 3196716, 3197845 ], 
+        [ 3197841, 3201756, 3197846, 3201760 ], 
+        [ 3201757, 3208054, 3201761, 3208058 ], 
+        [ 3208055, 3210828, 3208059, 3210833 ], 
+        [ 3210829, 3212953, 3210834, 3212958 ], 
+        [ 3212954, 3224927, 3212959, 3224931 ], 
+        [ 3224928, 3226292, 3224932, 3226297 ], 
+        [ 3226293, 3226762, 3226298, 3226767 ], 
+        [ 3226763, 3228540, 3226768, 3228544 ], 
+        [ 3228541, 3229224, 3228545, 3229228 ], 
+        [ 3229225, 3230485, 3229229, 3230490 ], 
+        [ 3230486, 3233260, 3230491, 3233264 ], 
+        [ 3233261, 3233743, 3233265, 3233748 ], 
+        [ 3233744, 3234567, 3233749, 3234572 ], 
+        [ 3234568, 3235194, 3234573, 3235199 ], 
+        [ 3235195, 3235499, 3235200, 3235504 ], 
+        [ 3235500, 3243889, 3235505, 3243894 ], 
+        [ 3243890, 3245053, 3243895, 3245057 ], 
+        [ 3245054, 3245941, 3245058, 3245945 ], 
+        [ 3245942, 3255842, 3245946, 3255838 ], 
+        [ 3255843, 3259251, 3255839, 3259256 ], 
+        [ 3259252, 3260019, 3259257, 3260023 ], 
+        [ 3260020, 3262432, 3260024, 3262437 ], 
+        [ 3262433, 3262672, 3262438, 3262677 ], 
+        [ 3262673, 3266221, 3262678, 3266225 ], 
+        [ 3266222, 3266686, 3266226, 3266691 ], 
+        [ 3266687, 3269046, 3266692, 3269051 ], 
+        [ 3269047, 3269620, 3269052, 3269625 ], 
+        [ 3269621, 3272036, 3269626, 3272041 ], 
+        [ 3272037, 3272516, 3272042, 3272521 ], 
+        [ 3272517, 3272796, 3272522, 3272801 ], 
+        [ 3272797, 3278978, 3272802, 3278983 ], 
+        [ 3278979, 3279467, 3278984, 3279472 ], 
+        [ 3279468, 3280283, 3279473, 3280288 ], 
+        [ 3280284, 3282531, 3280289, 3282536 ], 
+        [ 3282532, 3283074, 3282537, 3283078 ], 
+        [ 3283075, 3283850, 3283079, 3283854 ], 
+        [ 3283851, 3286305, 3283855, 3286310 ], 
+        [ 3286306, 3286606, 3286311, 3286611 ], 
+        [ 3286607, 3287302, 3286612, 3287307 ], 
+        [ 3287303, 3290573, 3287308, 3290569 ], 
+        [ 3290574, 3290776, 3290570, 3290781 ], 
+        [ 3290777, 3294305, 3290782, 3294310 ], 
+        [ 3294306, 3295201, 3294311, 3295205 ], 
+        [ 3295202, 3298010, 3295206, 3298015 ], 
+        [ 3298011, 3298799, 3298016, 3298804 ], 
+        [ 3298800, 3299744, 3298805, 3299749 ], 
+        [ 3299745, 3302402, 3299750, 3302407 ], 
+        [ 3302403, 3308399, 3302408, 3308403 ], 
+        [ 3308400, 3313629, 3308404, 3313633 ], 
+        [ 3313630, 3314750, 3313634, 3314755 ], 
+        [ 3314751, 3314777, 3314756, 3314782 ], 
+        [ 3314778, 3315543, 3314783, 3315548 ], 
+        [ 3315544, 3317191, 3315549, 3317195 ], 
+        [ 3317192, 3319495, 3317196, 3319500 ], 
+        [ 3319496, 3321744, 3319501, 3321749 ], 
+        [ 3321745, 3324685, 3321750, 3324690 ], 
+        [ 3324686, 3331190, 3324691, 3331194 ], 
+        [ 3331191, 3331241, 3331195, 3331246 ], 
+        [ 3331242, 3334147, 3331247, 3334151 ], 
+        [ 3334148, 3334546, 3334152, 3334550 ], 
+        [ 3334547, 3339219, 3334551, 3339215 ], 
+        [ 3339220, 3339452, 3339216, 3339456 ], 
+        [ 3339453, 3345624, 3339457, 3345629 ], 
+        [ 3345625, 3349642, 3345630, 3349646 ], 
+        [ 3349643, 3349729, 3349647, 3349734 ], 
+        [ 3349730, 3350579, 3349735, 3350584 ], 
+        [ 3350580, 3351752, 3350585, 3351756 ], 
+        [ 3351753, 3351958, 3351757, 3351962 ], 
+        [ 3351959, 3353994, 3351963, 3353999 ], 
+        [ 3353995, 3355238, 3354000, 3355243 ], 
+        [ 3355239, 3356216, 3355244, 3356220 ], 
+        [ 3356217, 3360120, 3356221, 3360125 ], 
+        [ 3360121, 3360807, 3360126, 3360811 ], 
+        [ 3360808, 3362361, 3360812, 3362365 ], 
+        [ 3362362, 3363476, 3362366, 3363480 ], 
+        [ 3363477, 3364333, 3363481, 3364337 ], 
+        [ 3364334, 3368828, 3364338, 3368833 ], 
+        [ 3368829, 3370235, 3368834, 3370239 ], 
+        [ 3370236, 3371627, 3370240, 3371631 ], 
+        [ 3371628, 3375963, 3371632, 3375967 ], 
+        [ 3375964, 3376335, 3375968, 3376340 ], 
+        [ 3376336, 3380722, 3376341, 3380727 ], 
+        [ 3380723, 3381309, 3380728, 3381314 ], 
+        [ 3381310, 3382080, 3381315, 3382085 ], 
+        [ 3382081, 3384674, 3382086, 3384679 ], 
+        [ 3384675, 3385188, 3384680, 3385193 ], 
+        [ 3385189, 3388713, 3385194, 3388718 ], 
+        [ 3388714, 3392079, 3388719, 3392084 ], 
+        [ 3392080, 3394131, 3392085, 3394136 ], 
+        [ 3394132, 3394381, 3394137, 3394386 ], 
+        [ 3394382, 3395362, 3394387, 3395367 ], 
+        [ 3395363, 3395419, 3395368, 3395423 ], 
+        [ 3395420, 3396615, 3395424, 3396620 ], 
+        [ 3396616, 3399453, 3396621, 3399458 ], 
+        [ 3399454, 3400585, 3399459, 3400590 ], 
+        [ 3400586, 3401981, 3400591, 3401977 ], 
+        [ 3401982, 3405494, 3401978, 3405499 ], 
+        [ 3405495, 3408302, 3405500, 3408306 ], 
+        [ 3408303, 3413040, 3408307, 3413045 ], 
+        [ 3413041, 3413955, 3413046, 3413960 ], 
+        [ 3413956, 3413965, 3413961, 3413970 ], 
+        [ 3413966, 3414900, 3413971, 3414904 ], 
+        [ 3414901, 3415450, 3414905, 3415455 ], 
+        [ 3415451, 3415543, 3415456, 3415548 ], 
+        [ 3415544, 3415693, 3415549, 3415698 ], 
+        [ 3415694, 3416832, 3415699, 3416828 ], 
+        [ 3416833, 3416866, 3416829, 3416871 ], 
+        [ 3416867, 3420715, 3416872, 3420719 ], 
+        [ 3420716, 3421885, 3420720, 3421890 ], 
+        [ 3421886, 3425027, 3421891, 3425031 ], 
+        [ 3425028, 3425142, 3425032, 3425147 ], 
+        [ 3425143, 3429164, 3425148, 3429168 ], 
+        [ 3429165, 3431958, 3429169, 3431962 ], 
+        [ 3431959, 3437815, 3431963, 3437820 ], 
+        [ 3437816, 3439239, 3437821, 3439243 ], 
+        [ 3439240, 3440231, 3439244, 3440236 ], 
+        [ 3440232, 3440415, 3440237, 3440411 ], 
+        [ 3440416, 3442385, 3440412, 3442390 ], 
+        [ 3442386, 3448532, 3442391, 3448536 ], 
+        [ 3448533, 3449018, 3448537, 3449014 ], 
+        [ 3449019, 3449766, 3449015, 3449771 ], 
+        [ 3449767, 3450597, 3449772, 3450601 ], 
+        [ 3450598, 3451510, 3450602, 3451514 ], 
+        [ 3451511, 3455799, 3451515, 3455804 ], 
+        [ 3455800, 3457236, 3455805, 3457240 ], 
+        [ 3457237, 3463488, 3457241, 3463492 ], 
+        [ 3463489, 3473047, 3463493, 3473052 ], 
+        [ 3473048, 3479777, 3473053, 3479773 ], 
+        [ 3479778, 3483375, 3479774, 3483380 ], 
+        [ 3483376, 3484793, 3483381, 3484797 ], 
+        [ 3484794, 3486395, 3484798, 3486399 ], 
+        [ 3486396, 3490246, 3486400, 3490242 ], 
+        [ 3490247, 3494295, 3490243, 3494299 ], 
+        [ 3494296, 3495597, 3494300, 3495601 ], 
+        [ 3495598, 3496721, 3495602, 3496725 ], 
+        [ 3496722, 3499522, 3496726, 3499526 ], 
+        [ 3499523, 3503195, 3499527, 3503199 ], 
+        [ 3503196, 3505500, 3503200, 3505505 ], 
+        [ 3505501, 3510463, 3505506, 3510467 ], 
+        [ 3510464, 3514082, 3510468, 3514087 ], 
+        [ 3514083, 3520619, 3514088, 3520623 ], 
+        [ 3520620, 3521049, 3520624, 3521053 ], 
+        [ 3521050, 3522092, 3521054, 3522097 ], 
+        [ 3522093, 3522111, 3522098, 3522116 ], 
+        [ 3522112, 3522311, 3522117, 3522315 ], 
+        [ 3522312, 3522767, 3522316, 3522772 ], 
+        [ 3522768, 3531627, 3522773, 3531632 ], 
+        [ 3531628, 3537780, 3531633, 3537785 ], 
+        [ 3537781, 3538989, 3537786, 3538993 ], 
+        [ 3538990, 3540393, 3538994, 3540397 ], 
+        [ 3540394, 3540644, 3540398, 3540649 ], 
+        [ 3540645, 3543017, 3540650, 3543022 ], 
+        [ 3543018, 3543842, 3543023, 3543847 ], 
+        [ 3543843, 3545546, 3543848, 3545551 ], 
+        [ 3545547, 3546913, 3545552, 3546917 ], 
+        [ 3546914, 3547077, 3546918, 3547082 ], 
+        [ 3547078, 3547149, 3547083, 3547154 ], 
+        [ 3547150, 3548533, 3547155, 3548538 ], 
+        [ 3548534, 3549829, 3548539, 3549834 ], 
+        [ 3549830, 3549935, 3549835, 3549940 ], 
+        [ 3549936, 3550203, 3549941, 3550208 ], 
+        [ 3550204, 3550227, 3550209, 3550232 ], 
+        [ 3550228, 3551480, 3550233, 3551485 ], 
+        [ 3551481, 3552210, 3551486, 3552215 ], 
+        [ 3552211, 3561260, 3552216, 3561264 ], 
+        [ 3561261, 3562847, 3561265, 3562852 ], 
+        [ 3562848, 3563068, 3562853, 3563073 ], 
+        [ 3563069, 3563973, 3563074, 3563978 ], 
+        [ 3563974, 3565130, 3563979, 3565135 ], 
+        [ 3565131, 3565565, 3565136, 3565570 ], 
+        [ 3565566, 3566132, 3565571, 3566137 ], 
+        [ 3566133, 3567018, 3566138, 3567023 ], 
+        [ 3567019, 3567627, 3567024, 3567632 ], 
+        [ 3567628, 3570838, 3567633, 3570843 ], 
+        [ 3570839, 3574124, 3570844, 3574129 ], 
+        [ 3574125, 3575098, 3574130, 3575103 ], 
+        [ 3575099, 3575586, 3575104, 3575591 ], 
+        [ 3575587, 3576602, 3575592, 3576607 ], 
+        [ 3576603, 3590383, 3576608, 3590388 ], 
+        [ 3590384, 3594697, 3590389, 3594702 ], 
+        [ 3594698, 3596771, 3594703, 3596775 ], 
+        [ 3596772, 3597307, 3596776, 3597312 ], 
+        [ 3597308, 3598184, 3597313, 3598188 ], 
+        [ 3598185, 3598837, 3598189, 3598842 ], 
+        [ 3598838, 3599839, 3598843, 3599844 ], 
+        [ 3599840, 3603578, 3599845, 3603583 ], 
+        [ 3603579, 3605362, 3603584, 3605366 ], 
+        [ 3605363, 3609322, 3605367, 3609327 ], 
+        [ 3609323, 3614549, 3609328, 3614554 ], 
+        [ 3614550, 3618664, 3614555, 3618669 ], 
+        [ 3618665, 3619899, 3618670, 3619904 ], 
+        [ 3619900, 3624824, 3619905, 3624829 ], 
+        [ 3624825, 3627309, 3624830, 3627313 ], 
+        [ 3627310, 3628159, 3627314, 3628164 ], 
+        [ 3628160, 3628423, 3628165, 3628428 ], 
+        [ 3628424, 3629521, 3628429, 3629525 ], 
+        [ 3629522, 3629584, 3629526, 3629588 ], 
+        [ 3629585, 3629833, 3629589, 3629837 ], 
+        [ 3629834, 3630285, 3629838, 3630290 ], 
+        [ 3630286, 3630486, 3630291, 3630491 ], 
+        [ 3630487, 3634237, 3630492, 3634242 ], 
+        [ 3634238, 3639209, 3634243, 3639214 ], 
+        [ 3639210, 3639649, 3639215, 3639645 ], 
+        [ 3639650, 3647161, 3639646, 3647165 ], 
+        [ 3647162, 3648227, 3647166, 3648231 ], 
+        [ 3648228, 3652188, 3648232, 3652193 ], 
+        [ 3652189, 3659027, 3652194, 3659032 ], 
+        [ 3659028, 3659079, 3659033, 3659084 ], 
+        [ 3659080, 3659207, 3659085, 3659212 ], 
+        [ 3659208, 3660377, 3659213, 3660381 ], 
+        [ 3660378, 3667507, 3660382, 3667512 ], 
+        [ 3667508, 3667741, 3667513, 3667746 ], 
+        [ 3667742, 3668429, 3667747, 3668434 ], 
+        [ 3668430, 3670470, 3668435, 3670475 ], 
+        [ 3670471, 3673148, 3670476, 3673153 ], 
+        [ 3673149, 3674083, 3673154, 3674088 ], 
+        [ 3674084, 3678214, 3674089, 3678219 ], 
+        [ 3678215, 3680677, 3678220, 3680682 ], 
+        [ 3680678, 3684205, 3680683, 3684210 ], 
+        [ 3684206, 3688887, 3684211, 3688883 ], 
+        [ 3688888, 3690753, 3688884, 3690758 ], 
+        [ 3690754, 3698350, 3690759, 3698355 ], 
+        [ 3698351, 3699287, 3698356, 3699292 ], 
+        [ 3699288, 3700655, 3699293, 3700659 ], 
+        [ 3700656, 3702298, 3700660, 3702303 ], 
+        [ 3702299, 3706224, 3702304, 3706229 ], 
+        [ 3706225, 3706948, 3706230, 3706953 ], 
+        [ 3706949, 3709050, 3706954, 3709055 ], 
+        [ 3709051, 3710401, 3709056, 3710405 ], 
+        [ 3710402, 3713151, 3710406, 3713155 ], 
+        [ 3713152, 3714587, 3713156, 3714591 ], 
+        [ 3714588, 3714794, 3714592, 3714798 ], 
+        [ 3714795, 3725109, 3714799, 3725114 ], 
+        [ 3725110, 3725822, 3725115, 3725818 ], 
+        [ 3725823, 3726413, 3725819, 3726409 ], 
+        [ 3726414, 3731356, 3726410, 3731352 ], 
+        [ 3731357, 3731514, 3731353, 3731519 ], 
+        [ 3731515, 3736239, 3731520, 3736244 ], 
+        [ 3736240, 3736361, 3736245, 3736366 ], 
+        [ 3736362, 3738698, 3736367, 3738703 ], 
+        [ 3738699, 3742314, 3738704, 3742318 ], 
+        [ 3742315, 3745350, 3742319, 3745355 ], 
+        [ 3745351, 3747516, 3745356, 3747521 ], 
+        [ 3747517, 3747787, 3747522, 3747791 ], 
+        [ 3747788, 3748248, 3747792, 3748253 ], 
+        [ 3748249, 3750382, 3748254, 3750387 ], 
+        [ 3750383, 3752531, 3750388, 3752527 ], 
+        [ 3752532, 3753792, 3752528, 3753788 ], 
+        [ 3753793, 3755999, 3753789, 3756003 ], 
+        [ 3756000, 3761090, 3756004, 3761095 ], 
+        [ 3761091, 3762084, 3761096, 3762089 ], 
+        [ 3762085, 3762616, 3762090, 3762621 ], 
+        [ 3762617, 3769672, 3762622, 3769677 ], 
+        [ 3769673, 3769809, 3769678, 3769814 ], 
+        [ 3769810, 3769962, 3769815, 3769967 ], 
+        [ 3769963, 3770651, 3769968, 3770655 ], 
+        [ 3770652, 3773164, 3770656, 3773168 ], 
+        [ 3773165, 3774893, 3773169, 3774898 ], 
+        [ 3774894, 3776296, 3774899, 3776300 ], 
+        [ 3776297, 3776322, 3776301, 3776327 ], 
+        [ 3776323, 3778089, 3776328, 3778094 ], 
+        [ 3778090, 3783192, 3778095, 3783188 ], 
+        [ 3783193, 3784214, 3783189, 3784219 ], 
+        [ 3784215, 3795080, 3784220, 3795084 ], 
+        [ 3795081, 3799015, 3795085, 3799020 ], 
+        [ 3799016, 3805176, 3799021, 3805180 ], 
+        [ 3805177, 3806065, 3805181, 3806070 ], 
+        [ 3806066, 3807768, 3806071, 3807773 ], 
+        [ 3807769, 3808991, 3807774, 3808995 ], 
+        [ 3808992, 3809153, 3808996, 3809157 ], 
+        [ 3809154, 3809882, 3809158, 3809886 ], 
+        [ 3809883, 3813249, 3809887, 3813253 ], 
+        [ 3813250, 3816682, 3813254, 3816687 ], 
+        [ 3816683, 3817044, 3816688, 3817049 ], 
+        [ 3817045, 3817768, 3817050, 3817773 ], 
+        [ 3817769, 3821121, 3817774, 3821125 ], 
+        [ 3821122, 3822167, 3821126, 3822172 ], 
+        [ 3822168, 3824032, 3822173, 3824037 ], 
+        [ 3824033, 3827315, 3824038, 3827311 ], 
+        [ 3827316, 3828542, 3827312, 3828547 ], 
+        [ 3828543, 3829917, 3828548, 3829921 ], 
+        [ 3829918, 3832118, 3829922, 3832123 ], 
+        [ 3832119, 3832453, 3832124, 3832458 ], 
+        [ 3832454, 3837573, 3832459, 3837578 ], 
+        [ 3837574, 3842658, 3837579, 3842663 ], 
+        [ 3842659, 3843673, 3842664, 3843677 ], 
+        [ 3843674, 3844593, 3843678, 3844597 ], 
+        [ 3844594, 3844599, 3844598, 3844604 ], 
+        [ 3844600, 3844788, 3844605, 3844793 ], 
+        [ 3844789, 3850826, 3844794, 3850831 ], 
+        [ 3850827, 3854490, 3850832, 3854494 ], 
+        [ 3854491, 3855395, 3854495, 3855400 ], 
+        [ 3855396, 3855755, 3855401, 3855751 ], 
+        [ 3855756, 3860530, 3855752, 3860535 ], 
+        [ 3860531, 3860887, 3860536, 3860883 ], 
+        [ 3860888, 3862913, 3860884, 3862917 ], 
+        [ 3862914, 3872850, 3862918, 3872854 ], 
+        [ 3872851, 3873056, 3872855, 3873061 ], 
+        [ 3873057, 3875254, 3873062, 3875258 ], 
+        [ 3875255, 3880197, 3875259, 3880202 ], 
+        [ 3880198, 3882479, 3880203, 3882483 ], 
+        [ 3882480, 3882820, 3882484, 3882825 ], 
+        [ 3882821, 3883310, 3882826, 3883315 ], 
+        [ 3883311, 3885744, 3883316, 3885749 ], 
+        [ 3885745, 3890942, 3885750, 3890946 ], 
+        [ 3890943, 3891218, 3890947, 3891223 ], 
+        [ 3891219, 3891354, 3891224, 3891359 ], 
+        [ 3891355, 3893483, 3891360, 3893487 ], 
+        [ 3893484, 3894419, 3893488, 3894424 ], 
+        [ 3894420, 3900500, 3894425, 3900505 ], 
+        [ 3900501, 3901493, 3900506, 3901489 ], 
+        [ 3901494, 3903140, 3901490, 3903136 ], 
+        [ 3903141, 3907313, 3903137, 3907318 ], 
+        [ 3907314, 3908755, 3907319, 3908759 ], 
+        [ 3908756, 3908919, 3908760, 3908924 ], 
+        [ 3908920, 3909807, 3908925, 3909812 ], 
+        [ 3909808, 3909977, 3909813, 3909982 ], 
+        [ 3909978, 3911959, 3909983, 3911955 ], 
+        [ 3911960, 3914009, 3911956, 3914005 ], 
+        [ 3914010, 3922759, 3914006, 3922763 ], 
+        [ 3922760, 3930585, 3922764, 3930590 ], 
+        [ 3930586, 3931083, 3930591, 3931087 ], 
+        [ 3931084, 3933248, 3931088, 3933252 ], 
+        [ 3933249, 3933363, 3933253, 3933368 ], 
+        [ 3933364, 3935176, 3933369, 3935181 ], 
+        [ 3935177, 3936871, 3935182, 3936876 ], 
+        [ 3936872, 3937525, 3936877, 3937529 ], 
+        [ 3937526, 3945198, 3937530, 3945203 ], 
+        [ 3945199, 3946390, 3945204, 3946395 ], 
+        [ 3946391, 3946986, 3946396, 3946991 ], 
+        [ 3946987, 3952348, 3946992, 3952344 ], 
+        [ 3952349, 3956408, 3952345, 3956413 ], 
+        [ 3956409, 3958333, 3956414, 3958338 ], 
+        [ 3958334, 3959031, 3958339, 3959036 ], 
+        [ 3959032, 3960932, 3959037, 3960937 ], 
+        [ 3960933, 3964190, 3960938, 3964195 ], 
+        [ 3964191, 3969413, 3964196, 3969418 ], 
+        [ 3969414, 3972146, 3969419, 3972151 ], 
+        [ 3972147, 3972344, 3972152, 3972349 ], 
+        [ 3972345, 3978065, 3972350, 3978070 ], 
+        [ 3978066, 3981977, 3978071, 3981982 ], 
+        [ 3981978, 3984768, 3981983, 3984773 ], 
+        [ 3984769, 3984918, 3984774, 3984923 ], 
+        [ 3984919, 3985704, 3984924, 3985709 ], 
+        [ 3985705, 3986544, 3985710, 3986548 ], 
+        [ 3986545, 3995454, 3986549, 3995459 ], 
+        [ 3995455, 3997410, 3995460, 3997415 ], 
+        [ 3997411, 4000982, 3997416, 4000987 ], 
+        [ 4000983, 4002297, 4000988, 4002301 ], 
+        [ 4002298, 4002514, 4002302, 4002519 ], 
+        [ 4002515, 4005689, 4002520, 4005694 ], 
+        [ 4005690, 4008445, 4005695, 4008449 ], 
+        [ 4008446, 4008591, 4008450, 4008595 ], 
+        [ 4008592, 4016078, 4008596, 4016083 ], 
+        [ 4016079, 4017237, 4016084, 4017242 ], 
+        [ 4017238, 4018412, 4017243, 4018417 ], 
+        [ 4018413, 4018717, 4018418, 4018722 ], 
+        [ 4018718, 4018835, 4018723, 4018839 ], 
+        [ 4018836, 4021930, 4018840, 4021934 ], 
+        [ 4021931, 4023281, 4021935, 4023286 ], 
+        [ 4023282, 4032076, 4023287, 4032081 ], 
+        [ 4032077, 4041164, 4032082, 4041169 ], 
+        [ 4041165, 4041295, 4041170, 4041300 ], 
+        [ 4041296, 4041920, 4041301, 4041925 ], 
+        [ 4041921, 4046747, 4041926, 4046752 ], 
+        [ 4046748, 4049001, 4046753, 4049005 ], 
+        [ 4049002, 4050345, 4049006, 4050349 ], 
+        [ 4050346, 4052606, 4050350, 4052611 ], 
+        [ 4052607, 4054469, 4052612, 4054474 ], 
+        [ 4054470, 4054629, 4054475, 4054634 ], 
+        [ 4054630, 4054968, 4054635, 4054973 ], 
+        [ 4054969, 4055333, 4054974, 4055338 ], 
+        [ 4055334, 4056058, 4055339, 4056063 ], 
+        [ 4056059, 4057967, 4056064, 4057963 ], 
+        [ 4057968, 4059084, 4057964, 4059089 ], 
+        [ 4059085, 4062508, 4059090, 4062513 ], 
+        [ 4062509, 4065383, 4062514, 4065388 ], 
+        [ 4065384, 4065588, 4065389, 4065592 ], 
+        [ 4065589, 4065643, 4065593, 4065648 ], 
+        [ 4065644, 4065670, 4065649, 4065674 ], 
+        [ 4065671, 4069949, 4065675, 4069954 ], 
+        [ 4069950, 4073053, 4069955, 4073057 ], 
+        [ 4073054, 4076608, 4073058, 4076612 ], 
+        [ 4076609, 4078343, 4076613, 4078348 ], 
+        [ 4078344, 4083896, 4078349, 4083901 ], 
+        [ 4083897, 4085884, 4083902, 4085889 ], 
+        [ 4085885, 4090152, 4085890, 4090157 ], 
+        [ 4090153, 4093908, 4090158, 4093913 ], 
+        [ 4093909, 4094118, 4093914, 4094123 ], 
+        [ 4094119, 4095249, 4094124, 4095254 ], 
+        [ 4095250, 4095382, 4095255, 4095386 ], 
+        [ 4095383, 4095456, 4095387, 4095460 ], 
+        [ 4095457, 4097811, 4095461, 4097816 ], 
+        [ 4097812, 4101896, 4097817, 4101901 ], 
+        [ 4101897, 4102182, 4101902, 4102186 ], 
+        [ 4102183, 4104214, 4102187, 4104218 ], 
+        [ 4104215, 4107088, 4104219, 4107093 ], 
+        [ 4107089, 4107551, 4107094, 4107556 ], 
+        [ 4107552, 4107580, 4107557, 4107585 ], 
+        [ 4107581, 4107671, 4107586, 4107675 ], 
+        [ 4107672, 4109180, 4107676, 4109185 ], 
+        [ 4109181, 4110537, 4109186, 4110542 ], 
+        [ 4110538, 4116188, 4110543, 4116192 ], 
+        [ 4116189, 4116491, 4116193, 4116496 ], 
+        [ 4116492, 4117909, 4116497, 4117914 ], 
+        [ 4117910, 4118469, 4117915, 4118474 ], 
+        [ 4118470, 4123661, 4118475, 4123666 ], 
+        [ 4123662, 4123865, 4123667, 4123870 ], 
+        [ 4123866, 4125127, 4123871, 4125132 ], 
+        [ 4125128, 4125135, 4125133, 4125139 ], 
+        [ 4125136, 4129187, 4125140, 4129192 ], 
+        [ 4129188, 4132972, 4129193, 4132977 ], 
+        [ 4132973, 4134272, 4132978, 4134277 ], 
+        [ 4134273, 4135470, 4134278, 4135475 ], 
+        [ 4135471, 4136837, 4135476, 4136842 ], 
+        [ 4136838, 4146292, 4136843, 4146297 ], 
+        [ 4146293, 4146443, 4146298, 4146448 ], 
+        [ 4146444, 4148935, 4146449, 4148940 ], 
+        [ 4148936, 4150723, 4148941, 4150727 ], 
+        [ 4150724, 4156926, 4150728, 4156930 ], 
+        [ 4156927, 4160939, 4156931, 4160943 ], 
+        [ 4160940, 4161425, 4160944, 4161421 ], 
+        [ 4161426, 4162265, 4161422, 4162270 ], 
+        [ 4162266, 4163096, 4162271, 4163100 ], 
+        [ 4163097, 4163991, 4163101, 4163995 ], 
+        [ 4163992, 4164781, 4163996, 4164786 ], 
+        [ 4164782, 4167637, 4164787, 4167633 ], 
+        [ 4167638, 4170898, 4167634, 4170903 ], 
+        [ 4170899, 4175178, 4170904, 4175174 ], 
+        [ 4175179, 4175563, 4175175, 4175567 ], 
+        [ 4175564, 4175870, 4175568, 4175875 ], 
+        [ 4175871, 4175960, 4175876, 4175965 ], 
+        [ 4175961, 4178040, 4175966, 4178044 ], 
+        [ 4178041, 4179795, 4178045, 4179799 ], 
+        [ 4179796, 4180869, 4179800, 4180874 ], 
+        [ 4180870, 4181479, 4180875, 4181484 ], 
+        [ 4181480, 4184808, 4181485, 4184812 ], 
+        [ 4184809, 4185316, 4184813, 4185320 ], 
+        [ 4185317, 4187692, 4185321, 4187696 ], 
+        [ 4187693, 4187785, 4187697, 4187790 ], 
+        [ 4187786, 4188293, 4187791, 4188289 ], 
+        [ 4188294, 4189984, 4188290, 4189980 ], 
+        [ 4189985, 4191368, 4189981, 4191372 ], 
+        [ 4191369, 4191989, 4191373, 4191993 ], 
+        [ 4191990, 4192187, 4191994, 4192191 ], 
+        [ 4192188, 4192423, 4192192, 4192428 ], 
+        [ 4192424, 4192625, 4192429, 4192630 ], 
+        [ 4192626, 4194747, 4192631, 4194752 ], 
+        [ 4194748, 4195600, 4194753, 4195605 ], 
+        [ 4195601, 4195842, 4195606, 4195847 ], 
+        [ 4195843, 4196615, 4195848, 4196619 ], 
+        [ 4196616, 4197634, 4196620, 4197639 ], 
+        [ 4197635, 4198036, 4197640, 4198041 ], 
+        [ 4198037, 4198447, 4198042, 4198451 ], 
+        [ 4198448, 4198840, 4198452, 4198836 ], 
+        [ 4198841, 4203137, 4198837, 4203141 ], 
+        [ 4203138, 4203155, 4203142, 4203159 ], 
+        [ 4203156, 4203840, 4203160, 4203844 ], 
+        [ 4203841, 4205660, 4203845, 4205665 ], 
+        [ 4205661, 4213510, 4205666, 4213515 ], 
+        [ 4213511, 4217238, 4213516, 4217243 ], 
+        [ 4217239, 4219123, 4217244, 4219127 ], 
+        [ 4219124, 4221217, 4219128, 4221222 ], 
+        [ 4221218, 4225159, 4221223, 4225164 ], 
+        [ 4225160, 4226183, 4225165, 4226188 ], 
+        [ 4226184, 4228901, 4226189, 4228906 ], 
+        [ 4228902, 4229490, 4228907, 4229494 ], 
+        [ 4229491, 4229774, 4229495, 4229779 ], 
+        [ 4229775, 4230559, 4229780, 4230564 ], 
+        [ 4230560, 4231316, 4230565, 4231312 ], 
+        [ 4231317, 4235572, 4231313, 4235577 ], 
+        [ 4235573, 4242029, 4235578, 4242034 ], 
+        [ 4242030, 4242765, 4242035, 4242770 ], 
+        [ 4242766, 4242869, 4242771, 4242865 ], 
+        [ 4242870, 4244054, 4242866, 4244059 ], 
+        [ 4244055, 4245120, 4244060, 4245116 ], 
+        [ 4245121, 4245334, 4245117, 4245339 ], 
+        [ 4245335, 4245565, 4245340, 4245569 ], 
+        [ 4245566, 4247741, 4245570, 4247745 ], 
+        [ 4247742, 4249019, 4247746, 4249024 ], 
+        [ 4249020, 4249100, 4249025, 4249105 ], 
+        [ 4249101, 4256705, 4249106, 4256710 ], 
+        [ 4256706, 4258303, 4256711, 4258307 ], 
+        [ 4258304, 4259509, 4258308, 4259514 ], 
+        [ 4259510, 4261410, 4259515, 4261415 ], 
+        [ 4261411, 4269352, 4261416, 4269356 ], 
+        [ 4269353, 4270525, 4269357, 4270530 ], 
+        [ 4270526, 4274109, 4270531, 4274114 ], 
+        [ 4274110, 4275137, 4274115, 4275141 ], 
+        [ 4275138, 4281838, 4275142, 4281842 ], 
+        [ 4281839, 4281849, 4281843, 4281854 ], 
+        [ 4281850, 4283260, 4281855, 4283264 ], 
+        [ 4283261, 4284055, 4283265, 4284059 ], 
+        [ 4284056, 4284552, 4284060, 4284556 ], 
+        [ 4284553, 4284762, 4284557, 4284767 ], 
+        [ 4284763, 4287988, 4284768, 4287992 ], 
+        [ 4287989, 4294545, 4287993, 4294549 ], 
+        [ 4294546, 4303042, 4294550, 4303047 ], 
+        [ 4303043, 4303258, 4303048, 4303263 ], 
+        [ 4303259, 4303753, 4303264, 4303757 ], 
+        [ 4303754, 4306632, 4303758, 4306637 ], 
+        [ 4306633, 4310014, 4306638, 4310018 ], 
+        [ 4310015, 4312216, 4310019, 4312221 ], 
+        [ 4312217, 4314890, 4312222, 4314895 ], 
+        [ 4314891, 4316460, 4314896, 4316465 ], 
+        [ 4316461, 4316626, 4316466, 4316631 ], 
+        [ 4316627, 4318092, 4316632, 4318097 ], 
+        [ 4318093, 4318604, 4318098, 4318609 ], 
+        [ 4318605, 4318772, 4318610, 4318777 ], 
+        [ 4318773, 4321424, 4318778, 4321429 ], 
+        [ 4321425, 4321489, 4321430, 4321494 ], 
+        [ 4321490, 4324980, 4321495, 4324984 ], 
+        [ 4324981, 4327535, 4324985, 4327540 ], 
+        [ 4327536, 4329548, 4327541, 4329553 ], 
+        [ 4329549, 4331509, 4329554, 4331514 ], 
+        [ 4331510, 4332147, 4331515, 4332152 ], 
+        [ 4332148, 4334445, 4332153, 4334450 ], 
+        [ 4334446, 4338820, 4334451, 4338825 ], 
+        [ 4338821, 4339739, 4338826, 4339744 ], 
+        [ 4339740, 4343682, 4339745, 4343687 ], 
+        [ 4343683, 4348264, 4343688, 4348269 ], 
+        [ 4348265, 4351770, 4348270, 4351774 ], 
+        [ 4351771, 4352206, 4351775, 4352211 ], 
+        [ 4352207, 4356621, 4352212, 4356626 ], 
+        [ 4356622, 4362927, 4356627, 4362923 ], 
+        [ 4362928, 4366184, 4362924, 4366189 ], 
+        [ 4366185, 4374134, 4366190, 4374139 ], 
+        [ 4374135, 4374749, 4374140, 4374754 ], 
+        [ 4374750, 4386564, 4374755, 4386568 ], 
+        [ 4386565, 4386786, 4386569, 4386790 ], 
+        [ 4386787, 4388049, 4386791, 4388054 ], 
+        [ 4388050, 4388548, 4388055, 4388553 ], 
+        [ 4388549, 4395145, 4388554, 4395141 ], 
+        [ 4395146, 4395214, 4395142, 4395219 ], 
+        [ 4395215, 4396301, 4395220, 4396297 ], 
+        [ 4396302, 4397725, 4396298, 4397730 ], 
+        [ 4397726, 4400829, 4397731, 4400833 ], 
+        [ 4400830, 4401917, 4400834, 4401922 ], 
+        [ 4401918, 4401962, 4401923, 4401967 ], 
+        [ 4401963, 4404470, 4401968, 4404475 ], 
+        [ 4404471, 4404603, 4404476, 4404608 ], 
+        [ 4404604, 4404677, 4404609, 4404682 ], 
+        [ 4404678, 4407845, 4404683, 4407850 ], 
+        [ 4407846, 4408723, 4407851, 4408727 ], 
+        [ 4408724, 4414102, 4408728, 4414106 ], 
+        [ 4414103, 4415693, 4414107, 4415698 ], 
+        [ 4415694, 4415957, 4415699, 4415962 ], 
+        [ 4415958, 4418305, 4415963, 4418309 ], 
+        [ 4418306, 4426334, 4418310, 4426339 ], 
+        [ 4426335, 4427143, 4426340, 4427148 ], 
+        [ 4427144, 4432989, 4427149, 4432994 ], 
+        [ 4432990, 4433640, 4432995, 4433645 ], 
+        [ 4433641, 4435236, 4433646, 4435241 ], 
+        [ 4435237, 4436966, 4435242, 4436962 ], 
+        [ 4436967, 4447677, 4436963, 4447681 ], 
+        [ 4447678, 4449373, 4447682, 4449377 ], 
+        [ 4449374, 4450981, 4449378, 4450986 ], 
+        [ 4450982, 4452121, 4450987, 4452126 ], 
+        [ 4452122, 4453471, 4452127, 4453475 ], 
+        [ 4453472, 4454417, 4453476, 4454422 ], 
+        [ 4454418, 4455164, 4454423, 4455169 ], 
+        [ 4455165, 4459226, 4455170, 4459231 ], 
+        [ 4459227, 4460531, 4459232, 4460535 ], 
+        [ 4460532, 4462863, 4460536, 4462868 ], 
+        [ 4462864, 4469714, 4462869, 4469719 ], 
+        [ 4469715, 4469976, 4469720, 4469980 ], 
+        [ 4469977, 4471008, 4469981, 4471013 ], 
+        [ 4471009, 4473114, 4471014, 4473119 ], 
+        [ 4473115, 4477852, 4473120, 4477857 ], 
+        [ 4477853, 4477874, 4477858, 4477879 ], 
+        [ 4477875, 4482921, 4477880, 4482926 ], 
+        [ 4482922, 4489809, 4482927, 4489814 ], 
+        [ 4489810, 4490912, 4489815, 4490917 ], 
+        [ 4490913, 4491974, 4490918, 4491979 ], 
+        [ 4491975, 4492157, 4491980, 4492162 ], 
+        [ 4492158, 4493614, 4492163, 4493619 ], 
+        [ 4493615, 4496829, 4493620, 4496834 ], 
+        [ 4496830, 4497697, 4496835, 4497702 ], 
+        [ 4497698, 4499157, 4497703, 4499162 ], 
+        [ 4499158, 4502248, 4499163, 4502253 ], 
+        [ 4502249, 4504493, 4502254, 4504498 ], 
+        [ 4504494, 4505336, 4504499, 4505341 ], 
+        [ 4505337, 4505567, 4505342, 4505571 ], 
+        [ 4505568, 4506680, 4505572, 4506685 ], 
+        [ 4506681, 4506961, 4506686, 4506966 ], 
+        [ 4506962, 4507601, 4506967, 4507606 ], 
+        [ 4507602, 4509484, 4507607, 4509488 ], 
+        [ 4509485, 4509536, 4509489, 4509532 ], 
+        [ 4509537, 4513351, 4509533, 4513356 ], 
+        [ 4513352, 4516356, 4513357, 4516361 ], 
+        [ 4516357, 4520650, 4516362, 4520655 ], 
+        [ 4520651, 4522948, 4520656, 4522952 ], 
+        [ 4522949, 4527592, 4522953, 4527596 ], 
+        [ 4527593, 4528820, 4527597, 4528825 ], 
+        [ 4528821, 4533216, 4528826, 4533212 ], 
+        [ 4533217, 4535971, 4533213, 4535976 ], 
+        [ 4535972, 4536320, 4535977, 4536324 ], 
+        [ 4536321, 4539874, 4536325, 4539878 ], 
+        [ 4539875, 4540172, 4539879, 4540177 ], 
+        [ 4540173, 4541756, 4540178, 4541752 ], 
+        [ 4541757, 4543862, 4541753, 4543858 ], 
+        [ 4543863, 4545833, 4543859, 4545829 ], 
+        [ 4545834, 4551230, 4545830, 4551235 ], 
+        [ 4551231, 4552997, 4551236, 4553002 ], 
+        [ 4552998, 4555491, 4553003, 4555496 ], 
+        [ 4555492, 4557748, 4555497, 4557744 ], 
+        [ 4557749, 4558033, 4557745, 4558038 ], 
+        [ 4558034, 4561276, 4558039, 4561280 ], 
+        [ 4561277, 4562123, 4561281, 4562128 ], 
+        [ 4562124, 4562284, 4562129, 4562288 ], 
+        [ 4562285, 4563100, 4562289, 4563105 ], 
+        [ 4563101, 4564382, 4563106, 4564386 ], 
+        [ 4564383, 4564639, 4564387, 4564644 ], 
+        [ 4564640, 4566006, 4564645, 4566011 ], 
+        [ 4566007, 4575457, 4566012, 4575462 ], 
+        [ 4575458, 4575809, 4575463, 4575814 ], 
+        [ 4575810, 4576253, 4575815, 4576258 ], 
+        [ 4576254, 4579647, 4576259, 4579652 ], 
+        [ 4579648, 4582407, 4579653, 4582411 ], 
+        [ 4582408, 4588823, 4582412, 4588828 ], 
+        [ 4588824, 4589254, 4588829, 4589259 ], 
+        [ 4589255, 4589933, 4589260, 4589929 ], 
+        [ 4589934, 4591334, 4589930, 4591338 ], 
+        [ 4591335, 4598670, 4591339, 4598675 ], 
+        [ 4598671, 4599152, 4598676, 4599156 ], 
+        [ 4599153, 4600707, 4599157, 4600703 ], 
+        [ 4600708, 4601105, 4600704, 4601110 ], 
+        [ 4601106, 4601445, 4601111, 4601449 ], 
+        [ 4601446, 4602566, 4601450, 4602571 ], 
+        [ 4602567, 4606392, 4602572, 4606396 ], 
+        [ 4606393, 4607895, 4606397, 4607899 ], 
+        [ 4607896, 4612068, 4607900, 4612073 ], 
+        [ 4612069, 4615603, 4612074, 4615608 ], 
+        [ 4615604, 4618026, 4615609, 4618030 ], 
+        [ 4618027, 4621061, 4618031, 4621065 ], 
+        [ 4621062, 4627887, 4621066, 4627892 ], 
+        [ 4627888, 4631394, 4627893, 4631399 ], 
+        [ 4631395, 4631631, 4631400, 4631636 ], 
+        [ 4631632, 4635963, 4631637, 4635968 ], 
+        [ 4635964, 4641129, 4635969, 4641134 ], 
+        [ 4641130, 4642188, 4641135, 4642192 ], 
+        [ 4642189, 4642980, 4642193, 4642985 ], 
+        [ 4642981, 4643635, 4642986, 4643640 ], 
+        [ 4643636, 4644147, 4643641, 4644152 ], 
+        [ 4644148, 4644814, 4644153, 4644818 ], 
+        [ 4644815, 4649017, 4644819, 4649021 ], 
+        [ 4649018, 4649332, 4649022, 4649337 ], 
+        [ 4649333, 4649464, 4649338, 4649469 ], 
+        [ 4649465, 4650584, 4649470, 4650588 ], 
+        [ 4650585, 4653836, 4650589, 4653840 ], 
+        [ 4653837, 4654913, 4653841, 4654917 ], 
+        [ 4654914, 4656366, 4654918, 4656371 ], 
+        [ 4656367, 4656864, 4656372, 4656869 ], 
+        [ 4656865, 4656933, 4656870, 4656938 ], 
+        [ 4656934, 4660056, 4656939, 4660061 ], 
+        [ 4660057, 4665881, 4660062, 4665886 ], 
+        [ 4665882, 4666341, 4665887, 4666345 ], 
+        [ 4666342, 4668837, 4666346, 4668842 ], 
+        [ 4668838, 4669896, 4668843, 4669900 ], 
+        [ 4669897, 4670841, 4669901, 4670845 ], 
+        [ 4670842, 4672873, 4670846, 4672878 ], 
+        [ 4672874, 4681462, 4672879, 4681467 ], 
+        [ 4681463, 4682181, 4681468, 4682185 ], 
+        [ 4682182, 4691924, 4682186, 4691928 ], 
+        [ 4691925, 4696368, 4691929, 4696373 ], 
+        [ 4696369, 4699474, 4696374, 4699479 ], 
+        [ 4699475, 4702530, 4699480, 4702534 ], 
+        [ 4702531, 4704523, 4702535, 4704528 ], 
+        [ 4704524, 4704899, 4704529, 4704903 ], 
+        [ 4704900, 4706008, 4704904, 4706013 ], 
+        [ 4706009, 4706120, 4706014, 4706124 ], 
+        [ 4706121, 4706510, 4706125, 4706515 ], 
+        [ 4706511, 4710334, 4706516, 4710330 ], 
+        [ 4710335, 4710765, 4710331, 4710769 ], 
+        [ 4710766, 4711295, 4710770, 4711300 ], 
+        [ 4711296, 4711543, 4711301, 4711548 ], 
+        [ 4711544, 4711935, 4711549, 4711940 ], 
+        [ 4711936, 4712790, 4711941, 4712795 ], 
+        [ 4712791, 4713126, 4712796, 4713131 ], 
+        [ 4713127, 4713287, 4713132, 4713291 ], 
+        [ 4713288, 4713730, 4713292, 4713735 ], 
+        [ 4713731, 4717619, 4713736, 4717624 ], 
+        [ 4717620, 4718789, 4717625, 4718785 ], 
+        [ 4718790, 4722736, 4718786, 4722740 ], 
+        [ 4722737, 4724224, 4722741, 4724229 ], 
+        [ 4724225, 4725868, 4724230, 4725873 ], 
+        [ 4725869, 4727653, 4725874, 4727658 ], 
+        [ 4727654, 4729069, 4727659, 4729074 ], 
+        [ 4729070, 4730833, 4729075, 4730838 ], 
+        [ 4730834, 4733099, 4730839, 4733104 ], 
+        [ 4733100, 4733576, 4733105, 4733581 ], 
+        [ 4733577, 4735011, 4733582, 4735015 ], 
+        [ 4735012, 4735924, 4735016, 4735928 ], 
+        [ 4735925, 4736754, 4735929, 4736759 ], 
+        [ 4736755, 4737511, 4736760, 4737507 ], 
+        [ 4737512, 4737991, 4737508, 4737995 ], 
+        [ 4737992, 4740307, 4737996, 4740311 ], 
+        [ 4740308, 4741684, 4740312, 4741689 ], 
+        [ 4741685, 4744830, 4741690, 4744835 ], 
+        [ 4744831, 4746768, 4744836, 4746773 ], 
+        [ 4746769, 4749037, 4746774, 4749042 ], 
+        [ 4749038, 4749801, 4749043, 4749806 ], 
+        [ 4749802, 4749864, 4749807, 4749869 ], 
+        [ 4749865, 4750090, 4749870, 4750094 ], 
+        [ 4750091, 4750966, 4750095, 4750971 ], 
+        [ 4750967, 4751355, 4750972, 4751359 ], 
+        [ 4751356, 4751493, 4751360, 4751497 ], 
+        [ 4751494, 4752345, 4751498, 4752349 ], 
+        [ 4752346, 4752965, 4752350, 4752970 ], 
+        [ 4752966, 4753059, 4752971, 4753063 ], 
+        [ 4753060, 4754115, 4753064, 4754119 ], 
+        [ 4754116, 4754237, 4754120, 4754242 ], 
+        [ 4754238, 4757191, 4754243, 4757196 ], 
+        [ 4757192, 4761010, 4757197, 4761014 ], 
+        [ 4761011, 4762052, 4761015, 4762057 ], 
+        [ 4762053, 4762604, 4762058, 4762600 ], 
+        [ 4762605, 4764164, 4762601, 4764169 ], 
+        [ 4764165, 4766341, 4764170, 4766346 ], 
+        [ 4766342, 4767519, 4766347, 4767524 ], 
+        [ 4767520, 4769451, 4767525, 4769456 ], 
+        [ 4769452, 4770366, 4769457, 4770371 ], 
+        [ 4770367, 4774504, 4770372, 4774509 ], 
+        [ 4774505, 4777167, 4774510, 4777171 ], 
+        [ 4777168, 4778234, 4777172, 4778238 ], 
+        [ 4778235, 4779310, 4778239, 4779315 ], 
+        [ 4779311, 4784157, 4779316, 4784161 ], 
+        [ 4784158, 4784713, 4784162, 4784718 ], 
+        [ 4784714, 4784960, 4784719, 4784965 ], 
+        [ 4784961, 4789181, 4784966, 4789186 ], 
+        [ 4789182, 4792300, 4789187, 4792304 ], 
+        [ 4792301, 4792894, 4792305, 4792899 ], 
+        [ 4792895, 4804321, 4792900, 4804326 ], 
+        [ 4804322, 4807780, 4804327, 4807785 ], 
+        [ 4807781, 4808367, 4807786, 4808372 ], 
+        [ 4808368, 4811025, 4808373, 4811030 ], 
+        [ 4811026, 4811936, 4811031, 4811940 ], 
+        [ 4811937, 4812883, 4811941, 4812887 ], 
+        [ 4812884, 4813062, 4812888, 4813067 ], 
+        [ 4813063, 4813117, 4813068, 4813121 ], 
+        [ 4813118, 4822160, 4813122, 4822165 ], 
+        [ 4822161, 4830957, 4822166, 4830961 ], 
+        [ 4830958, 4831410, 4830962, 4831414 ], 
+        [ 4831411, 4832326, 4831415, 4832330 ], 
+        [ 4832327, 4833156, 4832331, 4833161 ], 
+        [ 4833157, 4834005, 4833162, 4834001 ], 
+        [ 4834006, 4834485, 4834002, 4834489 ], 
+        [ 4834486, 4839621, 4834490, 4839626 ], 
+        [ 4839622, 4844592, 4839627, 4844588 ], 
+        [ 4844593, 4853316, 4844589, 4853321 ], 
+        [ 4853317, 4853434, 4853322, 4853438 ], 
+        [ 4853435, 4853704, 4853439, 4853708 ], 
+        [ 4853705, 4862268, 4853709, 4862273 ], 
+        [ 4862269, 4862689, 4862274, 4862694 ], 
+        [ 4862690, 4863453, 4862695, 4863458 ], 
+        [ 4863454, 4863657, 4863459, 4863662 ], 
+        [ 4863658, 4865285, 4863663, 4865289 ], 
+        [ 4865286, 4867215, 4865290, 4867220 ], 
+        [ 4867216, 4867943, 4867221, 4867948 ], 
+        [ 4867944, 4870367, 4867949, 4870372 ], 
+        [ 4870368, 4871260, 4870373, 4871265 ], 
+        [ 4871261, 4871925, 4871266, 4871930 ], 
+        [ 4871926, 4872824, 4871931, 4872829 ], 
+        [ 4872825, 4877259, 4872830, 4877263 ], 
+        [ 4877260, 4877520, 4877264, 4877524 ], 
+        [ 4877521, 4879935, 4877525, 4879940 ], 
+        [ 4879936, 4880330, 4879941, 4880334 ], 
+        [ 4880331, 4881593, 4880335, 4881598 ], 
+        [ 4881594, 4882087, 4881599, 4882092 ], 
+        [ 4882088, 4889351, 4882093, 4889356 ], 
+        [ 4889352, 4890443, 4889357, 4890448 ], 
+        [ 4890444, 4892812, 4890449, 4892816 ], 
+        [ 4892813, 4893056, 4892817, 4893052 ], 
+        [ 4893057, 4893088, 4893053, 4893092 ], 
+        [ 4893089, 4897454, 4893093, 4897458 ], 
+        [ 4897455, 4898485, 4897459, 4898490 ], 
+        [ 4898486, 4901057, 4898491, 4901062 ], 
+        [ 4901058, 4904245, 4901063, 4904250 ], 
+        [ 4904246, 4904281, 4904251, 4904285 ], 
+        [ 4904282, 4904668, 4904286, 4904673 ], 
+        [ 4904669, 4904984, 4904674, 4904989 ], 
+        [ 4904985, 4907736, 4904990, 4907740 ], 
+        [ 4907737, 4908072, 4907741, 4908076 ], 
+        [ 4908073, 4908096, 4908077, 4908100 ], 
+        [ 4908097, 4908561, 4908101, 4908565 ], 
+        [ 4908562, 4913327, 4908566, 4913323 ], 
+        [ 4913328, 4914224, 4913324, 4914229 ], 
+        [ 4914225, 4916537, 4914230, 4916542 ], 
+        [ 4916538, 4918099, 4916543, 4918103 ], 
+        [ 4918100, 4919908, 4918104, 4919913 ], 
+        [ 4919909, 4926663, 4919914, 4926668 ], 
+        [ 4926664, 4929329, 4926669, 4929334 ], 
+        [ 4929330, 4929560, 4929335, 4929564 ], 
+        [ 4929561, 4930673, 4929565, 4930678 ], 
+        [ 4930674, 4930954, 4930679, 4930959 ], 
+        [ 4930955, 4931594, 4930960, 4931599 ], 
+        [ 4931595, 4932928, 4931600, 4932932 ], 
+        [ 4932929, 4937282, 4932933, 4937287 ], 
+        [ 4937283, 4939667, 4937288, 4939672 ], 
+        [ 4939668, 4940551, 4939673, 4940555 ], 
+        [ 4940552, 4940908, 4940556, 4940912 ], 
+        [ 4940909, 4941837, 4940913, 4941842 ], 
+        [ 4941838, 4946673, 4941843, 4946677 ], 
+        [ 4946674, 4947030, 4946678, 4947035 ], 
+        [ 4947031, 4948839, 4947036, 4948843 ], 
+        [ 4948840, 4951071, 4948844, 4951076 ], 
+        [ 4951072, 4953999, 4951077, 4954004 ], 
+        [ 4954000, 4955481, 4954005, 4955486 ], 
+        [ 4955482, 4959224, 4955487, 4959229 ], 
+        [ 4959225, 4967229, 4959230, 4967233 ], 
+        [ 4967230, 4972603, 4967234, 4972607 ], 
+        [ 4972604, 4974094, 4972608, 4974098 ], 
+        [ 4974095, 4974624, 4974099, 4974629 ], 
+        [ 4974625, 4975683, 4974630, 4975687 ], 
+        [ 4975684, 4976599, 4975688, 4976603 ], 
+        [ 4976600, 4977429, 4976604, 4977434 ], 
+        [ 4977430, 4978186, 4977435, 4978182 ], 
+        [ 4978187, 4978666, 4978183, 4978670 ], 
+        [ 4978667, 4984448, 4978671, 4984453 ], 
+        [ 4984449, 4986670, 4984454, 4986675 ], 
+        [ 4986671, 4987571, 4986676, 4987575 ], 
+        [ 4987572, 4989614, 4987576, 4989618 ], 
+        [ 4989615, 4990698, 4989619, 4990702 ], 
+        [ 4990699, 4992038, 4990703, 4992043 ], 
+        [ 4992039, 4993566, 4992044, 4993570 ], 
+        [ 4993567, 4993811, 4993571, 4993816 ], 
+        [ 4993812, 4994767, 4993817, 4994771 ], 
+        [ 4994768, 4995631, 4994772, 4995636 ], 
+        [ 4995632, 4996624, 4995637, 4996629 ], 
+        [ 4996625, 4996668, 4996630, 4996673 ], 
+        [ 4996669, 4997203, 4996674, 4997207 ], 
+        [ 4997204, 4998818, 4997208, 4998823 ], 
+        [ 4998819, 5004186, 4998824, 5004191 ], 
+        [ 5004187, 5004432, 5004192, 5004436 ], 
+        [ 5004433, 5008758, 5004437, 5008754 ], 
+        [ 5008759, 5013598, 5008755, 5013603 ], 
+        [ 5013599, 5016180, 5013604, 5016185 ], 
+        [ 5016181, 5016267, 5016186, 5016271 ], 
+        [ 5016268, 5017625, 5016272, 5017629 ], 
+        [ 5017626, 5018455, 5017630, 5018460 ], 
+        [ 5018456, 5019212, 5018461, 5019208 ], 
+        [ 5019213, 5019692, 5019209, 5019696 ], 
+        [ 5019693, 5026663, 5019697, 5026667 ], 
+        [ 5026664, 5026770, 5026668, 5026775 ], 
+        [ 5026771, 5028841, 5026776, 5028846 ], 
+        [ 5028842, 5030486, 5028847, 5030490 ], 
+        [ 5030487, 5031862, 5030491, 5031867 ], 
+        [ 5031863, 5036331, 5031868, 5036336 ], 
+        [ 5036332, 5037861, 5036337, 5037866 ], 
+        [ 5037862, 5038887, 5037867, 5038892 ], 
+        [ 5038888, 5040440, 5038893, 5040445 ], 
+        [ 5040441, 5042902, 5040446, 5042907 ], 
+        [ 5042903, 5044827, 5042908, 5044832 ], 
+        [ 5044828, 5050524, 5044833, 5050529 ], 
+        [ 5050525, 5053866, 5050530, 5053871 ], 
+        [ 5053867, 5054707, 5053872, 5054712 ], 
+        [ 5054708, 5055021, 5054713, 5055026 ], 
+        [ 5055022, 5057873, 5055027, 5057878 ], 
+        [ 5057874, 5059653, 5057879, 5059657 ], 
+        [ 5059654, 5059734, 5059658, 5059739 ], 
+        [ 5059735, 5061548, 5059740, 5061553 ], 
+        [ 5061549, 5063342, 5061554, 5063347 ], 
+        [ 5063343, 5064119, 5063348, 5064124 ], 
+        [ 5064120, 5064638, 5064125, 5064643 ], 
+        [ 5064639, 5066316, 5064644, 5066320 ], 
+        [ 5066317, 5068774, 5066321, 5068779 ], 
+        [ 5068775, 5069157, 5068780, 5069162 ], 
+        [ 5069158, 5069375, 5069163, 5069380 ], 
+        [ 5069376, 5071533, 5069381, 5071538 ], 
+        [ 5071534, 5072259, 5071539, 5072264 ], 
+        [ 5072260, 5072332, 5072265, 5072337 ], 
+        [ 5072333, 5074288, 5072338, 5074293 ], 
+        [ 5074289, 5078241, 5074294, 5078237 ], 
+        [ 5078242, 5084929, 5078238, 5084933 ], 
+        [ 5084930, 5087508, 5084934, 5087513 ], 
+        [ 5087509, 5088409, 5087514, 5088414 ], 
+        [ 5088410, 5093963, 5088415, 5093968 ], 
+        [ 5093964, 5097754, 5093969, 5097750 ], 
+        [ 5097755, 5098261, 5097751, 5098266 ], 
+        [ 5098262, 5100144, 5098267, 5100148 ], 
+        [ 5100145, 5102713, 5100149, 5102709 ], 
+        [ 5102714, 5105308, 5102710, 5105312 ], 
+        [ 5105309, 5110195, 5105313, 5110199 ], 
+        [ 5110196, 5116037, 5110200, 5116042 ], 
+        [ 5116038, 5116647, 5116043, 5116652 ], 
+        [ 5116648, 5119282, 5116653, 5119287 ], 
+        [ 5119283, 5121619, 5119288, 5121623 ], 
+        [ 5121620, 5122889, 5121624, 5122893 ], 
+        [ 5122890, 5125691, 5122894, 5125695 ], 
+        [ 5125692, 5125943, 5125696, 5125947 ], 
+        [ 5125944, 5132940, 5125948, 5132945 ], 
+        [ 5132941, 5133068, 5132946, 5133072 ], 
+        [ 5133069, 5133405, 5133073, 5133410 ], 
+        [ 5133406, 5134558, 5133411, 5134563 ], 
+        [ 5134559, 5138091, 5134564, 5138095 ], 
+        [ 5138092, 5138432, 5138096, 5138437 ], 
+        [ 5138433, 5138944, 5138438, 5138949 ], 
+        [ 5138945, 5139157, 5138950, 5139162 ], 
+        [ 5139158, 5139587, 5139163, 5139592 ], 
+        [ 5139588, 5142617, 5139593, 5142622 ], 
+        [ 5142618, 5148183, 5142623, 5148188 ], 
+        [ 5148184, 5148672, 5148189, 5148677 ], 
+        [ 5148673, 5150053, 5148678, 5150058 ], 
+        [ 5150054, 5151087, 5150059, 5151092 ], 
+        [ 5151088, 5153217, 5151093, 5153222 ], 
+        [ 5153218, 5154383, 5153223, 5154388 ], 
+        [ 5154384, 5154947, 5154389, 5154951 ], 
+        [ 5154948, 5155016, 5154952, 5155021 ], 
+        [ 5155017, 5156599, 5155022, 5156604 ], 
+        [ 5156600, 5157802, 5156605, 5157807 ], 
+        [ 5157803, 5157970, 5157808, 5157975 ], 
+        [ 5157971, 5160625, 5157976, 5160630 ], 
+        [ 5160626, 5162852, 5160631, 5162857 ], 
+        [ 5162853, 5164824, 5162858, 5164829 ], 
+        [ 5164825, 5171077, 5164830, 5171082 ], 
+        [ 5171078, 5176566, 5171083, 5176570 ], 
+        [ 5176567, 5180104, 5176571, 5180108 ], 
+        [ 5180105, 5180591, 5180109, 5180596 ], 
+        [ 5180592, 5184142, 5180597, 5184138 ], 
+        [ 5184143, 5188235, 5184139, 5188240 ], 
+        [ 5188236, 5190430, 5188241, 5190434 ], 
+        [ 5190431, 5194013, 5190435, 5194018 ], 
+        [ 5194014, 5194634, 5194019, 5194638 ], 
+        [ 5194635, 5199338, 5194639, 5199342 ], 
+        [ 5199339, 5200363, 5199343, 5200368 ], 
+        [ 5200364, 5200380, 5200369, 5200385 ], 
+        [ 5200381, 5207919, 5200386, 5207923 ], 
+        [ 5207920, 5210484, 5207924, 5210480 ], 
+        [ 5210485, 5211327, 5210481, 5211331 ], 
+        [ 5211328, 5212227, 5211332, 5212231 ], 
+        [ 5212228, 5212416, 5212232, 5212421 ], 
+        [ 5212417, 5214189, 5212422, 5214194 ], 
+        [ 5214190, 5218448, 5214195, 5218453 ], 
+        [ 5218449, 5221514, 5218454, 5221519 ], 
+        [ 5221515, 5222166, 5221520, 5222170 ], 
+        [ 5222167, 5222235, 5222171, 5222239 ], 
+        [ 5222236, 5222405, 5222240, 5222410 ], 
+        [ 5222406, 5223121, 5222411, 5223126 ], 
+        [ 5223122, 5225062, 5223127, 5225067 ], 
+        [ 5225063, 5227034, 5225068, 5227039 ], 
+        [ 5227035, 5230060, 5227040, 5230064 ], 
+        [ 5230061, 5235911, 5230065, 5235915 ], 
+        [ 5235912, 5237062, 5235916, 5237067 ], 
+        [ 5237063, 5238549, 5237068, 5238554 ], 
+        [ 5238550, 5239941, 5238555, 5239946 ], 
+        [ 5239942, 5241160, 5239947, 5241165 ], 
+        [ 5241161, 5243887, 5241166, 5243891 ], 
+        [ 5243888, 5244364, 5243892, 5244368 ], 
+        [ 5244365, 5245009, 5244369, 5245014 ], 
+        [ 5245010, 5245420, 5245015, 5245425 ], 
+        [ 5245421, 5246665, 5245426, 5246670 ], 
+        [ 5246666, 5246882, 5246671, 5246887 ], 
+        [ 5246883, 5252321, 5246888, 5252326 ], 
+        [ 5252322, 5258113, 5252327, 5258117 ], 
+        [ 5258114, 5259300, 5258118, 5259304 ], 
+        [ 5259301, 5261182, 5259305, 5261187 ], 
+        [ 5261183, 5261507, 5261188, 5261503 ], 
+        [ 5261508, 5268860, 5261504, 5268864 ], 
+        [ 5268861, 5269941, 5268865, 5269945 ], 
+        [ 5269942, 5270945, 5269946, 5270949 ], 
+        [ 5270946, 5271167, 5270950, 5271171 ], 
+        [ 5271168, 5273111, 5271172, 5273116 ], 
+        [ 5273112, 5273132, 5273117, 5273137 ], 
+        [ 5273133, 5273680, 5273138, 5273685 ], 
+        [ 5273681, 5274282, 5273686, 5274287 ], 
+        [ 5274283, 5277485, 5274288, 5277490 ], 
+        [ 5277486, 5278602, 5277491, 5278607 ], 
+        [ 5278603, 5279312, 5278608, 5279316 ], 
+        [ 5279313, 5279965, 5279317, 5279969 ], 
+        [ 5279966, 5286668, 5279970, 5286673 ], 
+        [ 5286669, 5288844, 5286674, 5288849 ], 
+        [ 5288845, 5292505, 5288850, 5292509 ], 
+        [ 5292506, 5295145, 5292510, 5295149 ], 
+        [ 5295146, 5295426, 5295150, 5295431 ], 
+        [ 5295427, 5296411, 5295432, 5296407 ], 
+        [ 5296412, 5299331, 5296408, 5299336 ], 
+        [ 5299332, 5299740, 5299337, 5299745 ], 
+        [ 5299741, 5302074, 5299746, 5302079 ], 
+        [ 5302075, 5304927, 5302080, 5304932 ], 
+        [ 5304928, 5309929, 5304933, 5309925 ], 
+        [ 5309930, 5311027, 5309926, 5311023 ], 
+        [ 5311028, 5313142, 5311024, 5313138 ], 
+        [ 5313143, 5313612, 5313139, 5313616 ], 
+        [ 5313613, 5316196, 5313617, 5316201 ], 
+        [ 5316197, 5320424, 5316202, 5320428 ], 
+        [ 5320425, 5321884, 5320429, 5321889 ], 
+        [ 5321885, 5327443, 5321890, 5327448 ], 
+        [ 5327444, 5333009, 5327449, 5333014 ], 
+        [ 5333010, 5335558, 5333015, 5335563 ], 
+        [ 5335559, 5337934, 5335564, 5337939 ], 
+        [ 5337935, 5340296, 5337940, 5340301 ], 
+        [ 5340297, 5341322, 5340302, 5341326 ], 
+        [ 5341323, 5342510, 5341327, 5342515 ], 
+        [ 5342511, 5343834, 5342516, 5343839 ], 
+        [ 5343835, 5351733, 5343840, 5351737 ], 
+        [ 5351734, 5355838, 5351738, 5355842 ], 
+        [ 5355839, 5359283, 5355843, 5359288 ], 
+        [ 5359284, 5362430, 5359289, 5362434 ], 
+        [ 5362431, 5362544, 5362435, 5362549 ], 
+        [ 5362545, 5364468, 5362550, 5364472 ], 
+        [ 5364469, 5369245, 5364473, 5369241 ], 
+        [ 5369246, 5375729, 5369242, 5375734 ], 
+        [ 5375730, 5375790, 5375735, 5375795 ], 
+        [ 5375791, 5377253, 5375796, 5377258 ], 
+        [ 5377254, 5378696, 5377259, 5378701 ], 
+        [ 5378697, 5382060, 5378702, 5382065 ], 
+        [ 5382061, 5388003, 5382066, 5388007 ], 
+        [ 5388004, 5388224, 5388008, 5388229 ], 
+        [ 5388225, 5389155, 5388230, 5389159 ], 
+        [ 5389156, 5391633, 5389160, 5391638 ], 
+        [ 5391634, 5399712, 5391639, 5399716 ], 
+        [ 5399713, 5401417, 5399717, 5401422 ], 
+        [ 5401418, 5406297, 5401423, 5406301 ], 
+        [ 5406298, 5406537, 5406302, 5406542 ], 
+        [ 5406538, 5406850, 5406543, 5406854 ], 
+        [ 5406851, 5408637, 5406855, 5408642 ], 
+        [ 5408638, 5410093, 5408643, 5410097 ], 
+        [ 5410094, 5417270, 5410098, 5417275 ], 
+        [ 5417271, 5419353, 5417276, 5419358 ], 
+        [ 5419354, 5420144, 5419359, 5420149 ], 
+        [ 5420145, 5420216, 5420150, 5420221 ], 
+        [ 5420217, 5420740, 5420222, 5420745 ], 
+        [ 5420741, 5423081, 5420746, 5423085 ], 
+        [ 5423082, 5424075, 5423086, 5424079 ], 
+        [ 5424076, 5425137, 5424080, 5425141 ], 
+        [ 5425138, 5427477, 5425142, 5427482 ], 
+        [ 5427478, 5429323, 5427483, 5429328 ], 
+        [ 5429324, 5429631, 5429329, 5429635 ], 
+        [ 5429632, 5432849, 5429636, 5432853 ], 
+        [ 5432850, 5432874, 5432854, 5432878 ], 
+        [ 5432875, 5440584, 5432879, 5440588 ], 
+        [ 5440585, 5440833, 5440589, 5440837 ], 
+        [ 5440834, 5441634, 5440838, 5441639 ], 
+        [ 5441635, 5446602, 5441640, 5446606 ], 
+        [ 5446603, 5448663, 5446607, 5448668 ], 
+        [ 5448664, 5452231, 5448669, 5452236 ], 
+        [ 5452232, 5453350, 5452237, 5453354 ], 
+        [ 5453351, 5455164, 5453355, 5455168 ], 
+        [ 5455165, 5458274, 5455169, 5458279 ], 
+        [ 5458275, 5459524, 5458280, 5459529 ], 
+        [ 5459525, 5468509, 5459530, 5468514 ], 
+        [ 5468510, 5469773, 5468515, 5469778 ], 
+        [ 5469774, 5474040, 5469779, 5474044 ], 
+        [ 5474041, 5475379, 5474045, 5475384 ], 
+        [ 5475380, 5476063, 5475385, 5476068 ], 
+        [ 5476064, 5477860, 5476069, 5477865 ], 
+        [ 5477861, 5478124, 5477866, 5478129 ], 
+        [ 5478125, 5478577, 5478130, 5478582 ], 
+        [ 5478578, 5479176, 5478583, 5479181 ], 
+        [ 5479177, 5483012, 5479182, 5483017 ], 
+        [ 5483013, 5483809, 5483018, 5483814 ], 
+        [ 5483810, 5490967, 5483815, 5490963 ], 
+        [ 5490968, 5491739, 5490964, 5491743 ], 
+        [ 5491740, 5495234, 5491744, 5495239 ], 
+        [ 5495235, 5498449, 5495240, 5498449 ]
+      ]
+
+    def _cut(seq)
+      cuts = Bio::RestrictionEnzyme::Analysis.cut(seq,
+                                                  "SacI", "EcoRI", "BstEII",
+                                                  {:view_ranges => true})
+    end
+  end #TestEcoliO157H7_3enzymes
+
+
+end #module TestRestrictionEnzymeAnalysisCutLong
diff --git a/test/data/fasta/EFTU_BACSU.fasta b/test/data/fasta/EFTU_BACSU.fasta
new file mode 100644
index 0000000..4faaab3
--- /dev/null
+++ b/test/data/fasta/EFTU_BACSU.fasta
@@ -0,0 +1,8 @@
+>sp|P33166|EFTU_BACSU Elongation factor Tu;
+MAKEKFDRSKSHANIGTIGHVDHGKTTLTAAITTVLHKKSGKGTAMAYDQIDGAPEERER
+GITISTAHVEYETETRHYAHVDCPGHADYVKNMITGAAQMDGAILVVSAADGPMPQTREH
+ILLSKNVGVPYIVVFLNKCDMVDDEELLELVEMEVRDLLSEYDFPGDDVPVVKGSALKAL
+EGDAEWEAKIFELMDAVDEYIPTPERDTEKPFMMPVEDVFSITGRGTVATGRVERGQVKV
+GDEVEIIGLQEENKKTTVTGVEMFRKLLDYAEAGDNIGALLRGVSREEIQRGQVLAKPGT
+ITPHSKFKAEVYVLSKEEGGRHTPFFSNYRPQFYFRTTDVTGIIHLPEGVEMVMPGDNTE
+MNVELISTIAIEEGTRFSIREGGRTVGSGVVSTITE
diff --git a/test/data/genbank/CAA35997.gp b/test/data/genbank/CAA35997.gp
new file mode 100644
index 0000000..064fa15
--- /dev/null
+++ b/test/data/genbank/CAA35997.gp
@@ -0,0 +1,48 @@
+LOCUS       CAA35997                 100 aa            linear   MAM 12-SEP-1993
+DEFINITION  unnamed protein product [Bos taurus].
+ACCESSION   CAA35997
+VERSION     CAA35997.1  GI:8
+DBSOURCE    embl accession X51700.1
+KEYWORDS    .
+SOURCE      Bos taurus (cattle)
+  ORGANISM  Bos taurus
+            Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Euteleostomi;
+            Mammalia; Eutheria; Laurasiatheria; Cetartiodactyla; Ruminantia;
+            Pecora; Bovidae; Bovinae; Bos.
+REFERENCE   1  (residues 1 to 100)
+  AUTHORS   Kiefer,M.C., Saphire,A.C.S., Bauer,D.M. and Barr,P.J.
+  JOURNAL   Unpublished
+REFERENCE   2  (residues 1 to 100)
+  AUTHORS   Kiefer,M.C.
+  TITLE     Direct Submission
+  JOURNAL   Submitted (30-JAN-1990) Kiefer M.C., Chiron Corporation, 4560
+            Hortom St, Emeryville CA 94608-2916, U S A
+COMMENT     See <X15699> for Human sequence.
+            Data kindly reviewed (08-MAY-1990) by Kiefer M.C.
+FEATURES             Location/Qualifiers
+     source          1..100
+                     /organism="Bos taurus"
+                     /db_xref="taxon:9913"
+                     /clone="bBGP-3"
+                     /tissue_type="bone matrix"
+                     /clone_lib="Zap-bb"
+     Protein         1..100
+                     /name="unnamed protein product"
+     Region          33..97
+                     /region_name="Gla"
+                     /note="Vitamin K-dependent
+                     carboxylation/gamma-carboxyglutamic (GLA) domain; cl02449"
+                     /db_xref="CDD:141428"
+     CDS             1..100
+                     /coded_by="X51700.1:28..330"
+                     /note="bone Gla precursor (100 AA)"
+                     /db_xref="GOA:P02820"
+                     /db_xref="InterPro:IPR000294"
+                     /db_xref="InterPro:IPR002384"
+                     /db_xref="PDB:1Q3M"
+                     /db_xref="UniProtKB/Swiss-Prot:P02820"
+ORIGIN      
+        1 mrtpmllall alatlclagr adakpgdaes gkgaafvskq egsevvkrlr ryldhwlgap
+       61 apypdplepk revcelnpdc deladhigfq eayrrfygpv
+//
+
diff --git a/test/data/genbank/SCU49845.gb b/test/data/genbank/SCU49845.gb
new file mode 100644
index 0000000..b9ded70
--- /dev/null
+++ b/test/data/genbank/SCU49845.gb
@@ -0,0 +1,167 @@
+LOCUS       SCU49845                5028 bp    DNA     linear   PLN 23-MAR-2010
+DEFINITION  Saccharomyces cerevisiae TCP1-beta gene, partial cds; and Axl2p
+            (AXL2) and Rev7p (REV7) genes, complete cds.
+ACCESSION   U49845
+VERSION     U49845.1  GI:1293613
+KEYWORDS    .
+SOURCE      Saccharomyces cerevisiae (baker's yeast)
+  ORGANISM  Saccharomyces cerevisiae
+            Eukaryota; Fungi; Dikarya; Ascomycota; Saccharomyceta;
+            Saccharomycotina; Saccharomycetes; Saccharomycetales;
+            Saccharomycetaceae; Saccharomyces.
+REFERENCE   1  (bases 1 to 5028)
+  AUTHORS   Roemer,T., Madden,K., Chang,J. and Snyder,M.
+  TITLE     Selection of axial growth sites in yeast requires Axl2p, a novel
+            plasma membrane glycoprotein
+  JOURNAL   Genes Dev. 10 (7), 777-793 (1996)
+   PUBMED   8846915
+REFERENCE   2  (bases 1 to 5028)
+  AUTHORS   Roemer,T.
+  TITLE     Direct Submission
+  JOURNAL   Submitted (22-FEB-1996) Biology, Yale University, New Haven, CT
+            06520, USA
+FEATURES             Location/Qualifiers
+     source          1..5028
+                     /organism="Saccharomyces cerevisiae"
+                     /mol_type="genomic DNA"
+                     /db_xref="taxon:4932"
+                     /chromosome="IX"
+     mRNA            <1..>206
+                     /product="TCP1-beta"
+     CDS             <1..206
+                     /codon_start=3
+                     /product="TCP1-beta"
+                     /protein_id="AAA98665.1"
+                     /db_xref="GI:1293614"
+                     /translation="SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEA
+                     AEVLLRVDNIIRARPRTANRQHM"
+     gene            <687..>3158
+                     /gene="AXL2"
+     mRNA            <687..>3158
+                     /gene="AXL2"
+                     /product="Axl2p"
+     CDS             687..3158
+                     /gene="AXL2"
+                     /note="plasma membrane glycoprotein"
+                     /codon_start=1
+                     /product="Axl2p"
+                     /protein_id="AAA98666.1"
+                     /db_xref="GI:1293615"
+                     /translation="MTQLQISLLLTATISLLHLVVATPYEAYPIGKQYPPVARVNESF
+                     TFQISNDTYKSSVDKTAQITYNCFDLPSWLSFDSSSRTFSGEPSSDLLSDANTTLYFN
+                     VILEGTDSADSTSLNNTYQFVVTNRPSISLSSDFNLLALLKNYGYTNGKNALKLDPNE
+                     VFNVTFDRSMFTNEESIVSYYGRSQLYNAPLPNWLFFDSGELKFTGTAPVINSAIAPE
+                     TSYSFVIIATDIEGFSAVEVEFELVIGAHQLTTSIQNSLIINVTDTGNVSYDLPLNYV
+                     YLDDDPISSDKLGSINLLDAPDWVALDNATISGSVPDELLGKNSNPANFSVSIYDTYG
+                     DVIYFNFEVVSTTDLFAISSLPNINATRGEWFSYYFLPSQFTDYVNTNVSLEFTNSSQ
+                     DHDWVKFQSSNLTLAGEVPKNFDKLSLGLKANQGSQSQELYFNIIGMDSKITHSNHSA
+                     NATSTRSSHHSTSTSSYTSSTYTAKISSTSAAATSSAPAALPAANKTSSHNKKAVAIA
+                     CGVAIPLGVILVALICFLIFWRRRRENPDDENLPHAISGPDLNNPANKPNQENATPLN
+                     NPFDDDASSYDDTSIARRLAALNTLKLDNHSATESDISSVDEKRDSLSGMNTYNDQFQ
+                     SQSKEELLAKPPVQPPESPFFDPQNRSSSVYMDSEPAVNKSWRYTGNLSPVSDIVRDS
+                     YGSQKTVDTEKLFDLEAPEKEKRTSRDVTMSSLDPWNSNISPSPVRKSVTPSPYNVTK
+                     HRNRHLQNIQDSQSGKNGITPTTMSTSSSDDFVPVKDGENFCWVHSMEPDRRPSKKRL
+                     VDFSNKSNVNVGQVKDIHGRIPEML"
+     gene            complement(<3300..>4037)
+                     /gene="REV7"
+     mRNA            complement(<3300..>4037)
+                     /gene="REV7"
+                     /product="Rev7p"
+     CDS             complement(3300..4037)
+                     /gene="REV7"
+                     /codon_start=1
+                     /product="Rev7p"
+                     /protein_id="AAA98667.1"
+                     /db_xref="GI:1293616"
+                     /translation="MNRWVEKWLRVYLKCYINLILFYRNVYPPQSFDYTTYQSFNLPQ
+                     FVPINRHPALIDYIEELILDVLSKLTHVYRFSICIINKKNDLCIEKYVLDFSELQHVD
+                     KDDQIITETEVFDEFRSSLNSLIMHLEKLPKVNDDTITFEAVINAIELELGHKLDRNR
+                     RVDSLEEKAEIERDSNWVKCQEDENLPDNNGFQPPKIKLTSLVGSDVGPLIIHQFSEK
+                     LISGDDKILNGVYSQYEEGESIFGSLF"
+ORIGIN      
+        1 gatcctccat atacaacggt atctccacct caggtttaga tctcaacaac ggaaccattg
+       61 ccgacatgag acagttaggt atcgtcgaga gttacaagct aaaacgagca gtagtcagct
+      121 ctgcatctga agccgctgaa gttctactaa gggtggataa catcatccgt gcaagaccaa
+      181 gaaccgccaa tagacaacat atgtaacata tttaggatat acctcgaaaa taataaaccg
+      241 ccacactgtc attattataa ttagaaacag aacgcaaaaa ttatccacta tataattcaa
+      301 agacgcgaaa aaaaaagaac aacgcgtcat agaacttttg gcaattcgcg tcacaaataa
+      361 attttggcaa cttatgtttc ctcttcgagc agtactcgag ccctgtctca agaatgtaat
+      421 aatacccatc gtaggtatgg ttaaagatag catctccaca acctcaaagc tccttgccga
+      481 gagtcgccct cctttgtcga gtaattttca cttttcatat gagaacttat tttcttattc
+      541 tttactctca catcctgtag tgattgacac tgcaacagcc accatcacta gaagaacaga
+      601 acaattactt aatagaaaaa ttatatcttc ctcgaaacga tttcctgctt ccaacatcta
+      661 cgtatatcaa gaagcattca cttaccatga cacagcttca gatttcatta ttgctgacag
+      721 ctactatatc actactccat ctagtagtgg ccacgcccta tgaggcatat cctatcggaa
+      781 aacaataccc cccagtggca agagtcaatg aatcgtttac atttcaaatt tccaatgata
+      841 cctataaatc gtctgtagac aagacagctc aaataacata caattgcttc gacttaccga
+      901 gctggctttc gtttgactct agttctagaa cgttctcagg tgaaccttct tctgacttac
+      961 tatctgatgc gaacaccacg ttgtatttca atgtaatact cgagggtacg gactctgccg
+     1021 acagcacgtc tttgaacaat acataccaat ttgttgttac aaaccgtcca tccatctcgc
+     1081 tatcgtcaga tttcaatcta ttggcgttgt taaaaaacta tggttatact aacggcaaaa
+     1141 acgctctgaa actagatcct aatgaagtct tcaacgtgac ttttgaccgt tcaatgttca
+     1201 ctaacgaaga atccattgtg tcgtattacg gacgttctca gttgtataat gcgccgttac
+     1261 ccaattggct gttcttcgat tctggcgagt tgaagtttac tgggacggca ccggtgataa
+     1321 actcggcgat tgctccagaa acaagctaca gttttgtcat catcgctaca gacattgaag
+     1381 gattttctgc cgttgaggta gaattcgaat tagtcatcgg ggctcaccag ttaactacct
+     1441 ctattcaaaa tagtttgata atcaacgtta ctgacacagg taacgtttca tatgacttac
+     1501 ctctaaacta tgtttatctc gatgacgatc ctatttcttc tgataaattg ggttctataa
+     1561 acttattgga tgctccagac tgggtggcat tagataatgc taccatttcc gggtctgtcc
+     1621 cagatgaatt actcggtaag aactccaatc ctgccaattt ttctgtgtcc atttatgata
+     1681 cttatggtga tgtgatttat ttcaacttcg aagttgtctc cacaacggat ttgtttgcca
+     1741 ttagttctct tcccaatatt aacgctacaa ggggtgaatg gttctcctac tattttttgc
+     1801 cttctcagtt tacagactac gtgaatacaa acgtttcatt agagtttact aattcaagcc
+     1861 aagaccatga ctgggtgaaa ttccaatcat ctaatttaac attagctgga gaagtgccca
+     1921 agaatttcga caagctttca ttaggtttga aagcgaacca aggttcacaa tctcaagagc
+     1981 tatattttaa catcattggc atggattcaa agataactca ctcaaaccac agtgcgaatg
+     2041 caacgtccac aagaagttct caccactcca cctcaacaag ttcttacaca tcttctactt
+     2101 acactgcaaa aatttcttct acctccgctg ctgctacttc ttctgctcca gcagcgctgc
+     2161 cagcagccaa taaaacttca tctcacaata aaaaagcagt agcaattgcg tgcggtgttg
+     2221 ctatcccatt aggcgttatc ctagtagctc tcatttgctt cctaatattc tggagacgca
+     2281 gaagggaaaa tccagacgat gaaaacttac cgcatgctat tagtggacct gatttgaata
+     2341 atcctgcaaa taaaccaaat caagaaaacg ctacaccttt gaacaacccc tttgatgatg
+     2401 atgcttcctc gtacgatgat acttcaatag caagaagatt ggctgctttg aacactttga
+     2461 aattggataa ccactctgcc actgaatctg atatttccag cgtggatgaa aagagagatt
+     2521 ctctatcagg tatgaataca tacaatgatc agttccaatc ccaaagtaaa gaagaattat
+     2581 tagcaaaacc cccagtacag cctccagaga gcccgttctt tgacccacag aataggtctt
+     2641 cttctgtgta tatggatagt gaaccagcag taaataaatc ctggcgatat actggcaacc
+     2701 tgtcaccagt ctctgatatt gtcagagaca gttacggatc acaaaaaact gttgatacag
+     2761 aaaaactttt cgatttagaa gcaccagaga aggaaaaacg tacgtcaagg gatgtcacta
+     2821 tgtcttcact ggacccttgg aacagcaata ttagcccttc tcccgtaaga aaatcagtaa
+     2881 caccatcacc atataacgta acgaagcatc gtaaccgcca cttacaaaat attcaagact
+     2941 ctcaaagcgg taaaaacgga atcactccca caacaatgtc aacttcatct tctgacgatt
+     3001 ttgttccggt taaagatggt gaaaattttt gctgggtcca tagcatggaa ccagacagaa
+     3061 gaccaagtaa gaaaaggtta gtagattttt caaataagag taatgtcaat gttggtcaag
+     3121 ttaaggacat tcacggacgc atcccagaaa tgctgtgatt atacgcaacg atattttgct
+     3181 taattttatt ttcctgtttt attttttatt agtggtttac agatacccta tattttattt
+     3241 agtttttata cttagagaca tttaatttta attccattct tcaaatttca tttttgcact
+     3301 taaaacaaag atccaaaaat gctctcgccc tcttcatatt gagaatacac tccattcaaa
+     3361 attttgtcgt caccgctgat taatttttca ctaaactgat gaataatcaa aggccccacg
+     3421 tcagaaccga ctaaagaagt gagttttatt ttaggaggtt gaaaaccatt attgtctggt
+     3481 aaattttcat cttcttgaca tttaacccag tttgaatccc tttcaatttc tgctttttcc
+     3541 tccaaactat cgaccctcct gtttctgtcc aacttatgtc ctagttccaa ttcgatcgca
+     3601 ttaataactg cttcaaatgt tattgtgtca tcgttgactt taggtaattt ctccaaatgc
+     3661 ataatcaaac tatttaagga agatcggaat tcgtcgaaca cttcagtttc cgtaatgatc
+     3721 tgatcgtctt tatccacatg ttgtaattca ctaaaatcta aaacgtattt ttcaatgcat
+     3781 aaatcgttct ttttattaat aatgcagatg gaaaatctgt aaacgtgcgt taatttagaa
+     3841 agaacatcca gtataagttc ttctatatag tcaattaaag caggatgcct attaatggga
+     3901 acgaactgcg gcaagttgaa tgactggtaa gtagtgtagt cgaatgactg aggtgggtat
+     3961 acatttctat aaaataaaat caaattaatg tagcatttta agtataccct cagccacttc
+     4021 tctacccatc tattcataaa gctgacgcaa cgattactat tttttttttc ttcttggatc
+     4081 tcagtcgtcg caaaaacgta taccttcttt ttccgacctt ttttttagct ttctggaaaa
+     4141 gtttatatta gttaaacagg gtctagtctt agtgtgaaag ctagtggttt cgattgactg
+     4201 atattaagaa agtggaaatt aaattagtag tgtagacgta tatgcatatg tatttctcgc
+     4261 ctgtttatgt ttctacgtac ttttgattta tagcaagggg aaaagaaata catactattt
+     4321 tttggtaaag gtgaaagcat aatgtaaaag ctagaataaa atggacgaaa taaagagagg
+     4381 cttagttcat cttttttcca aaaagcaccc aatgataata actaaaatga aaaggatttg
+     4441 ccatctgtca gcaacatcag ttgtgtgagc aataataaaa tcatcacctc cgttgccttt
+     4501 agcgcgtttg tcgtttgtat cttccgtaat tttagtctta tcaatgggaa tcataaattt
+     4561 tccaatgaat tagcaatttc gtccaattct ttttgagctt cttcatattt gctttggaat
+     4621 tcttcgcact tcttttccca ttcatctctt tcttcttcca aagcaacgat ccttctaccc
+     4681 atttgctcag agttcaaatc ggcctctttc agtttatcca ttgcttcctt cagtttggct
+     4741 tcactgtctt ctagctgttg ttctagatcc tggtttttct tggtgtagtt ctcattatta
+     4801 gatctcaagt tattggagtc ttcagccaat tgctttgtat cagacaattg actctctaac
+     4861 ttctccactt cactgtcgag ttgctcgttt ttagcggaca aagatttaat ctcgttttct
+     4921 ttttcagtgt tagattgctc taattctttg agctgttctc tcagctcctc atatttttct
+     4981 tgccatgact cagattctaa ttttaagcta ttcaatttct ctttgatc
+//
+
diff --git a/test/data/litdb/1717226.litdb b/test/data/litdb/1717226.litdb
new file mode 100644
index 0000000..afcf7d5
--- /dev/null
+++ b/test/data/litdb/1717226.litdb
@@ -0,0 +1,13 @@
+CODE        1717226
+TITLE       Characterization of an Escherichia coli gene encoding 
+            betaine aldehyde dehydrogenase (BADH). Structural similarity 
+            to mammalian ALDHs and a plant BADH.
+FIELD       q (sequence analysis)
+JOURNAL     Gene
+VOLUME      Vol.103, No.1, 45-52 (1991)
+KEYWORD     *Betaine Aldehyde Dehydrogenase;;*betB Gene;E.coli;;
+            Seq Determination;1854bp;491AAs;;Hydropathy Plot;*EC1.2.1.8;;
+            Seq Comparison
+AUTHOR      Boyd,L.A.;Adam,L.;Pelcher,L.E.;McHughen,A.;Hirji,R.;
+            Selvaraj,G.
+END
diff --git a/test/data/pir/CRAB_ANAPL.pir b/test/data/pir/CRAB_ANAPL.pir
new file mode 100644
index 0000000..8f89942
--- /dev/null
+++ b/test/data/pir/CRAB_ANAPL.pir
@@ -0,0 +1,6 @@
+>P1;CRAB_ANAPL
+ALPHA CRYSTALLIN B CHAIN (ALPHA(B)-CRYSTALLIN).
+  MDITIHNPLI RRPLFSWLAP SRIFDQIFGE HLQESELLPA SPSLSPFLMR 
+  SPIFRMPSWL ETGLSEMRLE KDKFSVNLDV KHFSPEELKV KVLGDMVEIH 
+  GKHEERQDEH GFIAREFNRK YRIPADVDPL TITSSLSLDG VLTVSAPRKQ 
+  SDVPERSIPI TREEKPAIAG AQRK*
diff --git a/test/functional/bio/appl/blast/test_remote.rb b/test/functional/bio/appl/blast/test_remote.rb
new file mode 100644
index 0000000..2855845
--- /dev/null
+++ b/test/functional/bio/appl/blast/test_remote.rb
@@ -0,0 +1,93 @@
+#
+# = test/functional/bio/appl/blast/test_remote.rb - Unit test for Bio::Blast::Remote::Genomenet and Bio::Blast::Remote::DDBJ with network connection
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/sequence'
+require 'bio/appl/blast'
+
+module Bio
+module FuncTestBlastRemote
+
+  module NetTestBlastRemoteCommon
+
+    Programs = %w( blastn tblastn tblastx blastp blastx ).freeze
+    Programs.each { |x| x.freeze }
+
+    def test_databases
+      Programs.each do |prog|
+        databases = nil
+        assert_nothing_raised {
+          databases = @klass.databases(prog)
+        }
+        assert_kind_of(Array, databases, "wrong data type for #{prog}")
+        assert(!databases.empty?, "no database found for #{prog}")
+      end
+    end
+
+    # sampling test for blastn database
+    def test_databases_blastn
+      databases = @klass.databases("blastn")
+      self.class::BLASTN_DBNAME_KEYWORDS.each do |re|
+        assert(databases.find { |x| re =~ x })
+      end
+    end
+
+    # sampling test for blastp database
+    def test_databases_blastp
+      databases = @klass.databases("blastp")
+      self.class::BLASTP_DBNAME_KEYWORDS.each do |re|
+        assert(databases.find { |x| re =~ x })
+      end
+    end
+
+    def test_database_description
+      Programs.each do |prog|
+        @klass.databases(prog).each do |db|
+          assert_kind_of(String, @klass.database_description(prog, db))
+        end
+      end
+    end
+  end #module NetTestBlastRemoteCommon
+
+  # This test class only contains tests for meta information.
+  # BLAST execution tests are written in ../test_blast.rb 
+  class NetTestBlastRemoteGenomeNet < Test::Unit::TestCase
+
+    include NetTestBlastRemoteCommon
+
+    BLASTN_DBNAME_KEYWORDS = [ /genes/, /nt/ ]
+    BLASTP_DBNAME_KEYWORDS = [ /genes/, /uniprot/, /nr/ ]
+
+    def setup
+      @klass = Bio::Blast::Remote::GenomeNet
+    end
+  end #class NetTestBlastRemoteGenomeNet
+
+  # This test class only contains tests for meta information.
+  # BLAST execution tests are written in ../test_blast.rb 
+  class NetTestBlastRemoteDDBJ < Test::Unit::TestCase
+
+    include NetTestBlastRemoteCommon
+
+    BLASTN_DBNAME_KEYWORDS = [ /ddbj/i, /nt/i ]
+    BLASTP_DBNAME_KEYWORDS = [ /uniprot/i, /pdb/i ]
+
+    def setup
+      @klass = Bio::Blast::Remote::DDBJ
+    end
+  end #class NetTestBlastRemoteDDBJ
+
+end #module FuncTestBlastRemote
+end #module Bio
+
diff --git a/test/functional/bio/appl/test_blast.rb b/test/functional/bio/appl/test_blast.rb
new file mode 100644
index 0000000..93b4995
--- /dev/null
+++ b/test/functional/bio/appl/test_blast.rb
@@ -0,0 +1,61 @@
+#
+# = test/functional/bio/appl/test_blast.rb - Unit test for Bio::Blast with network connection
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 3,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/sequence'
+require 'bio/appl/blast'
+
+module Bio
+module FunctTestBlast
+
+  module NetTestBlastCommonProteinQuery
+    filename = File.join(BioRubyTestDataPath, 'fasta', 'EFTU_BACSU.fasta')
+    QuerySequence = File.read(filename).freeze
+
+    def test_query
+      report = nil
+      assert_nothing_raised {
+        report = @blast.query(QuerySequence)
+      }
+      assert(report.hits.size > 0)
+    end
+  end #module NetTestBlastCommonProteinQuery
+
+  class NetTestBlast_GenomeNet < Test::Unit::TestCase
+    include NetTestBlastCommonProteinQuery
+
+    def setup
+      @blast = Bio::Blast.new('blastp', 'mine-aa eco',
+                              [ '-e', '1e-10',
+                                '-v', '10',
+                                '-b', '10' ],
+                              'genomenet')
+    end
+  end #class NetTestBlast_GenomeNet
+
+  class NetTestBlast_DDBJ < Test::Unit::TestCase
+    include NetTestBlastCommonProteinQuery
+
+    def setup
+      @blast = Bio::Blast.new('blastp', 'SWISS',
+                              ['-e', '1e-10',
+                              '-v', '10',
+                              '-b', '10' ],
+                              'ddbj')
+    end
+  end #class NetTestBlast_DDBJ
+
+end #module FuncTestBlast
+end #module Bio
+
diff --git a/test/functional/bio/io/test_ddbjrest.rb b/test/functional/bio/io/test_ddbjrest.rb
new file mode 100644
index 0000000..49046a2
--- /dev/null
+++ b/test/functional/bio/io/test_ddbjrest.rb
@@ -0,0 +1,47 @@
+#
+# test/functional/bio/io/test_ddbjrest.rb - Functional test for Bio::DDBJ::REST
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 3,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'bio/io/ddbjrest'
+require 'test/unit'
+
+module Bio
+module NetTestDDBJREST
+
+  class TestDDBJ < Test::Unit::TestCase
+
+    def setup
+      @obj = Bio::DDBJ::REST::DDBJ.new
+    end
+
+    def test_countBasePair
+      text = @obj.countBasePair("AF237819")
+      expected = {
+        "a" => 47,
+        "t" => 38,
+        "g" => 48,
+        "c" => 38
+      }
+      h = {}
+      text.each_line do |line|
+        base, count, percent = line.split(/\t/)
+        count = count.to_i
+        h[base] = count if count > 0
+      end
+      assert_equal(expected, h)
+    end
+
+  end #class TestDDBJ
+
+end #module NetTestDDBJREST
+end #module Bio
diff --git a/test/functional/bio/test_command.rb b/test/functional/bio/test_command.rb
index 5cf1e48..9395501 100644
--- a/test/functional/bio/test_command.rb
+++ b/test/functional/bio/test_command.rb
@@ -96,9 +96,9 @@ module Bio
         @sort = "sort"
         @data = @data.join("\r\n") + "\r\n"
       else
-        @sort = "/usr/bin/sort"
-        unless FileTest.executable?(@sort) then
-          raise "Unsupported environment: /usr/bin/sort not found"
+        @sort = `which sort`.chomp
+        if @sort.empty? or !FileTest.executable?(@sort) then
+          raise "Unsupported environment: sort not found in PATH"
         end
         @data = @data.join("\n") + "\n"
       end
diff --git a/test/unit/bio/db/embl/test_sptr.rb b/test/unit/bio/db/embl/test_sptr.rb
index 83d0e3f..93c42e5 100644
--- a/test/unit/bio/db/embl/test_sptr.rb
+++ b/test/unit/bio/db/embl/test_sptr.rb
@@ -864,12 +864,12 @@ CC       URL="http://www.genetests.org/query?gene=GJB1".'
                     'NAME=Connexin-deafness homepage; URL="http://www.crg.es/deafness/".',
                     'NAME=GeneReviews; URL="http://www.genetests.org/query?gene=GJB1".'],
                    sp.cc['WEB RESOURCE'])
-      assert_equal([{'NAME' => "Inherited peripheral neuropathies mutation db", 
-                     'URL' => 'http://www.molgen.ua.ac.be/CMTMutations/', 'NOTE' => nil},
-                    {'NAME' => "Connexin-deafness homepage", 
-                     'URL' => 'http://www.crg.es/deafness/', 'NOTE' => nil},
-                    {'NAME' => "GeneReviews", 
-                     'URL' => 'http://www.genetests.org/query?gene=GJB1', 'NOTE' => nil}],
+      assert_equal([{'Name' => "Inherited peripheral neuropathies mutation db", 
+                     'URL' => 'http://www.molgen.ua.ac.be/CMTMutations/', 'Note' => nil},
+                    {'Name' => "Connexin-deafness homepage", 
+                     'URL' => 'http://www.crg.es/deafness/', 'Note' => nil},
+                    {'Name' => "GeneReviews", 
+                     'URL' => 'http://www.genetests.org/query?gene=GJB1', 'Note' => nil}],
                    sp.cc('WEB RESOURCE'))
 
     end
diff --git a/test/unit/bio/db/embl/test_uniprot_new_part.rb b/test/unit/bio/db/embl/test_uniprot_new_part.rb
new file mode 100644
index 0000000..24ea552
--- /dev/null
+++ b/test/unit/bio/db/embl/test_uniprot_new_part.rb
@@ -0,0 +1,208 @@
+#
+# test/unit/bio/db/embl/test_uniprot_new_part.rb - Unit test for Bio::UniProt for new file formats using part of psudo entries
+#
+# Copyright::  Copyright (C) 2011 Naohisa Goto <ng at bioruby.org>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/db/embl/uniprot'
+
+module Bio
+  class TestUniProt_ID_since_rel9_0 < Test::Unit::TestCase
+
+    def setup
+      text = "ID   ABC_DEFGH               Reviewed;         256 AA.\n"
+      @obj = Bio::UniProt.new(text)
+    end
+
+    def test_id_line
+      expected = {
+        "ENTRY_NAME" => "ABC_DEFGH",
+        "DATA_CLASS" => "Reviewed",
+        "SEQUENCE_LENGTH" => 256,
+        "MOLECULE_TYPE" => nil
+      }
+      assert_equal(expected, @obj.id_line)
+    end
+
+    def test_entry_id
+      assert_equal("ABC_DEFGH", @obj.entry_id)
+    end
+
+    def test_entry_name
+      assert_equal("ABC_DEFGH", @obj.entry_name)
+    end
+
+    def test_entry
+      assert_equal("ABC_DEFGH", @obj.entry)
+    end
+
+    def test_sequence_length
+      assert_equal(256, @obj.sequence_length)
+    end
+
+    def test_aalen
+      assert_equal(256, @obj.aalen)
+    end
+
+    def test_molecule
+      assert_nil(@obj.molecule)
+    end
+  end #class TestUniProt_ID_since_rel9_0
+
+  class TestUniProt_DE_since_rel14_0 < Test::Unit::TestCase
+
+    def setup
+      text = <<the_end_of_the_text
+ID   ABC_DEFGH               Unreviewed;       256 AA.
+DE   RecName: Full=Aaa Bbbb Ccccc-Dddddd Eeeeeee factor;
+DE            Short=ABC-DEF;
+DE            Short=A-DF;
+DE            EC=9.8.0.1;
+DE   AltName: Full=Bbbb-Aaa Eeeeeee Ccccc;
+DE            Short=Bbbb-Aaa;
+DE            EC=9.8.0.-;
+DE   AltName: Allergen=Bet v 1-B;
+DE   AltName: Biotech=this is fake entry;
+DE   AltName: CD_antigen=CD42c;
+DE   AltName: INN=Pseudo;
+DE   SubName: Full=submitter named this ABC_DEFGH;
+DE            EC=9.8.2.1;
+DE   Includes:
+DE     RecName: Full=Included protein example;
+DE              Short=IPE;
+DE              EC=9.9.9.9;
+DE     AltName: Full=Inclided protein altname;
+DE              Short=IPA;
+DE   Contains:
+DE     RecName: Full=Contained protein alpha chain;
+DE              Short=CPAC;
+DE   Flags: Precursor; Fragment;
+the_end_of_the_text
+
+      @obj = Bio::UniProt.new(text)
+    end
+
+    def test_private_parse_DE_line_rel14
+      expected =
+        [ [ "RecName",
+            ["Full", "Aaa Bbbb Ccccc-Dddddd Eeeeeee factor"],
+            ["Short", "ABC-DEF"],
+            ["Short", "A-DF"],
+            ["EC", "9.8.0.1"]
+          ],
+          [ "AltName",
+            ["Full", "Bbbb-Aaa Eeeeeee Ccccc"],
+            ["Short", "Bbbb-Aaa"],
+            ["EC", "9.8.0.-"]
+          ],
+          [ "AltName",
+            ["Allergen", "Bet v 1-B"]
+          ],
+          [ "AltName",
+            ["Biotech", "this is fake entry"]
+          ],
+          [ "AltName",
+            ["CD_antigen", "CD42c"]
+          ],
+          [ "AltName",
+            ["INN", "Pseudo"]
+          ],
+          [ "SubName",
+            ["Full", "submitter named this ABC_DEFGH"],
+            ["EC", "9.8.2.1"]
+          ],
+          [ "Includes" ],
+          [ "RecName",
+            ["Full", "Included protein example"],
+            ["Short", "IPE"],
+            ["EC", "9.9.9.9"]
+          ],
+          ["AltName",
+           ["Full", "Inclided protein altname"],
+           ["Short", "IPA"]
+          ],
+          [ "Contains" ],
+          [ "RecName",
+            ["Full", "Contained protein alpha chain"],
+            ["Short", "CPAC"]
+          ],
+          [ "Flags",
+            ["Precursor", "Fragment"]
+          ]
+        ]
+      @obj.protein_name
+      ary = @obj.instance_eval { @data['DE'] }
+      assert_equal(expected, ary)
+    end
+
+    def test_protein_name
+      assert_equal('Aaa Bbbb Ccccc-Dddddd Eeeeeee factor',
+                   @obj.protein_name)
+    end
+
+    def test_synonyms
+      expected = [ 'ABC-DEF',
+                   'A-DF',
+                   'EC 9.8.0.1',
+                   'Bbbb-Aaa Eeeeeee Ccccc',
+                   'Bbbb-Aaa',
+                   'EC 9.8.0.-',
+                   'Allergen=Bet v 1-B',
+                   'this is fake entry',
+                   'CD_antigen=CD42c',
+                   'Pseudo',
+                   'submitter named this ABC_DEFGH',
+                   'EC 9.8.2.1'
+                 ]
+      assert_equal(expected, @obj.synonyms)
+    end
+
+  end #class TestUniProt_DE_since_rel14_0
+
+  class TestUniProt_CC_WEB_RESOURCE_since_rel12_2 < Test::Unit::TestCase
+
+    def setup
+      text = <<the_end_of_the_text
+ID   ABC_DEFGH               Unreviewed;       256 AA.
+CC   -!- WEB RESOURCE: Name=BioRuby web site; Note=BioRuby main web site
+CC       located in Tokyo, Japan;
+CC       URL="http://bioruby.org";
+CC   -!- WEB RESOURCE: Name=official mirror of BioRuby web site hosted in
+CC       the Open Bioinformatics Foundation;
+CC       URL="http://bioruby.open-bio.org/";
+CC   -!- WEB RESOURCE: Name=BioRuby Wiki site;
+CC       URL="http://bioruby.open-bio.org/wiki/";
+the_end_of_the_text
+
+      @obj = Bio::UniProt.new(text)
+    end
+
+    def test_cc_web_resource
+      expected =
+        [ { "Name" => "BioRuby web site",
+            "Note" => "BioRuby main web site located in Tokyo, Japan",
+            "URL"  => "http://bioruby.org"
+          },
+          { "Name" => "official mirror of BioRuby web site hosted in the Open Bioinformatics Foundation",
+            "Note" => nil,
+            "URL"  => "http://bioruby.open-bio.org/"
+          },
+          { "Name" => "BioRuby Wiki site",
+            "Note" => nil,
+            "URL"  => "http://bioruby.open-bio.org/wiki/"
+          }
+        ]
+
+      assert_equal(expected, @obj.cc('WEB RESOURCE'))
+    end
+  end #class TestUniProt_CC_WEB_RESOURCE_since_rel12_2
+
+end #module Bio
diff --git a/test/unit/bio/db/genbank/test_common.rb b/test/unit/bio/db/genbank/test_common.rb
new file mode 100644
index 0000000..7f77f05
--- /dev/null
+++ b/test/unit/bio/db/genbank/test_common.rb
@@ -0,0 +1,274 @@
+#
+# test/unit/bio/db/genbank/test_common.rb - Unit test for Bio::NCBIDB::Common
+#
+# Copyright::  Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/db/genbank/common'
+require 'bio/reference'
+require 'bio/compat/references' #  Bio::References in this file seems to be obsolete, but Bio::NCBIDB::Common should require it.
+require 'bio/feature'
+require 'bio/compat/features'    #  Bio::Features in this file seems to be obsolete, but Bio::NCBIDB::Common should require it.
+
+
+# - This class has low coverage, because a sample entry used in it lacks a lot of fields.
+# - There are all the methods for test.
+module Bio
+  class NCBIDB
+    class TestCommon < Test::Unit::TestCase
+
+      #Mock Class including the target module.
+      #BioNCBIDBCommon is used for the test.
+      class BioNCBIDBCommon < Bio::NCBIDB
+        include Bio::NCBIDB::Common
+      end
+
+      #a sample entry is a part of data/genbank/SCU49845.gb
+      def setup
+entry =<<EOF
+LOCUS       SCU49845                5028 bp    DNA     linear   PLN 23-MAR-2010
+DEFINITION  Saccharomyces cerevisiae TCP1-beta gene, partial cds; and Axl2p
+            (AXL2) and Rev7p (REV7) genes, complete cds.
+ACCESSION   U49845
+VERSION     U49845.1  GI:1293613
+KEYWORDS    .
+SOURCE      Saccharomyces cerevisiae (baker's yeast)
+  ORGANISM  Saccharomyces cerevisiae
+            Eukaryota; Fungi; Dikarya; Ascomycota; Saccharomyceta;
+            Saccharomycotina; Saccharomycetes; Saccharomycetales;
+            Saccharomycetaceae; Saccharomyces.
+EOF
+        @obj = BioNCBIDBCommon.new(entry)
+      end
+
+      def test_locus
+        #Since locus method is supposed to be overloaded in a child class, it may not be neccesary to test the method here.
+      end
+      
+      def test_definition
+        expected = "Saccharomyces cerevisiae TCP1-beta gene, partial cds; and Axl2p (AXL2) and Rev7p (REV7) genes, complete cds."
+        assert_equal(expected, @obj.definition)
+      end
+
+      def test_accessions
+         expected = ["U49845"]
+        assert_equal(expected, @obj.accessions)
+      end
+
+      def test_accession
+         expected = "U49845"
+        assert_equal(expected, @obj.accession)
+      end
+
+      def test_versions
+         expected = ["U49845.1", "GI:1293613"]
+        assert_equal(expected, @obj.versions)
+      end
+
+      def test_version
+         expected = 1 
+        assert_equal(expected, @obj.version)
+      end
+
+      def test_acc_version
+         expected = "U49845.1"
+        assert_equal(expected, @obj.acc_version)
+      end
+
+      def test_gi
+         expected = "GI:1293613"
+        assert_equal(expected, @obj.gi)
+      end
+
+      def test_nid
+         expected = ""
+        assert_equal(expected, @obj.nid)
+      end
+
+      def test_keywords
+         expected = []
+        assert_equal(expected, @obj.keywords)
+      end
+
+      def test_segment
+         expected = ""
+        assert_equal(expected, @obj.segment)
+      end
+
+      def test_source
+         expected = {"organism"=>"Saccharomyces cerevisiae",
+                           "common_name"=>"Saccharomyces cerevisiae (baker's yeast)",
+                           "taxonomy"=>
+                                "Eukaryota; Fungi; Dikarya; Ascomycota; Saccharomyceta; Saccharomycotina; Saccharomycetes; Saccharomycetales; Saccharomycetaceae; Saccharomyces."}
+        assert_equal(expected, @obj.source)
+
+        #another pattern to pass line 103-105
+        source_pattern2 =<<EOS
+SOURCE      Saccharomyces cerevisiae (baker's yeast)
+  ORGANISM  Saccharomyces cerevisiae
+            Saccharomyces.
+EOS
+        obj2 = BioNCBIDBCommon.new(source_pattern2)
+          expected2 = {"organism"=>"Saccharomyces cerevisiae",
+                       "common_name"=>"Saccharomyces cerevisiae (baker's yeast)",
+                       "taxonomy"=>"Saccharomyces."}
+        assert_equal(expected2, obj2.source)
+
+        #the other pattern to pass line 106-109
+        source_pattern3 =<<EOS
+SOURCE      Saccharomyces cerevisiae (baker's yeast)
+  ORGANISM  Saccharomyces cerevisiae
+EOS
+        obj3 = BioNCBIDBCommon.new(source_pattern3)
+          expected3 = {"organism"=>"Saccharomyces cerevisiae",
+                       "common_name"=>"Saccharomyces cerevisiae (baker's yeast)",
+                       "taxonomy"=>""}
+        assert_equal(expected3, obj3.source)
+      end
+
+      def test_common_name
+         expected = "Saccharomyces cerevisiae (baker's yeast)"
+        assert_equal(expected, @obj.common_name)
+      end
+
+      def test_organism
+         expected = "Saccharomyces cerevisiae"
+        assert_equal(expected, @obj.organism)
+      end
+
+      def test_taxonomy
+         expected = "Eukaryota; Fungi; Dikarya; Ascomycota; Saccharomyceta; Saccharomycotina; Saccharomycetes; Saccharomycetales; Saccharomycetaceae; Saccharomyces."
+        assert_equal(expected, @obj.taxonomy)
+      end
+
+      def test_references
+        str=<<EOS
+REFERENCE   2  (bases 1 to 2264)
+  AUTHORS   Zhao,X., Brade,T., Cunningham,T.J. and Duester,G.
+  TITLE     Retinoic acid controls expression of tissue remodeling genes Hmgn1
+            and Fgf18 at the digit-interdigit junction
+  JOURNAL   Dev. Dyn. 239 (2), 665-671 (2010)
+   PUBMED   20034106
+  REMARK    GeneRIF: limited to the digit-interdigit junction rather than being
+            expressed throughout the interdigital zone
+EOS
+        com = BioNCBIDBCommon.new(str)
+        obj = com.references
+         expected = 
+           {:mesh=>[],
+            :volume=>"239",
+            :doi=>nil,
+            :pages=>"665-671",
+            :embl_gb_record_number=>2,
+            :pubmed=>"20034106",
+            :abstract=>"",
+            :issue=>"2",
+            :year=>"2010",
+            :sequence_position=>"1-2264",
+            :affiliations=>[],
+            :journal=>"Dev. Dyn.",
+            :title=>
+             "Retinoic acid controls expression of tissue remodeling genes Hmgn1 and Fgf18 at the digit-interdigit junction",
+            :authors=>["Zhao, X.", "Brade, T.", "Cunningham, T.J.", "Duester, G."],
+            :medline=>"",
+            :url=>nil,
+            :comments=>
+             ["GeneRIF: limited to the digit-interdigit junction rather than being expressed throughout the interdigital zone"]}  
+        actual            = {:abstract => obj[0].abstract,
+                             :affiliations => obj[0].affiliations,
+                             :authors => obj[0].authors,
+                             :comments => obj[0].comments,
+                             :doi => obj[0].doi,
+                             :embl_gb_record_number => obj[0].embl_gb_record_number,
+                             :issue => obj[0].issue,
+                             :journal =>  obj[0].journal,
+                             :medline => obj[0].medline,
+                             :mesh => obj[0].mesh,
+                             :pages => obj[0].pages,
+                             :pubmed => obj[0].pubmed,
+                             :sequence_position => obj[0].sequence_position,
+                             :title => obj[0].title,
+                             :url => obj[0].url,
+                             :volume => obj[0].volume,
+                             :year => obj[0].year}
+      assert_equal(expected, actual)
+        actual2 = ""
+      com.references do |reference|
+        actual2 = reference.authors
+        break
+      end
+      assert_equal(["Zhao, X.", "Brade, T.", "Cunningham, T.J.", "Duester, G."],actual2) 
+
+      
+      #the other pattern where a journal doesn't match the regexp.
+      ref=<<EOS
+REFERENCE   2  (bases 1 to 2264)
+  JOURNAL   testcase
+EOS
+      obj2 = BioNCBIDBCommon.new(ref)
+      actual3 = obj2.references[0].journal
+      assert_equal("testcase",actual3)
+      end
+
+      def test_comment
+         expected = ""
+        assert_equal(expected, @obj.comment)
+      end
+
+      def test_features
+        expected =
+        {:feature=>"CDS",
+         :position=>"<1..206",
+         :qualifiers=>
+          [{:qualifier=>"product",
+           :value=>"TCP1-beta"},
+           {:value=>3, :qualifier=>"codon_start"},
+           {:qualifier=>"translation",
+            :value=>
+             "SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEAAEVLLRVDNIIRARPRTANRQHM"}]}
+        fet =<<EOS
+FEATURES             Location/Qualifiers
+     CDS             <1..206
+                     /product="TCP1-beta"
+                     /codon_start=3
+                     /translation="SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEA
+                     AEVLLRVDNIIRARPRTANRQHM"
+EOS
+        obj = BioNCBIDBCommon.new(fet)
+        actual =
+        {:feature=>obj.features[0].feature,
+         :position=>obj.features[0].position,
+         :qualifiers=>
+           [{:qualifier=>obj.features[0].qualifiers[0].qualifier,
+             :value=>obj.features[0].qualifiers[0].value},
+            {:qualifier=>obj.features[0].qualifiers[1].qualifier,
+             :value=>
+              obj.features[0].qualifiers[1].value},
+            {:qualifier=>obj.features[0].qualifiers[2].qualifier,
+             :value=>
+              obj.features[0].qualifiers[2].value}]}
+        assert_equal(expected, actual)
+          actual2 = ""
+        obj.features do |feature|
+          actual2 = feature.feature
+        end
+          
+          assert_equal("CDS", actual2)
+      end
+
+      def test_origin
+         expected = ""
+        assert_equal(expected, @obj.origin)
+      end
+
+    end
+  end
+end
diff --git a/test/unit/bio/db/genbank/test_genbank.rb b/test/unit/bio/db/genbank/test_genbank.rb
new file mode 100644
index 0000000..416a4db
--- /dev/null
+++ b/test/unit/bio/db/genbank/test_genbank.rb
@@ -0,0 +1,401 @@
+#
+# test/unit/bio/db/genbank/test_genbank.rb - Unit test for Bio::GenBank
+#
+# Copyright::  Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/sequence'
+require 'bio/reference'
+require 'bio/feature'
+require 'bio/compat/features'
+require 'bio/compat/references'
+require 'bio/db/genbank/genbank'
+require 'bio/db/genbank/genbank_to_biosequence'
+
+
+module Bio
+  class TestBioGenBank < Test::Unit::TestCase
+
+    def setup
+      filename = File.join(BioRubyTestDataPath, 'genbank', 'SCU49845.gb')
+      @obj = Bio::GenBank.new(File.read(filename))
+    end
+
+    def test_locus_class
+      expected = Bio::GenBank::Locus
+      assert_equal(expected, @obj.locus.class)
+      locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"#another type of LOCUS line.(release 126)
+      obj_rel126 = Bio::GenBank.new(locus_rel126)
+      assert_equal(Bio::GenBank::Locus, obj_rel126.locus.class)
+    end
+    def test_locus_circular
+       expected = "linear"
+       assert_equal(expected, @obj.locus.circular)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("circular", obj_rel126.locus.circular)
+    end
+    def test_locus_date
+       expected = "23-MAR-2010"
+       assert_equal(expected, @obj.locus.date)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("05-FEB-1999", obj_rel126.locus.date)
+    end
+    def test_locus_division
+       expected = "PLN"
+       assert_equal(expected, @obj.locus.division)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("VRL", obj_rel126.locus.division)
+    end
+    def test_locus_entry_id
+       expected = "SCU49845"
+       assert_equal(expected, @obj.locus.entry_id)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("AB000383", obj_rel126.locus.entry_id)
+    end
+    def test_locus_length
+       expected = 5028
+       assert_equal(expected, @obj.locus.length)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal(5423, obj_rel126.locus.length)
+    end
+    def test_locus_natype
+       expected = "DNA"
+       assert_equal(expected, @obj.locus.natype)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("DNA", obj_rel126.locus.natype)
+    end
+    def test_locus_strand
+       expected = ""
+       assert_equal(expected, @obj.locus.strand)
+       locus_rel126 = "LOCUS       AB000383     5423 bp    DNA   circular  VRL       05-FEB-1999"
+       obj_rel126 = Bio::GenBank.new(locus_rel126)
+       assert_equal("", obj_rel126.locus.strand)
+    end
+    def test_entry_id
+      assert_equal("SCU49845", @obj.entry_id)
+    end
+
+    def test_length
+      assert_equal(5028, @obj.length)
+    end
+
+    def test_circular
+      assert_equal("linear", @obj.circular)
+    end
+
+    def test_division
+      assert_equal("PLN", @obj.division)
+    end
+
+    def test_date
+      assert_equal("23-MAR-2010", @obj.date)
+    end
+
+    def test_strand
+      assert_equal("", @obj.strand)
+    end
+
+    def test_natype
+      assert_equal("DNA", @obj.natype)
+    end
+
+    def test_each_cds_feature
+      @obj.each_cds do |feature|
+        assert_equal("CDS", feature.feature)
+      end
+    end
+=begin
+    def test_each_cds_qualifiers
+      @obj.each_cds do |feature|
+        feature.qualifiers do |qualifier|
+          assert_equal(Bio::Feature::Qualifier, qualifier.class)
+        end
+      end
+    end
+=end
+    def test_each_cds_qualifiers
+      expected = [[["codon_start", 3],
+                ["product", "TCP1-beta"],
+                ["protein_id", "AAA98665.1"],
+                ["db_xref", "GI:1293614"],
+                ["translation", "SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEAAEVLLRVDNIIRARPRTANRQHM"]],
+                [["gene", "AXL2"],
+                ["note", "plasma membrane glycoprotein"],
+                ["codon_start", 1],
+                ["product", "Axl2p"],
+                ["protein_id", "AAA98666.1"],
+                ["db_xref", "GI:1293615"],
+                ["translation", "MTQLQISLLLTATISLLHLVVATPYEAYPIGKQYPPVARVNESFTFQISNDTYKSSVDKTAQITYNCFDLPSWLSFDSSSRTFSGEPSSDLLSDANTTLYFNVILEGTDSADSTSLNNTYQFVVTNRPSISLSSDFNLLALLKNYGYTNGKNALKLDPNEVFNVTFDRSMFTNEESIVSYYGRSQLYNAPLPNWLFFDSGELKFTGTAPVINSAIAPETSYSFVIIATDIEGFSAVEVEFELVIGAHQLTTSIQNSLIINVTDTGNVSYDLPLNYVYLDDDPISSDKLGSINLLDAPDWVALDNATISGSVPDELLGKNSNPANFSVSIYDTYGDVIYFNFEVVSTTDLFAISSLPNINATRGEWFSYYFLPSQFTDYVNTNVSLEFTNSSQDHDWVKFQSSNLTLAGEVPKNFDKLSLGLKANQGSQSQELYFNIIGMDSKITHSNHSANATSTRSSHHSTSTSSYTSSTYTAKISSTSAAATSSAPAALPAANKTSSHNKKAVAIACGVAIPLGVILVALICFLIFWRRRRENPDDENLPHAISGPDLNNPANKPNQENATPLNNPFDDDASSYDDTSIARRLAALNTLKLDNHSATESDISSVDEKRDSLSGMNTYNDQFQSQSKEELLAKPPVQPPESPFFDPQNRSSSVYMDSEPAVNKSWRYTGNLSPVSDIVRDSYGSQKTVDTEKLFDLEAPEKEKRTSRDVTMSSLDPWNSNISPSPVRKSVTPSPYNVTKHRNRHLQNIQDSQSGKNGITPTTMSTSSSDDFVPVKDGENFCWVHSMEPDRRPSKKRLVDFSNKSNVNVGQVKDIHGRIPEML"]],
+               [["gene", "REV7"],
+                ["codon_start", 1],
+                ["product", "Rev7p"],
+                ["protein_id", "AAA98667.1"],
+                ["db_xref", "GI:1293616"],
+["translation", "MNRWVEKWLRVYLKCYINLILFYRNVYPPQSFDYTTYQSFNLPQFVPINRHPALIDYIEELILDVLSKLTHVYRFSICIINKKNDLCIEKYVLDFSELQHVDKDDQIITETEVFDEFRSSLNSLIMHLEKLPKVNDDTITFEAVINAIELELGHKLDRNRRVDSLEEKAEIERDSNWVKCQEDENLPDNNGFQPPKIKLTSLVGSDVGPLIIHQFSEKLISGDDKILNGVYSQYEEGESIFGSLF"]]]
+      actual = []
+      @obj.each_cds do |feature|
+        tmp = []
+        feature.qualifiers.each{|qualifier| 
+          tmp << [qualifier.qualifier, qualifier.value]
+        }
+        actual << tmp
+      end
+      assert_equal(expected, actual)
+    end
+    def test_each_gene
+      expected_position = ["<687..>3158", "complement(<3300..>4037)"]
+      expected_gene = [["gene","AXL2"], ["gene","REV7"]]
+      actual_position = []
+      actual_gene = []
+      @obj.each_gene do |gene| 
+        assert_equal("gene", gene.feature)
+        actual_position << gene.position
+        gene.qualifiers.each do |qualifier| 
+          actual_gene << [qualifier.qualifier, qualifier.value]
+        end
+      end
+      assert_equal(expected_position,actual_position)
+      assert_equal(expected_gene, actual_gene)
+    end
+
+    def test_basecount
+      assert_equal({}, @obj.basecount)
+    end
+
+    def test_seq
+      expected = "gatcctccatatacaacggtatctccacctcaggtttagatctcaacaacggaaccattgccgacatgagacagttaggtatcgtcgagagttacaagctaaaacgagcagtagtcagctctgcatctgaagccgctgaagttctactaagggtggataacatcatccgtgcaagaccaagaaccgccaatagacaacatatgtaacatatttaggatatacctcgaaaataataaaccgccacactgtcattattataattagaaacagaacgcaaaaattatccactatataattcaaagacgcgaaaaaaaaagaacaacgcgtcatagaacttttggcaattcgcgtcacaaataaattttggcaacttatgtttcctcttcgagcagtactcgagccctgtctcaagaatgtaataatacccatcgtaggtatggttaaagatagcatctccacaacctcaaagctccttgccgagagtcgccctcctttgtcgagtaattttcacttttcatatgagaacttattttcttattctttactctcacatcctgtagtgattgacactgcaacagccaccatcactagaagaacagaacaattacttaatagaaaaattatatcttcctcgaaacgatttcctgcttccaacatctacgtatatcaagaagcattcacttaccatgacacagcttcagatttcattattgctgacagctactatatcactactccatctagtagtggccacgccctatgaggcatatcctatcggaaaacaataccccccagtggcaagagtcaatgaatcgtttacatttcaaatttccaatgatacctataaatcgtctgtagacaagacagctcaaataacatacaattgcttcgacttaccgagctggctttcgtttgactctagttctagaacgttctcaggtgaaccttcttctgacttactatctgatgcgaacaccacgttgtatttcaatgtaatactcgagggtacggactctgccgacagcacgtctttgaacaatacataccaatttgttgttacaaaccgtccatccatctcgctatcgtcagatttcaatctattggcgttgttaaaaaactatggttatactaacggcaaaaacgctctgaaactagatcctaatgaagtcttcaacgtgacttttgaccgttcaatgttcactaacgaagaatccattgtgtcgtattacggacgttctcagttgtataatgcgccgttacccaattggctgttcttcgattctggcgagttgaagtttactgggacggcaccggtgataaactcggcgattgctccagaaacaagctacagttttgtcatcatcgctacagacattgaaggattttctgccgttgaggtagaattcgaattagtcatcggggctcaccagttaactacctctattcaaaatagtttgataatcaacgttactgacacaggtaacgtttcatatgacttacctctaaactatgtttatctcgatgacgatcctatttcttctgataaattgggttctataaacttattggatgctccagactgggtggcattagataatgctaccatttccgggtctgtcccagatgaattactcggtaagaactccaatcctgccaatttttctgtgtccatttatgatacttatggtgatgtgatttatttcaacttcgaagttgtctccacaacggatttgtttgccattagttctcttcccaatattaacgctacaaggggtgaatggttctcctactattttttgccttctcagtttacagactacgtgaatacaaacgtttcattagagtttactaattcaagccaagaccatgactgggtgaaattccaatcatctaatttaacattagctggagaagtgcccaagaatttcgacaagctttcattaggtttgaaagcgaaccaaggttcacaatctcaagagctatattttaacatcattggcatggattcaaagataactcactcaaaccacagtgcgaatgcaacgtccacaagaagttctcaccactccacctcaacaagttcttacacatcttctacttacactgcaaaaatttcttctacctccgctgctgctacttcttctgctccagcagcgctgccagcagccaataaaacttcatctcacaataaaaaagcagtagcaattgcgtgcggtgttgctatcccattaggcgttatcctagtagctctcatttgcttcctaatattctggagacgcagaagggaaaatccagacgatgaaaacttaccgcatgctattagtggacctgatttgaataatcctgcaaataaaccaaatcaagaaaacgctacacctttgaacaacccctttgatgatgatgcttcctcgtacgatgatacttcaatagcaagaagattggctgctttgaacactttgaaattggataaccactctgccactgaatctgatatttccagcgtggatgaaaagagagattctctatcaggtatgaatacatacaatgatcagttccaatcccaaagtaaagaagaattattagcaaaacccccagtacagcctccagagagcccgttctttgacccacagaataggtcttcttctgtgtatatggatagtgaaccagcagtaaataaatcctggcgatatactggcaacctgtcaccagtctctgatattgtcagagacagttacggatcacaaaaaactgttgatacagaaaaacttttcgatttagaagcaccagagaaggaaaaacgtacgtcaagggatgtcactatgtcttcactggacccttggaacagcaatattagcccttctcccgtaagaaaatcagtaacaccatcaccatataacgtaacgaagcatcgtaaccgccacttacaaaatattcaagactctcaaagcggtaaaaacggaatcactcccacaacaatgtcaacttcatcttctgacgattttgttccggttaaagatggtgaaaatttttgctgggtccatagcatggaaccagacagaagaccaagtaagaaaaggttagtagatttttcaaataagagtaatgtcaatgttggtcaagttaaggacattcacggacgcatcccagaaatgctgtgattatacgcaacgatattttgcttaattttattttcctgttttattttttattagtggtttacagataccctatattttatttagtttttatacttagagacatttaattttaattccattcttcaaatttcatttttgcacttaaaacaaagatccaaaaatgctctcgccctcttcatattgagaatacactccattcaaaattttgtcgtcaccgctgattaatttttcactaaactgatgaataatcaaaggccccacgtcagaaccgactaaagaagtgagttttattttaggaggttgaaaaccattattgtctggtaaattttcatcttcttgacatttaacccagtttgaatccctttcaatttctgctttttcctccaaactatcgaccctcctgtttctgtccaacttatgtcctagttccaattcgatcgcattaataactgcttcaaatgttattgtgtcatcgttgactttaggtaatttctccaaatgcataatcaaactatttaaggaagatcggaattcgtcgaacacttcagtttccgtaatgatctgatcgtctttatccacatgttgtaattcactaaaatctaaaacgtatttttcaatgcataaatcgttctttttattaataatgcagatggaaaatctgtaaacgtgcgttaatttagaaagaacatccagtataagttcttctatatagtcaattaaagcaggatgcctattaatgggaacgaactgcggcaagttgaatgactggtaagtagtgtagtcgaatgactgaggtgggtatacatttctataaaataaaatcaaattaatgtagcattttaagtataccctcagccacttctctacccatctattcataaagctgacgcaacgattactattttttttttcttcttggatctcagtcgtcgcaaaaacgtataccttctttttccgaccttttttttagctttctggaaaagtttatattagttaaacagggtctagtcttagtgtgaaagctagtggtttcgattgactgatattaagaaagtggaaattaaattagtagtgtagacgtatatgcatatgtatttctcgcctgtttatgtttctacgtacttttgatttatagcaaggggaaaagaaatacatactattttttggtaaaggtgaaagcataatgtaaaagctagaataaaatggacgaaataaagagaggcttagttcatcttttttccaaaaagcacccaatgataataactaaaatgaaaaggatttgccatctgtcagcaacatcagttgtgtgagcaataataaaatcatcacctccgttgcctttagcgcgtttgtcgtttgtatcttccgtaattttagtcttatcaatgggaatcataaattttccaatgaattagcaatttcgtccaattctttttgagcttcttcatatttgctttggaattcttcgcacttcttttcccattcatctctttcttcttccaaagcaacgatccttctacccatttgctcagagttcaaatcggcctctttcagtttatccattgcttccttcagtttggcttcactgtcttctagctgttgttctagatcctggtttttcttggtgtagttctcattattagatctcaagttattggagtcttcagccaattgctttgtatcagacaattgactctctaacttctccacttcactgtcgagttgctcgtttttagcggacaaagatttaatctcgttttctttttcagtgttagattgctctaattctttgagctgttctctcagctcctcatatttttcttgccatgactcagattctaattttaagctattcaatttctctttgatc"
+      assert_equal(expected, @obj.seq)
+    end
+
+    def test_seq_len
+      assert_equal(5028, @obj.seq_len)
+    end
+
+    def test_date_modified
+      assert_equal(Date, @obj.date_modified.class)
+      assert_equal('2010-03-23', @obj.date_modified.to_s)
+    end
+ 
+   def test_classification
+      expected = ["Eukaryota",
+ "Fungi",
+ "Dikarya",
+ "Ascomycota",
+ "Saccharomyceta",
+ "Saccharomycotina",
+ "Saccharomycetes",
+ "Saccharomycetales",
+ "Saccharomycetaceae",
+ "Saccharomyces"]
+      assert_equal(expected, @obj.classification)
+    end
+
+    def test_strandedness
+      assert_equal(nil, @obj.strandedness)
+    end
+
+    #test for bio_to_sequence
+    def test_to_biosequence
+      seq = @obj.to_biosequence
+      expected_seq = "gatcctccatatacaacggtatctccacctcaggtttagatctcaacaacggaaccattgccgacatgagacagttaggtatcgtcgagagttacaagctaaaacgagcagtagtcagctctgcatctgaagccgctgaagttctactaagggtggataacatcatccgtgcaagaccaagaaccgccaatagacaacatatgtaacatatttaggatatacctcgaaaataataaaccgccacactgtcattattataattagaaacagaacgcaaaaattatccactatataattcaaagacgcgaaaaaaaaagaacaacgcgtcatagaacttttggcaattcgcgtcacaaataaattttggcaacttatgtttcctcttcgagcagtactcgagccctgtctcaagaatgtaataatacccatcgtaggtatggttaaagatagcatctccacaacctcaaagctccttgccgagagtcgccctcctttgtcgagtaattttcacttttcatatgagaacttattttcttattctttactctcacatcctgtagtgattgacactgcaacagccaccatcactagaagaacagaacaattacttaatagaaaaattatatcttcctcgaaacgatttcctgcttccaacatctacgtatatcaagaagcattcacttaccatgacacagcttcagatttcattattgctgacagctactatatcactactccatctagtagtggccacgccctatgaggcatatcctatcggaaaacaataccccccagtggcaagagtcaatgaatcgtttacatttcaaatttccaatgatacctataaatcgtctgtagacaagacagctcaaataacatacaattgcttcgacttaccgagctggctttcgtttgactctagttctagaacgttctcaggtgaaccttcttctgacttactatctgatgcgaacaccacgttgtatttcaatgtaatactcgagggtacggactctgccgacagcacgtctttgaacaatacataccaatttgttgttacaaaccgtccatccatctcgctatcgtcagatttcaatctattggcgttgttaaaaaactatggttatactaacggcaaaaacgctctgaaactagatcctaatgaagtcttcaacgtgacttttgaccgttcaatgttcactaacgaagaatccattgtgtcgtattacggacgttctcagttgtataatgcgccgttacccaattggctgttcttcgattctggcgagttgaagtttactgggacggcaccggtgataaactcggcgattgctccagaaacaagctacagttttgtcatcatcgctacagacattgaaggattttctgccgttgaggtagaattcgaattagtcatcggggctcaccagttaactacctctattcaaaatagtttgataatcaacgttactgacacaggtaacgtttcatatgacttacctctaaactatgtttatctcgatgacgatcctatttcttctgataaattgggttctataaacttattggatgctccagactgggtggcattagataatgctaccatttccgggtctgtcccagatgaattactcggtaagaactccaatcctgccaatttttctgtgtccatttatgatacttatggtgatgtgatttatttcaacttcgaagttgtctccacaacggatttgtttgccattagttctcttcccaatattaacgctacaaggggtgaatggttctcctactattttttgccttctcagtttacagactacgtgaatacaaacgtttcattagagtttactaattcaagccaagaccatgactgggtgaaattccaatcatctaatttaacattagctggagaagtgcccaagaatttcgacaagctttcattaggtttgaaagcgaaccaaggttcacaatctcaagagctatattttaacatcattggcatggattcaaagataactcactcaaaccacagtgcgaatgcaacgtccacaagaagttctcaccactccacctcaacaagttcttacacatcttctacttacactgcaaaaatttcttctacctccgctgctgctacttcttctgctccagcagcgctgccagcagccaataaaacttcatctcacaataaaaaagcagtagcaattgcgtgcggtgttgctatcccattaggcgttatcctagtagctctcatttgcttcctaatattctggagacgcagaagggaaaatccagacgatgaaaacttaccgcatgctattagtggacctgatttgaataatcctgcaaataaaccaaatcaagaaaacgctacacctttgaacaacccctttgatgatgatgcttcctcgtacgatgatacttcaatagcaagaagattggctgctttgaacactttgaaattggataaccactctgccactgaatctgatatttccagcgtggatgaaaagagagattctctatcaggtatgaatacatacaatgatcagttccaatcccaaagtaaagaagaattattagcaaaacccccagtacagcctccagagagcccgttctttgacccacagaataggtcttcttctgtgtatatggatagtgaaccagcagtaaataaatcctggcgatatactggcaacctgtcaccagtctctgatattgtcagagacagttacggatcacaaaaaactgttgatacagaaaaacttttcgatttagaagcaccagagaaggaaaaacgtacgtcaagggatgtcactatgtcttcactggacccttggaacagcaatattagcccttctcccgtaagaaaatcagtaacaccatcaccatataacgtaacgaagcatcgtaaccgccacttacaaaatattcaagactctcaaagcggtaaaaacggaatcactcccacaacaatgtcaacttcatcttctgacgattttgttccggttaaagatggtgaaaatttttgctgggtccatagcatggaaccagacagaagaccaagtaagaaaaggttagtagatttttcaaataagagtaatgtcaatgttggtcaagttaaggacattcacggacgcatcccagaaatgctgtgattatacgcaacgatattttgcttaattttattttcctgttttattttttattagtggtttacagataccctatattttatttagtttttatacttagagacatttaattttaattccattcttcaaatttcatttttgcacttaaaacaaagatccaaaaatgctctcgccctcttcatattgagaatacactccattcaaaattttgtcgtcaccgctgattaatttttcactaaactgatgaataatcaaaggccccacgtcagaaccgactaaagaagtgagttttattttaggaggttgaaaaccattattgtctggtaaattttcatcttcttgacatttaacccagtttgaatccctttcaatttctgctttttcctccaaactatcgaccctcctgtttctgtccaacttatgtcctagttccaattcgatcgcattaataactgcttcaaatgttattgtgtcatcgttgactttaggtaatttctccaaatgcataatcaaactatttaaggaagatcggaattcgtcgaacacttcagtttccgtaatgatctgatcgtctttatccacatgttgtaattcactaaaatctaaaacgtatttttcaatgcataaatcgttctttttattaataatgcagatggaaaatctgtaaacgtgcgttaatttagaaagaacatccagtataagttcttctatatagtcaattaaagcaggatgcctattaatgggaacgaactgcggcaagttgaatgactggtaagtagtgtagtcgaatgactgaggtgggtatacatttctataaaataaaatcaaattaatgtagcattttaagtataccctcagccacttctctacccatctattcataaagctgacgcaacgattactattttttttttcttcttggatctcagtcgtcgcaaaaacgtataccttctttttccgaccttttttttagctttctggaaaagtttatattagttaaacagggtctagtcttagtgtgaaagctagtggtttcgattgactgatattaagaaagtggaaattaaattagtagtgtagacgtatatgcatatgtatttctcgcctgtttatgtttctacgtacttttgatttatagcaaggggaaaagaaatacatactattttttggtaaaggtgaaagcataatgtaaaagctagaataaaatggacgaaataaagagaggcttagttcatcttttttccaaaaagcacccaatgataataactaaaatgaaaaggatttgccatctgtcagcaacatcagttgtgtgagcaataataaaatcatcacctccgttgcctttagcgcgtttgtcgtttgtatcttccgtaattttagtcttatcaatgggaatcataaattttccaatgaattagcaatttcgtccaattctttttgagcttcttcatatttgctttggaattcttcgcacttcttttcccattcatctctttcttcttccaaagcaacgatccttctacccatttgctcagagttcaaatcggcctctttcagtttatccattgcttccttcagtttggcttcactgtcttctagctgttgttctagatcctggtttttcttggtgtagttctcattattagatctcaagttattggagtcttcagccaattgctttgtatcagacaattgactctctaacttctccacttcactgtcgagttgctcgtttttagcggacaaagatttaatctcgttttctttttcagtgttagattgctctaattctttgagctgttctctcagctcctcatatttttcttgccatgactcagattctaattttaagctattcaatttctctttgatc"
+      expected_id_namespace = "GenBank"
+      expected_entry_id = "SCU49845"
+      expected_primary_accession = "U49845"
+      expected_secondary_accessions = []
+      expected_other_seqids = ["1293613", "GI", []]
+      expected_molecule_type = "DNA"
+      expected_division = "PLN"
+      expected_topology = "linear"
+      expected_strandedness = nil
+      expected_keywords = []
+      expected_sequence_version = "1"
+      expected_date_modified = "2010-03-23"
+      expected_definition = "Saccharomyces cerevisiae TCP1-beta gene, partial cds; and Axl2p (AXL2) and Rev7p (REV7) genes, complete cds."
+      expected_species = []
+      expected_classification= ["Eukaryota", "Fungi", "Dikarya", "Ascomycota", "Saccharomyceta", "Saccharomycotina", "Saccharomycetes", "Saccharomycetales", "Saccharomycetaceae", "Saccharomyces"]
+      expected_comments = ""
+      expected_references = [{
+  :abstract=>"",
+  :affiliations=>[],
+  :authors=>["Roemer, T.", "Madden, K.", "Chang, J.", "Snyder, M."],
+  :comments=>nil,
+  :doi=>nil,
+  :embl_gb_record_number=>1,
+  :issue=>"7",
+  :journal=>"Genes Dev.",
+  :medline=>"",
+  :mesh=>[],
+  :pages=>"777-793",
+  :pubmed=>"8846915",
+  :sequence_position=>"1-5028",
+  :title=>
+   "Selection of axial growth sites in yeast requires Axl2p, a novel plasma membrane glycoprotein",
+  :url=>nil,
+  :volume=>"10",
+  :year=>"1996"},
+
+  {:abstract=>"",
+  :affiliations=>[],
+  :authors=>["Roemer, T."],
+  :comments=>nil,
+  :doi=>nil,
+  :embl_gb_record_number=>2,
+  :issue=>"",
+  :journal=>
+   "Submitted (22-FEB-1996) Biology, Yale University, New Haven, CT 06520, USA",
+  :medline=>"",
+  :mesh=>[],
+  :pages=>"",
+  :pubmed=>"",
+  :sequence_position=>"1-5028",
+  :title=>"Direct Submission",
+  :url=>nil,
+  :volume=>"",
+  :year=>""}]
+
+      expected_features = [
+ {:feature=>"source",
+  :position=>"1..5028",
+  :qualifiers=>
+   [{:qualifier=>"organism",
+     :value=>"Saccharomyces cerevisiae"},
+    {:qualifier=>"mol_type",
+     :value=>"genomic DNA"},
+    {:qualifier=>"db_xref",
+     :value=>"taxon:4932"},
+    {:qualifier=>"chromosome",
+      :value=>"IX"}]},
+  {:feature=>"mRNA",
+   :position=>"<1..>206",
+   :qualifiers=>
+   [{   
+     :qualifier=>"product",
+     :value=>"TCP1-beta"}]},
+  {:feature=>"CDS",
+   :position=>"<1..206",
+   :qualifiers=>   [{:qualifier=>"codon_start", :value=>3},    {:qualifier=>"product",     :value=>"TCP1-beta"},
+    {:qualifier=>"protein_id",
+     :value=>"AAA98665.1"},
+    {:qualifier=>"db_xref",
+     :value=>"GI:1293614"},
+    {:qualifier=>"translation",
+     :value=>
+      "SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEAAEVLLRVDNIIRARPRTANRQHM"}]},
+  {:feature=>"gene",
+   :position=>"<687..>3158",
+   :qualifiers=>
+   [{:qualifier=>"gene", :value=>"AXL2"}]},
+  {:feature=>"mRNA",
+   :position=>"<687..>3158",
+   :qualifiers=>
+   [{:qualifier=>"gene", :value=>"AXL2"},
+   {:qualifier=>"product",
+    :value=>"Axl2p"}]},
+  {:feature=>"CDS",
+   :position=>"687..3158",
+   :qualifiers=>
+   [{:qualifier=>"gene", :value=>"AXL2"},
+   {:qualifier=>"note",
+    :value=>"plasma membrane glycoprotein"},
+   {:qualifier=>"codon_start", :value=>1},   {:qualifier=>"product",
+     :value=>"Axl2p"},
+   {:qualifier=>"protein_id",
+    :value=>"AAA98666.1"},
+   {:qualifier=>"db_xref",
+    :value=>"GI:1293615"},
+   {:qualifier=>"translation",
+    :value=>
+      "MTQLQISLLLTATISLLHLVVATPYEAYPIGKQYPPVARVNESFTFQISNDTYKSSVDKTAQITYNCFDLPSWLSFDSSSRTFSGEPSSDLLSDANTTLYFNVILEGTDSADSTSLNNTYQFVVTNRPSISLSSDFNLLALLKNYGYTNGKNALKLDPNEVFNVTFDRSMFTNEESIVSYYGRSQLYNAPLPNWLFFDSGELKFTGTAPVINSAIAPETSYSFVIIATDIEGFSAVEVEFELVIGAHQLTTSIQNSLIINVTDTGNVSYDLPLNYVYLDDDPISSDKLGSINLLDAPDWVALDNATISGSVPDELLGKNSNPANFSVSIYDTYGDVIYFNFEVVSTTDLFAISSLPNINATRGEWFSYYFLPSQFTDYVNTNVSLEFTNSSQDHDWVKFQSSNLTLAGEVPKNFDKLSLGLKANQGSQSQELYFNIIGMDSKITHSNHSANATSTRSSHHSTSTSSYTSSTYTAKISSTSAAATSSAPAALPAANKTSSHNKKAVAIACGVAIPLGVILVALICFLIFWRRRRENPDDENLPHAISGPDLNNPANKPNQENATPLNNPFDDDASSYDDTSIARRLAALNTLKLDNHSATESDISSVDEKRDSLSGMNTYNDQFQSQSKEELLAKPPVQPPESPFFDPQNRSSSVYMDSEPAVNKSWRYTGNLSPVSDIVRDSYGSQKTVDTEKLFDLEAPEKEKRTSRDVTMSSLDPWNSNISPSPVRKSVTPSPYNVTKHRNRHLQNIQDSQSGKNGITPTTMSTSSSDDFVPVKDGENFCWVHSMEPDRRPSKKRLVDFSNKSNVNVGQVKDIHGRIPEML"}]},
+  {:feature=>"gene",
+   :position=>"complement(<3300..>4037)",
+   :qualifiers=>
+  [{:qualifier=>"gene", :value=>"REV7"}]},
+  {:feature=>"mRNA",
+   :position=>"complement(<3300..>4037)",
+   :qualifiers=>
+     [{:qualifier=>"gene", :value=>"REV7"},
+     {:qualifier=>"product",
+     :value=>"Rev7p"}]},
+  {:feature=>"CDS",
+   :position=>"complement(3300..4037)",
+   :qualifiers=>
+   [{:qualifier=>"gene", :value=>"REV7"},
+    {:qualifier=>"codon_start", :value=>1},
+    {:qualifier=>"product",
+     :value=>"Rev7p"},
+    {:qualifier=>"protein_id",
+     :value=>"AAA98667.1"},
+    {:qualifier=>"db_xref",
+     :value=>"GI:1293616"},
+    {:qualifier=>"translation",
+     :value=>
+      "MNRWVEKWLRVYLKCYINLILFYRNVYPPQSFDYTTYQSFNLPQFVPINRHPALIDYIEELILDVLSKLTHVYRFSICIINKKNDLCIEKYVLDFSELQHVDKDDQIITETEVFDEFRSSLNSLIMHLEKLPKVNDDTITFEAVINAIELELGHKLDRNRRVDSLEEKAEIERDSNWVKCQEDENLPDNNGFQPPKIKLTSLVGSDVGPLIIHQFSEKLISGDDKILNGVYSQYEEGESIFGSLF"}]}]
+
+      assert_equal(expected_seq, seq.seq)
+      assert_equal(expected_id_namespace, seq.id_namespace)
+      assert_equal(expected_entry_id, seq.entry_id)
+      assert_equal(expected_primary_accession, seq.primary_accession)
+      assert_equal(expected_secondary_accessions, seq.secondary_accessions)
+      seqids = seq.other_seqids.first
+      actual_other_seqids = [seqids.id, seqids.database, seqids.secondary_ids]
+      assert_equal(expected_other_seqids, actual_other_seqids)
+      assert_equal(expected_division, seq.division)
+      assert_equal(expected_strandedness, seq.strandedness)
+      assert_equal(expected_keywords, seq.keywords)
+      assert_equal(expected_classification, seq.classification)
+      assert_equal(expected_comments, seq.comments)
+      refs = seq.references
+      actual_references = []
+      refs.each do |ref|
+       actual_references << {:abstract => ref.abstract,
+                             :affiliations => ref.affiliations,
+                             :authors => ref.authors,
+                             :comments => ref.comments,
+                             :doi => ref.doi,
+                             :embl_gb_record_number => ref.embl_gb_record_number,
+                             :issue => ref.issue,
+                             :journal =>  ref.journal,
+                             :medline => ref.medline,
+                             :mesh => ref.mesh,
+                             :pages => ref.pages,
+                             :pubmed => ref.pubmed,
+                             :sequence_position => ref.sequence_position,
+                             :title => ref.title,
+                             :url => ref.url,
+                             :volume => ref.volume,
+                             :year => ref.year}
+      end
+      assert_equal(expected_references, actual_references)
+      fets = seq.features
+      actual_features = []
+      fets.each do |fet|
+        feature = fet.feature
+        position = fet.position
+        quals = []
+        fet.qualifiers.each do |qual|
+          quals << {:qualifier => qual.qualifier, :value => qual.value}
+        end
+      actual_features << {:feature => feature, :position => position, :qualifiers => quals}
+      end
+      assert_equal(expected_features, actual_features) # skip
+      
+
+    end
+
+  end #class TestBioGenBank
+end #module Bio
+
diff --git a/test/unit/bio/db/genbank/test_genpept.rb b/test/unit/bio/db/genbank/test_genpept.rb
new file mode 100644
index 0000000..48143a0
--- /dev/null
+++ b/test/unit/bio/db/genbank/test_genpept.rb
@@ -0,0 +1,81 @@
+#
+# test/unit/bio/db/genbank/test_genpept.rb - Unit test for Bio::GenPept
+#
+# Copyright::  Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/db/genbank/genpept.rb'
+
+#The coverage of this class is 100%
+#It tests only the methods descripbed in the soruce class.(It dosen't test the inherited methods from NCBIDB)
+module Bio
+  class TestBioGenPept < Test::Unit::TestCase
+
+    def setup
+      filename = File.join(BioRubyTestDataPath, 'genbank', 'CAA35997.gp')
+      @obj = Bio::GenPept.new(File.read(filename))
+    end
+
+    def test_locus
+      expected =
+        {:circular=>"linear",
+          :date=>"12-SEP-1993",
+          :division=>"MAM",
+          :entry_id=>"CAA35997",
+          :length=>100}
+      locus  = @obj.locus
+      actual =
+        {:entry_id=>locus.entry_id,
+          :circular=>locus.circular,
+          :date=>locus.date,
+          :division=>locus.division,
+          :length=>locus.length}
+        
+      assert_equal(expected, actual)
+    end
+
+    def test_entry_id
+      assert_equal("CAA35997", @obj.entry_id)
+    end
+
+    def test_length
+      assert_equal(100, @obj.length)
+    end
+
+    def test_circular
+      assert_equal("linear", @obj.circular)
+    end
+
+    def test_division
+      assert_equal("MAM", @obj.division)
+    end
+
+    def test_date
+      assert_equal("12-SEP-1993", @obj.date)
+    end
+
+    def test_seq
+      expected = "MRTPMLLALLALATLCLAGRADAKPGDAESGKGAAFVSKQEGSEVVKRLRRYLDHWLGAPAPYPDPLEPKREVCELNPDCDELADHIGFQEAYRRFYGPV"
+      assert_equal(expected, @obj.seq)
+    end
+
+    def test_seq_len
+      assert_equal(100, @obj.seq_len)
+    end
+
+    def test_dbsource
+      expected = "DBSOURCE    embl accession X51700.1\n"
+      assert_equal(expected, @obj.dbsource)
+    end
+
+  end #class TestBioGenPept
+end #module Bio
+
diff --git a/test/unit/bio/db/pdb/test_pdb.rb b/test/unit/bio/db/pdb/test_pdb.rb
index fbdd388..efca85d 100644
--- a/test/unit/bio/db/pdb/test_pdb.rb
+++ b/test/unit/bio/db/pdb/test_pdb.rb
@@ -1,8 +1,8 @@
 #
 # = test/unit/bio/db/pdb/test_pdb.rb - Unit test for Bio::PDB classes
 #
-# Copyright:: Copyright (C) 2006
-#             Naohisa Goto <ng at bioruby.org>
+# Copyright:: Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# Copyright:: Copyright (C) 2006 Naohisa Goto <ng at bioruby.org>
 #
 # License:: The Ruby License
 #
@@ -11,6 +11,7 @@
 
 # loading helper routine for testing bioruby
 require 'pathname'
+require 'matrix'
 load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
                             'bioruby_test_helper.rb')).cleanpath.to_s
 
@@ -19,8 +20,296 @@ require 'test/unit'
 require 'bio'
 
 module Bio
-  #class TestPDB < Test::Unit::TestCase
-  #end #class TestPDB
+
+  #This class tests Bio::PDB class.
+  #The sample record isn't sufficient because it cannot pass through all of the case statement...
+  class TestPDB < Test::Unit::TestCase
+    def setup
+      str =<<EOF
+HEADER    OXIDOREDUCTASE                          12-AUG-09   3INJ
+TITLE     HUMAN MITOCHONDRIAL ALDEHYDE DEHYDROGENASE COMPLEXED WITH
+DBREF  3INJ A    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+HELIX    1   1 ASP A   55  PHE A   70  1                                  16
+KEYWDS    OXIDOREDUCTASE, ALDH, E487K, ROSSMANN FOLD, ALDA-1,
+SEQRES   1 A  500  SER ALA ALA ALA THR GLN ALA VAL PRO ALA PRO ASN GLN
+SHEET    1   A 2 ILE A  22  ILE A  24  0
+SSBOND   1 CYS B  301    CYS B  303                          1555   1555  2.97
+REVDAT   1   12-JAN-10 3INJ
+MODEL        1
+ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N
+ANISOU    1  N   ALA A   7     2406   1892   1614    198    519   -328       N
+SIGUIJ    1  N   ALA A   7       10     10     10     10     10     10       N
+SIGATM    1  N   ALA     7       0.040   0.030   0.030  0.00  0.00           N
+ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C
+ANISOU    2  CA  ALA A   7     2748   2004   1679    -21    155   -419       C
+SIGUIJ    2  CA  ALA A   7       10     10     10     10     10     10       C
+SIGATM    2  CA  ALA     7       0.040   0.030   0.030  0.00  0.00           C
+ATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C
+ANISOU    3  C   ALA A   7     2555   1955   1468     87    357   -109       C
+SIGUIJ    3  C   ALA A   7       10     10     10     10     10     10       C
+SIGATM    3  N   ALA     7       0.040   0.030   0.030  0.00  0.00           C
+ATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O
+ANISOU    4  O   ALA A   7     2555   1955   1468     87    357   -109       O
+SIGUIJ    4  O   ALA A   7       10     10     10     10     10     10       O
+SIGATM    4  O   ALA     7       0.040   0.030   0.030  0.00  0.00           O
+ATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C
+ANISOU    5  CB  ALA A   7     2555   1955   1468     87    357   -109       C
+SIGUIJ    5  CB  ALA A   7       10     10     10     10     10     10       C
+SIGATM    1  CB  ALA     7       0.040   0.030   0.030  0.00  0.00           C
+MODEL        2
+ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N
+TER    3821      SER A 500
+HETATM30582  C1  EDO A 701      -0.205 -27.262  49.961  1.00 34.45           C
+HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O
+HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C
+HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O
+HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C
+HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O
+HETATM30588  C2  EDO A 702       3.678   7.589  66.425  1.00 15.31           C
+HETATM30589  O2  EDO A 702       3.391   6.512  65.550  1.00 17.67           O
+HETATM30857  O   HOH A 502      13.654 -16.451  49.711  1.00 12.79           O
+EOF
+      @pdb = Bio::PDB.new(str)
+    end
+    def test_accession
+      assert_equal("3INJ", @pdb.accession)
+    end
+    def test_addModel
+      assert_nothing_raised{@pdb.addModel(Bio::PDB::Model.new(1,nil))}
+    end
+    def test_authors
+      assert_equal([], at pdb.authors)
+    end
+    def test_classification
+      assert_equal("OXIDOREDUCTASE", at pdb.classification)
+    end
+    def test_dbref
+      assert_instance_of(Bio::PDB::Record::DBREF, at pdb.dbref.first)
+      assert_instance_of(Bio::PDB::Record::DBREF, at pdb.dbref("A").first)
+    end
+    def test_definition
+      assert_equal("HUMAN MITOCHONDRIAL ALDEHYDE DEHYDROGENASE COMPLEXED WITH", at pdb.definition)
+    end
+    def test_each
+      expected = [nil, 1, 2, 3]
+      pdb = Bio::PDB.new(" ")
+      pdb.addModel(Bio::PDB::Model.new(1,nil))
+      pdb.addModel(Bio::PDB::Model.new(2,nil))
+      pdb.addModel(Bio::PDB::Model.new(3,nil))
+      actual = []
+      pdb.each do |model|
+        actual << model.serial
+      end
+      assert_equal(expected,actual)
+    end
+    def test_each_model
+      expected = [nil, 1, 2, 3]
+      pdb = Bio::PDB.new("")
+      pdb.addModel(Bio::PDB::Model.new(1,nil))
+      pdb.addModel(Bio::PDB::Model.new(2,nil))
+      pdb.addModel(Bio::PDB::Model.new(3,nil))
+      actual = []
+      pdb.each_model do |model|
+        actual << model.serial
+      end
+      assert_equal(expected,actual)
+    end
+
+    def test_entry_id
+      assert_equal("3INJ", @pdb.entry_id)
+    end
+    def test_helix
+      assert_instance_of(Array, @pdb.helix)
+      assert_equal(nil, at pdb.helix(1))
+    end
+    def test_inspect
+      assert_equal("#<Bio::PDB entry_id=\"3INJ\">", at pdb.inspect)
+    end
+    def test_jrnl
+      assert_instance_of(Hash, @pdb.jrnl)
+    end
+    def test_keywords
+      assert_equal(["OXIDOREDUCTASE", "ALDH", "E487K", "ROSSMANN FOLD", "ALDA-1"], at pdb.keywords)
+    end
+    def test_remark
+      str =<<EOS
+REMARK   1 REFERENCE 1
+REMARK   1  AUTH   C.H.CHEN,G.R.BUDAS,E.N.CHURCHILL,M.H.DISATNIK
+REMARK   2 
+REMARK   3
+EOS
+
+      expected =
+     { 1 => {:remarkNum=>1,
+                :sub_record=>"AUTH",
+                :authorList=>["C.H.CHEN", "G.R.BUDAS", "E.N.CHURCHILL", "M.H.DISATNIK"]},
+        2=>[],
+        3=>[]}
+      obj = Bio::PDB.new(str)
+      actual = 
+      { 1 => {:remarkNum=>obj.remark[1][0].remarkNum,
+                :sub_record=>obj.remark[1][0].sub_record,
+                :authorList=>obj.remark[1][0].authorList},
+        2=>obj.remark[2],
+        3=>obj.remark[3]}
+
+      assert_equal(actual,expected)
+    end
+    def test_record
+      assert_instance_of(Hash, @pdb.record)
+    end
+    def test_seqres
+      assert_equal({"A"=>"SAAATQAVPAPNQ"}, at pdb.seqres)
+      assert_equal(nil, at pdb.seqres(7)) #I'm not sure why this returns nil
+      str =<<EOS
+SEQRES   1 X   39    U   C   C   C   C   C   G   U   G   C   C   C   A 
+EOS
+      obj = Bio::PDB.new(str)
+      assert_equal({"X"=>"ucccccgugccca"},obj.seqres)
+    end
+    # too redundant?
+    def test_sheet
+      seq =<<EOS
+SHEET    2 BS8 3 LYS   639  LYS   648 -1  N  PHE   643   O  HIS   662
+SHEET    3 BS8 3 ASN   596  VAL   600 -1  N  TYR   598   O  ILE   646
+EOS
+      s = Bio::PDB.new(seq)
+      actual = []
+      s.sheet.each do |obj2|
+        obj2.each do |obj|
+      
+      actual <<
+  {:strand=>obj.strand,
+   :sheetID=>obj.sheetID,
+   :numStrands=>obj.numStrands,
+   :initResName=>obj.initResName,
+   :initChainID=>obj.initChainID,
+   :initSeqNum=>obj.initSeqNum,
+   :initICode=>obj.initICode,
+   :endResName=>obj.endResName,
+   :endChainID=>obj.endChainID,
+   :endSeqNum=>obj.endSeqNum,
+   :endICode=>obj.endICode,
+   :sense=>obj.sense,
+   :curAtom=>obj.curAtom,
+   :curResName=>obj.curResName,
+   :curChainId=>obj.curChainId,
+   :curResSeq=>obj.curResSeq,
+   :curICode=>obj.curICode,
+   :prevAtom=>obj.prevAtom,
+   :prevResName=>obj.prevResName,
+   :prevChainId=>obj.prevChainId,
+   :prevResSeq=>obj.prevResSeq,
+   :prevICode=>obj.prevICode}
+      end
+      end
+      expected =
+  [
+  {:strand=>2,
+   :sheetID=>"BS8",
+   :numStrands=>3,
+   :initResName=>"LYS",
+   :initChainID=>" ",
+   :initSeqNum=>639,
+   :initICode=>"",
+   :endResName=>"LYS",
+   :endChainID=>" ",
+   :endSeqNum=>648,
+   :endICode=>"",
+   :sense=>-1,
+   :curAtom=>" N",
+   :curResName=>"PHE",
+   :curChainId=>" ",
+   :curResSeq=>643,
+   :curICode=>"",
+   :prevAtom=>" O",
+   :prevResName=>"HIS",
+   :prevChainId=>" ",
+   :prevResSeq=>662,
+   :prevICode=>""},
+
+   {:strand=>3,
+   :sheetID=>"BS8",
+   :numStrands=>3,
+   :initResName=>"ASN",
+   :initChainID=>" ",
+   :initSeqNum=>596,
+   :initICode=>"",
+   :endResName=>"VAL",
+   :endChainID=>" ",
+   :endSeqNum=>600,
+   :endICode=>"",
+   :sense=>-1,
+   :curAtom=>" N",
+   :curResName=>"TYR",
+   :curChainId=>" ",
+   :curResSeq=>598,
+   :curICode=>"",
+   :prevAtom=>" O",
+   :prevResName=>"ILE",
+   :prevChainId=>" ",
+   :prevResSeq=>646,
+   :prevICode=>""}]
+      actual2 = []
+      s.sheet("BS8").each do |obj2|
+        obj2.each do |obj|
+
+      actual2 <<
+  {:strand=>obj.strand,
+   :sheetID=>obj.sheetID,
+   :numStrands=>obj.numStrands,
+   :initResName=>obj.initResName,
+   :initChainID=>obj.initChainID,
+   :initSeqNum=>obj.initSeqNum,
+   :initICode=>obj.initICode,
+   :endResName=>obj.endResName,
+   :endChainID=>obj.endChainID,
+   :endSeqNum=>obj.endSeqNum,
+   :endICode=>obj.endICode,
+   :sense=>obj.sense,
+   :curAtom=>obj.curAtom,
+   :curResName=>obj.curResName,
+   :curChainId=>obj.curChainId,
+   :curResSeq=>obj.curResSeq,
+   :curICode=>obj.curICode,
+   :prevAtom=>obj.prevAtom,
+   :prevResName=>obj.prevResName,
+   :prevChainId=>obj.prevChainId,
+   :prevResSeq=>obj.prevResSeq,
+   :prevICode=>obj.prevICode}
+      end
+      end
+
+      assert_equal(expected,actual)
+      assert_equal(expected,actual2)
+    end
+    def test_ssbond
+      assert_instance_of(Bio::PDB::Record::SSBOND, at pdb.ssbond.first)
+    end
+    
+    #is this method correct?
+    def test_to_s
+      assert_equal("MODEL     1\nATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N  \nATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C  \nATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C  \nATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O  \nATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C  \nTER\nENDMDL\nMODEL     2\nATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N  \nTER\nHETATM30582  C1  EDO A 701      -0.205 -27.262  49.961  1.00 34.45           C  \nHETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O  \nHETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C  \nHETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O  \nHETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C  \nHETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O  \nHETATM30588  C2  EDO A 702       3.678   7.589  66.425  1.00 15.31           C  \nHETATM30589  O2  EDO A 702       3.391   6.512  65.550  1.00 17.67           O  \nHETATM30857  O   HOH A 502      13.654 -16.451  49.711  1.00 12.79           O  \nENDMDL\nEND\n", at pdb.to_s)
+    end
+    def test_turn
+      assert_equal([], at pdb.turn)
+      assert_equal(nil, at pdb.turn(1))
+
+    end
+    def test_version
+      assert_equal(1, at pdb.version)
+    end
+
+    def test_bracket #test for []
+      assert_equal(1, at pdb[1].serial)
+    end
+
+
+  end
+
+  #TestPDBRecord::Test* are unit tests for pdb field classes.
+  #each test class uses one line or several lines of PDB record.
+  #they tests all the methods described or generated in Bio::PDB::Record.
 
   module TestPDBRecord
 
@@ -66,23 +355,23 @@ module Bio
       end
 
       def test_x
-        assert_in_delta(29.909, @atom.x, Float::EPSILON)
+        assert_in_delta(29.909, @atom.x, 0.0001)
       end
 
       def test_y
-        assert_in_delta(16.996, @atom.y, Float::EPSILON)
+        assert_in_delta(16.996, @atom.y, 0.0001)
       end
 
       def test_z
-        assert_in_delta(55.922, @atom.z, Float::EPSILON)
+        assert_in_delta(55.922, @atom.z, 0.0001)
       end
 
       def test_occupancy
-        assert_in_delta(0.72, @atom.occupancy, Float::EPSILON)
+        assert_in_delta(0.72, @atom.occupancy, 0.001)
       end
 
       def test_tempFactor
-        assert_in_delta(13.25, @atom.tempFactor, Float::EPSILON)
+        assert_in_delta(13.25, @atom.tempFactor, 0.001)
       end
 
       def test_segID
@@ -121,9 +410,10 @@ module Bio
       end
 
       def test_to_s
-        assert_equal(@str + "\n", @atom.to_s)
+        assert_equal(@str + "\n", @atom.to_s) 
       end
 
+
       def test_original_data
         assert_equal([ @str ], @atom.original_data)
       end
@@ -147,8 +437,2994 @@ module Bio
       def test_ter
         assert_equal(nil, @atom.ter)
       end
+
+
     end #class TestATOM
 
-  end #module TestPDBRecord
+    # test of Bio::PDB::Record::ATOM
+    class TestHETATM < Test::Unit::TestCase
+      def setup
+        # the data is taken from
+        # http://www.rcsb.org/pdb/file_formats/pdb/pdbguide2.2/part_62.html
+        @str = 'HETATM30581 NA    NA A 601       5.037 -39.853  62.809  1.00 17.37          NA  '
+        @hetatm = Bio::PDB::Record::HETATM.new.initialize_from_string(@str)
+      end
+
+      def test_record_name
+        assert_equal('HETATM', @hetatm.record_name)
+      end
+
+      def test_serial
+        assert_equal(30581, @hetatm.serial)
+      end
+
+      def test_name
+        assert_equal('NA', @hetatm.name)
+      end
+
+      def test_altLoc
+        assert_equal(' ', @hetatm.altLoc)
+      end
+
+      def test_resName
+        assert_equal('NA', @hetatm.resName)
+      end
+
+      def test_chainID
+        assert_equal('A', @hetatm.chainID)
+      end
+
+      def test_resSeq
+        assert_equal(601, @hetatm.resSeq)
+      end
+
+      def test_iCode
+        assert_equal('', @hetatm.iCode)
+      end
+
+      def test_x
+        assert_in_delta(5.037, @hetatm.x, 0.0001)
+      end
+
+      def test_y
+        assert_in_delta(-39.853, @hetatm.y, 0.0001)
+      end
+
+      def test_z
+        assert_in_delta(62.809, @hetatm.z, 0.0001)
+      end
+
+      def test_occupancy
+        assert_in_delta(1.00, @hetatm.occupancy, 0.001)
+      end
+
+      def test_tempFactor
+        assert_in_delta(17.37, @hetatm.tempFactor, 0.001)
+      end
+
+      def test_segID
+        assert_equal('', @hetatm.segID)
+      end
+
+      def test_element
+        assert_equal('NA', @hetatm.element)
+      end
+
+      def test_charge
+        assert_equal('', @hetatm.charge)
+      end
+
+      def test_xyz
+        assert_equal(Bio::PDB::Coordinate[
+                       "5.037".to_f,
+                       "-39.853".to_f,
+                       "62.809".to_f ], @hetatm.xyz)
+      end
+
+      def test_to_a
+        assert_equal([ "5.037".to_f,
+                       "-39.853".to_f,
+                       "62.809".to_f ], @hetatm.to_a)
+      end
+
+      def test_comparable
+        a = Bio::PDB::Record::HETATM.new
+        a.serial = 40000
+        assert_equal(-1, @hetatm <=> a)
+        a.serial = 30581
+        assert_equal( 0, @hetatm <=> a)
+        a.serial = 30000
+        assert_equal( 1, @hetatm <=> a)
+      end
+
+      def test_to_s
+        assert_equal(@str + "\n", @hetatm.to_s)
+      end
+
+      def test_original_data
+        assert_equal([ @str ], @hetatm.original_data)
+      end
+
+      def test_do_parse
+        assert_equal(@hetatm, @hetatm.do_parse)
+      end
+
+      def test_residue
+        assert_equal(nil, @hetatm.residue)
+      end
+
+      def test_sigatm
+        assert_equal(nil, @hetatm.sigatm)
+      end
+
+      def test_anisou
+        assert_equal(nil, @hetatm.anisou)
+      end
+
+      def test_ter
+        assert_equal(nil, @hetatm.ter)
+      end
+    end #class TestATOM
+
+    class TestHEADER < Test::Unit::TestCase
+      def setup
+        @str = 'HEADER    OXIDOREDUCTASE                          12-AUG-09   3INJ              '
+        @header = Bio::PDB::Record::HEADER.new.initialize_from_string(@str)
+      end
+
+
+      def test_classification
+        assert_equal('OXIDOREDUCTASE', @header.classification)
+      end
+
+
+      def test_depDate
+        assert_equal('12-AUG-09', @header.depDate)
+      end
+
+
+      def test_idCode
+        assert_equal('3INJ', @header.idCode)
+      end
+
+
+    end
+
+    class TestOBSLTE < Test::Unit::TestCase
+      def setup
+        @str = 'OBSLTE     31-JAN-94 1MBP      2MBP                                   '
+        @obslte = Bio::PDB::Record::OBSLTE.new.initialize_from_string(@str)
+      end
+
+
+      def test_repDate
+        assert_equal('31-JAN-94', @obslte.repDate)
+      end
+
+
+      def test_idCode
+        assert_equal('1MBP', @obslte.idCode)
+      end
+
+
+      def test_rIdCode
+        assert_equal(["2MBP"], @obslte.rIdCode)
+      end
+
+    end
+
+    #Is this unit test correct?
+    class TestTITLE < Test::Unit::TestCase
+      def setup
+        @str =
+"TITLE     HUMAN MITOCHONDRIAL ALDEHYDE DEHYDROGENASE COMPLEXED WITH             \n
+TITLE    2 AGONIST ALDA-1                                                       "
+        @title = Bio::PDB::Record::TITLE.new.initialize_from_string(@str)
+      end
+
+
+      def test_title
+        assert_equal('HUMAN MITOCHONDRIAL ALDEHYDE DEHYDROGENASE COMPLEXED WITH', @title.title)
+      end
+
+
+    end
+
+    class TestCAVEAT < Test::Unit::TestCase
+      def setup
+        @str = 'CAVEAT     1ABC    INCORRECT'
+        @caveat = Bio::PDB::Record::CAVEAT.new.initialize_from_string(@str)
+      end
+
+
+      def test_idcode
+        assert_equal('1ABC', @caveat.idcode)
+      end
+
+
+      def test_comment
+        assert_equal('INCORRECT', @caveat.comment)
+      end
+
+
+    end
+
+    class TestCOMPND < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+COMPND    MOL_ID: 1;                                                            
+COMPND   2 MOLECULE: ALDEHYDE DEHYDROGENASE, MITOCHONDRIAL;                     
+COMPND   3 CHAIN: A, B, C, D, E, F, G, H;                                       
+COMPND   4 SYNONYM: ALDH CLASS 2, ALDHI, ALDH-E2;                               
+COMPND   5 EC: 1.2.1.3;                                                         
+COMPND   6 ENGINEERED: YES                                                      
+
+EOS
+        @compnd = Bio::PDB::Record::COMPND.new.initialize_from_string(@str)
+      end
+
+
+      def test_compound
+        assert_equal([["MOL_ID", "1"]], @compnd.compound)
+      end
+
+
+    end
+
+    class TestSOURCE < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+SOURCE    MOL_ID: 1;
+SOURCE   2 ORGANISM_SCIENTIFIC: HOMO SAPIENS;
+SOURCE   3 ORGANISM_COMMON: HUMAN;
+SOURCE   4 ORGANISM_TAXID: 9606;
+SOURCE   5 GENE: ALDH2, ALDM;
+SOURCE   6 EXPRESSION_SYSTEM: ESCHERICHIA COLI;
+SOURCE   7 EXPRESSION_SYSTEM_TAXID: 562;
+SOURCE   8 EXPRESSION_SYSTEM_STRAIN: BL21(DE3);
+SOURCE   9 EXPRESSION_SYSTEM_VECTOR_TYPE: PLASMID;
+SOURCE  10 EXPRESSION_SYSTEM_PLASMID: PT-7-7
+EOS
+        @source = Bio::PDB::Record::SOURCE.new.initialize_from_string(@str)
+      end
+
+
+      def test_srcName
+        expected =
+          [["MOL_ID", "1"], ["SOURCE   2 ORGANISM_SCIENTIFIC", "HOMO SAPIENS"], ["SOU"]]
+        assert_equal(expected, @source.srcName)
+      end
+    end
+
+    class TestKEYWDS < Test::Unit::TestCase
+      def setup
+        @str =<<EOF
+KEYWDS    OXIDOREDUCTASE, ALDH, E487K, ROSSMANN FOLD, ALDA-1,
+KEYWDS   2 ACTIVATOR, ACETYLATION, MITOCHONDRION, NAD, POLYMORPHISM,
+KEYWDS   3 TRANSIT PEPTIDE
+EOF
+        @keywds = Bio::PDB::Record::KEYWDS.new.initialize_from_string(@str)
+      end
+
+
+      def test_keywds
+        assert_equal(["OXIDOREDUCTASE", "ALDH", "E487K", "ROSSMANN FOLD", "ALDA-1", "KEYWDS"], @keywds.keywds)
+      end
+
+    end
+
+    class TestEXPDTA < Test::Unit::TestCase
+      def setup
+        @str = <<EOF
+EXPDTA    X-RAY DIFFRACTION
+EOF
+        @expdta = Bio::PDB::Record::EXPDTA.new.initialize_from_string(@str)
+      end
+
+
+      def test_technique
+        assert_equal(["X-RAY DIFFRACTION"], @expdta.technique)
+      end
+
+
+    end
+
+    class TestAUTHOR < Test::Unit::TestCase
+      def setup
+        @str = 'AUTHOR    S.PEREZ-MILLER,T.D.HURLEY'
+        @author = Bio::PDB::Record::AUTHOR.new.initialize_from_string(@str)
+      end
+
+
+      def test_authorList
+        assert_equal(["S.PEREZ-MILLER", "T.D.HURLEY"], @author.authorList)
+      end
+
+
+    end
+
+    class TestREVDAT < Test::Unit::TestCase
+      def setup
+        @str = 'REVDAT   1   12-JAN-10 3INJ    0'
+        @revdat = Bio::PDB::Record::REVDAT.new.initialize_from_string(@str)
+      end
+
+
+      def test_modNum
+        assert_equal(1, @revdat.modNum )
+      end
+
+
+      def test_modDate
+        assert_equal('12-JAN-10', @revdat.modDate)
+      end
+
+
+      def test_modId
+        assert_equal('3INJ', @revdat.modId  )
+      end
+
+
+      def test_modType
+        assert_equal(0, @revdat.modType)
+      end
+
+
+      def test_record
+        assert_equal([], @revdat.record )
+      end
+
+
+    end
+
+    class TestSPRSDE < Test::Unit::TestCase
+      def setup
+        @str = 'SPRSDE     17-JUL-84 4HHB      1HHB                             '
+        @sprsde = Bio::PDB::Record::SPRSDE.new.initialize_from_string(@str)
+      end
+
+
+      def test_sprsdeDate
+        assert_equal('17-JUL-84', @sprsde.sprsdeDate)
+      end
+
+
+      def test_idCode
+        assert_equal('4HHB', @sprsde.idCode)
+      end
+
+
+      def test_sIdCode
+        assert_equal(["1HHB"], @sprsde.sIdCode)
+      end
+
+    end
+
+    class TestDBREF < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+DBREF  3INJ A    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ B    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ C    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ D    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ E    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ F    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ G    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+DBREF  3INJ H    1   500  UNP    P05091   ALDH2_HUMAN     18    517
+EOS
+        @dbref = Bio::PDB::Record::DBREF.new.initialize_from_string(@str)
+      end
+
+
+      def test_idCode
+        assert_equal('3INJ', @dbref.idCode     )
+      end
+
+
+      def test_chainID
+        assert_equal('A', @dbref.chainID    )
+      end
+
+
+      def test_seqBegin
+        assert_equal(1, @dbref.seqBegin   )
+      end
+
+
+      def test_insertBegin
+        assert_equal('', @dbref.insertBegin)
+      end
+
+
+      def test_seqEnd
+        assert_equal(500, @dbref.seqEnd     )
+      end
+
+
+      def test_insertEnd
+        assert_equal('', @dbref.insertEnd  )
+      end
+
+
+      def test_database
+        assert_equal('UNP', @dbref.database   )
+      end
+
+
+      def test_dbAccession
+        assert_equal('P05091', @dbref.dbAccession)
+      end
+
+
+      def test_dbIdCode
+        assert_equal('ALDH2_HUMAN', @dbref.dbIdCode   )
+      end
+
+
+      def test_dbseqBegin
+        assert_equal(18, @dbref.dbseqBegin )
+      end
+
+
+      def test_idbnsBeg
+        assert_equal('', @dbref.idbnsBeg   )
+      end
+
+
+      def test_dbseqEnd
+        assert_equal(517, @dbref.dbseqEnd   )
+      end
+    end
+
+    class TestSEQADV < Test::Unit::TestCase
+      def setup
+        @str = 'SEQADV 3ABC MET A   -1  UNP  P10725              EXPRESSION TAG'
+        @seqadv = Bio::PDB::Record::SEQADV.new.initialize_from_string(@str)
+      end
+
+
+      def test_idCode
+        assert_equal('3ABC', @seqadv.idCode  )
+      end
+
+
+      def test_resName
+        assert_equal('MET', @seqadv.resName )
+      end
+
+
+      def test_chainID
+        assert_equal('A', @seqadv.chainID )
+      end
+
+
+      def test_seqNum
+        assert_equal(-1, @seqadv.seqNum  )
+      end
+
+
+      def test_iCode
+        assert_equal('', @seqadv.iCode   )
+      end
+
+
+      def test_database
+        assert_equal('UNP', @seqadv.database)
+      end
+
+
+      def test_dbIdCode
+        assert_equal('P10725', @seqadv.dbIdCode)
+      end
+
+
+      def test_dbRes
+        assert_equal('', @seqadv.dbRes   )
+      end
+
+
+      def test_dbSeq
+        assert_equal(0, @seqadv.dbSeq   )
+      end
+
+
+      def test_conflict
+        assert_equal('EXPRESSION TAG', @seqadv.conflict)
+      end
+
+
+    end
+
+    class TestSEQRES < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+SEQRES   1 A  500  SER ALA ALA ALA THR GLN ALA VAL PRO ALA PRO ASN GLN
+SEQRES   2 A  500  GLN PRO GLU VAL PHE CYS ASN GLN ILE PHE ILE ASN ASN
+SEQRES   3 A  500  GLU TRP HIS ASP ALA VAL SER ARG LYS THR PHE PRO THR
+SEQRES   4 A  500  VAL ASN PRO SER THR GLY GLU VAL ILE CYS GLN VAL ALA
+SEQRES   5 A  500  GLU GLY ASP LYS GLU ASP VAL ASP LYS ALA VAL LYS ALA
+SEQRES   6 A  500  ALA ARG ALA ALA PHE GLN LEU GLY SER PRO TRP ARG ARG
+SEQRES   7 A  500  MET ASP ALA SER HIS ARG GLY ARG LEU LEU ASN ARG LEU
+SEQRES   8 A  500  ALA ASP LEU ILE GLU ARG ASP ARG THR TYR LEU ALA ALA
+SEQRES   9 A  500  LEU GLU THR LEU ASP ASN GLY LYS PRO TYR VAL ILE SER          
+EOS
+
+        @seqres = Bio::PDB::Record::SEQRES.new.initialize_from_string(@str)
+      end
+
+      
+      def test_chainID
+        assert_equal('A', @seqres.chainID)
+      end
+
+
+      def test_numRes
+        assert_equal(500, @seqres.numRes )
+      end
+
+
+      def test_resName
+        expected =
+          ["SER",
+ "ALA",
+ "ALA",
+ "ALA",
+ "THR",
+ "GLN",
+ "ALA",
+ "VAL",
+ "PRO",
+ "ALA",
+ "PRO",
+ "ASN",
+ "GLN"]
+        assert_equal(expected, @seqres.resName)
+      end
+
+    end
+
+    class TestMODRES < Test::Unit::TestCase
+      def setup
+        @str = 'MODRES 2R0L ASN A   74  ASN  GLYCOSYLATION SITE                     '
+        @modres = Bio::PDB::Record::MODRES.new.initialize_from_string(@str)
+      end
+
+
+      def test_idCode
+        assert_equal('2R0L', @modres.idCode)
+      end
+
+
+      def test_resName
+        assert_equal('ASN', @modres.resName)
+      end
+
+
+      def test_chainID
+        assert_equal('A', @modres.chainID)
+      end
+
+
+      def test_seqNum
+        assert_equal(74, @modres.seqNum)
+      end
+
+
+      def test_iCode
+        assert_equal('', @modres.iCode)
+      end
+
+
+      def test_stdRes
+        assert_equal('ASN', @modres.stdRes)
+      end
+
+
+      def test_comment
+        assert_equal('GLYCOSYLATION SITE', @modres.comment)
+      end
+
+
+    end
+
+    class TestHET < Test::Unit::TestCase
+      def setup
+        @str = 'HET     NA  A 601       1                                                       '
+        @het = Bio::PDB::Record::HET.new.initialize_from_string(@str)
+      end
+
+
+      def test_hetID
+        assert_equal(' NA', @het.hetID)
+      end
+
+
+      def test_ChainID
+        assert_equal('A', @het.ChainID)
+      end
+
+
+      def test_seqNum
+        assert_equal(601, @het.seqNum)
+      end
+
+
+      def test_iCode
+        assert_equal('', @het.iCode)
+      end
+
+
+      def test_numHetAtoms
+        assert_equal(1, @het.numHetAtoms)
+      end
+
+
+      def test_text
+        assert_equal('', @het.text)
+      end
+
+
+    end
+
+    class TestSHEET < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+SHEET    1   A 2 ILE A  22  ILE A  24  0                             
+SHEET    2   A 2 GLU A  27  HIS A  29 -1  O  HIS A  29   N  ILE A  22
+SHEET    1   B 2 THR A  36  VAL A  40  0                             
+EOS
+        @sheet = Bio::PDB::Record::SHEET.new.initialize_from_string(@str)
+      end
+
+
+      def test_strand
+        assert_equal(1, @sheet.strand)
+      end
+
+
+      def test_sheetID
+        assert_equal('A', @sheet.sheetID)
+      end
+
+
+      def test_numStrands
+        assert_equal(2, @sheet.numStrands)
+      end
+
+
+      def test_initResName
+        assert_equal('ILE', @sheet.initResName)
+      end
+
+
+      def test_initChainID
+        assert_equal('A', @sheet.initChainID)
+      end
+
+
+      def test_initSeqNum
+        assert_equal(22, @sheet.initSeqNum)
+      end
+
+
+      def test_initICode
+        assert_equal('', @sheet.initICode)
+      end
+
+
+      def test_endResName
+        assert_equal('ILE', @sheet.endResName)
+      end
+
+
+      def test_endChainID
+        assert_equal('A', @sheet.endChainID)
+      end
+
+
+      def test_endSeqNum
+        assert_equal(24, @sheet.endSeqNum)
+      end
+
+
+      def test_endICode
+        assert_equal('', @sheet.endICode)
+      end
+
+
+      def test_sense
+        assert_equal(0, @sheet.sense)
+      end
+
+
+      def test_curAtom
+        assert_equal('', @sheet.curAtom)
+      end
+
+
+      def test_curResName
+        assert_equal('', @sheet.curResName)
+      end
+
+
+      def test_curChainId
+        assert_equal(' ', @sheet.curChainId)
+      end
+
+
+      def test_curResSeq
+        assert_equal(0, @sheet.curResSeq)
+      end
+
+
+      def test_curICode
+        assert_equal('', @sheet.curICode)
+      end
+
+
+      def test_prevAtom
+        assert_equal('', @sheet.prevAtom)
+      end
+
+
+      def test_prevResName
+        assert_equal('', @sheet.prevResName)
+      end
+
+
+      def test_prevChainId
+        assert_equal(' ', @sheet.prevChainId)
+      end
+
+
+      def test_prevResSeq
+        assert_equal(0, @sheet.prevResSeq)
+      end
+
+
+      def test_prevICode
+        assert_equal('', @sheet.prevICode)
+      end
+
+
+    end
+
+    class TestLINK < Test::Unit::TestCase
+      def setup
+        @str = 'LINK         O   VAL A  40                NA    NA A 601     1555   1555  2.41  '
+        @link = Bio::PDB::Record::LINK.new.initialize_from_string(@str)
+      end
+
+
+      def test_name1
+        assert_equal(' O', @link.name1)
+      end
+
+
+      def test_altLoc1
+        assert_equal(' ', @link.altLoc1)
+      end
+
+
+      def test_resName1
+        assert_equal('VAL', @link.resName1)
+      end
+
+
+      def test_chainID1
+        assert_equal('A', @link.chainID1)
+      end
+
+
+      def test_resSeq1
+        assert_equal(40, @link.resSeq1)
+      end
+
+
+      def test_iCode1
+        assert_equal('', @link.iCode1)
+      end
+
+
+      def test_name2
+        assert_equal("NA", @link.name2)
+      end
+
+
+      def test_altLoc2
+        assert_equal(' ', @link.altLoc2)
+      end
+
+
+      def test_resName2
+        assert_equal(' NA', @link.resName2)
+      end
+
+
+      def test_chainID2
+        assert_equal('A', @link.chainID2)
+      end
+
+
+      def test_resSeq2
+        assert_equal(601, @link.resSeq2)
+      end
+
+
+      def test_iCode2
+        assert_equal('', @link.iCode2)
+      end
+
+
+      def test_sym1
+        assert_equal('  1555', @link.sym1)
+      end
+
+
+      def test_sym2
+        assert_equal('  1555', @link.sym2)
+      end
+
+
+    end
+
+    class TestHYDBND < Test::Unit::TestCase
+      def setup
+        @str = 'HYDBND       O   PHE A    2        A    4  1HN  AIB A    4                    '
+        @hydbnd = Bio::PDB::Record::HYDBND.new.initialize_from_string(@str)
+      end
+
+
+      def test_name1
+        assert_equal(' O', @hydbnd.name1)
+      end
+
+
+      def test_altLoc1
+        assert_equal(' ', @hydbnd.altLoc1)
+      end
+
+
+      def test_resName1
+        assert_equal('PHE', @hydbnd.resName1)
+      end
+
+
+      def test_Chain1
+        assert_equal('A', @hydbnd.Chain1)
+      end
+
+
+      def test_resSeq1
+        assert_equal(2, @hydbnd.resSeq1)
+      end
+
+
+      def test_ICode1
+        assert_equal('', @hydbnd.ICode1)
+      end
+
+
+      def test_nameH
+        assert_equal('', @hydbnd.nameH)
+      end
+
+
+      def test_altLocH
+        assert_equal(' ', @hydbnd.altLocH)
+      end
+
+
+      def test_ChainH
+        assert_equal('A', @hydbnd.ChainH)
+      end
+
+
+      def test_resSeqH
+        assert_equal(4, @hydbnd.resSeqH)
+      end
+
+
+      def test_iCodeH
+        assert_equal('', @hydbnd.iCodeH)
+      end
+
+
+      def test_name2
+        assert_equal('1HN', @hydbnd.name2)
+      end
+
+
+      def test_altLoc2
+        assert_equal(' ', @hydbnd.altLoc2)
+      end
+
+
+      def test_resName2
+        assert_equal('AIB', @hydbnd.resName2)
+      end
+
+
+      def test_chainID2
+        assert_equal('A', @hydbnd.chainID2)
+      end
+
+
+      def test_resSeq2
+        assert_equal(4, @hydbnd.resSeq2)
+      end
+
+
+      def test_iCode2
+        assert_equal('', @hydbnd.iCode2)
+      end
+
+
+      def test_sym1
+        assert_equal('', @hydbnd.sym1)
+      end
+
+
+      def test_sym2
+        assert_equal('', @hydbnd.sym2)
+      end
+
+
+    end
+
+    #SLTBRG field is deprecated.
+    class TestSLTBRG < Test::Unit::TestCase
+      def setup
+        @str = ''
+        @sltbrg = Bio::PDB::Record::SLTBRG.new.initialize_from_string(@str)
+      end
+
+
+      def test_atom1
+        assert_equal('', @sltbrg.atom1)
+      end
+
+
+      def test_altLoc1
+        assert_equal("", @sltbrg.altLoc1)
+      end
+
+
+      def test_resName1
+        assert_equal("", @sltbrg.resName1)
+      end
+
+
+      def test_chainID1
+        assert_equal('', @sltbrg.chainID1)
+      end
+
+
+      def test_resSeq1
+        assert_equal(0, @sltbrg.resSeq1)
+      end
+
+
+      def test_iCode1
+        assert_equal('', @sltbrg.iCode1)
+      end
+
+
+      def test_atom2
+        assert_equal('', @sltbrg.atom2)
+      end
+
+
+      def test_altLoc2
+        assert_equal('', @sltbrg.altLoc2)
+      end
+
+
+      def test_resName2
+        assert_equal('', @sltbrg.resName2)
+      end
+
+
+      def test_chainID2
+        assert_equal('', @sltbrg.chainID2)
+      end
+
+
+      def test_resSeq2
+        assert_equal(0, @sltbrg.resSeq2)
+      end
+
+
+      def test_iCode2
+        assert_equal('', @sltbrg.iCode2)
+      end
+
+
+      def test_sym1
+        assert_equal('', @sltbrg.sym1)
+      end
+
+
+      def test_sym2
+        assert_equal('', @sltbrg.sym2)
+      end
+
+
+    end
+
+    class TestCISPEP < Test::Unit::TestCase
+      def setup
+        @str = 'CISPEP   1 GLY A  116    GLY A  117          0        18.50         '
+        @cispep = Bio::PDB::Record::CISPEP.new.initialize_from_string(@str)
+      end
+
+
+      def test_serNum
+        assert_equal(1, @cispep.serNum)
+      end
+
+
+      def test_pep1
+        assert_equal("GLY", @cispep.pep1)
+      end
+
+
+      def test_chainID1
+        assert_equal('A', @cispep.chainID1)
+      end
+
+
+      def test_seqNum1
+        assert_equal(116, @cispep.seqNum1)
+      end
+
+
+      def test_icode1
+        assert_equal('', @cispep.icode1)
+      end
+
+
+      def test_pep2
+        assert_equal('GLY', @cispep.pep2)
+      end
+
+
+      def test_chainID2
+        assert_equal('A', @cispep.chainID2)
+      end
+
+
+      def test_seqNum2
+        assert_equal(117, @cispep.seqNum2)
+      end
+
+
+      def test_icode2
+        assert_equal('', @cispep.icode2)
+      end
+
+
+      def test_modNum
+        assert_equal(0, @cispep.modNum)
+      end
+
+
+      def test_measure
+        assert_equal(18.5, @cispep.measure)
+      end
+
+
+    end
+
+    class TestSITE < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+SITE     1 AC1  5 THR A  39  VAL A  40  ASP A 109  GLN A 196
+SITE     2 AC1  5 HOH A4009                                                     
+EOS
+        @site = Bio::PDB::Record::SITE.new.initialize_from_string(@str)
+      end
+
+
+      def test_seqNum
+        assert_equal(1, @site.seqNum   )
+      end
+
+
+      def test_siteID
+        assert_equal('AC1', @site.siteID   )
+      end
+
+
+      def test_numRes
+        assert_equal(5, @site.numRes   )
+      end
+
+
+      def test_resName1
+        assert_equal('THR', @site.resName1 )
+      end
+
+
+      def test_chainID1
+        assert_equal('A', @site.chainID1 )
+      end
+
+
+      def test_seq1
+        assert_equal(39, @site.seq1     )
+      end
+
+
+      def test_iCode1
+        assert_equal('', @site.iCode1   )
+      end
+
+
+      def test_resName2
+        assert_equal('VAL', @site.resName2 )
+      end
+
+
+      def test_chainID2
+        assert_equal('A', @site.chainID2 )
+      end
+
+
+      def test_seq2
+        assert_equal(40, @site.seq2     )
+      end
+
+
+      def test_iCode2
+        assert_equal('', @site.iCode2   )
+      end
+
+
+      def test_resName3
+        assert_equal('ASP', @site.resName3 )
+      end
+
+
+      def test_chainID3
+        assert_equal('A', @site.chainID3 )
+      end
+
+
+      def test_seq3
+        assert_equal(109, @site.seq3     )
+      end
+
+
+      def test_iCode3
+        assert_equal('', @site.iCode3   )
+      end
+
+
+      def test_resName4
+        assert_equal('GLN', @site.resName4 )
+      end
+
+
+      def test_chainID4
+        assert_equal('A', @site.chainID4 )
+      end
+
+
+      def test_seq4
+        assert_equal(196, @site.seq4     )
+      end
+
+
+      def test_iCode4
+        assert_equal('', @site.iCode4   )
+      end
+
+
+    end
+
+    class TestCRYST1 < Test::Unit::TestCase
+      def setup
+        @str = 'CRYST1  117.000   15.000   39.000  90.00  90.00  90.00 P 21 21 21    8'
+        @cryst1 = Bio::PDB::Record::CRYST1.new.initialize_from_string(@str)
+      end
+
+
+      def test_a
+        assert_equal(117.0, @cryst1.a)
+      end
+
+
+      def test_b
+        assert_equal(15.0, @cryst1.b)
+      end
+
+
+      def test_c
+        assert_equal(39.0, @cryst1.c)
+      end
+
+
+      def test_alpha
+        assert_equal(90.0, @cryst1.alpha)
+      end
+
+
+      def test_beta
+        assert_equal(90.0, @cryst1.beta)
+      end
+
+
+      def test_gamma
+        assert_equal(90.0, @cryst1.gamma)
+      end
+
+
+      def test_sGroup
+        assert_equal("P 21 21 21 ", @cryst1.sGroup)
+      end
+
+
+      def test_z
+        assert_equal(8, @cryst1.z)
+      end
+
+
+    end
+
+    class TestORIGX1 < Test::Unit::TestCase
+      def setup
+        @str = 'ORIGX1      1.000000  0.000000  0.000000        0.00000                         '
+        @origx1 = Bio::PDB::Record::ORIGX1.new.initialize_from_string(@str)
+      end
+
+
+      def test_On1
+        assert_equal(1.0, @origx1.On1)
+      end
+
+
+      def test_On2
+        assert_equal(0.0, @origx1.On2)
+      end
+
+
+      def test_On3
+        assert_equal(0.0, @origx1.On3)
+      end
+
+
+      def test_Tn
+        assert_equal(0.0, @origx1.Tn)
+      end
+
+
+    end
+
+    class TestSCALE1 < Test::Unit::TestCase
+      def setup
+        @str = 'SCALE1      0.019231  0.000000  0.000000        0.00000               '
+        @scale1 = Bio::PDB::Record::SCALE1.new.initialize_from_string(@str)
+      end
+
+
+      def test_Sn1
+        assert_equal(0.019231, @scale1.Sn1)
+      end
+
+
+      def test_Sn2
+        assert_equal(0.0, @scale1.Sn2)
+      end
+
+
+      def test_Sn3
+        assert_equal(0.0, @scale1.Sn3)
+      end
+
+
+      def test_Un
+        assert_equal(0.0, @scale1.Un)
+      end
+
+
+    end
+
+    class TestSCALE2 < Test::Unit::TestCase
+      def setup
+        @str = 'SCALE2      0.000000  0.017065  0.000000        0.00000               '
+        @scale2 = Bio::PDB::Record::SCALE2.new.initialize_from_string(@str)
+      end
+
+
+      def test_Sn1
+        assert_equal(0.0, @scale2.Sn1)
+      end
+
+
+      def test_Sn2
+        assert_equal(0.017065, @scale2.Sn2)
+      end
+
+
+      def test_Sn3
+        assert_equal(0.0, @scale2.Sn3)
+      end
+
+
+      def test_Un
+        assert_equal(0.0, @scale2.Un)
+      end
+
+
+    end
+
+    class TestSCALE3 < Test::Unit::TestCase
+      def setup
+        @str = 'SCALE3      0.000000  0.000000  0.016155        0.00000               '
+        @scale3 = Bio::PDB::Record::SCALE3.new.initialize_from_string(@str)
+      end
+
+
+      def test_Sn1
+        assert_equal(0.0, @scale3.Sn1)
+      end
+
+
+      def test_Sn2
+        assert_equal(0.0, @scale3.Sn2)
+      end
+
+
+      def test_Sn3
+        assert_equal(0.016155, @scale3.Sn3)
+      end
+
+
+      def test_Un
+        assert_equal(0.0, @scale3.Un)
+      end
+
+
+    end
+
+    class TestMTRIX1 < Test::Unit::TestCase
+      def setup
+        @str = 'MTRIX1   1 -1.000000  0.000000 -0.000000        0.00001    1          '
+        @mtrix1 = Bio::PDB::Record::MTRIX1.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(1, @mtrix1.serial)
+      end
+
+
+      def test_Mn1
+        assert_equal(-1.0, @mtrix1.Mn1)
+      end
+
+
+      def test_Mn2
+        assert_equal(0.0, @mtrix1.Mn2)
+      end
+
+
+      def test_Mn3
+        assert_equal(-0.0, @mtrix1.Mn3)
+      end
+
+
+      def test_Vn
+        assert_equal(1.0e-05, @mtrix1.Vn)
+      end
+
+
+      def test_iGiven
+        assert_equal(1, @mtrix1.iGiven)
+      end
+
+
+    end
+
+    class TestMTRIX2 < Test::Unit::TestCase
+      def setup
+        @str = 'MTRIX2   1 -0.000000  1.000000  0.000000        0.00002    1          '
+        @mtrix2 = Bio::PDB::Record::MTRIX2.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(1, @mtrix2.serial)
+      end
+
+
+      def test_Mn1
+        assert_equal(-0.0, @mtrix2.Mn1)
+      end
+
+
+      def test_Mn2
+        assert_equal(1.0, @mtrix2.Mn2)
+      end
+
+
+      def test_Mn3
+        assert_equal(0.0, @mtrix2.Mn3)
+      end
+
+
+      def test_Vn
+        assert_equal(2.0e-05, @mtrix2.Vn)
+      end
+
+
+      def test_iGiven
+        assert_equal(1, @mtrix2.iGiven)
+      end
+
+
+    end
+
+    class TestMTRIX3 < Test::Unit::TestCase
+      def setup
+        @str = 'MTRIX3   1  0.000000 -0.000000 -1.000000        0.00002    1          '
+        @mtrix3 = Bio::PDB::Record::MTRIX3.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(1, @mtrix3.serial)
+      end
+
+
+      def test_Mn1
+        assert_equal(0.0, @mtrix3.Mn1)
+      end
+
+
+      def test_Mn2
+        assert_equal(-0.0, @mtrix3.Mn2)
+      end
+
+
+      def test_Mn3
+        assert_equal(-1.0, @mtrix3.Mn3)
+      end
+
+
+      def test_Vn
+        assert_equal(2.0e-05, @mtrix3.Vn)
+      end
+
+
+      def test_iGiven
+        assert_equal(1, @mtrix3.iGiven)
+      end
+
+
+    end
+
+    class TestTVECT < Test::Unit::TestCase
+      def setup
+        @str = 'TVECT    1   0.00000   0.00000  28.30000                              '
+        @tvect = Bio::PDB::Record::TVECT.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(1, @tvect.serial)
+      end
+
+
+      def test_t1
+        assert_equal(0.0, @tvect.t1)
+      end
+
+
+      def test_t2
+        assert_equal(0.0, @tvect.t2)
+      end
+
+
+      def test_t3
+        assert_equal(28.3, @tvect.t3)
+      end
+
+
+      def test_text
+        assert_equal('', @tvect.text)
+      end
+
+
+    end
+
+    class TestMODEL < Test::Unit::TestCase
+      def setup
+        @str = 'MODEL        1'
+        @model = Bio::PDB::Record::MODEL.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(1, @model.serial)
+      end
+
+
+    end
+
+    class TestSIGATM < Test::Unit::TestCase
+
+      def setup
+        @str = 'SIGATM  230  N   PRO    15       0.040   0.030   0.030  0.00  0.00           N'
+        @sigatm = Bio::PDB::Record::SIGATM.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(230, @sigatm.serial)
+      end
+
+
+      def test_name
+        assert_equal(' N', @sigatm.name)
+      end
+
+
+      def test_altLoc
+        assert_equal(' ', @sigatm.altLoc)
+      end
+
+
+      def test_resName
+        assert_equal('PRO', @sigatm.resName)
+      end
+
+
+      def test_chainID
+        assert_equal(' ', @sigatm.chainID)
+      end
+
+
+      def test_resSeq
+        assert_equal(15, @sigatm.resSeq)
+      end
+
+
+      def test_iCode
+        assert_equal('', @sigatm.iCode)
+      end
+
+
+      def test_sigX
+        assert_equal(0.04, @sigatm.sigX)
+      end
+
+
+      def test_sigY
+        assert_equal(0.03, @sigatm.sigY)
+      end
+
+
+      def test_sigZ
+        assert_equal(0.03, @sigatm.sigZ)
+      end
+
+
+      def test_sigOcc
+        assert_equal(0.0, @sigatm.sigOcc)
+      end
+
+
+      def test_sigTemp
+        assert_equal(0.0, @sigatm.sigTemp)
+      end
+
+
+      def test_segID
+        assert_equal('    ', @sigatm.segID)
+      end
+
+
+      def test_element
+        assert_equal(' N', @sigatm.element)
+      end
+
+
+      def test_charge
+        assert_equal('  ', @sigatm.charge)
+      end
+
+
+    end
+
+    class TestANISOU < Test::Unit::TestCase
+      def setup
+        @str = 'ANISOU  107  N   GLY    13     2406   1892   1614    198    519   -328       N'
+        @anisou = Bio::PDB::Record::ANISOU.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(107, @anisou.serial)
+      end
+
+
+      def test_name
+        assert_equal(' N', @anisou.name)
+      end
+
+
+      def test_altLoc
+        assert_equal(' ', @anisou.altLoc)
+      end
+
+
+      def test_resName
+        assert_equal('GLY', @anisou.resName)
+      end
+
+
+      def test_chainID
+        assert_equal(' ', @anisou.chainID)
+      end
+
+
+      def test_resSeq
+        assert_equal(13, @anisou.resSeq)
+      end
+
+
+      def test_iCode
+        assert_equal('', @anisou.iCode)
+      end
+
+
+      def test_U11
+        assert_equal(2406, @anisou.U11)
+      end
+
+
+      def test_U22
+        assert_equal(1892, @anisou.U22)
+      end
+
+
+      def test_U33
+        assert_equal(1614, @anisou.U33)
+      end
+
+
+      def test_U12
+        assert_equal(198, @anisou.U12)
+      end
+
+
+      def test_U13
+        assert_equal(519, @anisou.U13)
+      end
+
+
+      def test_U23
+        assert_equal(-328, @anisou.U23)
+      end
+
+
+      def test_segID
+        assert_equal('    ', @anisou.segID)
+      end
+
+
+      def test_element
+        assert_equal(' N', @anisou.element)
+      end
+
+
+      def test_charge
+        assert_equal('  ', @anisou.charge)
+      end
+
+
+    end
+
+    class TestSIGUIJ < Test::Unit::TestCase
+      def setup
+        @str = 'SIGUIJ  107  N   GLY    13       10     10     10     10    10      10       N'
+        @siguij = Bio::PDB::Record::SIGUIJ.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(107, @siguij.serial)
+      end
+
+
+      def test_name
+        assert_equal(' N', @siguij.name)
+      end
+
+
+      def test_altLoc
+        assert_equal(' ', @siguij.altLoc)
+      end
+
+
+      def test_resName
+        assert_equal("GLY", @siguij.resName)
+      end
+
+
+      def test_chainID
+        assert_equal(" ", @siguij.chainID)
+      end
+
+
+      def test_resSeq
+        assert_equal(13, @siguij.resSeq)
+      end
+
+
+      def test_iCode
+        assert_equal('', @siguij.iCode)
+      end
+
+
+      def test_SigmaU11
+        assert_equal(10, @siguij.SigmaU11)
+      end
+
+
+      def test_SigmaU22
+        assert_equal(10, @siguij.SigmaU22)
+      end
+
+
+      def test_SigmaU33
+        assert_equal(10, @siguij.SigmaU33)
+      end
+
+
+      def test_SigmaU12
+        assert_equal(10, @siguij.SigmaU12)
+      end
+
+
+      def test_SigmaU13
+        assert_equal(10, @siguij.SigmaU13)
+      end
+
+
+      def test_SigmaU23
+        assert_equal(10, @siguij.SigmaU23)
+      end
+
+
+      def test_segID
+        assert_equal('    ', @siguij.segID)
+      end
+
+
+      def test_element
+        assert_equal(' N', @siguij.element)
+      end
+
+
+      def test_charge
+        assert_equal('  ', @siguij.charge)
+      end
+
+
+    end
+
+    class TestTER < Test::Unit::TestCase
+      def setup
+        @str = 'TER    3821      SER A 500                                                      '
+        @ter = Bio::PDB::Record::TER.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(3821, @ter.serial)
+      end
+
+
+      def test_resName
+        assert_equal('SER', @ter.resName)
+      end
+
+
+      def test_chainID
+        assert_equal('A', @ter.chainID)
+      end
+
+
+      def test_resSeq
+        assert_equal(500, @ter.resSeq)
+      end
+
+
+      def test_iCode
+        assert_equal('', @ter.iCode)
+      end
+
+
+    end
+
+    class TestENDMDL < Test::Unit::TestCase
+      def setup
+        @str = 'ENDMDL'
+        @endmdl = Bio::PDB::Record::ENDMDL.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(0, @endmdl.serial)
+      end
+
+
+    end
+
+    class TestCONECT < Test::Unit::TestCase
+      def setup
+        @str = 'CONECT  27230581                                                                '
+        @conect = Bio::PDB::Record::CONECT.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal([272, 30581], @conect.serial)
+      end
+
+
+    end
+
+    class TestMASTER < Test::Unit::TestCase
+      def setup
+        @str = 'MASTER      589    0   41  150  164    0   77    634857    8  322  312          '
+        @master = Bio::PDB::Record::MASTER.new.initialize_from_string(@str)
+      end
+
+
+      def test_numRemark
+        assert_equal(589, @master.numRemark)
+      end
+
+
+      def test_numHet
+        assert_equal(41, @master.numHet)
+      end
+
+
+      def test_numHelix
+        assert_equal(150, @master.numHelix)
+      end
+
+
+      def test_numSheet
+        assert_equal(164, @master.numSheet)
+      end
+
+
+      def test_numTurn
+        assert_equal(0, @master.numTurn)
+      end
+
+
+      def test_numSite
+        assert_equal(77, @master.numSite)
+      end
+
+
+      def test_numXform
+        assert_equal(6, @master.numXform)
+      end
+
+
+      def test_numCoord
+        assert_equal(34857, @master.numCoord)
+      end
+
+
+      def test_numTer
+        assert_equal(8, @master.numTer)
+      end
+
+
+      def test_numConect
+        assert_equal(322, @master.numConect)
+      end
+
+
+      def test_numSeq
+        assert_equal(312, @master.numSeq)
+      end
+
+
+    end
+
+    class TestRemarkN < Test::Unit::TestCase
+      def setup
+        @str =<<EOS
+REMARK   3 REFINEMENT.
+REMARK   3   PROGRAM     : PHENIX (PHENIX.REFINE: 1.4_4)
+REMARK   3   AUTHORS     : PAUL ADAMS,PAVEL AFONINE,VICENT CHEN,IAN
+REMARK   3               : DAVIS,KRESHNA GOPAL,RALF GROSSE-
+REMARK   3               : KUNSTLEVE,LI-WEI HUNG,ROBERT IMMORMINO,
+REMARK   3               : TOM IOERGER,AIRLIE MCCOY,ERIK MCKEE,NIGEL
+REMARK   3               : MORIARTY,REETAL PAI,RANDY READ,JANE
+REMARK   3               : RICHARDSON,DAVID RICHARDSON,TOD ROMO,JIM
+REMARK   3               : SACCHETTINI,NICHOLAS SAUTER,JACOB SMITH,
+REMARK   3               : LAURENT STORONI,TOM TERWILLIGER,PETER
+REMARK   3               : ZWART
+REMARK   3
+REMARK   3    REFINEMENT TARGET : TWIN_LSQ_F                                    
+EOS
+        @remarkn = Bio::PDB::Record::RemarkN.new.initialize_from_string(@str)
+      end
+
+
+      def test_remarkNum
+        assert_equal(3, @remarkn.remarkNum)
+      end
+
+      #Is the output correct?
+      def test_text
+        assert_equal("REFINEMENT.\nREMARK   3   PROGRAM     : PHENIX (PHENIX.REFIN", @remarkn.text)
+      end
+
+
+    end
+
+    #What is this record?
+    class TestDefault < Test::Unit::TestCase
+      def setup
+        @str = ''
+        @default = Bio::PDB::Record::Default.new.initialize_from_string(@str)
+      end
+
+
+      def test_text
+        assert_equal('', @default.text)
+      end
+
+
+    end
+
+    class TestEnd < Test::Unit::TestCase
+      def setup
+        @str = "END                                                                             "
+        @end = Bio::PDB::Record::End.new.initialize_from_string(@str)
+      end
+
+
+      def test_serial
+        assert_equal(0, @end.serial)
+      end
+
+
+    end
+
+
+    #end
+  end #module TestPDBRecord
+  
+  #This class tests the behaviors of the complex types defined and used only in Bio::PDB classes.
+  class TestDataType < Test::Unit::TestCase      
+      
+    def test_pdb_integer
+      actual = Bio::PDB::DataType::Pdb_Integer.new("1")
+      assert_equal(1, actual)
+    end
+    def test_pdb_slist
+      actual = Bio::PDB::DataType::Pdb_SList.new("hoge; foo;  bar")
+      assert_equal(["hoge", "foo", "bar"], actual)
+    end    
+    def test_pdb_list
+      actual = Bio::PDB::DataType::Pdb_List.new("hoge, foo,  bar")
+      assert_equal(["hoge", "foo", "bar"], actual)
+    end
+    def test_specification_list
+      actual = Bio::PDB::DataType::Pdb_Specification_list.new("hoge: 1; foo: 2; bar: 3;")
+      assert_equal([["hoge", "1"], ["foo", "2"], ["bar","3"]], actual)
+    end
+
+    def test_pdb_string
+      actual = Bio::PDB::DataType::Pdb_String.new("hoge  \n  ")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_String[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    def test_pdb_lstring
+      actual = Bio::PDB::DataType::Pdb_LString.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_LString[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    def test_pdb_real
+      actual = Bio::PDB::DataType::Pdb_Real.new("1.25")
+      assert_equal(1.25, actual)
+      actual =Bio::PDB::DataType::Pdb_Real[10]
+      #include actual
+      #assert_equal(10, @@format)
+    end
+
+    def test_pdb_stringrj
+      actual = Bio::PDB::DataType::Pdb_StringRJ.new("      hoge")
+      assert_equal("hoge", actual)
+    end
+
+    def test_pdb_date
+      actual = Bio::PDB::DataType::Pdb_Date.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Date[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+
+    def test_pdb_idcode
+      actual = Bio::PDB::DataType::Pdb_IDcode.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_IDcode[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    
+    def test_pdb_resudue_name
+      actual = Bio::PDB::DataType::Pdb_Residue_name.new("hoge  \n  ")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Residue_name[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    
+    def test_pdb_symop
+      actual = Bio::PDB::DataType::Pdb_Residue_name.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Residue_name[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    
+    def test_pdb_atom
+      actual = Bio::PDB::DataType::Pdb_Residue_name.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Residue_name[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    
+    def test_pdb_achar
+      actual = Bio::PDB::DataType::Pdb_Residue_name.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Residue_name[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+
+    def test_pdb_character
+      actual = Bio::PDB::DataType::Pdb_Residue_name.new("hoge")
+      assert_equal("hoge", actual)
+      actual =Bio::PDB::DataType::Pdb_Residue_name[10].new("hoge")
+      assert_equal("hoge      ", actual)
+    end
+    
+    def test_const_like_method
+      extend Bio::PDB::DataType::ConstLikeMethod
+      actual = Pdb_LString(5).new("aaa")
+      assert_equal("aaa  ", actual)
+      actual = Pdb_String(5).new("aaa")
+      assert_equal("aaa  ", actual)
+      actual = Pdb_Real(3).new("1.25")
+      assert_equal(1.25, actual)
+    end
+    
+  end
+
+  # test of Bio::PDB::Record::ATOM
+  class TestResidue < Test::Unit::TestCase
+    def setup
+      @res = Bio::PDB::Residue.new(resName="ALA",resSeq = 7, iCode = "", chain = nil)
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C"))
+
+    end
+    def test_get_residue_id_from_atom
+      id = Bio::PDB::Residue.get_residue_id_from_atom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      1  N   ALA A   7      23.48    4 -35.866  44.510  1.00 28.52           N"))
+      assert_equal("7",id)
+    end
+
+    def test_addAtom
+     assert_nothing_raised {
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string(" ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C"))
+      }
+    end
+    def test_square_bracket
+     expected = {:tempFactor=>27.89,
+ :iCode=>"",
+ :serial=>2,
+ :charge=>"",
+ :z=>44.904,
+ :chainID=>"A",
+ :segID=>"",
+ :x=>23.849,
+ :altLoc=>" ",
+ :occupancy=>1.0,
+ :resSeq=>7,
+ :element=>"C",
+ :name=>"CA",
+ :y=>-34.509,
+ :resName=>"ALA"}
+      actual = {}
+      @res["CA"].each_pair do |m, v|
+        actual[m] = v
+      end
+      assert_equal(expected, actual)
+    end 
+    
+    def test_each_atom
+expected = [{:serial=>1, :name=>"N", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.484, :y=>-35.866, :z=>44.51, :occupancy=>1.0, :tempFactor=>28.52, :segID=>"", :element=>"N", :charge=>""},
+{:serial=>2, :name=>"CA", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.849, :y=>-34.509, :z=>44.904, :occupancy=>1.0, :tempFactor=>27.89, :segID=>"", :element=>"C", :charge=>""},
+{:serial=>3, :name=>"C", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.102, :y=>-34.082, :z=>46.159, :occupancy=>1.0, :tempFactor=>26.68, :segID=>"", :element=>"C", :charge=>""},{:serial=>4, :name=>"O", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.097, :y=>-32.903, :z=>46.524, :occupancy=>1.0, :tempFactor=>30.02, :segID=>"", :element=>"O", :charge=>""},
+{:serial=>5, :name=>"CB", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.581, :y=>-33.526, :z=>43.77, :occupancy=>1.0, :tempFactor=>31.41, :segID=>"", :element=>"C", :charge=>""}]
+      actual = []
+      @res.each_atom do |atom|
+        actual << {:serial=>atom.serial, :name=>atom.name, :altLoc=>atom.altLoc, :resName=>atom.resName, :chainID=>atom.chainID, :resSeq=>atom.resSeq, :iCode=>atom.iCode, :x=>atom.x, :y=>atom.y, :z=>atom.z, :occupancy=>atom.occupancy, :tempFactor=>atom.tempFactor, :segID=>atom.segID, :element=>atom.element, :charge=>atom.charge}
+      end
+      assert_equal(expected, actual)
+    end    
+
+    def test_each
+expected = [{:serial=>1, :name=>"N", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.484, :y=>-35.866, :z=>44.51, :occupancy=>1.0, :tempFactor=>28.52, :segID=>"", :element=>"N", :charge=>""},
+{:serial=>2, :name=>"CA", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.849, :y=>-34.509, :z=>44.904, :occupancy=>1.0, :tempFactor=>27.89, :segID=>"", :element=>"C", :charge=>""},
+{:serial=>3, :name=>"C", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.102, :y=>-34.082, :z=>46.159, :occupancy=>1.0, :tempFactor=>26.68, :segID=>"", :element=>"C", :charge=>""},{:serial=>4, :name=>"O", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.097, :y=>-32.903, :z=>46.524, :occupancy=>1.0, :tempFactor=>30.02, :segID=>"", :element=>"O", :charge=>""},
+{:serial=>5, :name=>"CB", :altLoc=>" ", :resName=>"ALA", :chainID=>"A", :resSeq=>7, :iCode=>"", :x=>23.581, :y=>-33.526, :z=>43.77, :occupancy=>1.0, :tempFactor=>31.41, :segID=>"", :element=>"C", :charge=>""}]
+      actual = []
+      @res.each do |atom|
+        actual << {:serial=>atom.serial, :name=>atom.name, :altLoc=>atom.altLoc, :resName=>atom.resName, :chainID=>atom.chainID, :resSeq=>atom.resSeq, :iCode=>atom.iCode, :x=>atom.x, :y=>atom.y, :z=>atom.z, :occupancy=>atom.occupancy, :tempFactor=>atom.tempFactor, :segID=>atom.segID, :element=>atom.element, :charge=>atom.charge}
+      end
+      assert_equal(expected, actual)
+    end    
+    def test_het_atom
+      assert_equal(false, @res.hetatm)
+    end
+    def test_iCode
+      assert_equal( 1, @res.iCode=1)
+    end
+    def test_resSeq
+      assert_equal( 1, @res.resSeq=1)
+    end
+    def test_to_s
+      expected ="ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N  \nATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C  \nATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C  \nATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O  \nATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C  \n"
+      assert_equal(expected, @res.to_s)
+    end
+    def test_inspect
+      expected = "#<Bio::PDB::Residue resName=\"ALA\" id=\"7\" chain.id=nil resSeq=7 iCode=\"\" atoms.size=5>"
+      assert_equal(expected, at res.inspect)
+    end
+    def test_sort #<=>
+      expected = [Bio::PDB::Residue.new(resName="ALA",resSeq = 6, iCode = 2, chain = nil),
+                  Bio::PDB::Residue.new(resName="ALA",resSeq = 7, iCode = 1, chain = nil),
+                  Bio::PDB::Residue.new(resName="ALA",resSeq = 7,  iCode = 3, chain = nil)]
+      ress = [Bio::PDB::Residue.new(resName="ALA",resSeq = 7, iCode = 1, chain = nil)]
+      ress << Bio::PDB::Residue.new(resName="ALA",resSeq = 6, iCode = 2, chain = nil)
+      ress << Bio::PDB::Residue.new(resName="ALA",resSeq = 7,  iCode = 3, chain = nil)
+      actual = ress.sort do |a, b|
+        a <=> b
+      end
+      assert_equal(expected,actual)
+    end
+    def test_update_resudue_id
+      res = Bio::PDB::Residue.new(resName="ALA", resSeq = nil, iCode = nil, chain = nil)
+      assert_equal(nil, res.residue_id)
+    end
+  end
+  
+  class TestHeterogen < Test::Unit::TestCase
+    def setup
+      @res = Bio::PDB::Heterogen.new(resName="EDO",resSeq = 701, iCode = "", chain = nil)
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O"))
+
+    end
+    def test_get_residue_id_from_atom
+      id = Bio::PDB::Residue.get_residue_id_from_atom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30582  C1  EDO A 701      -0.205 -27.262  49.961  1.00 34.45           C"))
+      assert_equal("701",id)
+    end
+
+    def test_addAtom
+     assert_nothing_raised {
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"))
+      @res.addAtom(Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O")) 
+     }
+    end
+    def test_square_bracket
+     expected = {
+:serial=>30586, 
+:name=>"C1", 
+:altLoc=>" ", 
+:resName=>"EDO", 
+:chainID=>"A", 
+:resSeq=>702, 
+:iCode=>"", 
+:x=>2.792, 
+:y=>7.449,
+:z=>67.655, 
+:occupancy=>1.0,
+:tempFactor=>17.09, 
+:segID=>"", 
+:element=>"C",
+:charge=>""
+}
+      actual = {}
+      @res["C1"].each_pair do |m, v|
+        actual[m] = v
+      end
+      assert_equal(expected, actual)
+    end 
+    
+    def test_each_hetatm
+expected = [{:z=>49.587, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>35.2, :chainID=>"A", :y=>-26.859, :segID=>"", :x=>-1.516, :name=>"O1", :charge=>"", :element=>"O", :serial=>30583}, {:z=>51.219, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>34.49, :chainID=>"A", :y=>-28.124, :segID=>"", :x=>-0.275, :name=>"C2", :charge=>"", :element=>"C", :serial=>30584}, {:z=>51.167, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>33.95, :chainID=>"A", :y=>-28.941, :segID=>"", :x=>-1.442, :name=>"O2", :charge=>"", :element=>"O", :serial=>30585}, {:z=>67.655, :resName=>"EDO", :altLoc=>" ", :resSeq=>702, :occupancy=>1.0, :iCode=>"", :tempFactor=>17.09, :chainID=>"A", :y=>7.449, :segID=>"", :x=>2.792, :name=>"C1", :charge=>"", :element=>"C", :serial=>30586}, {:z=>67.213, :resName=>"EDO", :altLoc=>" ", :resSeq=>702, :occupancy=>1.0, :iCode=>"", :tempFactor=>15.74, :chainID=>"A", :y=>7.273, :segID=>"", :x=>1.451, :name=>"O1", :charge=>"", :element=>"O", :serial=>30587}]
+      actual = []
+      @res.each_hetatm do |hetatm|
+        actual << {:serial=>hetatm.serial, :name=>hetatm.name, :altLoc=>hetatm.altLoc, :resName=>hetatm.resName, :chainID=>hetatm.chainID, :resSeq=>hetatm.resSeq, :iCode=>hetatm.iCode, :x=>hetatm.x, :y=>hetatm.y, :z=>hetatm.z, :occupancy=>hetatm.occupancy, :tempFactor=>hetatm.tempFactor, :segID=>hetatm.segID, :element=>hetatm.element, :charge=>hetatm.charge}
+      end
+      assert_equal(expected, actual)
+    end    
+    def test_each
+expected = [{:z=>49.587, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>35.2, :chainID=>"A", :y=>-26.859, :segID=>"", :x=>-1.516, :name=>"O1", :charge=>"", :element=>"O", :serial=>30583}, {:z=>51.219, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>34.49, :chainID=>"A", :y=>-28.124, :segID=>"", :x=>-0.275, :name=>"C2", :charge=>"", :element=>"C", :serial=>30584}, {:z=>51.167, :resName=>"EDO", :altLoc=>" ", :resSeq=>701, :occupancy=>1.0, :iCode=>"", :tempFactor=>33.95, :chainID=>"A", :y=>-28.941, :segID=>"", :x=>-1.442, :name=>"O2", :charge=>"", :element=>"O", :serial=>30585}, {:z=>67.655, :resName=>"EDO", :altLoc=>" ", :resSeq=>702, :occupancy=>1.0, :iCode=>"", :tempFactor=>17.09, :chainID=>"A", :y=>7.449, :segID=>"", :x=>2.792, :name=>"C1", :charge=>"", :element=>"C", :serial=>30586}, {:z=>67.213, :resName=>"EDO", :altLoc=>" ", :resSeq=>702, :occupancy=>1.0, :iCode=>"", :tempFactor=>15.74, :chainID=>"A", :y=>7.273, :segID=>"", :x=>1.451, :name=>"O1", :charge=>"", :element=>"O", :serial=>30587}]
+      actual = []
+      @res.each do |hetatm|
+        actual << {:serial=>hetatm.serial, :name=>hetatm.name, :altLoc=>hetatm.altLoc, :resName=>hetatm.resName, :chainID=>hetatm.chainID, :resSeq=>hetatm.resSeq, :iCode=>hetatm.iCode, :x=>hetatm.x, :y=>hetatm.y, :z=>hetatm.z, :occupancy=>hetatm.occupancy, :tempFactor=>hetatm.tempFactor, :segID=>hetatm.segID, :element=>hetatm.element, :charge=>hetatm.charge}
+      end
+      assert_equal(expected, actual)
+    end    
+
+    def test_het_atom
+      assert_equal(true, @res.hetatm)
+    end
+    def test_iCode
+      assert_equal( 1, @res.iCode=1)
+    end
+    def test_resSeq
+      assert_equal( 1, @res.resSeq=1)
+    end
+    def test_to_s
+      expected = "HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O  \nHETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C  \nHETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O  \nHETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C  \nHETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O  \n"
+      assert_equal(expected, @res.to_s)
+    end
+    def test_inspect
+      expected = "#<Bio::PDB::Heterogen resName=\"EDO\" id=\"701\" chain.id=nil resSeq=701 iCode=\"\" atoms.size=5>"
+      assert_equal(expected, at res.inspect)
+    end
+    def test_sort #<=>
+      expected = [Bio::PDB::Heterogen.new(resName="EDD",resSeq = 1, iCode = 2, chain = nil),
+                  Bio::PDB::Heterogen.new(resName="EDD",resSeq = 1, iCode = 3, chain = nil),
+                  Bio::PDB::Heterogen.new(resName="EDD",resSeq = 2,  iCode = 1, chain = nil)]
+      ress = [Bio::PDB::Heterogen.new(resName="EDD",resSeq = 1, iCode = 2, chain = nil)]
+      ress << Bio::PDB::Heterogen.new(resName="EDD",resSeq = 1, iCode = 3, chain = nil)
+      ress << Bio::PDB::Heterogen.new(resName="EDD",resSeq = 2,  iCode = 1, chain = nil)
+      actual = ress.sort do |a, b|
+        a <=> b
+      end
+      assert_equal(expected,actual)
+    end
+    def test_update_resudue_id
+      res = Bio::PDB::Heterogen.new(resName="EDD", resSeq = nil, iCode = nil, chain = nil)
+      assert_equal(nil, res.residue_id)
+    end
+  end
+  
+  class TestChain < Test::Unit::TestCase
+      def setup
+        @chain = Bio::PDB::Chain.new('A',nil)
+        @chain.addResidue(Bio::PDB::Residue.new(resName="ALA",resSeq = 7, iCode = 1, chain = @chain))
+        @chain.addResidue(Bio::PDB::Residue.new(resName="ALA",resSeq = 6, iCode = 2, chain = @chain))
+        @chain.addResidue(Bio::PDB::Residue.new(resName="ALA",resSeq = 7,  iCode = 3, chain = @chain))
+        @chain.addLigand(Bio::PDB::Heterogen.new(resName="EDD",resSeq = 1, iCode = 2, chain = @chain)) 
+      end
+
+      def test_square_brace #[]
+        expected = {:iCode=>1,
+                    :chain_id=>'A',
+                    :atoms_size=>0,
+                    :resSeq=>7,
+                    :id=>"71",
+                    :resName=>"ALA"}
+        residue = @chain["71"]
+        actual = {:resName => residue.resName, :id => residue.id, :chain_id => residue.chain.id, :resSeq => residue.resSeq, :iCode => residue.iCode, :atoms_size => residue.atoms.size}
+        assert_equal(expected, actual)
+      end
+      def test_comp #<=> 
+        expected = [{:iCode=>2,
+                     :chain_id=>'A',
+                     :atoms_size=>0,
+                     :resSeq=>6,
+                     :id=>"62",
+                     :resName=>"ALA"},
+                    {:iCode=>1,
+                     :chain_id=>'A',
+                     :atoms_size=>0,
+                     :resSeq=>7,
+                     :id=>"71",
+                     :resName=>"ALA"},
+                    {:iCode=>3,
+                     :chain_id=>'A',
+                     :atoms_size=>0,
+                     :resSeq=>7,
+                     :id=>"73",
+                     :resName=>"ALA"}]
+        sorted = @chain.sort do |a, b|
+          a<=>b
+        end
+        actual = []
+        sorted.each do |residue|
+          actual << {:resName => residue.resName, :id => residue.id, :chain_id => residue.chain.id, :resSeq => residue.resSeq, :iCode => residue.iCode, :atoms_size => residue.atoms.size}
+        end
+        assert_equal(expected, actual)
+      end
+      def test_addResidue
+        assert_nothing_raised{ @chain.addResidue(Bio::PDB::Residue.new(resName="ALA",resSeq = 9, iCode = 1, chain = @chain))}
+      end
+      def test_aaseq
+        assert_equal("AAA", @chain.aaseq)
+      end
+      def test_addLigand
+         assert_nothing_raised{ @chain.addLigand(Bio::PDB::Heterogen.new(resName="EDD",resSeq = 10, iCode = 2, chain = @chain)) }
+      end
+      def test_atom_seq
+        assert_equal("AAA", @chain.atom_seq)
+      end
+      def test_each
+        expected = [{:atoms_size=>0, :resSeq=>7, :chain_id=>'A', :iCode=>1, :id=>"71", :resName=>"ALA"}, {:atoms_size=>0, :resSeq=>6, :chain_id=>'A', :iCode=>2, :id=>"62", :resName=>"ALA"}, {:atoms_size=>0, :resSeq=>7, :chain_id=>'A', :iCode=>3, :id=>"73", :resName=>"ALA"}]
+        actual = []
+        @chain.each do |residue|
+           actual << {:resName => residue.resName, :id => residue.id, :chain_id => residue.chain.id, :resSeq => residue.resSeq, :iCode => residue.iCode, :atoms_size => residue.atoms.size}
+        end
+        assert_equal(expected, actual)
+      end
+      def test_each_residue
+        expected = [{:atoms_size=>0, :resSeq=>7, :chain_id=>'A', :iCode=>1, :id=>"71", :resName=>"ALA"}, {:atoms_size=>0, :resSeq=>6, :chain_id=>'A', :iCode=>2, :id=>"62", :resName=>"ALA"}, {:atoms_size=>0, :resSeq=>7, :chain_id=>'A', :iCode=>3, :id=>"73", :resName=>"ALA"}]
+        actual = []
+        @chain.each do |residue|
+           actual << {:resName => residue.resName, :id => residue.id, :chain_id => residue.chain.id, :resSeq => residue.resSeq, :iCode => residue.iCode, :atoms_size => residue.atoms.size}
+        end
+        assert_equal(expected, actual)
+      end
+      def test_each_heterogen
+        expected = [{:iCode=>2,
+                      :chain_id=>'A',
+                      :resSeq=>1,
+                      :id=>"12",
+                      :atoms_size=>0,
+                      :resName=>"EDD"}]
+        actual = []
+        @chain.each_heterogen do |heterogen|
+           actual << {:resName => heterogen.resName, :id => heterogen.id, :chain_id => heterogen.chain.id, :resSeq => heterogen.resSeq, :iCode => heterogen.iCode, :atoms_size => heterogen.atoms.size}
+        end
+        assert_equal(expected, actual)
+      end
+      def test_get_heterogen_by_id
+        heterogen = @chain.get_heterogen_by_id("12")
+        expected = {:iCode=>2,
+                      :chain_id=>'A',
+                      :resSeq=>1,
+                      :id=>"12",
+                      :atoms_size=>0,
+                      :resName=>"EDD"}
+        actual = {:resName => heterogen.resName, :id => heterogen.id, :chain_id => heterogen.chain.id,     :resSeq => heterogen.resSeq, :iCode => heterogen.iCode, :atoms_size => heterogen.atoms.size}
+        assert_equal(expected, actual)
+      end
+      def test_get_residue_by_id
+        residue = @chain.get_residue_by_id("71")
+        expected = {:atoms_size=>0, :resSeq=>7, :chain_id=>'A', :iCode=>1, :id=>"71", :resName=>"ALA"}
+        actual = {:resName => residue.resName, :id => residue.id, :chain_id => residue.chain.id,     :resSeq => residue.resSeq, :iCode => residue.iCode, :atoms_size => residue.atoms.size}
+        assert_equal(expected, actual)
+      end
+      def test_inspect
+        expected = "#<Bio::PDB::Chain id=\"A\" model.serial=nil residues.size=3 heterogens.size=1 aaseq=\"AAA\">"
+        assert_equal(expected, @chain.inspect)
+      end
+      def test_rehash
+        assert_nothing_raised{@chain.rehash}
+      end
+      def test_rehash_heterogens
+        assert_nothing_raised{@chain.rehash_heterogens}
+        
+        #assert_raise{@chain.rehash_heterogens}
+      end
+      def test_rehash_residues
+        assert_nothing_raised{@chain.rehash_residues}
+      end
+      def test_to_s
+        assert_equal("TER\n", at chain.to_s)
+      end
+  end
+
+  class TestModel < Test::Unit::TestCase
+      def setup
+        @model = Bio::PDB::Model.new(1,nil)
+        @model.addChain(Bio::PDB::Chain.new(1, @model))
+        @model.addChain(Bio::PDB::Chain.new(2, @model))
+        @model.addChain(Bio::PDB::Chain.new(3, @model))
+      end
+
+      def test_square_brace #[]
+        expected = {:id=>1, :model_serial=>1, :residues_size=>0, :heterogens_size=>0, :aaseq=>""}
+        residue = @model[1]
+        actual = {:id=>residue.id, :model_serial=>residue.model.serial, :residues_size=>residue.residues.size, :heterogens_size=>residue.heterogens.size, :aaseq=>residue.aaseq}
+
+        assert_equal(expected, actual)
+      end
+      def test_comp #<=> 
+        models = [Bio::PDB::Model.new(2,nil), Bio::PDB::Model.new(1,nil), Bio::PDB::Model.new(3,nil)]
+        expected = [{:serial=>1, :chains_size=>0},
+ {:serial=>2, :chains_size=>0},
+ {:serial=>3, :chains_size=>0}]
+
+        sorted = models.sort do |a, b|
+          a<=>b
+        end
+        actual = []
+        sorted.each do |model|
+          actual << {:serial => model.serial, :chains_size => model.chains.size }
+        end
+        assert_equal(expected, actual)
+      end
+      def test_addChain
+        assert_nothing_raised{ @model.addChain(Bio::PDB::Chain.new("D", @model))}
+      end
+      def test_each
+        expected = [{:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>1},
+                    {:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>2},
+                    {:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>3}]
+        actual = []
+        @model.each do |m|
+           actual << {:id => m.id, :model_serial => m.model.serial, :residues_size => m.residues.size, :heterogens_size => m.heterogens.size, :aaseq => m.aaseq }
+        end
+        assert_equal(expected, actual)
+      end
+
+      def test_each_chain
+        expected = [{:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>1},
+                    {:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>2},
+                    {:model_serial=>1,
+                     :aaseq=>"",
+                     :residues_size=>0,
+                     :heterogens_size=>0,
+                     :id=>3}]
+        actual = []
+        @model.each_chain do |m|
+           actual << {:id => m.id, :model_serial => m.model.serial, :residues_size => m.residues.size, :heterogens_size => m.heterogens.size, :aaseq => m.aaseq }
+        end
+        assert_equal(expected, actual)
+      end
+      def test_inspect
+        expected = "#<Bio::PDB::Model serial=1 chains.size=3>"
+        assert_equal(expected, @model.inspect)
+      end
+      def test_rehash
+        assert_nothing_raised{@model.rehash}
+      end
+      def test_to_s
+        assert_equal("MODEL     1\nTER\nTER\nTER\nENDMDL\n", at model.to_s)
+      end
+  end
+
+  #this class tests Bio::PDB::Utils with Bio::PDB::Residue class witch is generated directly
+  class TestUtils < Test::Unit::TestCase
+    def setup
+      @res = Bio::PDB::Residue.new(resName="ALA",resSeq = 7, iCode = "", chain = nil)
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      1  N   ALA A   7      23.484 -35.866  44.510  1.00 28.52           N"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      3  C   ALA A   7      23.102 -34.082  46.159  1.00 26.68           C"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      4  O   ALA A   7      23.097 -32.903  46.524  1.00 30.02           O"))
+      @res.addAtom(Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      5  CB  ALA A   7      23.581 -33.526  43.770  1.00 31.41           C"))
+    end
+
+    def test_geometricCentre
+      assert_instance_of(Bio::PDB::Coordinate, at res.geometricCentre())
+#      assert_equal(Vector[23.4226, -34.1772, 45.1734], @res.geometricCentre())
+      expected = [ 23.4226, -34.1772, 45.1734 ]
+      @res.geometricCentre().to_a.each do |num|
+        assert_in_delta(expected.shift, num, 0.001)
+      end
+      assert(expected.empty?)
+    end
+
+    def test_centreOfGravity
+      assert_instance_of(Bio::PDB::Coordinate, at res.centreOfGravity())
+      expected = [ 23.4047272727273, -34.1511515151515, 45.2351515151515 ]
+      @res.centreOfGravity().to_a.each do |num|
+        assert_in_delta(expected.shift, num, 0.001)
+      end
+      assert(expected.empty?)
+    end
+    
+    def test_distance
+      actual1 = Bio::PDB::Utils.distance(
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      7  CA  VAL A   8      21.887 -34.822  48.124  1.00 23.78           C")
+      )
+
+      actual2 = Bio::PDB::Utils.distance([23.849, -34.509,  44.904], [21.887, -34.822,  48.124])
+      assert_in_delta(3.78362432067456, actual1, 0.001)
+      assert_in_delta(3.78362432067456, actual2, 0.001)
+    end
+    def test_dihedral_angle
+      actual1 = Bio::PDB::Utils.dihedral_angle(
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      7  CA  VAL A   8      21.887 -34.822  48.124  1.00 23.78           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM     14  CA  PRO A   9      24.180 -35.345  51.107  1.00 22.35           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM     21  CA  ALA A  10      23.833 -38.844  52.579  1.00 23.41           C")
+      )
+
+
+      actual2 = Bio::PDB::Utils.dihedral_angle(
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849  34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      7  CA  VAL A   8      21.887  34.822  48.124  1.00 23.78           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM     14  CA  PRO A   9      24.180  35.345  51.107  1.00 22.35           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM     21  CA  ALA A  10      23.833  38.844  52.579  1.00 23.41           C")
+      )
+      assert_in_delta(-1.94387328933899, actual1, 0.001)
+      assert_in_delta( 1.94387328933899, actual2, 0.001)
+
+    end
+    def test_rad2deg
+      deg = Bio::PDB::Utils::rad2deg(3.14159265358979)
+      assert_in_delta(180.0, deg, 0.0000000001)
+    end
+
+  end #class Test_Utils
+
+  #The following classes is unit tests for Test_*Finder
+  #The sample data are arrays generated from corresponding Bio::PDB::* classes, witch has  Bio::PDB::Utils::*Finder
+
+  class TestModelFinder < Test::Unit::TestCase
+    def setup
+      @models = [Bio::PDB::Model.new(1), Bio::PDB::Model.new(2), Bio::PDB::Model.new(3)]
+      def @models.each_model
+        self.each do |model|
+          yield model
+        end
+      end
+      @models.extend(Bio::PDB::ModelFinder)
+    end
+
+    def test_find_model
+      expected = [Bio::PDB::Model.new(1), Bio::PDB::Model.new(2), Bio::PDB::Model.new(3)]
+      actual = @models.find_model{|m| true}
+      assert_equal(expected,actual)
+    end
+
+  end
+
+  class TestChainFinder < Test::Unit::TestCase
+    def setup
+      @model = [Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3)]
+    end
+
+    def test_find_chain
+      def @model.each_chain
+        self.each do |chain|
+          yield chain
+        end
+      end
+      @model.extend(Bio::PDB::ChainFinder)
+      expected = [Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3)]
+      actual = @model.find_chain{|m| true}
+      assert_equal(expected,actual)
+    end
+    def test_each_chain
+      expected = [Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3), Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3)]
+      models = [@model, at model]
+      def models.each_model
+        self.each do |model|
+          yield model
+        end
+      end
+      models.extend(Bio::PDB::ChainFinder)
+      actual = []
+      models.each_chain{|chain| actual << chain}
+      assert_equal(expected, actual)
+    end
+
+    def test_chains
+      expected = [Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3), Bio::PDB::Chain.new(1), Bio::PDB::Chain.new(2), Bio::PDB::Chain.new(3)]
+      @model.instance_eval{
+        def chains
+          return self
+        end
+      }
+      models = [@model, at model]
+      def models.each_model
+          self.each do |model|
+            yield model
+          end
+      end
+      models.extend(Bio::PDB::ChainFinder)
+      models.extend(Bio::PDB::ModelFinder)
+      actual = models.chains
+      assert_equal(expected,actual)
+    end
+  end #TestChainFinder
+
+  class TestResidueFinder < Test::Unit::TestCase
+    def setup
+      @residues = [Bio::PDB::Residue.new("",1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3)]
+    end
+
+    def test_find_residue
+      def @residues.each_residue
+        self.each do |residue|
+          yield residue
+        end
+      end
+      @residues.extend(Bio::PDB::ResidueFinder)
+#      expected = [Bio::PDB::Residue.new("",1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3)]
+      expected = [
+        {:resName=>"", :id=>"1", :chain=>nil, :resSeq=>1, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"2", :chain=>nil, :resSeq=>2, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"3", :chain=>nil, :resSeq=>3, :iCode=>nil, :atoms_size=>0},
+      ]
+      finded = @residues.find_residue{|m| true}
+      actual = []
+      finded.each do |res|
+         actual << {:resName=> res.resName, :id=> res.id, :chain=> res.chain, :resSeq=> res.resSeq, :iCode=> res.iCode, :atoms_size=> res.atoms.size}    
+      end
+      assert_equal(expected,actual)
+    end
+
+    def test_each_residue
+#      expected = [Bio::PDB::Residue.new("", 1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3), Bio::PDB::Residue.new("",1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3)]
+      expected = [
+        {:resName=>"", :id=>"1", :chain=>nil, :resSeq=>1, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"2", :chain=>nil, :resSeq=>2, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"3", :chain=>nil, :resSeq=>3, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"1", :chain=>nil, :resSeq=>1, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"2", :chain=>nil, :resSeq=>2, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"3", :chain=>nil, :resSeq=>3, :iCode=>nil, :atoms_size=>0}
+      ]
+      chains = [@residues, at residues]
+      def chains.each_chain
+        self.each do |chain|
+          yield chain
+        end
+      end
+      chains.extend(Bio::PDB::ResidueFinder)
+      actual = []
+      chains.each_residue do |res|
+         actual << {:resName=> res.resName, :id=> res.id, :chain=> res.chain, :resSeq=> res.resSeq, :iCode=> res.iCode, :atoms_size=> res.atoms.size}
+      end
+      assert_equal(expected, actual)
+    end
+
+    def test_residues
+#      expected = [Bio::PDB::Residue.new("", 1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3), Bio::PDB::Residue.new("",1), Bio::PDB::Residue.new("",2), Bio::PDB::Residue.new("",3)]
+      expected = [ 
+        {:resName=>"", :id=>"1", :chain=>nil, :resSeq=>1, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"2", :chain=>nil, :resSeq=>2, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"3", :chain=>nil, :resSeq=>3, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"1", :chain=>nil, :resSeq=>1, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"2", :chain=>nil, :resSeq=>2, :iCode=>nil, :atoms_size=>0},
+        {:resName=>"", :id=>"3", :chain=>nil, :resSeq=>3, :iCode=>nil, :atoms_size=>0}]
+      @residues.instance_eval{
+        def residues
+          return self
+        end
+     }
+      chains = [@residues, at residues]
+      def chains.each_chain
+        self.each do |chain|
+          yield chain
+        end
+      end
+      chains.extend(Bio::PDB::ResidueFinder)
+      chains.extend(Bio::PDB::ChainFinder)
+      actual = []
+      chains.residues.each do |res|
+        actual << {:resName=> res.resName, :id=> res.id, :chain=> res.chain, :resSeq=> res.resSeq, :iCode=> res.iCode, :atoms_size=> res.atoms.size}
+      end
+      assert_equal(expected,actual)
+    end
+  end #TestResidueFinder
+
+  class TestAtomFinder < Test::Unit::TestCase
+    def setup
+      @atoms = [Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+                Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+                Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C")]
+    end
+
+    def test_find_atom
+      expected = 
+        [Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+         Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+         Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C")]
+      def @atoms.each_atom
+        self.each do |atom|
+          yield atom
+        end
+      end
+      @atoms.extend(Bio::PDB::AtomFinder)
+      actual = @atoms.find_atom{|a| true}
+      assert_equal(expected,actual)
+    end
+
+    def test_each_atom
+      expected = [
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C")
+      ]
+      residues = [@atoms, at atoms]
+      def residues.each_residue
+        self.each do |residue|
+          yield residue
+        end
+      end
+      residues.extend(Bio::PDB::AtomFinder)
+      actual = []
+      residues.each_atom{|atom| actual << atom}
+      assert_equal(expected, actual)
+    end
+
+    def test_atoms
+      expected = [
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C"),
+        Bio::PDB::Record::ATOM.new.initialize_from_string("ATOM      2  CA  ALA A   7      23.849 -34.509  44.904  1.00 27.89           C")
+      ]
+      @atoms.instance_eval{
+        def atoms
+          return self
+        end
+     }
+      residues = [@atoms, at atoms]
+      def residues.each_residue
+        self.each do |atom|
+          yield atom
+        end
+      end
+      residues.extend(Bio::PDB::AtomFinder)
+      residues.extend(Bio::PDB::ResidueFinder)
+      actual = residues.atoms
+      assert_equal(expected,actual)
+    end
+  end #AtomFinder
+
+  class TestHetatmFinder < Test::Unit::TestCase
+    def setup
+      @hetatms =
+        [Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O")
+        ]
+    end
+
+    def test_find_hetatm
+      expected =
+        [Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+         Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O")
+        ]
+      def @hetatms.each_hetatm
+        self.each do |hetatm|
+          yield hetatm
+        end
+      end
+      @hetatms.extend(Bio::PDB::HetatmFinder)
+      actual = @hetatms.find_hetatm{|a| true}
+
+      assert_equal(expected,actual)
+    end
+
+    def test_each_hetatm
+      expected = [
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O")
+
+      ]
+      heterogens = [@hetatms, at hetatms]
+      def heterogens.each_heterogen
+        self.each do |heterogen|
+          yield heterogen
+        end
+      end
+      heterogens.extend(Bio::PDB::HetatmFinder)
+      actual = []
+      heterogens.each_hetatm{|hetatm| actual << hetatm}
+
+      assert_equal(expected, actual)
+    end
+
+    def test_hetatms
+      expected = [
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30583  O1  EDO A 701      -1.516 -26.859  49.587  1.00 35.20           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30584  C2  EDO A 701      -0.275 -28.124  51.219  1.00 34.49           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30585  O2  EDO A 701      -1.442 -28.941  51.167  1.00 33.95           O"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30586  C1  EDO A 702       2.792   7.449  67.655  1.00 17.09           C"),
+        Bio::PDB::Record::HETATM.new.initialize_from_string("HETATM30587  O1  EDO A 702       1.451   7.273  67.213  1.00 15.74           O")
+      ]
+      @hetatms.instance_eval{
+        def hetatms
+          return self
+        end
+     }
+      heterogens = [@hetatms, at hetatms]
+      def heterogens.each_heterogen
+        self.each do |heterogen|
+          yield heterogen
+        end
+      end
+      heterogens.extend(Bio::PDB::HetatmFinder)
+      heterogens.extend(Bio::PDB::HeterogenFinder)
+      actual = heterogens.hetatms
+      assert_equal(expected,actual)
+    end
+  end #HetatmFinder
+
+  class TestHeterogenFinder < Test::Unit::TestCase
+    def setup
+      @heterogens =
+        [Bio::PDB::Heterogen.new(),
+         Bio::PDB::Heterogen.new(),
+         Bio::PDB::Heterogen.new(),
+         Bio::PDB::Heterogen.new()
+        ]
+    end
+
+    def test_find_heterogen
+      def @heterogens.each_heterogen
+        self.each do |heterogen|
+          yield heterogen
+        end
+      end
+      @heterogens.extend(Bio::PDB::HeterogenFinder)
+      expected = [
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+      ]
+      hets = @heterogens.find_heterogen{|a| true}
+      actual = []
+      hets.each do |het|
+        actual << {:resName=> het.resName, :id=> het.id, :chain=> het.chain, :resSeq=> het.resSeq, :iCode=> het.iCode, :atoms_size=> het.atoms.size}
+      end
+      assert_equal(expected,actual)
+    end
+
+    def test_each_heterogen
+#      expected = [
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new()
+#      ]
+      expected = [
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0}
+      ]
+      def @heterogens.each_heterogen
+        self.each do |heterogen|
+          yield heterogen
+        end
+      end
+      chains = [@heterogens, at heterogens]
+      def chains.each_chain
+        self.each do |chain|
+          yield chain
+        end
+      end
+      chains.extend(Bio::PDB::HeterogenFinder)
+      actual = []
+      chains.each_heterogen do |het|
+        actual << {:resName=> het.resName, :id=> het.id, :chain=> het.chain, :resSeq=> het.resSeq, :iCode=> het.iCode, :atoms_size=> het.atoms.size}
+      end
+      assert_equal(expected, actual)
+    end
+
+    def test_heterogens
+#      expected = [
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new(),
+#        Bio::PDB::Heterogen.new()
+#      ]
+      expected = [
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0},
+        {:resName=>nil, :id=>nil, :chain=>nil, :resSeq=>nil, :iCode=>nil, :atoms_size=>0}
+      ]
+      @heterogens.instance_eval{
+        def heterogens
+          return self
+        end
+     }
+      chains = [@heterogens, at heterogens]
+      def chains.each_chain
+        self.each do |chain|
+          yield chain
+        end
+      end
+      chains.extend(Bio::PDB::HeterogenFinder)
+      chains.extend(Bio::PDB::ChainFinder)
+      hets = chains.heterogens
+        actual = []
+        hets.each do |het|
+           actual << {:resName=> het.resName, :id=> het.id, :chain=> het.chain, :resSeq=> het.resSeq, :iCode=> het.iCode, :atoms_size=> het.atoms.size}
+        end
 
+      assert_equal(expected,actual)
+    end
+  end #HetatmFinder
 end #module Bio
diff --git a/test/unit/bio/db/test_fasta.rb b/test/unit/bio/db/test_fasta.rb
index e89de1c..bd37e10 100644
--- a/test/unit/bio/db/test_fasta.rb
+++ b/test/unit/bio/db/test_fasta.rb
@@ -140,6 +140,40 @@ END
       assert_equal(data, @obj.entry)
     end
 
+    def test_entry_overrun
+      data =<<END
+>gi|55416190|gb|AAV50057.1| NADH dehydrogenase subunit 2 [Dasyurus hallucatus]
+MSPYVLMILTLSLFIGTCLTIFSNHWFTAWMGLEINTLAIIPLMTAPNNPRSTEAATKYFLTQATASMLMMFAIIYNAWS
+TNQWALPQLSDDWISLLMTVALAIKLGLAPFHFWVPEVTQGIPLLTGMILLTWQKIAPTAILFQIAPYLNMKFLVILAIL
+STLVGGWGGLNQTHLRKILAYSSIAHMGWMIIIVQINPTLSIFTLTIYVMATLTTFLTLNLSNSTKIKSLGNLWNKSATA
+TIIIFLTLLSLGGLPPLTGFMPKWLILQELINNGNIITATMMALSALLNLFFYMRLIYASSLTMFPSINNSKMQWYNNSM
+KTTTLIPTATVISSLLLPLTPLFVTLY
+END
+      assert_equal(data, @obj.entry_overrun)
+    end
+
+    class DummyFactory
+      def query(str)
+        @query_str = str
+        "DummyFactoryResult#{str.length}"
+      end
+      attr_reader :query_str
+    end #class DummyFactory
+
+    def test_query
+      data =<<END
+>gi|55416189|gb|AAV50056.1| NADH dehydrogenase subunit 1 [Dasyurus hallucatus]
+MFTINLLIYIIPILLAVAFLTLIERKMLGYMQFRKGPNIVGPYGLLQPFADAVKLFTKEPLRPLTSSISIFIIAPILALT
+IALTIWTPLPMPNTLLDLNLGLIFILSLSGLSVYSILWSGWASNSKYALIGALRAVAQTISYEVSLAIILLSIMLINGSF
+TLKTLSITQENLWLIITTWPLAMMWYISTLAETNRAPFDLTEGESELVSGFNVEYAAGPFAMFFLAEYANIIAMNAITTI
+LFLGPSLTPNLSHLNTLSFMLKTLLLTMVFLWVRASYPRFRYDQLMHLLWKNFLPMTLAMCLWFISLPIALSCIPPQL
+END
+
+      factory = DummyFactory.new
+      assert_equal("DummyFactoryResult401", @obj.query(factory))
+      assert_equal(data, factory.query_str)
+    end
+
     def test_entry_id
       assert_equal('gi|55416189', @obj.entry_id)
     end
@@ -194,16 +228,4 @@ END
 
   end # class TestFastaFormat
 
-
-
-
-  class TestFastaDefinition < Test::Unit::TestCase
-
-    def setup
-    end
-
-    def test_defline
-    end
-  end # class TestFastaDefinition
-
 end
diff --git a/test/unit/bio/db/test_fastq.rb b/test/unit/bio/db/test_fastq.rb
index 90c68f1..24688ff 100644
--- a/test/unit/bio/db/test_fastq.rb
+++ b/test/unit/bio/db/test_fastq.rb
@@ -278,6 +278,20 @@ _9_
         end
       end
 
+      def test_to_s
+        ids = IDLINES.dup
+        seqs = SEQS.dup
+        qstrs = QUALITY_STRINGS.dup
+        ent = []
+        while !ids.empty?
+          ent.push "@#{ids.shift}\n#{seqs.shift}\n+\n#{qstrs.shift}\n"
+        end
+        @ff.each do |e|
+          assert_equal(ent.shift, e.to_s)
+        end
+        assert(ent.empty?)
+      end
+
       def test_definition
         ids = IDLINES.dup
         @ff.each do |e|
@@ -369,6 +383,18 @@ _9_
         end
       end
 
+      def test_to_biosequence_and_output
+        @ff.each_with_index do |e, i|
+          id_line = IDLINES[i]
+          seq_line = SEQS[i]
+          qual_line = QUALITY_STRINGS[i]
+          # Changed default width to nil (no wrapping)
+          expected = "@#{id_line}\n#{seq_line}\n+\n#{qual_line}\n"
+          actual = e.to_biosequence.output(:fastq_sanger)
+          assert_equal(expected, actual)
+        end
+      end
+
       def test_roundtrip
         @ff.each_with_index do |e, i|
           str_orig = @ff.entry_raw
diff --git a/test/unit/bio/db/test_litdb.rb b/test/unit/bio/db/test_litdb.rb
new file mode 100644
index 0000000..cfb021b
--- /dev/null
+++ b/test/unit/bio/db/test_litdb.rb
@@ -0,0 +1,95 @@
+#
+# test/unit/bio/db/litdb.rb - Unit test for Bio::LITDB
+#
+# Copyright::  Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 3,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/db/litdb'
+require 'bio/reference'
+
+module Bio
+  class TestBioLITDB < Test::Unit::TestCase
+
+    def setup
+      filename = File.join(BioRubyTestDataPath, 'litdb', '1717226.litdb')
+      @obj = Bio::LITDB.new(File.read(filename))
+    end
+
+    # it return the reference infromation formatted as part of a Bio::Reference object.
+    def test_reference
+      expected = 
+ {:authors=>
+  ["Boyd, L.A.",
+   "Adam, L.",
+   "Pelcher, L.E.",
+   "McHughen, A.",
+   "Hirji, R.",
+   " Selvaraj, G."],
+
+ :issue=>"1",
+ :journal=>"Gene",
+ :pages=>"45-52",
+ :title=>
+  "Characterization of an Escherichia coli gene encoding betaine aldehyde dehydrogenase (BADH). Structural similarity to mammalian ALDHs and a plant BADH.",
+ :volume=>"103",
+ :year=>"(1991)"}
+     litdb_ref = @obj.reference
+       actual = {:authors=>litdb_ref.authors,
+         :journal=> litdb_ref.journal,
+         :pages=> litdb_ref.pages,
+         :volume=>litdb_ref.volume,
+         :year=>litdb_ref.year,
+         :issue=>litdb_ref.issue,
+         :title=>litdb_ref.title
+       }
+      assert_equal(expected, actual)
+    end
+
+    #access to the each field with field_fetch method.
+   #most methods are the same as values of Bio::Refence object.
+    def test_entry_id
+      assert_equal("1717226", @obj.entry_id)
+    end
+
+    def test_title
+      expected = "Characterization of an Escherichia coli gene encoding betaine aldehyde dehydrogenase (BADH). Structural similarity to mammalian ALDHs and a plant BADH."
+      assert_equal(expected, @obj.title)
+    end
+
+    def test_field
+      assert_equal("q (sequence analysis)", @obj.field)
+    end
+
+    def test_journal
+      assert_equal("Gene", @obj.journal)
+    end
+
+    def test_volume
+      assert_equal("Vol.103, No.1, 45-52 (1991)", @obj.volume)
+    end
+
+    def test_keyword
+      expected = ["*Betaine Aldehyde Dehydrogenase",
+ "*betB Gene;E.coli",
+ "Seq Determination;1854bp;491AAs",
+ "Hydropathy Plot;*EC1.2.1.8",
+ "Seq Comparison"]
+      assert_equal(expected, @obj.keyword)
+    end
+
+    def test_author
+      expected = "Boyd,L.A.;Adam,L.;Pelcher,L.E.;McHughen,A.;Hirji,R.; Selvaraj,G."
+      assert_equal(expected, @obj.author)
+    end
+
+  end #class TestBioLITDB
+end #module Bio
+
diff --git a/test/unit/bio/db/test_medline.rb b/test/unit/bio/db/test_medline.rb
index e9d3c37..9c7d3fc 100644
--- a/test/unit/bio/db/test_medline.rb
+++ b/test/unit/bio/db/test_medline.rb
@@ -41,6 +41,7 @@ module Bio
         'volume' => "11",
         'year' => "2010",
         'pubmed' => "20146148",
+        'doi' => "10.1080/15389580903471126",
         'mesh' =>
         [ "Accidents, Traffic/mortality/*statistics & numerical data",
           "Adult",
diff --git a/test/unit/bio/db/test_nbrf.rb b/test/unit/bio/db/test_nbrf.rb
new file mode 100644
index 0000000..d033a90
--- /dev/null
+++ b/test/unit/bio/db/test_nbrf.rb
@@ -0,0 +1,82 @@
+#
+# test/unit/bio/db/test_nbrf.rb - Unit test for Bio::NBRF
+#
+# Copyright::  Copyright (C) 2010 Kazuhiro Hayashi <k.hayashi.info at gmail.com>
+# License::    The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 3,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/db/nbrf'
+
+#some condition is not covered with it. This unit test need a nucleotide acid sequence.
+#I can't find a nucleic acid sequence in PIR format 
+module Bio
+  class TestBioNBRF < Test::Unit::TestCase
+
+    def setup
+      filename = File.join(BioRubyTestDataPath, 'pir', 'CRAB_ANAPL.pir')
+      @obj = Bio::NBRF.new(File.read(filename))
+    end
+
+
+    def test_entry
+      expected = <<END_OF_EXPECTED_ENTRY
+>P1;CRAB_ANAPL
+ALPHA CRYSTALLIN B CHAIN (ALPHA(B)-CRYSTALLIN).
+  MDITIHNPLI RRPLFSWLAP SRIFDQIFGE HLQESELLPA SPSLSPFLMR 
+  SPIFRMPSWL ETGLSEMRLE KDKFSVNLDV KHFSPEELKV KVLGDMVEIH 
+  GKHEERQDEH GFIAREFNRK YRIPADVDPL TITSSLSLDG VLTVSAPRKQ 
+  SDVPERSIPI TREEKPAIAG AQRK*
+END_OF_EXPECTED_ENTRY
+      assert_equal(expected, @obj.entry)
+    end
+
+    def test_seq_class
+      assert_equal(Bio::Sequence::AA, @obj.seq_class)
+    end
+
+    def test_seq
+      expected = "MDITIHNPLIRRPLFSWLAPSRIFDQIFGEHLQESELLPASPSLSPFLMRSPIFRMPSWLETGLSEMRLEKDKFSVNLDVKHFSPEELKVKVLGDMVEIHGKHEERQDEHGFIAREFNRKYRIPADVDPLTITSSLSLDGVLTVSAPRKQSDVPERSIPITREEKPAIAGAQRK"
+      assert_equal(expected, @obj.seq)
+    end
+
+    def test_length
+      assert_equal(174, @obj.length)
+    end
+
+    def test_naseq
+      assert_raise(RuntimeError){ @obj.naseq} #@obj is a protein sequence. the method must output error.
+    end
+
+    def test_nalen
+      assert_raise(RuntimeError){ @obj.nalen} #@obj is a protein sequence. the method must output error.
+    end
+
+    def test_aaseq
+      expected = "MDITIHNPLIRRPLFSWLAPSRIFDQIFGEHLQESELLPASPSLSPFLMRSPIFRMPSWLETGLSEMRLEKDKFSVNLDVKHFSPEELKVKVLGDMVEIHGKHEERQDEHGFIAREFNRKYRIPADVDPLTITSSLSLDGVLTVSAPRKQSDVPERSIPITREEKPAIAGAQRK"
+      assert_equal(expected, @obj.aaseq)
+    end
+
+    def test_aalen
+      assert_equal(174, @obj.aalen)
+    end
+
+    def test_to_nbrf
+      expected =<<EOS
+>aaa;ABCD
+this is a fake entry.
+atgc*
+EOS
+      nbrf = {:seq_type=>"aaa", :seq=>"atgc", :width=>7, :entry_id=>"ABCD", :definition=>"this is a fake entry."}
+      assert_equal(expected, Bio::NBRF.to_nbrf(nbrf))
+    end
+
+  end #class TestBioNBRF
+end #module Bio
+
diff --git a/test/unit/bio/db/test_newick.rb b/test/unit/bio/db/test_newick.rb
index 81d0842..db48401 100644
--- a/test/unit/bio/db/test_newick.rb
+++ b/test/unit/bio/db/test_newick.rb
@@ -39,9 +39,12 @@ module Bio
     )[0.1250];
     END_OF_TREE_STRING
 
+    def setup
+      @newick = Bio::Newick.new(TREE_STRING)
+    end
+
     def test_string_tree
-      newick = Bio::Newick.new(TREE_STRING)
-      tree = newick.tree
+      tree = @newick.tree
       assert_equal(3, tree.children(tree.root).size)
       assert_equal(9, tree.descendents(tree.root).size)
       assert_equal(6, tree.leaves.size)
@@ -52,6 +55,18 @@ module Bio
       assert_equal("HexFLZ83", leaf.name)
     end
 
+    def test_reparse
+      tree = @newick.tree
+      assert_equal(@newick, @newick.reparse)
+    end
+
+    def test_reparse_before_lazy_parsing
+      # not to use @newick to guarantee that the Newick object
+      # is before lazy parsing.
+      newick = Bio::Newick.new(TREE_STRING)
+      assert_equal(newick, newick.reparse)
+    end
+
   end #class TestNewick
 
   class TestNewick2 < Test::Unit::TestCase
@@ -72,9 +87,12 @@ module Bio
     )root;
     END_OF_TREE_STRING
 
+    def setup
+      @newick = Bio::Newick.new(TREE_STRING)
+    end
+
     def test_string_tree
-      newick = Bio::Newick.new(TREE_STRING)
-      tree = newick.tree
+      tree = @newick.tree
       assert_equal('root', tree.root.name)
       assert_equal([ 
                     "this is test",
diff --git a/test/unit/bio/test_reference.rb b/test/unit/bio/test_reference.rb
index 5ad396e..13bc05d 100644
--- a/test/unit/bio/test_reference.rb
+++ b/test/unit/bio/test_reference.rb
@@ -85,6 +85,11 @@ module Bio
       assert_equal(str, @obj.affiliations)
     end
 
+    def test_pubmed_url
+      assert_equal("http://www.ncbi.nlm.nih.gov/pubmed/12345678",
+                   @obj.pubmed_url)
+    end
+
     def test_format_general
       str = 'Hoge, J.P., Fuga, F.B. (2001). "Title of the study." Theor. J. Hoge 12:123-145.'
       assert_equal(str, @obj.format)
@@ -201,6 +206,36 @@ __END__
 
   end
 
+  class TestReference_noURL < Test::Unit::TestCase
+    def setup
+      hash = {
+        'authors' => [ "Hoge, J.P.", "Fuga, F.B." ],
+        'title' => "Title of the study.",
+        'journal' => "Theor. J. Hoge",
+        'volume' => 12,
+        'issue' => 3,
+        'pages' => "123-145",
+        'year' => 2001,
+        'pubmed' => 12345678,
+        'medline' => 98765432,
+        'abstract' => "Hoge fuga. hoge fuga.",
+        'mesh' => ['Hoge'],
+        'affiliations' => ['Tokyo']
+      }
+      @obj = Bio::Reference.new(hash)
+    end
+
+    def test_url
+      assert_equal(nil, @obj.url)
+    end
+
+    def test_format_endnote
+      str = "%0 Journal Article\n%A Hoge, J.P.\n%A Fuga, F.B.\n%D 2001\n%T Title of the study.\n%J Theor. J. Hoge\n%V 12\n%N 3\n%P 123-145\n%M 12345678\n%U http://www.ncbi.nlm.nih.gov/pubmed/12345678\n%X Hoge fuga. hoge fuga.\n%K Hoge\n%+ Tokyo"
+      assert_equal(str, @obj.format('endnote'))
+      assert_equal(str, @obj.endnote)
+    end
+  end #class TestReference_noURL
+
   class TestReferences < Test::Unit::TestCase
 
     class NullStderr
diff --git a/test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb b/test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb
new file mode 100644
index 0000000..b59d8d4
--- /dev/null
+++ b/test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb
@@ -0,0 +1,201 @@
+#
+# test/unit/bio/util/restriction_enzyme/test_dense_int_array.rb - Unit test for Bio::RestrictionEnzyme::DenseIntArray
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/util/restriction_enzyme'
+require 'bio/util/restriction_enzyme/dense_int_array'
+
+module Bio
+module TestRestrictionEnzyme
+
+  class TestDenseIntArray < Test::Unit::TestCase
+
+    def setup
+      @klass = Bio::RestrictionEnzyme::DenseIntArray
+      @obj = @klass[ -1, 11, 12, 13, 14, 15, 50, 60 ]
+    end
+
+    def test_self_bracket
+      assert_equal([ -1, 11, 12, 13, 14, 15, 50, 60 ], @obj.to_a)
+    end
+
+    def test_self_new
+      a = @klass.new
+      assert_instance_of(Bio::RestrictionEnzyme::DenseIntArray, a)
+    end
+
+    def test_dup
+      assert_equal(@obj.to_a, @obj.dup.to_a)
+      d_obj = @obj.instance_eval { internal_data }
+      d_dup = @obj.dup.instance_eval { internal_data }
+      assert(d_obj == d_dup)
+      assert_not_equal(d_obj.__id__, d_dup.__id__)
+    end
+
+    def test_internal_data
+      d = @obj.instance_eval { internal_data }
+      r = @klass::MutableRange
+      expected = [ r.new(-1, -1), r.new(11, 15),
+                   r.new(50, 50), r.new(60, 60) ]
+      assert_equal(expected, d)
+    end
+
+    def test_internal_data_eq
+      r = @klass::MutableRange
+      d = [ r.new(-2, -2), r.new(50, 50), r.new(65, 70) ]
+      @obj.instance_eval { self.internal_data = d }
+      assert_equal(70, @obj.last)
+      assert_equal([-2, 50, 65, 66, 67, 68, 69, 70], @obj.to_a)
+    end
+
+    def test_bracket
+      assert_equal(-1, @obj[0])
+      assert_equal(13, @obj[3])
+      assert_equal(60, @obj[-1])
+      assert_equal([-1, 11, 12], @obj[0..2])
+      assert_equal([14, 15, 50], @obj[4,3])
+    end
+
+    def test_bracket_eq
+      assert_raise(NotImplementedError) {
+        @obj[3] = 999
+      }
+    end
+
+    def test_each
+      expected_values = [ -1, 11, 12, 13, 14, 15, 50, 60 ]
+      @obj.each do |i|
+        assert_equal(expected_values.shift, i)
+      end
+    end
+
+    def test_reverse_each
+      expected_values = [ -1, 11, 12, 13, 14, 15, 50, 60 ]
+      @obj.reverse_each do |i|
+        assert_equal(expected_values.pop, i)
+      end
+    end
+
+    def test_plus
+      obj2 = @klass[ 9, 10, 11, 12, 30 ]
+      assert_equal([ -1, 9, 10, 11, 12, 13, 14, 15, 30, 50, 60 ],
+                   (@obj + obj2).to_a)
+    end
+
+    def test_plus_error
+      assert_raise(TypeError) {
+        @obj + 2
+      }
+    end
+
+    def test_eqeq
+      obj2 = @klass[ -1, 11, 12, 13, 14, 15, 50, 60 ]
+      assert_equal(true, @obj == obj2)
+    end
+
+    def test_eqeq_self
+      assert_equal(true, @obj == @obj)
+    end
+
+    def test_eqeq_false
+      obj2 = @klass[ 2, 3, 14, 15 ]
+      assert_equal(false, @obj == obj2)
+    end
+
+    def test_eqeq_other
+      obj2 = 'test'
+      assert_equal(false, @obj == obj2)
+    end
+
+    def test_concat
+      ary = [ 61, 62, -2, 14, 15 ]
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60, 61, 62, -2, 14, 15 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj.concat(ary))
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_push
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60, 61, 62, -2, 14, 15 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj.push(61, 62, -2, 14, 15))
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_unshift
+      assert_raise(NotImplementedError) { @obj.unshift(-5, -2) }
+    end
+
+    def test_ltlt
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60, 61 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj << 61)
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_ltlt_larger
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60, 70 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj << 70)
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_ltlt_middle
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60, 30 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj << 30)
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_include?
+      assert_equal(true, @obj.include?(13))
+      assert_equal(false, @obj.include?(999))
+    end
+
+    def test_size
+      assert_equal(8, @obj.size)
+    end
+
+    def test_length
+      assert_equal(8, @obj.length)
+    end
+
+    def test_delete
+      assert_raise(NotImplementedError) { @obj.delete(11) }
+    end
+
+    def test_sort!
+      assert_equal(@obj, @obj.sort!)
+    end
+
+    def test_uniq!
+      assert_equal(@obj, @obj.uniq!)
+    end
+
+    def test_to_a
+      expected = [ -1, 11, 12, 13, 14, 15, 50, 60 ]
+      assert_equal(expected, @obj.to_a)
+    end
+
+  end #class TestDenseIntArray
+
+end #module TestRestrictionEnzyme
+end #module Bio
+
+
diff --git a/test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb b/test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb
new file mode 100644
index 0000000..c96e417
--- /dev/null
+++ b/test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb
@@ -0,0 +1,281 @@
+#
+# test/unit/bio/util/restriction_enzyme/test_sorted_num_array.rb - Unit test for Bio::RestrictionEnzyme::SortedNumArray
+#
+# Copyright::   Copyright (C) 2011
+#               Naohisa Goto <ng at bioruby.org>
+# License::     The Ruby License
+#
+
+# loading helper routine for testing bioruby
+require 'pathname'
+load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
+                            'bioruby_test_helper.rb')).cleanpath.to_s
+
+# libraries needed for the tests
+require 'test/unit'
+require 'bio/util/restriction_enzyme'
+require 'bio/util/restriction_enzyme/sorted_num_array'
+
+module Bio
+module TestRestrictionEnzyme
+
+  class TestSortedNumArray < Test::Unit::TestCase
+
+    def setup
+      @klass = Bio::RestrictionEnzyme::SortedNumArray
+      @obj = @klass[14, 265, 4626, -1, 358, 159, 979, 3238, 3]
+    end
+
+    def test_self_bracket
+      assert_equal([ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ],
+                   @obj.to_a)
+    end
+
+    def test_self_new
+      a = @klass.new
+      assert_instance_of(Bio::RestrictionEnzyme::SortedNumArray, a)
+    end
+
+    def test_dup
+      assert_equal(@obj.to_a, @obj.dup.to_a)
+      h_obj = @obj.instance_eval { internal_data_hash }
+      h_dup = @obj.dup.instance_eval { internal_data_hash }
+      assert(h_obj == h_dup)
+      assert_not_equal(h_obj.__id__, h_dup.__id__)
+    end
+
+    def test_internal_data_hash
+      h = @obj.instance_eval { internal_data_hash }
+      expected = { -1 => true,
+        3 => true, 14 => true, 159 => true, 265 => true,
+        358 => true, 979 => true, 3238 => true, 4626 => true }
+      assert_equal(expected, h)
+    end
+
+    def test_internal_data_hash_eq
+      h = { 0 => true, 50 => true, 100 => true }
+      @obj.last # creating cache (if exists)
+      @obj.instance_eval { self.internal_data_hash = h }
+      assert_equal(100, @obj.last)
+      assert_equal([0, 50, 100], @obj.to_a)
+    end
+
+    #def test_private_clear_cache
+    #  assert_nothing_raised {
+    #    @obj.instance_eval { clear_cache }
+    #  }
+    #  @obj.last # creating cache
+    #  @obj.instance_eval { clear_cache }
+    #  assert_nil(@obj.instance_eval { @sorted_keys })
+    #end
+
+    def test_private_sorted_keys
+      a = @obj.instance_eval { sorted_keys }
+      assert_equal([ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ], a)
+    end
+
+    def test_private_push_element
+      assert_equal(false, @obj.include?(50))
+      @obj.instance_eval {
+        push_element(50)
+      }
+      assert_equal(true, @obj.include?(50))
+    end
+
+    def test_private_push_element_noeffect
+      assert_equal(true, @obj.include?(159))
+      @obj.instance_eval {
+        push_element(159)
+      }
+      assert_equal(true, @obj.include?(159))
+    end
+
+    def test_private_push_element_last
+      @obj.last # creating cache (if exists)
+      @obj.instance_eval {
+        push_element(9999)
+      }
+      assert_equal(true, @obj.include?(9999))
+      assert_equal(9999, @obj.last)
+    end
+
+    def test_private_push_element_intermediate
+      @obj.last # creating cache (if exists)
+      @obj.instance_eval {
+        push_element(100)
+      }
+      assert_equal(true, @obj.include?(100))
+      assert_equal(4626, @obj.last)
+    end
+
+    def test_private_unshift_element
+      assert_equal(false, @obj.include?(50))
+      @obj.instance_eval {
+        unshift_element(50)
+      }
+      assert_equal(true, @obj.include?(50))
+    end
+
+    def test_private_unshift_element_noeffect
+      assert_equal(true, @obj.include?(159))
+      @obj.instance_eval {
+        unshift_element(159)
+      }
+      assert_equal(true, @obj.include?(159))
+    end
+
+    def test_private_unshift_element_first
+      @obj.last # creating cache (if exists)
+      @obj.instance_eval {
+        unshift_element(-999)
+      }
+      assert_equal(true, @obj.include?(-999))
+      assert_equal(-999, @obj.first)
+    end
+
+    def test_private_unshift_element_intermediate
+      @obj.last # creating cache (if exists)
+      @obj.instance_eval {
+        unshift_element(100)
+      }
+      assert_equal(true, @obj.include?(100))
+      assert_equal(-1, @obj.first)
+    end
+
+    def test_bracket
+      assert_equal(-1, @obj[0])
+      assert_equal(159, @obj[3])
+      assert_equal(4626, @obj[-1])
+      assert_equal([14, 159, 265], @obj[2..4])
+      assert_equal([14, 159, 265], @obj[2,3])
+    end
+
+    def test_bracket_eq
+      assert_raise(NotImplementedError) {
+        @obj[3] = 999
+      }
+    end
+
+    def test_each
+      expected_values = [ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ]
+      @obj.each do |i|
+        assert_equal(expected_values.shift, i)
+      end
+    end
+
+    def test_reverse_each
+      expected_values = [ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ]
+      @obj.reverse_each do |i|
+        assert_equal(expected_values.pop, i)
+      end
+    end
+
+    def test_plus
+      obj2 = @klass[ 2, 3, 14, 15 ]
+      assert_equal([ -1, 2, 3, 14, 15, 159, 265, 358, 979, 3238, 4626 ],
+                   (@obj + obj2).to_a)
+    end
+
+    def test_plus_error
+      assert_raise(TypeError) {
+        @obj + 2
+      }
+    end
+
+    def test_eqeq
+      obj2 = @klass[ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ]
+      assert_equal(true, @obj == obj2)
+    end
+
+    def test_eqeq_self
+      assert_equal(true, @obj == @obj)
+    end
+
+    def test_eqeq_false
+      obj2 = @klass[ 2, 3, 14, 15 ]
+      assert_equal(false, @obj == obj2)
+    end
+
+    def test_eqeq_other
+      obj2 = 'test'
+      assert_equal(false, @obj == obj2)
+    end
+
+    def test_concat
+      ary = [ 9999, -2, 14, 15 ]
+      expected = [ -2, -1, 3, 14, 15, 159, 265, 358, 979, 3238, 4626, 9999 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj.concat(ary))
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_push
+      expected = [ -2, -1, 3, 14, 15, 159, 265, 358, 979, 3238, 4626, 9999 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj.push(15, 14, -2, 9999))
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_unshift
+      expected = [ -2, -1, 3, 14, 15, 159, 265, 358, 979, 3238, 4626, 9999 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj.unshift(15, 14, -2, 9999))
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_ltlt
+      expected = [ -1, 3, 14, 15, 159, 265, 358, 979, 3238, 4626 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj << 15)
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_ltlt_noeffect
+      expected = [ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ]
+      # checks if the method returns self
+      assert_equal(@obj, @obj << 159)
+      # checks the value
+      assert_equal(expected, @obj.to_a)
+    end
+
+    def test_include?
+      assert_equal(true, @obj.include?(159))
+      assert_equal(false, @obj.include?(999))
+    end
+
+    def test_size
+      assert_equal(9, @obj.size)
+    end
+
+    def test_length
+      assert_equal(9, @obj.length)
+    end
+
+    def test_delete
+      assert_equal(nil, @obj.delete(100))
+      assert_equal(159, @obj.delete(159))
+    end
+
+    def test_sort!
+      assert_equal(@obj, @obj.sort!)
+    end
+
+    def test_uniq!
+      assert_equal(@obj, @obj.uniq!)
+    end
+
+    def test_to_a
+      expected = [ -1, 3, 14, 159, 265, 358, 979, 3238, 4626 ]
+      assert_equal(expected, @obj.to_a)
+    end
+
+  end #class TestSortedNumArray
+
+end #module TestRestrictionEnzyme
+end #module Bio
+
+

-- 
ruby-bio.git



More information about the Pkg-ruby-extras-commits mailing list