Squashed 'third_party/boostorg/range/' content from commit 4cfd4d8

Change-Id: I641c49f21039952b16f888223a952503e43a28a9
git-subtree-dir: third_party/boostorg/range
git-subtree-split: 4cfd4d8287ca949d7f29256adf3e796a0d1775ec
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3e84d7c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,96 @@
+* text=auto !eol svneol=native#text/plain
+*.gitattributes text svneol=native#text/plain
+
+# Scriptish formats
+*.bat        text svneol=native#text/plain
+*.bsh        text svneol=native#text/x-beanshell
+*.cgi        text svneol=native#text/plain
+*.cmd        text svneol=native#text/plain
+*.js         text svneol=native#text/javascript
+*.php        text svneol=native#text/x-php
+*.pl         text svneol=native#text/x-perl
+*.pm         text svneol=native#text/x-perl
+*.py         text svneol=native#text/x-python
+*.sh         eol=lf svneol=LF#text/x-sh
+configure    eol=lf svneol=LF#text/x-sh
+
+# Image formats
+*.bmp        binary svneol=unset#image/bmp
+*.gif        binary svneol=unset#image/gif
+*.ico        binary svneol=unset#image/ico
+*.jpeg       binary svneol=unset#image/jpeg
+*.jpg        binary svneol=unset#image/jpeg
+*.png        binary svneol=unset#image/png
+*.tif        binary svneol=unset#image/tiff
+*.tiff       binary svneol=unset#image/tiff
+*.svg        text svneol=native#image/svg%2Bxml
+
+# Data formats
+*.pdf        binary svneol=unset#application/pdf
+*.avi        binary svneol=unset#video/avi
+*.doc        binary svneol=unset#application/msword
+*.dsp        text svneol=crlf#text/plain
+*.dsw        text svneol=crlf#text/plain
+*.eps        binary svneol=unset#application/postscript
+*.gz         binary svneol=unset#application/gzip
+*.mov        binary svneol=unset#video/quicktime
+*.mp3        binary svneol=unset#audio/mpeg
+*.ppt        binary svneol=unset#application/vnd.ms-powerpoint
+*.ps         binary svneol=unset#application/postscript
+*.psd        binary svneol=unset#application/photoshop
+*.rdf        binary svneol=unset#text/rdf
+*.rss        text svneol=unset#text/xml
+*.rtf        binary svneol=unset#text/rtf
+*.sln        text svneol=native#text/plain
+*.swf        binary svneol=unset#application/x-shockwave-flash
+*.tgz        binary svneol=unset#application/gzip
+*.vcproj     text svneol=native#text/xml
+*.vcxproj    text svneol=native#text/xml
+*.vsprops    text svneol=native#text/xml
+*.wav        binary svneol=unset#audio/wav
+*.xls        binary svneol=unset#application/vnd.ms-excel
+*.zip        binary svneol=unset#application/zip
+
+# Text formats
+.htaccess    text svneol=native#text/plain
+*.bbk        text svneol=native#text/xml
+*.cmake      text svneol=native#text/plain
+*.css        text svneol=native#text/css
+*.dtd        text svneol=native#text/xml
+*.htm        text svneol=native#text/html
+*.html       text svneol=native#text/html
+*.ini        text svneol=native#text/plain
+*.log        text svneol=native#text/plain
+*.mak        text svneol=native#text/plain
+*.qbk        text svneol=native#text/plain
+*.rst        text svneol=native#text/plain
+*.sql        text svneol=native#text/x-sql
+*.txt        text svneol=native#text/plain
+*.xhtml      text svneol=native#text/xhtml%2Bxml
+*.xml        text svneol=native#text/xml
+*.xsd        text svneol=native#text/xml
+*.xsl        text svneol=native#text/xml
+*.xslt       text svneol=native#text/xml
+*.xul        text svneol=native#text/xul
+*.yml        text svneol=native#text/plain
+boost-no-inspect text svneol=native#text/plain
+CHANGES      text svneol=native#text/plain
+COPYING      text svneol=native#text/plain
+INSTALL      text svneol=native#text/plain
+Jamfile      text svneol=native#text/plain
+Jamroot      text svneol=native#text/plain
+Jamfile.v2   text svneol=native#text/plain
+Jamrules     text svneol=native#text/plain
+Makefile*    text svneol=native#text/plain
+README       text svneol=native#text/plain
+TODO         text svneol=native#text/plain
+
+# Code formats
+*.c          text svneol=native#text/plain
+*.cpp        text svneol=native#text/plain
+*.h          text svneol=native#text/plain
+*.hpp        text svneol=native#text/plain
+*.ipp        text svneol=native#text/plain
+*.tpp        text svneol=native#text/plain
+*.jam        text svneol=native#text/plain
+*.java       text svneol=native#text/plain
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..314afb9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,131 @@
+# Copyright 2016, 2017 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
+
+language: cpp
+
+sudo: false
+
+python: "2.7"
+
+branches:
+  only:
+    - master
+    - develop
+    - /feature\/.*/
+
+env:
+  matrix:
+    - BOGUS_JOB=true
+
+matrix:
+
+  exclude:
+    - env: BOGUS_JOB=true
+
+  include:
+    - os: linux
+      compiler: g++
+      env: TOOLSET=gcc CXXSTD=03,11
+
+    - os: linux
+      compiler: g++-5
+      env: TOOLSET=gcc-5 CXXSTD=03,11
+      addons:
+        apt:
+          packages:
+            - g++-5
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-5
+      env: TOOLSET=gcc-5 CXXSTD=14,1z
+      addons:
+        apt:
+          packages:
+            - g++-5
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-6
+      env: TOOLSET=gcc-6 CXXSTD=03,11
+      addons:
+        apt:
+          packages:
+            - g++-6
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-6
+      env: TOOLSET=gcc-6 CXXSTD=14,1z
+      addons:
+        apt:
+          packages:
+            - g++-6
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-7
+      env: TOOLSET=gcc-7 CXXSTD=03,11
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-7
+      env: TOOLSET=gcc-7 CXXSTD=14,17
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: clang++
+      env: TOOLSET=clang CXXSTD=03,11
+
+    - os: linux
+      compiler: clang++
+      env: TOOLSET=clang CXXSTD=14,1z
+      addons:
+        apt:
+          packages:
+            - libstdc++-4.9-dev
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: osx
+      compiler: clang++
+      env: TOOLSET=clang CXXSTD=03,11
+
+    - os: osx
+      compiler: clang++
+      env: TOOLSET=clang CXXSTD=14,1z
+
+install:
+  - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
+  - cd ..
+  - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
+  - cd boost-root
+  - git submodule update --init tools/build
+  - git submodule update --init libs/config
+  - git submodule update --init tools/boostdep
+  - cp -r $TRAVIS_BUILD_DIR/* libs/range
+  - python tools/boostdep/depinst/depinst.py range
+  - ./bootstrap.sh
+  - ./b2 headers
+
+script:
+  - ./b2 -j 3 libs/range/test toolset=$TOOLSET cxxstd=$CXXSTD
+
+notifications:
+  email:
+    on_success: always
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..2d19fc7
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1 @@
+*.html
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..c507180
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,35 @@
+#// Boost.Range library
+#//
+#//  Copyright Thorsten Ottosen 2003-2008. Use, modification and
+#//  distribution is subject to the Boost Software License, Version
+#//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+#//  http://www.boost.org/LICENSE_1_0.txt)
+#//
+#// For more information, see http://www.boost.org/libs/range/
+#//
+
+project boost/libs/range/doc ;
+using boostbook ;
+using quickbook ;
+
+path-constant images_location : html ;
+
+boostbook quickbook
+  :
+    boost_range.qbk
+  :
+    <xsl:param>boost.root=../../../..
+    <xsl:param>chunk.section.depth=4
+    <xsl:param>chunk.first.sections=1
+    <xsl:param>toc.section.depth=3
+    <xsl:param>toc.max.depth=3
+    <xsl:param>generate.section.toc.level=4
+    <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
+    <format>pdf:<xsl:param>img.src.path=$(images_location)/
+  ;
+
+###############################################################################
+alias boostdoc ;
+explicit boostdoc ;
+alias boostrelease : quickbook ;
+explicit boostrelease ;
diff --git a/doc/boost_range.qbk b/doc/boost_range.qbk
new file mode 100644
index 0000000..d509fb9
--- /dev/null
+++ b/doc/boost_range.qbk
@@ -0,0 +1,199 @@
+[/==============================================================================
+    Copyright (C) 2003-2010 Thorsten Ottosen, Neil Groves
+
+    Use, modification and distribution is subject to the Boost Software
+    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+    http://www.boost.org/LICENSE_1_0.txt
+==============================================================================/]
+[library Range
+    [quickbook 1.5]
+    [version 2.0]
+    [authors [Ottosen, Thorsten], [Groves, Neil]]
+    [copyright 2003-2010 Thorsten Ottosen, Neil Groves]
+    [purpose Half-open range library]
+    [license
+        Distributed under the Boost Software License, Version 1.0.
+        (See accompanying file LICENSE_1_0.txt or copy at
+        [@http://www.boost.org/LICENSE_1_0.txt])
+    ]
+]
+
+[/ Converted to Quickbook format by Darren Garvey, 2007]
+
+[def __note__                   [$images/note.png]]
+[def __alert__                  [$images/alert.png]]
+[def __tip__                    [$images/tip.png]]
+[def __caution__                [$images/caution.png]]
+
+[def __boost_range_home__       [link range Boost.Range]]
+[def __ranges__                 [link range.concepts Ranges]]
+[def __range_concepts__         [link range.concepts Range concepts]]
+[def __forward_range__          [link range.concepts.forward_range Forward Range]]
+[def __single_pass_range__      [link range.concepts.single_pass_range Single Pass Range]]
+[def __bidirectional_range__    [link range.concepts.bidirectional_range Bidirectional Range]]
+[def __random_access_range__    [link range.concepts.random_access_range Random Access Range]]
+
+[def __iterator_range__         [link range.reference.utilities.iterator_range `iterator_range`]]
+[def __sub_range__              [link range.reference.utilities.sub_range `sub_range`]]
+[def __minimal_interface__      [link range.reference.extending minimal interface]]
+[def __range_result_iterator__  [link range.reference.concept_implementation.semantics.metafunctions `range_result_iterator`]]
+[def __extending_for_udts__ [link range.reference.extending Extending the library for UDTs]]
+[def __implementation_of_metafunctions__ [link range.reference.concept_implementation.semantics.metafunctions Implementation of metafunctions]]
+[def __implementation_of_functions__     [link range.reference.concept_implementation.semantics.functions Implementation of functions]]
+
+[def __range_value__            [link range.reference.concept_implementation.semantics.metafunctions `range_value`]]
+[def __range_iterator__         [link range.reference.concept_implementation.semantics.metafunctions `range_iterator`]]
+[def __range_difference__       [link range.reference.concept_implementation.semantics.metafunctions `range_difference`]]
+[def __range_pointer__          [link range.reference.concept_implementation.semantics.metafunctions `range_pointer`]]
+[def __range_category__         [link range.reference.concept_implementation.semantics.metafunctions `range_category`]]
+[def __range_reverse_iterator__ [link range.reference.concept_implementation.semantics.metafunctions `range_reverse_iterator`]]
+[def __begin__                  [link range.reference.concept_implementation.semantics.functions `begin`]]
+[def __const_begin__            [link range.reference.concept_implementation.semantics.functions `const_begin`]]
+[def __end__                    [link range.reference.concept_implementation.semantics.functions `end`]]
+[def __const_end__              [link range.reference.concept_implementation.semantics.functions `const_end`]]
+[def __empty__                  [link range.reference.concept_implementation.semantics.functions `empty`]]
+[def __distance__               [link range.reference.concept_implementation.semantics.functions `distance`]]
+[def __size__                   [link range.reference.concept_implementation.semantics.functions `size`]]
+[def __rbegin__                 [link range.reference.concept_implementation.semantics.functions `rbegin`]]
+[def __const_rbegin__           [link range.reference.concept_implementation.semantics.functions `const_rbegin`]]
+[def __rend__                   [link range.reference.concept_implementation.semantics.functions `rend`]]
+[def __const_rend__             [link range.reference.concept_implementation.semantics.functions `const_rend`]]
+[def __as_array__               [link range.reference.concept_implementation.semantics.functions `as_array`]]
+[def __as_literal__             [link range.reference.concept_implementation.semantics.functions `as_literal`]]
+[def __counting_range__         [link range.reference.ranges.counting_range `counting_range`]]
+[def __irange__                 [link range.reference.ranges.irange `irange`]]
+[def __istream_range__          [link range.reference.ranges.istream_range `istream_range`]]
+[def __combine__                [link range.reference.utilities.combine `combine`]]
+[def __join__                   [link range.reference.utilities.join `join`]]
+
+[def __range_adaptors__                   [link range.reference.adaptors Range adaptors]]
+[def __range_adaptors_adjacent_filtered__ [link range.reference.adaptors.reference.adjacent_filtered adjacent_filtered]]
+[def __range_adaptors_copied__            [link range.reference.adaptors.reference.copied copied]]
+[def __range_adaptors_filtered__          [link range.reference.adaptors.reference.filtered filtered]]
+[def __range_adaptors_formatted__         [link.range.reference.adaptors.reference.formatted formatted]]
+[def __range_adaptors_indexed__           [link range.reference.adaptors.reference.indexed indexed]]
+[def __range_adaptors_indirected__        [link range.reference.adaptors.reference.indirected indirected]]
+[def __range_adaptors_map_keys__          [link range.reference.adaptors.reference.map_keys map_keys]]
+[def __range_adaptors_map_values__        [link range.reference.adaptors.reference.map_values map_values]]
+[def __range_adaptors_replaced__          [link range.reference.adaptors.reference.replaced replaced]]
+[def __range_adaptors_replaced_if__       [link range.reference.adaptors.reference.replaced_if replaced_if]]
+[def __range_adaptors_reversed__          [link range.reference.adaptors.reference.reversed reversed]]
+[def __range_adaptors_sliced__            [link range.reference.adaptors.reference.sliced sliced]]
+[def __range_adaptors_strided__           [link range.reference.adaptors.reference.strided strided]]
+[def __range_adaptors_type_erased__       [link range.reference.adaptors.reference.type_erased type_erased]]
+[def __range_adaptors_tokenized__         [link range.reference.adaptors.reference.tokenized tokenized]]
+[def __range_adaptors_transformed__       [link range.reference.adaptors.reference.transformed transformed]]
+[def __range_adaptors_uniqued__           [link range.reference.adaptors.reference.uniqued uniqued]]
+
+
+[def __range_algorithms__                         [link range.reference.algorithms Range algorithms]]
+[def __range_algorithms_adjacent_find__           [link range.reference.algorithms.non_mutating.adjacent_find adjacent_find]]
+[def __range_algorithms_binary_search__           [link range.reference.algorithms.non_mutating.binary_search binary_search]]
+[def __range_algorithms_count__                   [link range.reference.algorithms.non_mutating.count count]]
+[def __range_algorithms_count_if__                [link range.reference.algorithms.non_mutating.count_if count_if]]
+[def __range_algorithms_equal__                   [link range.reference.algorithms.non_mutating.equal equal]]
+[def __range_algorithms_equal_range__             [link range.reference.algorithms.non_mutating.equal_range equal_range]]
+[def __range_algorithms_for_each__                [link range.reference.algorithms.non_mutating.for_each for_each]]
+[def __range_algorithms_find__                    [link range.reference.algorithms.non_mutating.find find]]
+[def __range_algorithms_find_end__                [link range.reference.algorithms.non_mutating.find_end find_end]]
+[def __range_algorithms_find_first_of__           [link range.reference.algorithms.non_mutating.find_first_of find_first_of]]
+[def __range_algorithms_find_if__                 [link range.reference.algorithms.non_mutating.find_if find_if]]
+[def __range_algorithms_lexicographical_compare__ [link range.reference.algorithms.non_mutating.lexicographical_compare lexicographical_compare]]
+[def __range_algorithms_lower_bound__             [link range.reference.algorithms.non_mutating.lower_bound lower_bound]]
+[def __range_algorithms_max_element__             [link range.reference.algorithms.non_mutating.max_element max_element]]
+[def __range_algorithms_min_element__             [link range.reference.algorithms.non_mutating.min_element min_element]]
+[def __range_algorithms_mismatch__                [link range.reference.algorithms.non_mutating.mismatch mismatch]]
+[def __range_algorithms_search__                  [link range.reference.algorithms.non_mutating.search search]]
+[def __range_algorithms_search_n__                [link range.reference.algorithms.non_mutating.search_n search_n]]
+[def __range_algorithms_upper_bound__             [link range.reference.algorithms.non_mutating.upper_bound upper_bound]]
+
+[def __range_algorithms_copy__                    [link range.reference.algorithms.mutating.copy copy]]
+[def __range_algorithms_copy_backward__           [link range.reference.algorithms.mutating.copy_backward copy_backward]]
+[def __range_algorithms_fill__                    [link range.reference.algorithms.mutating.fill fill]]
+[def __range_algorithms_fill_n__                  [link range.reference.algorithms.mutating.fill_n fill_n]]
+[def __range_algorithms_generate__                [link range.reference.algorithms.mutating.generate generate]]
+[def __range_algorithms_inplace_merge__           [link range.reference.algorithms.mutating.inplace_merge inplace_merge]]
+[def __range_algorithms_merge__                   [link range.reference.algorithms.mutating.merge merge]]
+[def __range_algorithms_nth_element__             [link range.reference.algorithms.mutating.nth_element nth_element]]
+[def __range_algorithms_partial_sort__            [link range.reference.algorithms.mutating.partial_sort partial_sort]]
+[def __range_algorithms_partition__               [link range.reference.algorithms.mutating.partition partition]]
+[def __range_algorithms_random_shuffle__          [link range.reference.algorithms.mutating.random_shuffle random_shuffle]]
+[def __range_algorithms_remove__                  [link range.reference.algorithms.mutating.remove remove]]
+[def __range_algorithms_remove_copy__             [link range.reference.algorithms.mutating.remove_copy remove_copy]]
+[def __range_algorithms_remove_copy_if__          [link range.reference.algorithms.mutating.remove_copy_if remove_copy_if]]
+[def __range_algorithms_remove_if__               [link range.reference.algorithms.mutating.remove_if remove_if]]
+[def __range_algorithms_replace__                 [link range.reference.algorithms.mutating.replace replace]]
+[def __range_algorithms_replace_copy__            [link range.reference.algorithms.mutating.replace_copy replace_copy]]
+[def __range_algorithms_replace_copy_if__         [link range.reference.algorithms.mutating.replace_copy_if replace_copy_if]]
+[def __range_algorithms_replace_if__              [link range.reference.algorithms.mutating.replace_if replace_if]]
+[def __range_algorithms_reverse__                 [link range.reference.algorithms.mutating.reverse reverse]]
+[def __range_algorithms_reverse_copy__            [link range.reference.algorithms.mutating.reverse_copy reverse_copy]]
+[def __range_algorithms_rotate__                  [link range.reference.algorithms.mutating.rotate rotate]]
+[def __range_algorithms_rotate_copy__             [link range.reference.algorithms.mutating.rotate_copy rotate_copy]]
+[def __range_algorithms_sort__                    [link range.reference.algorithms.mutating.sort sort]]
+[def __range_algorithms_stable_partition__        [link range.reference.algorithms.mutating.stable_partition stable_partition]]
+[def __range_algorithms_stable_sort__             [link range.reference.algorithms.mutating.stable_sort stable_sort]]
+[def __range_algorithms_swap_ranges__             [link range.reference.algorithms.mutating.swap_ranges swap_ranges]]
+[def __range_algorithms_transform__               [link range.reference.algorithms.mutating.transform transform]]
+[def __range_algorithms_unique__                  [link range.reference.algorithms.mutating.unique unique]]
+[def __range_algorithms_unique_copy__             [link range.reference.algorithms.mutating.unique_copy unique_copy]]
+
+[def __range_algorithms_includes__                 [link range.reference.algorithms.set.includes includes]]
+[def __range_algorithms_set_union__                [link range.reference.algorithms.set.set_union set_union]]
+[def __range_algorithms_set_intersection__         [link range.reference.algorithms.set.set_intersection set_intersection]]
+[def __range_algorithms_set_difference__           [link range.reference.algorithms.set.set_difference set_difference]]
+[def __range_algorithms_set_symmetric_difference__ [link range.reference.algorithms.set.set_symmetric_difference set_symmetric_difference]]
+
+[def __range_algorithms_push_heap__         [link range.reference.algorithms.heap.push_heap push_heap]]
+[def __range_algorithms_pop_heap__          [link range.reference.algorithms.heap.pop_heap pop_heap]]
+[def __range_algorithms_make_heap__         [link range.reference.algorithms.heap.make_heap make_heap]]
+[def __range_algorithms_sort_heap__         [link range.reference.algorithms.heap.sort_heap sort_heap]]
+
+[def __range_algorithms_next_permutation__  [link range.reference.algorithms.permutation.next_permutation next_permutation]]
+[def __range_algorithms_prev_permutation__ [link range.reference.algorithms.permutation.prev_permutation prev_permutation]]
+
+[def __range_algorithm_ext_copy_n__         [link range.reference.algorithms.new.copy_n copy_n]]
+[def __range_algorithm_ext_erase__          [link range.reference.algorithms.new.erase erase]]
+[def __range_algorithm_ext_for_each__       [link range.reference.algorithms.new.for_each for_each]]
+[def __range_algorithm_ext_insert__         [link range.reference.algorithms.new.insert insert]]
+[def __range_algorithm_ext_iota__           [link range.reference.algorithms.new.iota iota]]
+[def __range_algorithm_ext_is_sorted__      [link range.reference.algorithms.new.is_sorted is_sorted]]
+[def __range_algorithm_ext_overwrite__      [link range.reference.algorithms.new.overwrite overwrite]]
+[def __range_algorithm_ext_push_back__      [link range.reference.algorithms.new.push_back push_back]]
+[def __range_algorithm_ext_push_front__     [link range.reference.algorithms.new.push_front push_front]]
+
+[def __single_pass_iterator__   [@boost:/libs/iterator/doc/new-iter-concepts.html#singls-pass-iterators-lib-single-pass-iterators Single Pass Iterator]]
+[def __forward_traversal_iterator__ [@boost:/libs/iterator/doc/new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators Forward Traversal Iterator]]
+[def __bidirectional_traversal_iterator__ [@boost:/libs/iterator/doc/new-iter-concepts.html#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators Bidirectional Traversal Iterator]]
+[def __random_access_traversal_iterator__ [@boost:/libs/iterator/doc/new-iter-concepts.html#random-access-traversal-iterators-lib-random-access-traversal-iterators Random Access Traversal Iterator]]
+[def __new_style_iterators__    [@boost:/libs/iterator/doc/new-iter-concepts.html new style iterators]]
+[def __iterator_concepts__      [@boost:/libs/iterator/doc/iterator_concepts.html Iterator concepts]]
+
+[def __container__              [@http://www.sgi.com/Technology/STL/Container.html Container]]
+[def __metafunctions__          [@boost:/libs/mpl/doc/refmanual/metafunction.html metafunctions]]
+[def __concept_check__          [@boost:/libs/concept_check/index.html Boost Concept Check library]]
+[def __boost_array__            [@boost:/libs/array/index.html boost::array]]
+[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]]
+
+[def __sgi_inner_product__      [@http://www.sgi.com/tech/stl/inner_product.html inner_product]]
+[def __sgi_partial_sum__        [@http://www.sgi.com/tech/stl/partial_sum.html partial_sum]]
+[def __type_erasure_article__   [@http://www.artima.com/cppsource/type_erasure.html type erasure article]]
+
+Boost.Range is a collection of concepts and utilities, range-based algorithms,
+as well as range adaptors that allow for efficient and expressive code.
+
+Using Boost.Range inplace of the standard library alternatives results in more
+readable code and in many cases greater efficiency.
+
+[include introduction.qbk]
+[include concepts.qbk]
+[include reference.qbk]
+[include style.qbk]
+[include headers.qbk]
+[include examples.qbk]
+[include mfc_atl.qbk]
+[include upgrade.qbk]
+[include portability.qbk]
+[include faq.qbk]
+[include history_ack.qbk]
+
diff --git a/doc/concepts.qbk b/doc/concepts.qbk
new file mode 100644
index 0000000..e0b5f41
--- /dev/null
+++ b/doc/concepts.qbk
@@ -0,0 +1,255 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:concepts Range Concepts]
+
+[section Overview]
+
+A Range is a [*/concept/] similar to the STL [@http://www.sgi.com/tech/stl/Container.html Container] concept. A Range provides iterators for accessing a half-open range `[first,one_past_last)` of elements and provides information about the number of elements in the Range. However, a Range has fewer requirements than a Container.
+
+The motivation for the Range concept is that there are many useful Container-like types that do not meet the full requirements of Container, and many algorithms that can be written with this reduced set of requirements. In particular, a Range does not necessarily
+
+* own the elements that can be accessed through it,
+* have copy semantics,
+
+Because of the second requirement, a Range object must be passed by (const or non-const) reference in generic code.
+
+The operations that can be performed on a Range is dependent on the [@boost:/libs/iterator/doc/new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal traversal category] of the underlying iterator type. Therefore the range concepts are named to reflect which traversal category its iterators support. See also terminology and style guidelines. for more information about naming of ranges.
+
+The concepts described below specifies associated types as [@boost:/libs/mpl/doc/refmanual/metafunction.html metafunctions] and all functions as free-standing functions to allow for a layer of indirection.
+
+[endsect]
+
+
+[section Single Pass Range]
+
+[heading Notation]
+
+[table
+    []
+    [[`X`] [A type that is a model of __single_pass_range__.]]
+    [[`a`] [Object of type X.]]
+]
+
+[heading Description]
+
+A range `X` where `boost::range_iterator<X>::type` is a model of __single_pass_iterator__.
+
+[heading Associated types]
+
+[table
+  []
+  [[Iterator type      ] [`boost::range_iterator<X>::type`      ] [The type of iterator used to iterate through a Range's elements. The iterator's value type is expected to be the Range's value type. A conversion from the iterator type to the `const` iterator type must exist.]]
+  [[Const iterator type] [`boost::range_iterator<const X>::type`] [A type of iterator that may be used to examine, but not to modify, a Range's elements.]]
+]
+
+[heading Valid expressions]
+
+The following expressions must be valid.
+
+[table
+  [[Name              ] [Expression       ] [Return type        ]]
+  [[Beginning of range] [`boost::begin(a)`] [`boost::range_iterator<X>::type` if `a` is mutable, `boost::range_iterator<const X>::type` otherwise]]
+  [[End of range      ] [`boost::end(a)`  ] [`boost::range_iterator<X>::type` if `a` is mutable, `boost::range_iterator<const X>::type` otherwise]]
+]
+
+[heading Expression semantics]
+
+[table
+  [[Expression       ] [Semantics                                                               ] [Postcondition]]
+  [[`boost::begin(a)`] [Returns an iterator pointing to the first element in the Range.         ] [`boost::begin(a)` is either dereferenceable or past-the-end. It is past-the-end if and only if `boost::distance(a) == 0`.]]
+  [[`boost::end(a)`  ] [Returns an iterator pointing one past the last element in the Range.    ] [`boost::end(a)` is past-the-end.]]
+]
+
+[heading Complexity guarantees]
+
+`boost::end(a)` is at most amortized linear time, `boost::begin(a)` is amortized constant time. For most practical purposes, one can expect both to be amortized constant time.
+
+[heading Invariants]
+
+[table
+  []
+  [[Valid range ] [For any Range `a`, `[boost::begin(a),boost::end(a))` is a valid range, that is, `boost::end(a)` is reachable from `boost::begin(a)` in a finite number of increments.]]
+
+  [[Completeness] [An algorithm that iterates through the range `[boost::begin(a),boost::end(a))` will pass through every element of `a`.]]
+]
+
+[heading See also]
+
+__extending_for_udts__
+
+__implementation_of_metafunctions__
+
+__implementation_of_functions__
+
+__container__
+
+[endsect]
+
+
+[section Forward Range]
+
+[heading Notation]
+
+[table
+    []
+    [[`X`] [A type that is a model of __forward_range__.]]
+    [[`a`] [Object of type X.]]
+]
+
+[heading Description]
+
+A range `X` where `boost::range_iterator<X>::type` is a model of __forward_traversal_iterator__.
+
+[heading Refinement of]
+
+__single_pass_range__
+
+[heading Associated types]
+
+[table
+  []
+  [[Distance type] [`boost::range_difference<X>::type`] [A signed integral type used to represent the distance between two of the Range's iterators. This type must be the same as the iterator's distance type.]]
+  [[Size type    ] [`boost::range_size<X>::type`      ] [An unsigned integral type that can represent any nonnegative value of the Range's distance type.]]
+]
+
+[heading See also]
+
+__implementation_of_metafunctions__
+
+__implementation_of_functions__
+
+[endsect]
+
+
+[section Bidirectional Range]
+
+[heading Notation]
+
+[table
+    []
+    [[`X`] [A type that is a model of __bidirectional_range__.]]
+    [[`a`] [Object of type X.]]
+]
+
+[heading Description]
+
+This concept provides access to iterators that traverse in both directions (forward and reverse). The `boost::range_iterator<X>::type` iterator must meet all of the requirements of __bidirectional_traversal_iterator__.
+
+[heading Refinement of]
+
+__forward_range__
+
+[heading Associated types]
+
+[table
+  []
+  [[Reverse Iterator type      ] [`boost::range_reverse_iterator<X>::type`      ] [The type of iterator used to iterate through a Range's elements in reverse order. The iterator's value type is expected to be the Range's value type. A conversion from the reverse iterator type to the const reverse iterator type must exist.]]
+
+  [[Const reverse iterator type] [`boost::range_reverse_iterator<const X>::type`] [A type of reverse iterator that may be used to examine, but not to modify, a Range's elements.]]
+]
+
+[heading Valid expressions]
+
+[table
+  [[Name              ] [Expression        ] [Return type] [Semantics]]
+  [[Beginning of range] [`boost::rbegin(a)`] [`boost::range_reverse_iterator<X>::type` if `a` is mutable `boost::range_reverse_iterator<const X>::type` otherwise.] [Equivalent to `boost::range_reverse_iterator<X>::type(boost::end(a))`.]]
+
+  [[End of range      ] [`boost::rend(a)`  ] [`boost::range_reverse_iterator<X>::type` if `a` is mutable, `boost::range_reverse_iterator<const X>::type` otherwise.] [Equivalent to `boost::range_reverse_iterator<X>::type(boost::begin(a))`.]]
+]
+
+[heading Complexity guarantees]
+
+`boost::rbegin(a)` has the same complexity as `boost::end(a)` and `boost::rend(a)` has the same complexity as `boost::begin(a)` from __forward_range__.
+
+[heading Invariants]
+
+[table
+  []
+  [[Valid reverse range] [For any Bidirectional Range a, `[boost::rbegin(a),boost::rend(a))` is a valid range, that is, `boost::rend(a)` is reachable from `boost::rbegin(a)` in a finite number of increments.]]
+
+  [[Completeness       ] [An algorithm that iterates through the range `[boost::rbegin(a),boost::rend(a))` will pass through every element of `a`.]]
+]
+
+[heading See also]
+
+__implementation_of_metafunctions__
+
+__implementation_of_functions__
+
+[endsect]
+
+
+[section Random Access Range]
+
+[heading Description]
+
+A range `X` where `boost::range_iterator<X>::type` is a model of __random_access_traversal_iterator__.
+
+[heading Refinement of]
+
+__bidirectional_range__
+
+[heading Valid expressions]
+
+[table
+  [[Name         ] [Expression      ] [Return type                 ]]
+  [[Size of range] [`boost::size(a)`] [`boost::range_size<X>::type`]]
+]
+
+[heading Expression semantics]
+
+[table
+  [[Expression      ] [Semantics] [Postcondition]]
+  [[`boost::size(a)`] [Returns the size of the Range, that is, its number of elements. Note `boost::size(a) == 0u` is equivalent to `boost::empty(a)`.] [`boost::size(a) >= 0`]]
+]
+
+[heading Complexity guarantees]
+
+`boost::size(a)` completes in amortized constant time.
+
+[heading Invariants]
+
+[table
+  []
+  [[Range size] [`boost::size(a)` is equal to the `boost::end(a)` - `boost::begin(a)`.]]
+]
+
+[endsect]
+
+
+[section Concept Checking]
+
+Each of the range concepts has a corresponding concept checking class in the file [@boost:/boost/range/concepts.hpp `<boost/range/concepts.hpp>`]. These classes may be used in conjunction with the __concept_check__ to ensure that the type of a template parameter is compatible with a range concept. If not, a meaningful compile time error is generated. Checks are provided for the range concepts related to iterator traversal categories. For example, the following line checks that the type `T` models the __forward_range__ concept.
+
+``
+BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<T> ));
+``
+
+An additional concept check is required for the value access property of the range based on the range's iterator type. For example to check for a ForwardReadableRange, the following code is required.
+
+``
+BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<T> ));
+BOOST_CONCEPT_ASSERT(( ReadableIteratorConcept<typename range_iterator<T>::type> ));
+``
+
+The following range concept checking classes are provided.
+
+* Class SinglePassRangeConcept checks for __single_pass_range__
+* Class ForwardRangeConcept checks for __forward_range__
+* Class BidirectionalRangeConcept checks for __bidirectional_range__
+* Class RandomAccessRangeConcept checks for __random_access_range__
+
+[heading See also]
+
+[link range.style_guide Range Terminology and style guidelines]
+
+__iterator_concepts__
+
+__concept_check__
+
+[endsect]
+[endsect]
+
diff --git a/doc/example.cpp b/doc/example.cpp
new file mode 100644
index 0000000..d3dec7c
--- /dev/null
+++ b/doc/example.cpp
@@ -0,0 +1,151 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range.hpp>
+#include <iterator>         // for std::iterator_traits, std::distance()
+
+namespace Foo
+{
+        //
+        // Our sample UDT. A 'Pair'
+        // will work as a range when the stored
+        // elements are iterators.
+        //
+        template< class T >
+        struct Pair
+        {
+                T first, last;
+        };
+
+} // namespace 'Foo'
+
+namespace boost
+{
+        //
+        // Specialize metafunctions. We must include the range.hpp header.
+        // We must open the 'boost' namespace.
+        //
+        /*
+        template< class T >
+        struct range_value< Foo::Pair<T> >
+        {
+                typedef typename std::iterator_traits<T>::value_type type;
+        };
+        */
+
+        template< class T >
+        struct range_iterator< Foo::Pair<T> >
+        {
+                typedef T type;
+        };
+
+        template< class T >
+        struct range_const_iterator< Foo::Pair<T> >
+        {
+                //
+                // Remark: this is defined similar to 'range_iterator'
+                //         because the 'Pair' type does not distinguish
+                //         between an iterator and a const_iterator.
+                //
+                typedef T type;
+        };
+
+        /*
+    template< class T >
+        struct range_difference< Foo::Pair<T> >
+        {
+                typedef typename std::iterator_traits<T>::difference_type type;
+        };
+        */
+
+        template< class T >
+    struct range_size< Foo::Pair<T> >
+        {
+                int static_assertion[ sizeof( std::size_t ) >=
+                          sizeof( typename range_difference< Foo::Pair<T> >::type ) ];
+                typedef std::size_t type;
+        };
+
+} // namespace 'boost'
+
+namespace Foo
+{
+        //
+        // The required functions. These should be defined in
+        // the same namespace as 'Pair', in this case
+        // in namespace 'Foo'.
+        //
+
+        template< class T >
+        inline T boost_range_begin( Pair<T>& x )
+        {
+                return x.first;
+        }
+
+    template< class T >
+        inline T boost_range_begin( const Pair<T>& x )
+        {
+                return x.first;
+        }
+
+        template< class T >
+    inline T boost_range_end( Pair<T>& x )
+        {
+                return x.last;
+        }
+
+        template< class T >
+    inline T boost_range_end( const Pair<T>& x )
+        {
+                return x.last;
+        }
+
+        template< class T >
+        inline typename boost::range_size< Pair<T> >::type
+        boost_range_size( const Pair<T>& x )
+        {
+                return std::distance(x.first,x.last);
+        }
+
+} // namespace 'Foo'
+
+#include <vector>
+
+int main()
+{
+        typedef std::vector<int>::iterator  iter;
+        std::vector<int>                    vec;
+        vec.push_back( 42 );
+        Foo::Pair<iter>                     pair  = { vec.begin(), vec.end() };
+        const Foo::Pair<iter>&              cpair = pair;
+        //
+        // Notice that we call 'begin' etc with qualification.
+        //
+        iter i = boost::begin( pair );
+        iter e = boost::end( pair );
+        i      = boost::begin( cpair );
+        e      = boost::end( cpair );
+        boost::range_size< Foo::Pair<iter> >::type s = boost::size( pair );
+        s      = boost::size( cpair );
+        boost::range_const_reverse_iterator< Foo::Pair<iter> >::type
+        ri     = boost::rbegin( cpair ),
+        re         = boost::rend( cpair );
+
+        //
+        // Test metafunctions
+        //
+
+        boost::range_value< Foo::Pair<iter> >::type
+        v = *boost::begin(pair);
+
+        boost::range_difference< Foo::Pair<iter> >::type
+        d = boost::end(pair) - boost::begin(pair);
+}
+
diff --git a/doc/examples.qbk b/doc/examples.qbk
new file mode 100644
index 0000000..1dfb924
--- /dev/null
+++ b/doc/examples.qbk
@@ -0,0 +1,28 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:examples Examples]
+
+Some examples are given in the accompanying test files:
+
+* [@http://www.boost.org/libs/range/test/string.cpp string.cpp] shows how to implement a container version of `std::find()` that works with `char[]`,`wchar_t[]`,`char*`,`wchar_t*`.
+
+* [@http://www.boost.org/libs/range/test/algorithm_example.cpp algorithm_example.cpp] shows the replace example from the introduction.
+
+* [@http://www.boost.org/libs/range/test/iterator_range.cpp iterator_range.cpp]
+
+* [@http://www.boost.org/libs/range/test/sub_range.cpp sub_range.cpp]
+
+* [@http://www.boost.org/libs/range/test/iterator_pair.cpp iterator_pair.cpp]
+
+* [@http://www.boost.org/libs/range/test/reversible_range.cpp reversible_range.cpp]
+
+* [@http://www.boost.org/libs/range/test/std_container.cpp std_container.cpp]
+
+* [@http://www.boost.org/libs/range/test/array.cpp array.cpp]
+
+[endsect]
+
+
diff --git a/doc/faq.qbk b/doc/faq.qbk
new file mode 100644
index 0000000..ada6361
--- /dev/null
+++ b/doc/faq.qbk
@@ -0,0 +1,30 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:faq FAQ]
+
+1. ['[*Why is there no difference between `range_iterator<C>::type`  and `range_const_iterator<C>::type` for `std::pair<iterator, iterator>`?]]
+
+[:In general it is not possible nor desirable to find a corresponding `const_iterator`. When it is possible to come up with one, the client might choose to construct a `std::pair<const_iterator,const_iterator>` object.]
+
+[:Note that an __iterator_range__ is somewhat more convenient than a `pair` and that a __sub_range__ does propagate const-ness.]
+
+2. ['[*Why is there not supplied more types or more functions?]]
+
+[:The library has been kept small because its current interface will serve most purposes. If and when a genuine need arises for more functionality, it can be implemented.]
+
+3. ['[*How should I implement generic algorithms for ranges?]]
+
+[:One should always start with a generic algorithm that takes two iterators (or more) as input. Then use Boost.Range to build handier versions on top of the iterator based algorithm. Please notice that once the range version of the algorithm is done, it makes sense not to expose the iterator version in the public interface.]
+
+4. ['[*Why is there no Incrementable Range concept?]]
+
+[:Even though we speak of incrementable iterators, it would not make much sense for ranges; for example, we cannot determine the size and emptiness of a range since we cannot even compare its iterators.]
+
+[:Note also that incrementable iterators are derived from output iterators and so there exist no output range.]
+
+[endsect]
+
+
diff --git a/doc/headers.qbk b/doc/headers.qbk
new file mode 100644
index 0000000..2e5ae02
--- /dev/null
+++ b/doc/headers.qbk
@@ -0,0 +1,143 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:headers Library Headers]
+
+[section:general General]
+[table
+    [[Header                              ] [Includes                   ] [Related Concept         ]]
+    [[`<boost/range.hpp>`                 ] [everything from Boost.Range version 1 (Boost versions 1.42 and below). Includes the core range functions and metafunctions, but excludes Range Adaptors and Range Algorithms. ] [-                       ]]
+    [[`<boost/range/metafunctions.hpp>`   ] [every metafunction         ] [-                       ]]
+    [[`<boost/range/functions.hpp>`       ] [every function             ] [-                       ]]
+    [[`<boost/range/value_type.hpp>`      ] [__range_value__            ] [__single_pass_range__   ]]
+    [[`<boost/range/iterator.hpp>`        ] [__range_iterator__         ] [__single_pass_range__   ]]
+    [[`<boost/range/difference_type.hpp>` ] [__range_difference__       ] [__forward_range__       ]]
+    [[`<boost/range/pointer.hpp>`         ] [__range_pointer__          ] [-]]
+    [[`<boost/range/category.hpp>`        ] [__range_category__         ] [-]]
+    [[`<boost/range/reverse_iterator.hpp>`] [__range_reverse_iterator__ ] [__bidirectional_range__ ]]
+    [[`<boost/range/begin.hpp>`           ] [__begin__ and __const_begin__ ] [__single_pass_range__   ]]
+    [[`<boost/range/end.hpp>`             ] [__end__ and __const_end__  ] [__single_pass_range__   ]]
+    [[`<boost/range/empty.hpp>`           ] [__empty__                  ] [__single_pass_range__   ]]
+    [[`<boost/range/distance.hpp>`        ] [__distance__               ] [__forward_range__       ]]
+    [[`<boost/range/size.hpp>`            ] [__size__                   ] [__random_access_range__ ]]
+    [[`<boost/range/rbegin.hpp>`          ] [__rbegin__ and __const_rbegin__] [__bidirectional_range__ ]]
+    [[`<boost/range/rend.hpp>`            ] [__rend__ and __const_rend__ ] [__bidirectional_range__ ]]
+    [[`<boost/range/as_array.hpp>`        ] [__as_array__               ] [-                       ]]
+    [[`<boost/range/as_literal.hpp>`      ] [__as_literal__             ] [-                       ]]
+    [[`<boost/range/iterator_range.hpp>`  ] [__iterator_range__         ] [-                       ]]
+    [[`<boost/range/sub_range.hpp>`       ] [__sub_range__              ] [-                       ]]
+    [[`<boost/range/concepts.hpp>`        ] [__range_concepts__         ] [-                       ]]
+    [[`<boost/range/adaptors.hpp>`        ] [every range adaptor        ] [-                       ]]
+    [[`<boost/range/algorithm.hpp>`       ] [every range equivalent of an STL algorithm ] [-                       ]]
+    [[`<boost/range/algorithm_ext.hpp>`   ] [every range algorithm that is an extension of the STL algorithms ] [-                       ]]
+    [[`<boost/range/counting_range.hpp>`  ] [ __counting_range__ ] [-]]
+    [[`<boost/range/istream_range.hpp>`   ] [ __istream_range__ ] [-]]
+    [[`<boost/range/irange.hpp>`          ] [ __irange__ ] [-]]
+    [[`<boost/range/join.hpp>`            ] [ __join__ ] [-]]
+]
+[endsect]
+
+[section:adaptors Adaptors]
+[table
+    [[Header                                        ][Includes                                           ]]
+    [[`<boost/range/adaptor/adjacent_filtered.hpp>`] [__range_adaptors_adjacent_filtered__ ]]
+    [[`<boost/range/adaptor/copied.hpp>`]            [__range_adaptors_copied__]]
+    [[`<boost/range/adaptor/filtered.hpp>`]          [__range_adaptors_filtered__]]
+    [[`<boost/range/adaptor/indexed.hpp>`]           [__range_adaptors_indexed__]]
+    [[`<boost/range/adaptor/indirected.hpp>`]        [__range_adaptors_indirected__]]
+    [[`<boost/range/adaptor/map.hpp>`]               [__range_adaptors_map_keys__ __range_adaptors_map_values__]]
+    [[`<boost/range/adaptor/replaced.hpp>`]          [__range_adaptors_replaced__]]
+    [[`<boost/range/adaptor/replaced_if.hpp>`]       [__range_adaptors_replaced_if__]]
+    [[`<boost/range/adaptor/reversed.hpp>`]          [__range_adaptors_reversed__]]
+    [[`<boost/range/adaptor/sliced.hpp>`]            [__range_adaptors_sliced__]]
+    [[`<boost/range/adaptor/strided.hpp>`]           [__range_adaptors_strided__]]
+    [[`<boost/range/adaptor/tokenized.hpp>`]         [__range_adaptors_tokenized__]]
+    [[`<boost/range/adaptor/transformed.hpp>`]       [__range_adaptors_transformed__]]
+    [[`<boost/range/adaptor/uniqued.hpp>`]           [__range_adaptors_uniqued__]]
+]
+[endsect]
+
+[section:algorithm Algorithm]
+[table
+    [[Header                                        ][Includes                                           ]]
+    [[`<boost/range/algorithm/adjacent_find.hpp>`]           [__range_algorithms_adjacent_find__]]
+    [[`<boost/range/algorithm/binary_search.hpp>`]           [__range_algorithms_binary_search__]]
+    [[`<boost/range/algorithm/copy.hpp>`]                    [__range_algorithms_copy__]]
+    [[`<boost/range/algorithm/copy_backward.hpp>`]           [__range_algorithms_copy_backward__]]
+    [[`<boost/range/algorithm/count.hpp>`]                   [__range_algorithms_count__]]
+    [[`<boost/range/algorithm/count_if.hpp>`]                [__range_algorithms_count_if__]]
+    [[`<boost/range/algorithm/equal.hpp>`]                   [__range_algorithms_equal__]]
+    [[`<boost/range/algorithm/equal_range.hpp>`]             [__range_algorithms_equal_range__]]
+    [[`<boost/range/algorithm/fill.hpp>`]                    [__range_algorithms_fill__]]
+    [[`<boost/range/algorithm/fill_n.hpp>`]                  [__range_algorithms_fill_n__]]
+    [[`<boost/range/algorithm/find.hpp>`]                    [__range_algorithms_find__]]
+    [[`<boost/range/algorithm/find_end.hpp>`]                [__range_algorithms_find_end__]]
+    [[`<boost/range/algorithm/find_first_of.hpp>`]           [__range_algorithms_find_first_of__]]
+    [[`<boost/range/algorithm/find_if.hpp>`]                 [__range_algorithms_find_if__]]
+    [[`<boost/range/algorithm/for_each.hpp>`]                [__range_algorithms_for_each__]]
+    [[`<boost/range/algorithm/generate.hpp>`]                [__range_algorithms_generate__]]
+    [[`<boost/range/algorithm/heap_algorithm.hpp>`]          [__range_algorithms_push_heap__
+                                                              __range_algorithms_pop_heap__
+                                                              __range_algorithms_make_heap__
+                                                              __range_algorithms_sort_heap__]]
+    [[`<boost/range/algorithm/inplace_merge.hpp>`]           [__range_algorithms_inplace_merge__]]
+    [[`<boost/range/algorithm/lexicographical_compare.hpp>`] [__range_algorithms_lexicographical_compare__]]
+    [[`<boost/range/algorithm/lower_bound.hpp>`]             [__range_algorithms_lower_bound__]]
+    [[`<boost/range/algorithm/max_element.hpp>`]             [__range_algorithms_max_element__]]
+    [[`<boost/range/algorithm/merge.hpp>`]                   [__range_algorithms_merge__]]
+    [[`<boost/range/algorithm/min_element.hpp>`]             [__range_algorithms_min_element__]]
+    [[`<boost/range/algorithm/mismatch.hpp>`]                [__range_algorithms_mismatch__]]
+    [[`<boost/range/algorithm/nth_element.hpp>`]             [__range_algorithms_nth_element__]]
+    [[`<boost/range/algorithm/partial_sort.hpp>`]            [__range_algorithms_partial_sort__]]
+    [[`<boost/range/algorithm/partition.hpp>`]               [__range_algorithms_partition__]]
+    [[`<boost/range/algorithm/permutation.hpp>`]             [__range_algorithms_next_permutation__
+                                                              __range_algorithms_prev_permutation__]]
+    [[`<boost/range/algorithm/random_shuffle.hpp>`]          [__range_algorithms_random_shuffle__]]
+    [[`<boost/range/algorithm/remove.hpp>`]                  [__range_algorithms_remove__]]
+    [[`<boost/range/algorithm/remove_copy.hpp>`]             [__range_algorithms_remove_copy__]]
+    [[`<boost/range/algorithm/remove_copy_if.hpp>`]          [__range_algorithms_remove_copy_if__]]
+    [[`<boost/range/algorithm/remove_if.hpp>`]               [__range_algorithms_remove_if__]]
+    [[`<boost/range/algorithm/replace.hpp>`]                 [__range_algorithms_replace__]]
+    [[`<boost/range/algorithm/replace_copy.hpp>`]            [__range_algorithms_replace_copy__]]
+    [[`<boost/range/algorithm/replace_copy_if.hpp>`]         [__range_algorithms_replace_copy_if__]]
+    [[`<boost/range/algorithm/replace_if.hpp>`]              [__range_algorithms_replace_if__]]
+    [[`<boost/range/algorithm/reverse.hpp>`]                 [__range_algorithms_reverse__]]
+    [[`<boost/range/algorithm/reverse_copy.hpp>`]            [__range_algorithms_reverse_copy__]]
+    [[`<boost/range/algorithm/rotate.hpp>`]                  [__range_algorithms_rotate__]]
+    [[`<boost/range/algorithm/rotate_copy.hpp>`]             [__range_algorithms_rotate_copy__]]
+    [[`<boost/range/algorithm/search.hpp>`]                  [__range_algorithms_search__]]
+    [[`<boost/range/algorithm/search_n.hpp>`]                [__range_algorithms_search_n__]]
+    [[`<boost/range/algorithm/set_algorithm.hpp>`]           [__range_algorithms_includes__
+                                                              __range_algorithms_set_union__
+                                                              __range_algorithms_set_intersection__
+                                                              __range_algorithms_set_difference__
+                                                              __range_algorithms_set_symmetric_difference__]]
+    [[`<boost/range/algorithm/sort.hpp>`]                    [__range_algorithms_sort__]]
+    [[`<boost/range/algorithm/stable_partition.hpp>`]        [__range_algorithms_stable_partition__]]
+    [[`<boost/range/algorithm/swap_ranges.hpp>`]             [__range_algorithms_swap_ranges__]]
+    [[`<boost/range/algorithm/transform.hpp>`]               [__range_algorithms_transform__]]
+    [[`<boost/range/algorithm/unique.hpp>`]                  [__range_algorithms_unique__]]
+    [[`<boost/range/algorithm/unique_copy.hpp>`]             [__range_algorithms_unique_copy__]]
+    [[`<boost/range/algorithm/upper_bound.hpp>`]             [__range_algorithms_upper_bound__]]
+]
+[endsect]
+
+[section:algorithm_ext Algorithm Extensions]
+[table
+    [[Header                                        ][Includes                                           ]]
+    [[`<boost/range/algorithm_ext/copy_n.hpp>`]     [__range_algorithm_ext_copy_n__]]
+    [[`<boost/range/algorithm_ext/erase.hpp>`]      [__range_algorithm_ext_erase__]]
+    [[`<boost/range/algorithm_ext/for_each.hpp>`]   [__range_algorithm_ext_for_each__]]
+    [[`<boost/range/algorithm_ext/insert.hpp>`]     [__range_algorithm_ext_insert__]]
+    [[`<boost/range/algorithm_ext/iota.hpp>`]       [__range_algorithm_ext_iota__]]
+    [[`<boost/range/algorithm_ext/is_sorted.hpp>`]  [__range_algorithm_ext_is_sorted__]]
+    [[`<boost/range/algorithm_ext/overwrite.hpp>`]  [__range_algorithm_ext_overwrite__]]
+    [[`<boost/range/algorithm_ext/push_back.hpp>`]  [__range_algorithm_ext_push_back__]]
+    [[`<boost/range/algorithm_ext/push_front.hpp>`] [__range_algorithm_ext_push_front__]]
+]
+[endsect]
+
+[endsect]
+
diff --git a/doc/history_ack.qbk b/doc/history_ack.qbk
new file mode 100644
index 0000000..27f9e2a
--- /dev/null
+++ b/doc/history_ack.qbk
@@ -0,0 +1,58 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:history_ack History and Acknowledgement]
+
+[heading Version 1 - before Boost 1.43]
+The library have been under way for a long time. Dietmar Kühl originally intended to submit an `array_traits` class template which had most of the functionality present now, but only for arrays and standard containers.
+
+Meanwhile work on algorithms for containers in various contexts showed the need for handling pairs of iterators, and string libraries needed special treatment of character arrays. In the end it made sense to formalize the minimal requirements of these similar concepts. And the results are the Range concepts found in this library.
+
+The term Range was adopted because of paragraph 24.1/7 from the C++ standard:
+
+Most of the library's algorithmic templates that operate on data structures have interfaces that use ranges. A range is a pair of iterators that designate the beginning and end of the computation. A range [i, i) is an empty range; in general, a range [i, j) refers to the elements in the data structure starting with the one pointed to by i and up to but not including the one pointed to by j. Range [i, j) is valid if and only if j is reachable from i. The result of the application of functions in the library to invalid ranges is undefined.
+
+Special thanks goes to
+
+* Pavol Droba for help with documentation and implementation
+* Pavel Vozenilek for help with porting the library
+* Jonathan Turkanis and John Torjo for help with documentation
+* Hartmut Kaiser for being review manager
+* Jonathan Turkanis for porting the lib (as far as possible) to vc6 and vc7.
+
+The concept checks and their documentation was provided by Daniel Walker.
+
+[heading Version 2 - Boost 1.43 and beyond]
+This version introduced Range Adaptors and Range Algorithms. This version 2 is
+the result of a merge of all of the RangeEx features into Boost.Range.
+
+There were an enormous number of very significant contributors through all
+stages of this library.
+
+Prior to Boost.RangeEx there had been a number of Range library implementations,
+these include library implementations by Eric Niebler, Adobe,
+Shunsuke Sogame etc. Eric Niebler contributed the Range Adaptor idea which is
+arguably the single biggest innovation in this library. Inevitably a great deal
+of commonality evolved in each of these libraries, but a considerable amount
+of effort was expended to learn from all of the divergent techniques.
+
+The people in the following list all made contributions in the form of reviews,
+user feedback, design suggestions, or defect detection:
+
+* Thorsten Ottosen: review management, design advice, documentation feedback
+* Eric Niebler:     early implementation, and review feedback
+* Joel de Guzman:   review
+* Mathias Gaunard:  review
+* David Abrahams:   implementation advice
+* Robert Jones:     defect reports, usage feedback
+* Sean Parent:      contributed experience from the Adobe range library
+* Arno Schoedl:     implementations, and review
+* Rogier van Dalen: review
+* Vincente Botet:   review, documentation feedback
+
+Regardless of how I write this section it will never truly fairly capture the
+gratitude that I feel to all who have contributed. Thank you everyone.
+
+[endsect]
diff --git a/doc/introduction.qbk b/doc/introduction.qbk
new file mode 100644
index 0000000..d03a65b
--- /dev/null
+++ b/doc/introduction.qbk
@@ -0,0 +1,43 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:introduction Introduction]
+
+Generic algorithms have so far been specified in terms of two or more iterators. Two iterators would together form a range of values that the algorithm could work on. This leads to a very general interface, but also to a somewhat clumsy use of the algorithms with redundant specification of container names. Therefore we would like to raise the abstraction level for algorithms so they specify their interface in terms of __ranges__ as much as possible.
+
+The most common form of ranges used throughout the C++ community are standard library containers. When writing algorithms however, one often finds it desirable for the algorithm to accept other types that offer enough functionality to satisfy the needs of the generic code [*/if a suitable layer of indirection is applied/] . For example, raw arrays are often suitable for use with generic code that works with containers, provided a suitable adapter is used. Likewise, null terminated strings can be treated as containers of characters, if suitably adapted.
+
+This library therefore provides the means to adapt standard-like containers, null terminated strings, `std::pairs` of iterators, and raw arrays (and more), such that the same generic code can work with them all. The basic idea is to add another layer of indirection using __metafunctions__ and free-standing functions so syntactic and/or semantic differences can be removed.
+
+The main advantages are
+
+* simpler implementation and specification of generic range algorithms
+* more flexible, compact and maintainable client code
+* safe use of built-in arrays (for legacy code; why else would you use built-in arrays?)
+
+[heading Example - Iterate over the values in a map]
+``
+using namespace boost;
+using namespace boost::adaptors;
+for_each( my_map | map_values, fn );
+``
+
+[heading Example - Iterate over the keys in a map]
+``
+using namespace boost;
+using namespace boost::adaptors;
+for_each( my_map | map_keys, fn );
+``
+
+[heading Example - Push the even values from a map in reverse order into the container `target`]
+``
+using namespace boost;
+using namespace boost::adaptors;
+// Assume that is_even is a predicate that has been implemented elsewhere...
+push_back(target, my_map | map_values | filtered(is_even()) | reversed);
+``
+
+[endsect]
+
diff --git a/doc/mfc_atl.qbk b/doc/mfc_atl.qbk
new file mode 100644
index 0000000..0056283
--- /dev/null
+++ b/doc/mfc_atl.qbk
@@ -0,0 +1,148 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[def __mfc_collections__ [@http://msdn.microsoft.com/en-us/library/942860sh.aspx MFC Collection Classes]]
+[def __atl_collections__ [@http://msdn.microsoft.com/en-us/library/15e672bd.aspx ATL Collection Classes]]
+
+[section:mfc_atl MFC/ATL (courtesy of Shunsuke Sogame)]
+
+[h4 Introduction]
+This implementation was kindly donated by Shunsuke Sogame. This header adapts MFC and ATL containers to the appropriate Range concepts.
+
+[table
+    []
+    [[[*Author:]]    [Shunsuke Sogame]]
+    [[[*Contact:]]   [mb2act@yahoo.co.jp]]
+    [[[*Date:]]      [26th of May 2006]]
+    [[[*Copyright:]] [Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0]]
+]
+
+[h4 Overview]
+
+Boost.Range MFC/ATL Extension provides Boost.Range support for MFC/ATL collection and string types.
+
+``
+CTypedPtrArray<CPtrArray, CList<CString> *> myArray;
+...
+BOOST_FOREACH (CList<CString> *theList, myArray)
+{
+    BOOST_FOREACH (CString& str, *theList)
+    {
+        boost::to_upper(str);
+        std::sort(boost::begin(str), boost::end(str));
+        ...
+    }
+}
+``
+
+[section:requirements Requirements]
+
+* Boost C++ Libraries Version 1.34.0 or later (no compilation required)
+* Visual C++ 7.1 or later (for MFC and ATL)
+
+[endsect]
+
+[section:mfc_ranges MFC Ranges]
+If the `<boost/range/mfc.hpp>` is included before or after Boost.Range headers, the MFC collections and strings become models of Range. The table below lists the Traversal Category and `range_reference` of MFC ranges.
+
+[table
+    [[Range] [Traversal Category] [`range_reference<Range>::type`]]
+    [[`CArray<T,A>`]           [__random_access_range__]   [`T&`]]
+    [[`CList<T,A>`]            [__bidirectional_range__]   [`T&`]]
+    [[`CMap<K,AK,M,AM>`]       [__forward_range__]         [`Range::CPair&`]]
+    [[`CTypedPtrArray<B,T*>`]  [__random_access_range__]   [`T* const`]]
+    [[`CTypedPtrList<B,T*>`]   [__bidirectional_range__]   [`T* const`]]
+    [[`CTypedPtrMap<B,T*,V*>`] [__forward_range__]         [`std::pair<T*,V*> const`]]
+    [[`CByteArray`]            [__random_access_range__]   [`BYTE&`]]
+    [[`CDWordArray`]           [__random_access_range__]   [`DWORD&`]]
+    [[`CObArray`]              [__random_access_range__]   [`CObject*&`]]
+    [[`CPtrArray`]             [__random_access_range__]   [`void*&`]]
+    [[`CStringArray`]          [__random_access_range__]   [`CString&`]]
+    [[`CUIntArray`]            [__random_access_range__]   [`UINT&`]]
+    [[`CWordArray`]            [__random_access_range__]   [`WORD&`]]
+    [[`CObList`]               [__bidirectional_range__]   [`CObject*&`]]
+    [[`CPtrList`]              [__bidirectional_range__]   [`void*&`]]
+    [[`CStringList`]           [__bidirectional_range__]   [`CString&`]]
+    [[`CMapPtrToWord`]         [__forward_range__]         [`std::pair<void*,WORD> const`]]
+    [[`CMapPtrToPtr`]          [__forward_range__]         [`std::pair<void*,void*> const`]]
+    [[`CMapStringToOb`]        [__forward_range__]         [`std::pair<String,CObject*> const`]]
+    [[`CMapStringToString`]    [__forward_range__]         [`Range::CPair&`]]
+    [[`CMapWordToOb`]          [__forward_range__]         [`std::pair<WORD,CObject*> const`]]
+    [[`CMapWordToPtr`]         [__forward_range__]         [`std::pair<WORD,void*> const`]]
+]
+
+Other Boost.Range metafunctions are defined by the following. Let `Range` be any type listed above and `Ref` be the same as `range_reference<Range>::type`. `range_value<Range>::type` is the same as `remove_reference<remove_const<Ref>::type>::type`, `range_difference<Range>::type` is the same as `std::ptrdiff_t`, and `range_pointer<Range>::type` is the same as `add_pointer<remove_reference<Ref>::type>::type`. As for `const Range`, see below.
+
+Adam Walling has provided the header `<boost/range/mfc_map.hpp>` to add support
+for the map adaptor with MFC map types.
+
+[endsect]
+
+[section:atl_ranges ATL Ranges]
+
+If the `<boost/range/atl.hpp>` is included before or after Boost.Range headers, the ATL collections and strings become models of Range. The table below lists the Traversal Category and `range_reference` of ATL ranges.
+
+[table
+    [[Range]                    [Traversal Category]      [`range_reference<Range>::type`]]
+    [[`CAtlArray<E,ET>`]        [__random_access_range__] [`E&`]]
+    [[`CAutoPtrArray<E>`]       [__random_access_range__] [`E&`]]
+    [[`CInterfaceArray<I,pi>`]  [__random_access_range__] [`CComQIPtr<I,pi>&`]]
+    [[`CAtlList<E,ET>`]         [__bidirectional_range__] [`E&`]]
+    [[`CAutoPtrList<E>`]        [__bidirectional_range__] [`E&`]]
+    [[`CHeapPtrList<E,A>`]      [__bidirectional_range__] [`E&`]]
+    [[`CInterfaceList<I,pi>`]   [__bidirectional_range__] [`CComQIPtr<I,pi>&`]]
+    [[`CAtlMap<K,V,KT,VT>`]     [__forward_range__]       [`Range::CPair&`]]
+    [[`CRBTree<K,V,KT,VT>`]     [__bidirectional_range__] [`Range::CPair&`]]
+    [[`CRBMap<K,V,KT,VT>`]      [__bidirectional_range__] [`Range::CPair&`]]
+    [[`CRBMultiMap<K,V,KT,VT>`] [__bidirectional_range__] [`Range::CPair&`]]
+    [[`CSimpleStringT<B,b>`]    [__random_access_range__] [`B&`]]
+    [[`CStringT<B,ST>`]         [__random_access_range__] [`B&`]]
+    [[`CFixedStringT<S,n>`]     [__random_access_range__] [`range_reference<S>::type`]]
+    [[`CComBSTR`]               [__random_access_range__] [`OLECHAR&`]]
+    [[`CSimpleArray<T,TE>`]     [__random_access_range__] [`T&`]]
+]
+
+Other __boost_range_home__ metafunctions are defined by the following. Let `Range` be any type listed above and `Ref` be the same as `range_reference<Range>::type`. `range_value<Range>::type` is the same as `remove_reference<Ref>::type`, `range_difference<Range>::type` is the same as `std::ptrdiff_t`, and `range_pointer<Range>::type` is the same as `add_pointer<remove_reference<Ref>::type>::type`. As for `const Range`, see below.
+
+[endsect]
+
+[section:const_ranges const Ranges]
+
+`range_reference<const Range>::type` is defined by the following algorithm. Let `Range` be any type listed above and `Ref` be the same as `range_reference<Range>::type`.
+
+``
+if (Range is CObArray || Range is CObList)
+    return CObject const * &
+else if (Range is CPtrArray || Range is CPtrList)
+    return void const * &
+else if (there is a type X such that X& is the same as Ref)
+    return X const &
+else if (there is a type X such that X* const is the same as Ref)
+    return X const * const
+else
+    return Ref
+``
+
+
+Other Boost.Range metafunctions are defined by the following.
+
+[table
+    [[Range metafunction]                    [Result]]
+    [[`range_value<const Range>::type`]      [`range_value<Range>::type`]]
+    [[`range_difference<const Range>::type`] [`std::ptrdiff_t`]]
+    [[`range_pointer<const Range>::type`]    [`add_pointer<remove_reference<range_reference<const Range>::type>::type>::type`]]
+]
+
+[endsect]
+
+[section:references References]
+
+# __boost_range_home__
+# __mfc_collections__
+# __atl_collections__
+
+[endsect]
+
+[endsect]
diff --git a/doc/mfc_atl.rst b/doc/mfc_atl.rst
new file mode 100644
index 0000000..67498fb
--- /dev/null
+++ b/doc/mfc_atl.rst
@@ -0,0 +1,232 @@
+
+++++++++++++++++++++++++++++++++
+ |Boost| Range MFC/ATL Extension
+++++++++++++++++++++++++++++++++
+
+.. |Boost| image:: http://www.boost.org/libs/ptr_container/doc/boost.png
+
+
+
+:Author:        Shunsuke Sogame
+:Contact:       mb2act@yahoo.co.jp
+:date:          26th of May 2006
+:copyright:     Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__).
+
+__ http://www.boost.org/LICENSE_1_0.txt
+
+
+
+========
+Overview
+========
+
+Boost.Range MFC/ATL Extension provides `Boost.Range`_ support for MFC/ATL collection and string types.
+
+
+.. parsed-literal::
+
+        CTypedPtrArray<CPtrArray, CList<CString> \*> myArray;
+        ...
+        BOOST_FOREACH (CList<CString> \*theList, myArray)
+        {
+            BOOST_FOREACH (CString& str, \*theList)
+            {
+                boost::to_upper(str);
+                std::sort(boost::begin(str), boost::end(str));
+                ...
+            }
+        }
+
+
+
+* `Requirements`_
+* `MFC Ranges`_
+* `ATL Ranges`_
+* `const Ranges`_
+* `References`_
+
+
+
+============
+Requirements
+============
+
+- `Boost C++ Libraries Version 1.34.0`__ or later (no compilation required)
+- Visual C++ 7.1 or Visual C++ 8.0
+
+__ Boost_
+
+
+
+==========
+MFC Ranges
+==========
+
+If the ``<boost/range/mfc.hpp>`` is included before or after `Boost.Range`_ headers,
+the MFC collections and strings become models of Range.
+The table below lists the Traversal Category and ``range_reference`` of MFC ranges.
+
+
+============================= ================== =======================================
+``Range``                     Traversal Category ``range_reference<Range>::type``
+============================= ================== =======================================
+``CArray<T,A>``               Random Access      ``T&``
+----------------------------- ------------------ ---------------------------------------
+``CList<T,A>``                Bidirectional      ``T&``
+----------------------------- ------------------ ---------------------------------------
+``CMap<K,AK,M,AM>``           Forward            ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CTypedPtrArray<B,T*>``      Random Access      ``T* const``
+----------------------------- ------------------ ---------------------------------------
+``CTypedPtrList<B,T*>``       Bidirectional      ``T* const``
+----------------------------- ------------------ ---------------------------------------
+``CTypedPtrMap<B,T*,V*>``     Forward            ``std::pair<T*,V*> const``
+----------------------------- ------------------ ---------------------------------------
+``CByteArray``                Random Access      ``BYTE&``
+----------------------------- ------------------ ---------------------------------------
+``CDWordArray``               Random Access      ``DWORD&``
+----------------------------- ------------------ ---------------------------------------
+``CObArray``                  Random Access      ``CObject* &``
+----------------------------- ------------------ ---------------------------------------
+``CPtrArray``                 Random Access      ``void* &``
+----------------------------- ------------------ ---------------------------------------
+``CStringArray``              Random Access      ``CString&``
+----------------------------- ------------------ ---------------------------------------
+``CUIntArray``                Random Access      ``UINT&``
+----------------------------- ------------------ ---------------------------------------
+``CWordArray``                Random Access      ``WORD&``
+----------------------------- ------------------ ---------------------------------------
+``CObList``                   Bidirectional      ``CObject* &``
+----------------------------- ------------------ ---------------------------------------
+``CPtrList``                  Bidirectional      ``void* &``
+----------------------------- ------------------ ---------------------------------------
+``CStringList``               Bidirectional      ``CString&``
+----------------------------- ------------------ ---------------------------------------
+``CMapPtrToWord``             Forward            ``std::pair<void*,WORD> const``
+----------------------------- ------------------ ---------------------------------------
+``CMapPtrToPtr``              Forward            ``std::pair<void*,void*> const``
+----------------------------- ------------------ ---------------------------------------
+``CMapStringToOb``            Forward            ``std::pair<String,CObject*> const``
+----------------------------- ------------------ ---------------------------------------
+``CMapStringToString``        Forward            ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CMapWordToOb``              Forward            ``std::pair<WORD,CObject*> const``
+----------------------------- ------------------ ---------------------------------------
+``CMapWordToPtr``             Forward            ``std::pair<WORD,void*> const``
+============================= ================== =======================================
+
+
+Other `Boost.Range`_ metafunctions are defined by the following.
+Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
+``range_value<Range>::type`` is the same as ``remove_reference<remove_const<Ref>::type>::type``,
+``range_difference<Range>::type`` is the same as ``std::ptrdiff_t``, and
+``range_pointer<Range>::type`` is the same as ``add_pointer<remove_reference<Ref>::type>::type``.
+As for ``const Range``, see `const Ranges`_.
+
+
+
+==========
+ATL Ranges
+==========
+
+If the ``<boost/range/atl.hpp>`` is included before or after `Boost.Range`_ headers,
+the ATL collections and strings become models of Range.
+The table below lists the Traversal Category and ``range_reference`` of ATL ranges.
+
+
+============================= ================== =======================================
+``Range``                     Traversal Category ``range_reference<Range>::type``
+============================= ================== =======================================
+``CAtlArray<E,ET>``           Random Access      ``E&``
+----------------------------- ------------------ ---------------------------------------
+``CAutoPtrArray<E>``          Random Access      ``E&``
+----------------------------- ------------------ ---------------------------------------
+``CInterfaceArray<I,pi>``     Random Access      ``CComQIPtr<I,pi>&``
+----------------------------- ------------------ ---------------------------------------
+``CAtlList<E,ET>``            Bidirectional      ``E&``
+----------------------------- ------------------ ---------------------------------------
+``CAutoPtrList<E>``           Bidirectional      ``E&``
+----------------------------- ------------------ ---------------------------------------
+``CHeapPtrList<E,A>``         Bidirectional      ``E&``
+----------------------------- ------------------ ---------------------------------------
+``CInterfaceList<I,pi>``      Bidirectional      ``CComQIPtr<I,pi>&``
+----------------------------- ------------------ ---------------------------------------
+``CAtlMap<K,V,KT,VT>``        Forward            ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CRBTree<K,V,KT,VT>``        Bidirectional      ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CRBMap<K,V,KT,VT>``         Bidirectional      ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CRBMultiMap<K,V,KT,VT>``    Bidirectional      ``Range::CPair&``
+----------------------------- ------------------ ---------------------------------------
+``CSimpleStringT<B,b>``       Random Access      ``B&``
+----------------------------- ------------------ ---------------------------------------
+``CStringT<B,ST>``            Random Access      ``B&``
+----------------------------- ------------------ ---------------------------------------
+``CFixedStringT<S,n>``        Random Access      ``range_reference<S>::type``
+----------------------------- ------------------ ---------------------------------------
+``CStringT<B,ST>``            Random Access      ``B&``
+----------------------------- ------------------ ---------------------------------------
+``CComBSTR``                  Random Access      ``OLECHAR&``
+----------------------------- ------------------ ---------------------------------------
+``CSimpleArray<T,TE>``        Random Access      ``T&``
+============================= ================== =======================================
+
+
+Other `Boost.Range`_ metafunctions are defined by the following.
+Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
+``range_value<Range>::type`` is the same as ``remove_reference<Ref>::type``,
+``range_difference<Range>::type`` is the same as ``std::ptrdiff_t``, and
+``range_pointer<Range>::type`` is the same as ``add_pointer<remove_reference<Ref>::type>::type``.
+As for ``const Range``, see `const Ranges`_.
+
+
+
+============
+const Ranges
+============
+
+``range_reference<const Range>::type`` is defined by the following algorithm.
+Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
+
+
+.. parsed-literal::
+
+    if (Range is CObArray || Range is CObList)
+        return CObject const \* &
+    else if (Range is CPtrArray || Range is CPtrList)
+        return void const \* &
+    else if (there is a type X such that X& is the same as ReF)
+        return X const &
+    else if (there is a type X such that X* const is the same as ReF)
+        return X const \* const
+    else
+        return ReF
+
+
+Other `Boost.Range`_ metafunctions are defined by the following.
+``range_value<const Range>::type`` is the same as ``range_value<Range>::type``,
+``range_difference<const Range>::type`` is the same as ``std::ptrdiff_t``, and
+``range_pointer<const Range>::type`` is the same as ``add_pointer<remove_reference<range_reference<const Range>::type>::type>::type``.
+
+
+
+==========
+References
+==========
+- `Boost.Range`_
+- `MFC Collections`__
+- `ATL Collection Classes`__
+
+__ http://msdn2.microsoft.com/en-us/library/942860sh.aspx
+__ http://msdn2.microsoft.com/en-US/library/15e672bd.aspx
+
+
+
+.. _Boost C++ Libraries: http://www.boost.org/
+.. _Boost: `Boost C++ Libraries`_
+.. _Boost.Range: ../index.html
+.. _forward: range.html#forward_range
+.. _bidirectional: range.html#forward_range
+.. _random access: range.html#random_access_range
+
diff --git a/doc/portability.qbk b/doc/portability.qbk
new file mode 100644
index 0000000..fabaafc
--- /dev/null
+++ b/doc/portability.qbk
@@ -0,0 +1,27 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:portability Portability]
+
+A huge effort has been made to port the library to as many compilers as possible.
+
+Full support for built-in arrays require that the compiler supports class template partial specialization. For non-conforming compilers there might be a chance that it works anyway thanks to workarounds in the type traits library.
+Visual C++ 6/7.0 has a limited support for arrays: as long as the arrays are of built-in type it should work.
+
+Notice also that some compilers cannot do function template ordering properly. In that case one must rely of __range_iterator__ and a single function definition instead of overloaded versions for const and non-const arguments. So if one cares about old compilers, one should not pass rvalues to the functions.
+
+For maximum portability you should follow these guidelines:
+
+# do not use built-in arrays,
+# do not pass rvalues to __begin__`()`, __end__`()` and __iterator_range__ Range constructors and assignment operators,
+# use __const_begin__`()` and __const_end__`()` whenever your code by intention is read-only; this will also solve most rvalue problems,
+# do not rely on ADL:
+  * if you overload functions, include that header before the headers in this library,
+  * put all overloads in namespace boost.
+
+
+
+[endsect]
+
diff --git a/doc/reference.qbk b/doc/reference.qbk
new file mode 100644
index 0000000..14cf8e8
--- /dev/null
+++ b/doc/reference.qbk
@@ -0,0 +1,21 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:reference Reference]
+
+[include reference/overview.qbk]
+
+[section:concept_implementation Range concept implementation]
+[include reference/synopsis.qbk]
+[include reference/semantics.qbk]
+[endsect]
+
+[include reference/adaptors.qbk]
+[include reference/algorithms.qbk]
+[include reference/ranges.qbk]
+[include reference/utilities.qbk]
+[include reference/extending.qbk]
+
+[endsect]
diff --git a/doc/reference/adaptors.qbk b/doc/reference/adaptors.qbk
new file mode 100644
index 0000000..2cead36
--- /dev/null
+++ b/doc/reference/adaptors.qbk
@@ -0,0 +1,188 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:adaptors Range Adaptors]
+
+[section:introduction Introduction and motivation]
+
+A [*Range Adaptor] is a class that wraps an existing Range to provide a new Range with different behaviour. Since the behaviour of Ranges is determined by their associated iterators, a Range Adaptor simply wraps the underlying iterators with new special iterators. In this example
+
+``
+#include <boost/range/adaptors.hpp>
+#include <boost/range/algorithm.hpp>
+#include <iostream>
+#include <vector>
+
+std::vector<int> vec;
+boost::copy( vec | boost::adaptors::reversed,
+             std::ostream_iterator<int>(std::cout) );
+``
+
+the iterators from `vec` are wrapped `reverse_iterator`s. The type of the underlying Range Adapter is not documented because you do not need to know it. All that is relevant is that the expression
+
+``
+vec | boost::adaptors::reversed
+``
+
+returns a Range Adaptor where the iterator type is now the iterator type of the range `vec` wrapped in `reverse_iterator`. The expression `boost::adaptors::reversed` is called an *Adaptor Generator*.
+
+There are two ways of constructing a range adaptor. The first is by using `operator|()`. This is my preferred technique, however while discussing range adaptors with others it became clear that some users of the library strongly prefer a more familiar function syntax, so equivalent functions of the present tense form have been added as an alternative syntax. The equivalent to `rng | reversed` is `adaptors::reverse(rng)` for example.
+
+Why do I prefer the `operator|` syntax? The answer is readability:
+
+``
+std::vector<int> vec;
+boost::copy( boost::adaptors::reverse(vec),
+             std::ostream_iterator<int>(std::cout) );
+``
+
+This might not look so bad, but when we apply several adaptors, it becomes much worse. Just compare
+
+``
+std::vector<int> vec;
+boost::copy( boost::adaptors::unique( boost::adaptors::reverse( vec ) ),
+             std::ostream_iterator<int>(std::cout) );
+``
+
+to
+
+``
+std::vector<int> vec;
+boost::copy( vec | boost::adaptors::reversed
+                 | boost::adaptors::uniqued,
+             std::ostream_iterator<int>(std::cout) );
+``
+
+Furthermore, some of the adaptor generators take arguments themselves and these arguments are expressed with function call notation too. In those situations, you will really appreciate the succinctness of `operator|()`.
+
+[heading Composition of Adaptors]
+
+Range Adaptors are a powerful complement to Range algorithms. The reason is that adaptors are ['*orthogonal*] to algorithms. For example, consider these Range algorithms:
+
+* `boost::copy( rng, out )`
+* `boost::count( rng, pred )`
+
+What should we do if we only want to copy an element `a` if it satisfies some predicate, say `pred(a)`? And what if we only want to count the elements that satisfy the same predicate? The naive answer would be to use these algorithms:
+
+* `boost::copy_if( rng, pred, out )`
+* `boost::count_if( rng, pred )`
+
+These algorithms are only defined to maintain a one to one relationship with the standard library algorithms. This approach of adding algorithm suffers a combinatorial explosion. Inevitably many algorithms are missing `_if` variants and there is redundant development overhead for each new algorithm. The Adaptor Generator is the design solution to this problem. It is conceivable that some algorithms are capable of optimization by tightly coupling the filter with the algorithm. The adaptors provide a more general solution with superior separation of orthogonal concerns.
+
+[heading Range Adaptor alternative to copy_if algorithm]
+``
+boost::copy_if( rng, pred, out );
+``
+can be expressed as
+``
+boost::copy( rng | boost::adaptors::filtered(pred), out );
+``
+
+[heading Range Adaptor alternative to count_if algorithm]
+``
+boost::count_if( rng, pred );
+``
+can be expressed as
+``
+boost::size( rng | boost::adaptors::filtered(pred) );
+``
+
+What this means is that many algorithms no longer require nor benefit from an optimized implementation with an `_if` suffix. Furthermore, it turns out that algorithms with the `_copy` suffix are often not needed either. Consider `replace_copy_if()` which may be used as
+
+``
+std::vector<int> vec;
+boost::replace_copy_if( rng, std::back_inserter(vec), pred, new_value );
+``
+
+With adaptors and algorithms we can express this as
+
+``
+std::vector<int> vec;
+boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value));
+``
+
+The latter code has several benefits:
+
+1. it is more ['*efficient*] because we avoid extra allocations as might happen with `std::back_inserter`
+
+2. it is ['*flexible*] as we can subsequently apply even more adaptors, for example: ``
+boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value)
+                          | boost::adaptors::reversed);
+``
+
+3. it is ['*safer*] because there is no use of an unbounded output iterator.
+
+In this manner, the ['*composition*] of Range Adaptors has the following consequences:
+
+1. we no longer need many of the `_if`, `_copy`, `_copy_if` and `_n` variants of algorithms.
+
+2. we can generate a multitude of new algorithms on the fly, for example, above we generated `reverse_replace_copy_if()`
+
+In other words:
+
+[*Range Adaptors are to algorithms what algorithms are to containers]
+
+[endsect]
+
+[section:general_requirements General Requirements]
+
+In the description of generator expressions, the following notation is used:
+
+* `fwdRng` is an expression of a type `R` that models `ForwardRange`
+* `biRng` is an expression of a type `R` that models `BidirectionalRange`
+* `rndRng` is an expression of a type `R` that models `RandomAccessRange`
+* `pred` is an expression of a type that models `UnaryPredicate`
+* `bi_pred` is an expression of a type that models `BinaryPredicate`
+* `fun` is an expression of a type that models `UnaryFunction`
+* `value`, `new_value` and `old_value` are objects convertible to `boost::range_value<R>::type`
+* `n,m` are integer expressions convertible to `range_difference<R>::type`
+
+Also note that `boost::range_value<R>::type` must be implicitly convertible to the type arguments to `pred`, `bi_pred` and `fun`.
+
+Range Category in the following adaptor descriptions refers to the minimum range concept required by the range passed to the adaptor. The resultant range is a model of the same range concept as the input range unless specified otherwise.
+
+Returned Range Category is the concept of the returned range. In some cases the returned range is of a lesser category than the range passed to the adaptor. For example, the `filtered` adaptor returns only a `ForwardRange` regardless of the input.
+
+Furthermore, the following rules apply to any expression of the form
+``
+rng | boost::adaptors::adaptor_generator
+``
+
+1. Applying `operator|()` to a range `R` (always left argument) and a range adapter `RA` (always right argument) yields a new range type which may not conform to the same range concept as `R`.
+
+2. The return-type of `operator|()` is otherwise unspecified.
+
+3. `operator|()` is found by Argument Dependent Lookup (ADL) because a range adaptor is implemented in namespace `boost::adaptors`.
+
+4. `operator|()` is used to add new behaviour ['*lazily*] and never modifies its left argument.
+
+5. All iterators extracted from the left argument are extracted using qualified calls to `boost::begin()` and `boost::end()`.
+
+6. In addition to the `throw`-clauses below, `operator|()` may throw exceptions as a result of copying iterators. If such copying cannot throw an exception, then neither can the whole expression.
+
+[endsect]
+
+[section:reference Reference]
+[include adaptors/adjacent_filtered.qbk]
+[include adaptors/copied.qbk]
+[include adaptors/filtered.qbk]
+[include adaptors/indexed.qbk]
+[include adaptors/indirected.qbk]
+[include adaptors/map_keys.qbk]
+[include adaptors/map_values.qbk]
+[include adaptors/ref_unwrapped.qbk]
+[include adaptors/replaced.qbk]
+[include adaptors/replaced_if.qbk]
+[include adaptors/reversed.qbk]
+[include adaptors/sliced.qbk]
+[include adaptors/strided.qbk]
+[include adaptors/type_erased.qbk]
+[include adaptors/tokenized.qbk]
+[include adaptors/transformed.qbk]
+[include adaptors/uniqued.qbk]
+[endsect]
+
+[endsect]
+
diff --git a/doc/reference/adaptors/adjacent_filtered.qbk b/doc/reference/adaptors/adjacent_filtered.qbk
new file mode 100644
index 0000000..312646c
--- /dev/null
+++ b/doc/reference/adaptors/adjacent_filtered.qbk
@@ -0,0 +1,32 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:adjacent_filtered adjacent_filtered]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::adjacent_filtered(bi_pred)`]]
+    [[Function] [`boost::adaptors::adjacent_filter(rng, bi_pred)`]]
+]
+
+* [*Precondition:]  The `value_type` of the range is convertible to both argument types of `bi_pred`.
+* [*Postcondition:] For all adjacent elements `[x,y]` in the returned range, `bi_pred(x,y)` is `true`.
+* [*Throws:] Whatever the copy constructor of `bi_pred` might throw.
+* [*Range Category:] __forward_range__
+* [*Return Type:] `boost::adjacent_filtered_range<decltype(rng), decltype(bi_pred)>`
+* [*Returned Range Category:] The minimum of the range category of `rng` and __forward_range__
+
+[section:adjacent_filtered_example adjacent_filtered example]
+[import ../../../test/adaptor_test/adjacent_filtered_example.cpp]
+[adjacent_filtered_example]
+[endsect]
+
+This would produce the output:
+``
+1,2,3,4,5,6,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/copied.qbk b/doc/reference/adaptors/copied.qbk
new file mode 100644
index 0000000..2a8abcc
--- /dev/null
+++ b/doc/reference/adaptors/copied.qbk
@@ -0,0 +1,30 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:copied copied]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::copied(n, m)`]]
+    [[Function] [`boost::adaptors::copy(rng, n, m)`]]
+]
+
+* [*Precondition:]  `0 <= n && n <= m && m < distance(rng)`
+* [*Returns:] A new `iterator_range` that holds the sliced range `[n,m)` of the original range.
+* [*Range Category:] __random_access_range__
+* [*Returned Range Category:] __random_access_range__
+
+[section:copied_example copied example]
+[import ../../../test/adaptor_test/copied_example.cpp]
+[copied_example]
+[endsect]
+
+This would produce the output:
+``
+2,3,4,5,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/examples/indirected.cpp b/doc/reference/adaptors/examples/indirected.cpp
new file mode 100644
index 0000000..efb9d13
--- /dev/null
+++ b/doc/reference/adaptors/examples/indirected.cpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/indirected.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/shared_ptr.hpp>
+#include <algorithm>
+#include <iostream>
+#include <vector>
+
+int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    
+    std::vector<boost::shared_ptr<int> > input;
+    
+    for (int i = 0; i < 10; ++i)
+        input.push_back(boost::shared_ptr<int>(new int(i)));
+        
+    boost::copy(
+        input | indirected,
+        std::ostream_iterator<int>(std::cout, ","));
+        
+    return 0;
+}
+
diff --git a/doc/reference/adaptors/filtered.qbk b/doc/reference/adaptors/filtered.qbk
new file mode 100644
index 0000000..4ca3f91
--- /dev/null
+++ b/doc/reference/adaptors/filtered.qbk
@@ -0,0 +1,32 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:filtered filtered]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::filtered(pred)`]]
+    [[Function] [`boost::adaptors::filter(rng, pred)`]]
+]
+
+* [*Precondition:]  The `value_type` of the range is convertible to the argument type of `pred`.
+* [*Postcondition:] For all elements `[x]` in the returned range, `pred(x)` is `true`.
+* [*Throws:] Whatever the copy constructor of `pred` might throw.
+* [*Range Category:] __singlepass_range__
+* [*Range Return Type:] `boost::filtered_range<decltype(rng)>`
+* [*Returned Range Category:] The minimum of the range category of `rng` and __bidirectional_range__
+
+[section:filtered_example filtered example]
+[import ../../../test/adaptor_test/filtered_example.cpp]
+[filtered_example]
+[endsect]
+
+This would produce the output:
+``
+2,4,6,8,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/formatted.qbk b/doc/reference/adaptors/formatted.qbk
new file mode 100644
index 0000000..9dd69c2
--- /dev/null
+++ b/doc/reference/adaptors/formatted.qbk
@@ -0,0 +1,51 @@
+[/
+    Copyright 2014 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:formatted formatted]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::formatted()`]]
+    [[Pipe] [`rng | boost::adaptors::formatted(sep)`]]
+    [[Pipe] [`rng | boost::adaptors::formatted(sep, prefix)`]]
+    [[Pipe] [`rng | boost::adaptors::formatted(sep, prefix, postfix)`]]
+    [[Function] [`boost::adaptors::format(rng)`]]
+    [[Function] [`boost::adaptors::format(rng, sep)`]]
+    [[Function] [`boost::adaptors::format(rng, sep, prefix)`]]
+    [[Function] [`boost::adaptors::format(rng, sep, prefix, postfix)`]]
+]
+
+This adaptor produces a range that can be output streamed to a
+`std::basic_ostream` to produce the output string formatted output. With the
+default paramters given numbers 1 to 5 inclusively in a range the output when
+streamed would be "{0,1,2,3,4,5}". The prefix, separator and postfix may be
+passed as parameters.
+
+The general format of the output is thus:
+<prefix><element_1><sep><element_2><sep>...<element_n><postfix>
+
+* [*Precondition:]
+    * `0 <= n`.
+    * `sep` has a type that is CopyConstructible and able to be streamed to `std::basic_ostream<Char,Traits>`
+    * `prefix` has a type that is CopyConstructible and able to be streamed to `std::basic_ostream<Char,Traits>`
+    * `postfix` has a type that is CopyConstructible and able to be streamed to `std::basic_ostream<Char,Traits>`
+* [*Returns:] `boost::range::formatted_range<Iter, Sep, Prefix, Postfix>` where
+`Iter` is `typename boost::range_iterator<Rng>::type`, `Sep` is the separator
+type, `Prefix` is the prefix type and `Postfix` is the postfix type.
+* [*Range Category:] __single_pass_range__
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:formatted_example formatted example]
+[import ../../../test/adaptor_test/formatted_example.cpp]
+[separated_example]
+[endsect]
+
+This would produce the output:
+``
+{1,2,3,4,5}
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/indexed.qbk b/doc/reference/adaptors/indexed.qbk
new file mode 100644
index 0000000..4503fe6
--- /dev/null
+++ b/doc/reference/adaptors/indexed.qbk
@@ -0,0 +1,84 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:indexed indexed]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::indexed()`]]
+    [[Pipe] [`rng | boost::adaptors::indexed(start_index)`]]
+    [[Function] [`boost::adaptors::index(rng)`]]
+    [[Function] [`boost::adaptors::index(rng, start_index)`]]
+]
+
+[heading Description]
+The index within each returned `boost::range::index_value` is equal to
+`start_index` + the offset of the element from the beginning of the range. In
+the versions of the functions that omit `start_index` the starting index is
+taken to be `0`.
+
+* [*Purpose:] Adapt `rng` to return elements that have the corresponding value
+from `rng` and a numeric index.
+* [*Returns:] A range adapted to return both the element and the associated
+index. The returned range has elements of type:
+
+``
+boost::range::index_value<
+    typename boost::range_reference<decltype(rng)>::type,
+    typename boost::range_difference<decltype(rng)>::type
+>
+``
+
+The synopsis of index_value is as follows:
+``
+template<class T, class Indexable=std::ptrdiff_t>
+class index_value : public boost::tuple<Indexable, T>
+{
+public:
+
+    typedef ...unspecified...       index_type;
+    typedef ...unspecified...       const_index_type;
+
+    typedef ...unspecified...       value_type;
+    typedef ...unspecified...       const_value_type;
+
+    // ...unspecified... constructors
+
+    index_type index();
+    const_index_type index() const;
+
+    value_type value();
+    const_value_type value() const;
+};
+``
+
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::indexed_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng` if and only if `rng`
+is not a __bidirectional_range__. If `rng` is a __bidirectional_range__ then the
+returned range category is __forward_range__. The rationale for the demotion of
+__bidirectional_range__ inputs to __forward_range__ is to avoid slow calculation
+of indices for `boost::end(rng)`.
+
+[section:indexed_example indexed example]
+[import ../../../test/adaptor_test/indexed_example.cpp]
+[indexed_example]
+[endsect]
+
+This would produce the output:
+``
+Element = 10 Index = 0
+Element = 20 Index = 1
+Element = 30 Index = 2
+Element = 40 Index = 3
+Element = 50 Index = 4
+Element = 60 Index = 5
+Element = 70 Index = 6
+Element = 80 Index = 7
+Element = 90 Index = 8
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/indirected.qbk b/doc/reference/adaptors/indirected.qbk
new file mode 100644
index 0000000..3d6f416
--- /dev/null
+++ b/doc/reference/adaptors/indirected.qbk
@@ -0,0 +1,31 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:indirected indirected]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::indirected`]]
+    [[Function] [`boost::adaptors::indirect(rng)`]]
+]
+
+* [*Precondition:] The `value_type` of the range defines unary `operator*()`
+* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `*y` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::indirected_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`
+
+[section:indirected_example indirected example]
+[import ../../../test/adaptor_test/indirected_example.cpp]
+[indirected_example]
+[endsect]
+
+This would produce the output:
+``
+0,1,2,3,4,5,6,7,8,9,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/map_keys.qbk b/doc/reference/adaptors/map_keys.qbk
new file mode 100644
index 0000000..e70b4b8
--- /dev/null
+++ b/doc/reference/adaptors/map_keys.qbk
@@ -0,0 +1,31 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:map_keys map_keys]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::map_keys`]]
+    [[Function] [`boost::adaptors::keys(rng)`]]
+]
+
+* [*Precondition:] The `value_type` of the range is an instantiation of `std::pair`.
+* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `y.first` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::select_first_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:map_keys_example map_keys example]
+[import ../../../test/adaptor_test/map_keys_example.cpp]
+[map_keys_example]
+[endsect]
+
+This would produce the output:
+``
+0,1,2,3,4,5,6,7,8,9,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/map_values.qbk b/doc/reference/adaptors/map_values.qbk
new file mode 100644
index 0000000..845c9e8
--- /dev/null
+++ b/doc/reference/adaptors/map_values.qbk
@@ -0,0 +1,31 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:map_values map_values]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::map_values`]]
+    [[Function] [`boost::adaptors::values(rng)`]]
+]
+
+* [*Precondition:] The `value_type` of the range is an instantiation of `std::pair`.
+* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `y.second` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] for constant ranges, `boost::select_second_const<decltype(rng)>` otherwise `boost:select_second_mutable<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:map_values_example map_values example]
+[import ../../../test/adaptor_test/map_values_example.cpp]
+[map_values_example]
+[endsect]
+
+This would produce the output:
+``
+0,10,20,30,40,50,60,70,80,90,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/ref_unwrapped.qbk b/doc/reference/adaptors/ref_unwrapped.qbk
new file mode 100644
index 0000000..156ad67
--- /dev/null
+++ b/doc/reference/adaptors/ref_unwrapped.qbk
@@ -0,0 +1,32 @@
+[/
+    Copyright 2015 Robin Eckert
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:ref_unwrapped ref_unwrapped]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::ref_unwrapped`]]
+    [[Function] [`boost::adaptors::ref_unwrap(rng)`]]
+]
+
+This adaptor produces a range than applies `.get()` on all values in
+the range. It is useful for iterating ranges of
+`std::reference_wrapper` values or values using similar semantics.
+
+The adaptor is C++11 (and above) only.
+
+* [*Precondition:] The `value_type` of the range has a `.get() const`.
+* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `y.get()` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::unwrap_ref_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:ref_unwrapped_example ref_unwrapped example]
+[import ../../../test/adaptor_test/ref_unwrapped_example.cpp]
+[ref_unwrapped_example]
+[endsect]
+
+This would produce the output `123`.
+[endsect]
diff --git a/doc/reference/adaptors/replaced.qbk b/doc/reference/adaptors/replaced.qbk
new file mode 100644
index 0000000..1c34ab9
--- /dev/null
+++ b/doc/reference/adaptors/replaced.qbk
@@ -0,0 +1,33 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replaced replaced]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::replaced(old_value, new_value)`]]
+    [[Function] [`boost::adaptors::replace(rng, old_value, new_value)`]]
+]
+
+* [*Precondition:]
+    * `new_value` is convertible to the `value_type` of the range.
+    * `old_value` is convertible to the `value_type` of the range.
+* [*Postcondition:] For all elements `x` in the returned range, the value `x` is equal to the value of `(y == old_value) ? new_value : y` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::replaced_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:replaced_example replaced example]
+[import ../../../test/adaptor_test/replaced_example.cpp]
+[replaced_example]
+[endsect]
+
+This would produce the output:
+``
+1,10,3,10,5,10,7,10,9,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/replaced_if.qbk b/doc/reference/adaptors/replaced_if.qbk
new file mode 100644
index 0000000..99c1ed8
--- /dev/null
+++ b/doc/reference/adaptors/replaced_if.qbk
@@ -0,0 +1,33 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replaced_if replaced_if]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::replaced_if(pred, new_value)`]]
+    [[Function] [`boost::adaptors::replace_if(rng, pred, new_value)`]]
+]
+
+* [*Precondition:]
+    * The range `value_type` is convertible to the argument type of `pred`.
+    * `new_value` is convertible to the `value_type` of the range.
+* [*Postconditions:] For all elements `x` in the returned range, the value `x` is equal to the value of `pred(y) ? new_value : y` where `y` is the corresponding element in the original range.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::replaced_if_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:replaced_if_example replaced_if example]
+[import ../../../test/adaptor_test/replaced_if_example.cpp]
+[replaced_if_example]
+[endsect]
+
+This would produce the output:
+``
+1,10,3,10,5,10,7,10,9,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/reversed.qbk b/doc/reference/adaptors/reversed.qbk
new file mode 100644
index 0000000..8fe813f
--- /dev/null
+++ b/doc/reference/adaptors/reversed.qbk
@@ -0,0 +1,30 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:reversed reversed]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::reversed`]]
+    [[Function] [`boost::adaptors::reverse(rng)`]]
+]
+
+* [*Returns:] A range whose iterators behave as if they were the original iterators wrapped in `reverse_iterator`.
+* [*Range Category:] __bidirectional_range__
+* [*Range Return Type:] `boost::reversed_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:reversed_example reversed example]
+[import ../../../test/adaptor_test/reversed_example.cpp]
+[reversed_example]
+[endsect]
+
+This would produce the output:
+``
+9,8,7,6,5,4,3,2,1,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/sliced.qbk b/doc/reference/adaptors/sliced.qbk
new file mode 100644
index 0000000..81b4a16
--- /dev/null
+++ b/doc/reference/adaptors/sliced.qbk
@@ -0,0 +1,31 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:sliced sliced]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::sliced(n, m)`]]
+    [[Function] [`boost::adaptors::slice(rng, n, m)`]]
+]
+
+* [*Precondition:] `0 <= n && n <= m && m < distance(rng)`
+* [*Returns:] `make_range(rng, n, m)`
+* [*Range Category:] __random_access_range__
+* [*Range Return Type:] `boost::sliced_range<decltype(rng)>`
+* [*Returned Range Category:] __random_access_range__
+
+[section:sliced_example sliced example]
+[import ../../../test/adaptor_test/sliced_example.cpp]
+[sliced_example]
+[endsect]
+
+This would produce the output:
+``
+3,4,5,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/strided.qbk b/doc/reference/adaptors/strided.qbk
new file mode 100644
index 0000000..a672e3d
--- /dev/null
+++ b/doc/reference/adaptors/strided.qbk
@@ -0,0 +1,30 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:strided strided]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::strided(n)`]]
+    [[Function] [`boost::adaptors::stride(rng, n)`]]
+]
+
+* [*Precondition:] `0 <= n`.
+* [*Returns:] A new range based on `rng` where traversal is performed in steps of `n`.
+* [*Range Category:] __single_pass_range__
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:strided_example strided example]
+[import ../../../test/adaptor_test/strided_example.cpp]
+[strided_example]
+[endsect]
+
+This would produce the output:
+``
+1,3,5,7,9,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/tokenized.qbk b/doc/reference/adaptors/tokenized.qbk
new file mode 100644
index 0000000..2105323
--- /dev/null
+++ b/doc/reference/adaptors/tokenized.qbk
@@ -0,0 +1,67 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:tokenized tokenized]
+
+[table
+    [[Syntax] [Code]]
+    [
+        [Pipe]
+        [
+            ``
+            rng | boost::adaptors::tokenized(regex)
+            rng | boost::adaptors::tokenized(regex, i)
+            rng | boost::adaptors::tokenized(regex, rndRng)
+            rng | boost::adaptors::tokenized(regex, i, flags)
+            rng | boost::adaptors::tokenized(regex, rndRng, flags)
+            ``
+        ]
+    ]
+    [
+        [Function]
+        [
+            ``
+            boost::adaptors::tokenize(rng, regex)
+            boost::adaptors::tokenize(rng, regex, i)
+            boost::adaptors::tokenize(rng, regex, rndRng)
+            boost::adaptors::tokenize(rng, regex, i, flags)
+            boost::adaptors::tokenize(rng, regex, rndRng, flags)
+            ``
+        ]
+    ]
+]
+
+* [*Precondition:]
+    * Let `T` denote `typename range_value<decltype(rng)>::type`, then `regex` has the type `basic_regex<T>` or is implicitly convertible to one of these types.
+    * `i` has the type `int`.
+    * the `value_type` of `rndRng` is `int`.
+    * `flags` has the type `regex_constants::syntax_option_type`.
+* [*Returns:] A range whose iterators behave as if they were the original iterators wrapped in `regex_token_iterator`. The first iterator in the range would be constructed by forwarding all the arguments of `tokenized()` to the `regex_token_iterator` constructor.
+* [*Throws:] Whatever constructing and copying equivalent `regex_token_iterator`s might throw.
+* [*Range Category:] __random_access_range__
+* [*Range Return Type:] `boost::tokenized_range<decltype(rng)>`
+* [*Returned Range Category:] __random_access_range__
+
+[section:tokenized_example tokenized_example]
+[import ../../../test/adaptor_test/tokenized_example.cpp]
+[tokenized_example]
+[endsect]
+
+This would produce the output:
+``
+a
+b
+c
+d
+e
+f
+g
+hijklmnopqrstuvwxyz
+
+``
+
+[endsect]
+
+
diff --git a/doc/reference/adaptors/transformed.qbk b/doc/reference/adaptors/transformed.qbk
new file mode 100644
index 0000000..0c71e8d
--- /dev/null
+++ b/doc/reference/adaptors/transformed.qbk
@@ -0,0 +1,32 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:transformed transformed]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::transformed(fun)`]]
+    [[Function] [`boost::adaptors::transform(rng, fun)`]]
+]
+
+* [*Precondition:] The `value_type` of the range is convertible to the argument type of `fun`.
+* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `fun(y)` where `y` is the corresponding element in the original range.
+* [*Throws:] Whatever the copy-constructor of `fun` might throw.
+* [*Range Category:] __single_pass_range__
+* [*Range Return Type:] `boost::transformed_range<decltype(rng)>`
+* [*Returned Range Category:] The range category of `rng`.
+
+[section:transformed_example transformed example]
+[import ../../../test/adaptor_test/transformed_example.cpp]
+[transformed_example]
+[endsect]
+
+This would produce the output:
+``
+2,4,6,8,10,12,14,16,18,20,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/type_erased.qbk b/doc/reference/adaptors/type_erased.qbk
new file mode 100644
index 0000000..e55ff66
--- /dev/null
+++ b/doc/reference/adaptors/type_erased.qbk
@@ -0,0 +1,65 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:type_erased type_erased]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::type_erased<Value, Traversal, Reference, Difference, Buffer>()`]]
+    [[Function] [`boost::adaptors::type_erase(rng, boost::adaptors::type_erased<Value, Traversal, Reference, Difference, Buffer>)`]]
+]
+
+Please note that it is frequently unnecessary to use the `type_erased` adaptor. It is often better to use the implicit conversion to `any_range`.
+
+Let `Rng` be the type of `rng`.
+
+* [*Template parameters:]
+    * `Value` is the `value_type` for the `any_range`. If this is set to boost::use_default, `Value` will be calculated from the
+        range type when the adaptor is applied.
+    * `Traversal` is the tag used to identify the traversal of the resultant range. Frequently it is desirable to set a traversal category lower than the source container or range to maximize the number of ranges that can convert to the `any_range`. If this is left as boost::use_default then `Traversal` will be `typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type`
+    * `Reference` is the `reference` for the `any_range`. `boost::use_default` will equate to `typename range_reference<Rng>::type`.
+    * `Difference` is the `difference_type` for the any_range. `boost::use_default` will equate to `typename boost::range_difference<Rng>::type`
+    * `Buffer` is the storage used to allocate the underlying iterator wrappers. This can typically be ignored, but is available as a template parameter for customization. Buffer must be a model of the `AnyIteratorBufferConcept`.
+* [*Precondition:]  `Traversal` is one of `{ boost::use_default, boost::single_pass_traversal_tag, boost::forward_traversal_tag, boost::bidirectional_traversal_tag, boost::random_access_traversal_tag }`
+* [*Returns:] The returned value is the same as `typename any_range_type_generator< Rng, Value, Traversal, Reference, Difference, Buffer >` that represents `rng` in a type-erased manner.
+* [*Range Category:] __single_pass_range__
+* [*Returned Range Category:] if `Traversal` was specified as `boost::use_default` then `typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type`, otherwise `Traversal`.
+
+[heading AnyIteratorBufferConcept]
+``
+class AnyIteratorBufferConcept
+{
+public:
+    AnyIteratorBufferConcept();
+    ~AnyIteratorBufferConcept();
+
+    // bytes is the requested size to allocate. This function
+    // must return a pointer to an adequate area of memory.
+    // throws: bad_alloc
+    //
+    // The buffer will only ever have zero or one
+    // outstanding memory allocations.
+    void* allocate(std::size_t bytes);
+
+    // deallocate this buffer
+    void deallocate();
+};
+``
+
+[section:type_erased_example type-erased example]
+[import ../../../test/adaptor_test/type_erased_example.cpp]
+[type_erased_example]
+[endsect]
+
+This would produce the output:
+``
+1,2,3,4,5,
+6,7,8,9,10,
+11,12,13,14,15,
+11,12,13,14,15,
+``
+[endsect]
+
+
diff --git a/doc/reference/adaptors/uniqued.qbk b/doc/reference/adaptors/uniqued.qbk
new file mode 100644
index 0000000..3fb38d7
--- /dev/null
+++ b/doc/reference/adaptors/uniqued.qbk
@@ -0,0 +1,31 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:uniqued uniqued]
+
+[table
+    [[Syntax] [Code]]
+    [[Pipe] [`rng | boost::adaptors::uniqued`]]
+    [[Function] [`boost::adaptors::unique(rng)`]]
+]
+
+* [*Precondition:] The `value_type` of the range is comparable with `operator==()`.
+* [*Postcondition:] For all adjacent elements `[x,y]` in the returned range, `x==y` is false.
+* [*Range Category:] __forward_range__
+* [*Range Return Type:] `boost::uniqued_range<decltype(rng)>`
+* [*Returned Range Category:] The minimum of the range concept of `rng` and __forward_range__.
+
+[section:uniqued_example uniqued example]
+[import ../../../test/adaptor_test/uniqued_example.cpp]
+[uniqued_example]
+[endsect]
+
+This would produce the output:
+``
+1,2,3,4,5,6,
+``
+[endsect]
+
+
diff --git a/doc/reference/algorithm/adjacent_find.qbk b/doc/reference/algorithm/adjacent_find.qbk
new file mode 100644
index 0000000..67d78d4
--- /dev/null
+++ b/doc/reference/algorithm/adjacent_find.qbk
@@ -0,0 +1,85 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:adjacent_find adjacent_find]
+
+[heading Prototype]
+
+``
+template<class ForwardRange>
+typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange& rng);
+
+template<class ForwardRange>
+typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange& rng, BinaryPred pred);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng, BinaryPred pred);
+
+template<range_return_value_re, class ForwardRange>
+typename range_return<ForwardRange, re>::type
+adjacent_find(ForwardRange& rng);
+
+template<range_return_value_re, class ForwardRange>
+typename range_return<const ForwardRange, re>::type
+adjacent_find(const ForwardRange& rng);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<ForwardRange, re>::type
+adjacent_find(ForwardRange& rng, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<const ForwardRange, re>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+[*Non-predicate versions:]
+
+`adjacent_find` finds the first adjacent elements `[x,y]` in `rng` where `x == y`
+
+[*Predicate versions:]
+
+`adjacent_find` finds the first adjacent elements `[x,y]` in `rng` where `pred(x,y)` is `true`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/adjacent_find.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions of adjacent_find:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange`'s value type is a model of the `EqualityComparableConcept`.
+
+[*For the predicate versions of adjacent_find:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange`'s value type is convertible to `BinaryPredicate`'s first argument type and to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+Linear. If `empty(rng)` then no comparisons are performed; otherwise, at most `distance(rng) - 1` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/binary_search.qbk b/doc/reference/algorithm/binary_search.qbk
new file mode 100644
index 0000000..42031b3
--- /dev/null
+++ b/doc/reference/algorithm/binary_search.qbk
@@ -0,0 +1,60 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:binary_search binary_search]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Value>
+bool binary_search(const ForwardRange& rng, const Value& val);
+
+template<class ForwardRange, class Value, class BinaryPredicate>
+bool binary_search(const ForwardRange& rng, const Value& val, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`binary_search` returns `true` if and only if the value `val` exists in the range `rng`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/binary_search.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions of binary_search:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `Value` is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `Value` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* `ForwardRange`'s value type is the same type as `Value`.
+
+[*For the predicate versions of binary_search:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `ForwardRange`'s value type is the same type as `Value`.
+* `ForwardRange`'s value type is convertible to `BinaryPredicate`'s argument type.
+
+[heading Precondition:]
+
+[*For the non-predicate version:]
+
+`rng` is ordered in ascending order according to `operator<`.
+
+[*For the predicate version:]
+
+`rng` is ordered in ascending order according to the function object `pred`.
+
+[heading Complexity]
+
+For non-random-access ranges, the complexity is `O(N)` where `N` is `distance(rng)`.
+
+For random-access ranges, the complexity is `O(log N)` where `N` is `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/copy.qbk b/doc/reference/algorithm/copy.qbk
new file mode 100644
index 0000000..e40f1b1
--- /dev/null
+++ b/doc/reference/algorithm/copy.qbk
@@ -0,0 +1,41 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:copy copy]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class OutputIterator>
+OutputIterator copy(const SinglePassRange& source_rng, OutputIterator out_it);
+``
+
+[heading Description]
+
+`copy` copies all elements from `source_rng` to the range `[out_it, out_it + distance(source_rng))`.
+The return value is `out_it + distance(source_rng)`
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/copy.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* The `value_type` of __single_pass_range__ Concept is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+* `out_it` is not an iterator within the `source_rng`.
+* `[out_it, out_it + distance(source_rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. Exactly `distance(source_rng)` assignments are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/copy_backward.qbk b/doc/reference/algorithm/copy_backward.qbk
new file mode 100644
index 0000000..8fdac5a
--- /dev/null
+++ b/doc/reference/algorithm/copy_backward.qbk
@@ -0,0 +1,46 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:copy_backward copy_backward]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange, class BidirectionalOutputIterator>
+    BidirectionalOutputIterator
+        copy_backward(const BidirectionalRange& source_rng,
+                      BidirectionalOutputIterator out_it);
+``
+
+[heading Description]
+
+`copy_backward` copies all elements from `source_rng` to the range `[out_it - distance(source_rng), out_it)`.
+
+The values are copied in reverse order. The return value is `out_it - distance(source_rng)`.
+
+Note well that unlike all other standard algorithms `out_it` denotes the *end* of the output sequence.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/copy_backward.hpp`
+
+[heading Requirements]
+
+* `BidirectionalRange` is a model of __bidirectional_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* The `value_type` of __bidirectional_range__ Concept is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+* `out_it` is not an iterator within the `source_rng`.
+* `[out_it, out_it + distance(source_rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. Exactly `distance(source_rng)` assignments are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/count.qbk b/doc/reference/algorithm/count.qbk
new file mode 100644
index 0000000..a84af3c
--- /dev/null
+++ b/doc/reference/algorithm/count.qbk
@@ -0,0 +1,41 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:count count]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class Value>
+typename range_difference<SinglePassRange>::type
+count(SinglePassRange& rng, const Value& val);
+
+template<class SinglePassRange, class Value>
+typename range_difference<const SinglePassRange>::type
+count(const SinglePassRange& rng, const Value& val);
+``
+
+[heading Description]
+
+`count` returns the number of elements `x` in `rng` where `x == val` is `true`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/count.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `Value` is a model of the `EqualityComparableConcept`.
+* `SinglePassRange`'s value type is a model of the `EqualityComparableConcept`.
+* An object of `SinglePassRange`'s value type can be compared for equality with an object of type `Value`.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/count_if.qbk b/doc/reference/algorithm/count_if.qbk
new file mode 100644
index 0000000..b95cc91
--- /dev/null
+++ b/doc/reference/algorithm/count_if.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:count_if count_if]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class UnaryPredicate>
+typename range_difference<const SinglePassRange>::type
+count_if(const SinglePassRange& rng, UnaryPredicate pred);
+``
+
+[heading Description]
+
+`count_if` returns the number of elements `x` in `rng` where `pred(x)` is `true`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/count_if.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `UnaryPredicate` is a model of the `UnaryPredicateConcept`.
+* `SinglePassRange`'s value type is a model of the `EqualityComparableConcept`.
+* The value type of `SinglePassRange` is convertible to the argument type of `UnaryPredicate`.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` invocations of `pred`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/equal.qbk b/doc/reference/algorithm/equal.qbk
new file mode 100644
index 0000000..37d1c02
--- /dev/null
+++ b/doc/reference/algorithm/equal.qbk
@@ -0,0 +1,64 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:equal equal]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2
+>
+bool equal(const SinglePassRange1& rng1,
+           const SinglePassRange2& rng2);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+>
+bool equal(const SinglePassRange1& rng1,
+           const SinglePassRange2& rng2,
+           BinaryPredicate         pred);
+``
+
+[heading Description]
+
+`equal` returns `true` if `distance(rng1)` is equal to the `distance(rng2)` and for each element `x` in `rng1`, the corresponding element `y` in `rng2` is equal. Otherwise `false` is returned.
+
+In this range version of `equal` it is perfectly acceptable to pass in two ranges of unequal lengths.
+
+Elements are considered equal in the non-predicate version if `operator==` returns `true`. Elements are considered equal in the predicate version if `pred(x,y)` is `true`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/equal.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1`'s value type is a model of the `EqualityComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `EqualityComparableConcept`.
+* `SinglePassRange1`'s value type can be compared for equality with `SinglePassRange2`'s value type.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+Linear. At most `min(distance(rng1), distance(rng2))` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/equal_range.qbk b/doc/reference/algorithm/equal_range.qbk
new file mode 100644
index 0000000..2d6c342
--- /dev/null
+++ b/doc/reference/algorithm/equal_range.qbk
@@ -0,0 +1,83 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:equal_range equal_range]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange,
+    class Value
+    >
+std::pair<typename range_iterator<ForwardRange>::type,
+          typename range_iterator<ForwardRange>::type>
+equal_range(ForwardRange& rng, const Value& val);
+
+template<
+    class ForwardRange,
+    class Value
+    >
+std::pair<typename range_iterator<const ForwardRange>::type,
+          typename range_iterator<const ForwardRange>::type>
+equal_range(const ForwardRange& rng, const Value& val);
+
+template<
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+std::pair<typename range_iterator<ForwardRange>::type,
+          typename range_iterator<ForwardRange>::type>
+equal_range(ForwardRange& rng, const Value& val, SortPredicate pred);
+
+template<
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+std::pair<typename range_iterator<const ForwardRange>::type,
+          typename range_iterator<const ForwardRange>::type>
+equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred);                      
+ ``
+
+[heading Description]
+
+`equal_range` returns a range in the form of a pair of iterators where all of the elements are equal to `val`. If no values are found that are equal to `val`, then an empty range is returned, hence `result.first == result.second`. For the non-predicate versions of `equal_range`  the equality of elements is determined by `operator<`.
+For the predicate versions of `equal_range` the equality of elements is determined by `pred`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/equal_range.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `Value` is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `Value` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* `ForwardRange`'s value type is the same type as `Value`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `SortPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `ForwardRange`'s value type is the same as `Value`.
+* `ForwardRange`'s value type is convertible to both of `SortPredicate`'s argument types.
+
+[heading Precondition:]
+
+For the non-predicate versions: `rng` is ordered in ascending order according to `operator<`.
+
+For the predicate versions: `rng` is ordered in ascending order according to `pred`.
+
+[heading Complexity]
+
+For random-access ranges, the complexity is `O(log N)`, otherwise the complexity is `O(N)`. 
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/fill.qbk b/doc/reference/algorithm/fill.qbk
new file mode 100644
index 0000000..4df2c0f
--- /dev/null
+++ b/doc/reference/algorithm/fill.qbk
@@ -0,0 +1,36 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:fill fill]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Value>
+ForwardRange& fill( ForwardRange& rng, const Value& val );
+``
+
+[heading Description]
+
+`fill` assigns the value `val` to every element in the range `rng`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/fill.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is a model of the `AssignableConcept`.
+* `Value` is convertible to `ForwardRange`'s value type.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` assignments are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/fill_n.qbk b/doc/reference/algorithm/fill_n.qbk
new file mode 100644
index 0000000..1375d4e
--- /dev/null
+++ b/doc/reference/algorithm/fill_n.qbk
@@ -0,0 +1,36 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:fill_n fill_n]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Size, class Value>
+ForwardRange& fill( ForwardRange& rng, Size n, const Value& val );
+``
+
+[heading Description]
+
+`fill_n` assigns the value `val` to `n` elements in the range `rng` beginning with `boost::begin(rng)`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/fill_n.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is a model of the `AssignableConcept`.
+* `Value` is convertible to `ForwardRange`'s value type.
+
+[heading Complexity]
+
+Linear. Exactly `n` assignments are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/find.qbk b/doc/reference/algorithm/find.qbk
new file mode 100644
index 0000000..ba57637
--- /dev/null
+++ b/doc/reference/algorithm/find.qbk
@@ -0,0 +1,45 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:find find]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class Value>
+typename range_iterator<SinglePassRange>::type
+find(SinglePassRange& rng, Value val);
+
+template<
+    range_return_value re,
+    class SinglePassRange,
+    class Value
+    >
+typename range_return<SinglePassRange, re>::type
+find(SinglePassRange& rng, Value val);
+``
+
+[heading Description]
+
+The versions of `find` that return an iterator, returns the first iterator in the range `rng` such that `*i == value`. `end(rng)` is returned if no such iterator exists.
+The versions of find that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/find.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `Value` is a model of the `EqualityComparableConcept`.
+* The `operator==` is defined for type `Value` to be compared with the `SinglePassRange`'s value type.
+
+[heading Complexity]
+
+Linear. At most `distance(rng)` comparisons for equality.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/find_end.qbk b/doc/reference/algorithm/find_end.qbk
new file mode 100644
index 0000000..dff17cd
--- /dev/null
+++ b/doc/reference/algorithm/find_end.qbk
@@ -0,0 +1,74 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:find_end find_end]
+
+[heading Prototype]
+
+``
+template<class ForwardRange1, class ForwardRange2>
+typename range_iterator<ForwardRange1>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_iterator<ForwardRange1>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2
+    >
+typename range_return<ForwardRange1, re>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_return<ForwardRange1, re>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `find_end` that return an iterator, return an iterator to the beginning of the last sub-sequence equal to `rng2` within `rng1`.
+Equality is determined by `operator==` for non-predicate versions of `find_end`, and by satisfying `pred` in the predicate versions. The versions of `find_end` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/find_end.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange1` is a model of the __forward_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `ForwardRange1`'s value type is a model of the `EqualityComparableConcept`.
+* `ForwardRange2`'s value type is a model of the `EqualityComparableConcept`.
+* Objects of `ForwardRange1`'s value type can be compared for equality with objects of `ForwardRange2`'s value type.
+
+[*For the predicate versions:]
+
+* `ForwardRange1` is a model of the __forward_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `ForwardRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+The number of comparisons is proportional to `distance(rng1) * distance(rng2)`. If both `ForwardRange1` and `ForwardRange2` are models of `BidirectionalRangeConcept` then the average complexity is linear and the worst case is `distance(rng1) * distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/find_first_of.qbk b/doc/reference/algorithm/find_first_of.qbk
new file mode 100644
index 0000000..d10d986
--- /dev/null
+++ b/doc/reference/algorithm/find_first_of.qbk
@@ -0,0 +1,74 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:find_first_of find_first_of]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange1, class ForwardRange2>
+typename range_iterator<SinglePassRange1>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    class SinglePassRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_iterator<SinglePassRange1>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class SinglePassRange1,
+    class ForwardRange2
+    >
+typename range_return<SinglePassRange1, re>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    range_return_value re,
+    class SinglePassRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_return<SinglePassRange1, re>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `find_first_of` that return an iterator, return an iterator to the first occurrence in `rng1` of any of the elements in `rng2`.
+Equality is determined by `operator==` for non-predicate versions of `find_first_of`, and by satisfying `pred` in the predicate versions.
+
+The versions of `find_first_of` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/find_first_of.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `SinglePassRange1`'s value type is a model of the `EqualityComparableConcept`, and can be compared for equality with `ForwardRange2`'s value type.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `ForwardRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+At most `distance(rng1) * distance(rng2)` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/find_if.qbk b/doc/reference/algorithm/find_if.qbk
new file mode 100644
index 0000000..12ff91b
--- /dev/null
+++ b/doc/reference/algorithm/find_if.qbk
@@ -0,0 +1,50 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:find_if find_if]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class UnaryPredicate>
+typename range_iterator<SinglePassRange>::type
+find_if(SinglePassRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class SinglePassRange,
+    class UnaryPredicate
+    >
+typename range_return<SinglePassRange, re>::type
+find_if(SinglePassRange& rng, UnaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `find_if` that return an iterator, returns the first iterator in the range `rng` such that `pred(*i)` is `true`. `end(rng)` is returned if no such iterator exists.
+
+The versions of `find_if` that return a `range_return`, defines found in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/find_if.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `UnaryPredicate` is a model of the `PredicateConcept`.
+* The value type of `SinglePassRange` is convertible to the argument type of `UnaryPredicate`.
+
+[heading Precondition:]
+
+For each iterator `i` in `rng`, `*i` is in the domain of `UnaryPredicate`.
+
+[heading Complexity]
+
+Linear. At most `distance(rng)` invocations of `pred`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/for_each.qbk b/doc/reference/algorithm/for_each.qbk
new file mode 100644
index 0000000..3661368
--- /dev/null
+++ b/doc/reference/algorithm/for_each.qbk
@@ -0,0 +1,45 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:for_each for_each]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange,
+    class UnaryFunction
+    >
+UnaryFunction for_each(SinglePassRange& rng, UnaryFunction fun);
+
+template<
+    class SinglePassRange,
+    class UnaryFunction
+    >
+UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun);    
+``
+
+[heading Description]
+
+`for_each` traverses forward through `rng` and for each element `x` it invokes `fun(x)`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/for_each.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `UnaryFunction` is a model of the `UnaryFunctionConcept`.
+* `UnaryFunction` does not apply any non-constant operation through its argument.
+* `SinglePassRange`'s value type is convertible to `UnaryFunction`'s argument type.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` applications of `UnaryFunction`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/generate.qbk b/doc/reference/algorithm/generate.qbk
new file mode 100644
index 0000000..3d19664
--- /dev/null
+++ b/doc/reference/algorithm/generate.qbk
@@ -0,0 +1,44 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:generate generate]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Generator>
+ForwardRange& generate( ForwardRange& rng, Generator gen );
+
+template<class ForwardRange, class Generator>
+const ForwardRange& generate( const ForwardRange& rng, Generator gen );
+``
+
+[heading Description]
+
+`generate` assigns the result of `gen()` to each element in range `rng`. Returns the resultant range.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/generate.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Generator` is a model of the `GeneratorConcept`.
+* The `value_type` of `SinglePassRange` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+* `out_it` is not an iterator within `rng`.
+* `[out_it, out_it + distance(rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` assignments are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/includes.qbk b/doc/reference/algorithm/includes.qbk
new file mode 100644
index 0000000..5f1ca5f
--- /dev/null
+++ b/doc/reference/algorithm/includes.qbk
@@ -0,0 +1,69 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:includes includes]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange1, class SinglePassRange2>
+bool includes(const SinglePassRange1& rng1, const SinglePassRange2& rng2);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+bool includes(const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+              BinaryPredicate pred);    
+``
+
+[heading Description]
+
+`includes` returns `true` if and only if, for every element in `rng2`, an equivalent element is also present in `rng1`.
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions. 
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/set_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `SinglePassRange1`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* The ordering of objects of type `SinglePassRange2`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+Linear. `O(N)`, where `N` is `distance(rng1) + distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/inplace_merge.qbk b/doc/reference/algorithm/inplace_merge.qbk
new file mode 100644
index 0000000..015d9bb
--- /dev/null
+++ b/doc/reference/algorithm/inplace_merge.qbk
@@ -0,0 +1,77 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:inplace_merge inplace_merge]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange>
+BidirectionalRange&
+inplace_merge( BidirectionalRange& rng,
+               typename range_iterator<BidirectionalRange>::type middle );
+
+template<class BidirectionalRange>
+const BidirectionalRange&
+inplace_merge( const BidirectionalRange& rng,
+               typename range_iterator<const BidirectionalRange>::type middle );
+
+template<class BidirectionalRange, class BinaryPredicate>
+BidirectionalRange&
+inplace_merge( BidirectionalRange& rng,
+               typename range_iterator<BidirectionalRange>::type middle,
+               BinaryPredicate pred );
+
+template<class BidirectionalRange, class BinaryPredicate>
+const BidirectionalRange&
+inplace_merge( const BidirectionalRange& rng,
+               typename range_iterator<const BidirectionalRange>::type middle,
+               BinaryPredicate pred );
+``
+
+[heading Description]
+
+`inplace_merge` combines two consecutive sorted ranges `[begin(rng), middle)` and `[middle, end(rng))` into a single sorted range `[begin(rng), end(rng))`. That is, it starts with a range `[begin(rng), end(rng))` that consists of two pieces each of which is in ascending order, and rearranges it so that the entire range is in ascending order. `inplace_merge` is stable, meaning both that the relative order of elements within each input range is preserved.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/inplace_merge.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate version:]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `range_value<BidirectionalRange>::type` is a model of `LessThanComparableConcept`
+* The ordering on objects of `range_type<BidirectionalRange>::type` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate version:]
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `BidirectionalRange`'s value type is convertible to both `BinaryPredicate`'s argument types.
+
+[heading Precondition:]
+
+[heading For the non-predicate version:]
+
+* `middle` is in the range `rng`.
+* `[begin(rng), middle)` is in ascending order. That is for each pair of adjacent elements `[x,y]`, `y < x` is `false`.
+* `[middle, end(rng))` is in ascending order. That is for each pair of adjacent elements `[x,y]`, `y < x` is `false`.
+
+[heading For the predicate version:]
+
+* `middle` is in the range `rng`.
+* `[begin(rng), middle)` is in ascending order. That is for each pair of adjacent elements `[x,y]`, `pred(y,x) == false`.
+* `[middle, end(rng))` is in ascending order. That is for each pair of adjacent elements `[x,y]`, `pred(y,x) == false`.
+
+[heading Complexity]
+
+Worst case: `O(N log(N))`
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/lexicographical_compare.qbk b/doc/reference/algorithm/lexicographical_compare.qbk
new file mode 100644
index 0000000..8160b15
--- /dev/null
+++ b/doc/reference/algorithm/lexicographical_compare.qbk
@@ -0,0 +1,60 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:lexicographical_compare lexicographical_compare]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2
+    >
+bool lexicographical_compare(const SinglePassRange1& rng1,
+                             const SinglePassRange2& rng2);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+bool lexicographical_compare(const SinglePassRange1& rng1,
+                             const SinglePassRange2& rng2,
+                             BinaryPredicate pred);    
+``
+
+[heading Description]
+
+`lexicographical_compare` compares element by element `rng1` against `rng2`. If the element from `rng1` is less than the element from `rng2` then `true` is returned. If the end of `rng1` without reaching the end of `rng2` this also causes the return value to be `true`. The return value is `false` in all other circumstances. The elements are compared using `operator<` in the non-predicate versions of `lexicographical_compare` and using `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/lexicographical_compare.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions of lexicographical_compare:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* Let `x` be an object of `SinglePassRange1`'s value type. Let `y` be an object of `SinglePassRange2`'s value type. `x < y` must be valid. `y < x` must be valid.
+
+[*For the predicate versions of lexicographical_compare:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+Linear. At most `2 * min(distance(rng1), distance(rng2))` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/lower_bound.qbk b/doc/reference/algorithm/lower_bound.qbk
new file mode 100644
index 0000000..2917d26
--- /dev/null
+++ b/doc/reference/algorithm/lower_bound.qbk
@@ -0,0 +1,93 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:lower_bound lower_bound]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange, 
+    class Value
+    >
+typename range_iterator<ForwardRange>::type
+lower_bound(ForwardRange& rng, Value val);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value
+    >
+typename range_return<ForwardRange, re>::type
+lower_bound(ForwardRange& rng, Value val);
+
+template<
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+typename range_iterator<ForwardRange>::type
+lower_bound(ForwardRange& rng, Value val, SortPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+typename range_return<ForwardRange,re>::type
+lower_bound(ForwardRange& rng, Value val, SortPredicate pred);
+``
+
+[heading Description]
+
+The versions of `lower_bound` that return an iterator, returns the first iterator in the range `rng` such that:
+without predicate - `*i < value` is `false`,
+with predicate - `pred(*i, value)` is `false`.
+
+`end(rng)` is returned if no such iterator exists.
+
+The versions of `lower_bound` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/lower_bound.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `Value` is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `Value` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* `ForwardRange`'s value type is the same type as `Value`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `ForwardRange`'s value type is the same type as `Value`.
+* `ForwardRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng` is sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng` is sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+For ranges that model the __random_access_range__ concept the complexity is `O(log N)`, where `N` is `distance(rng)`.
+
+For all other range types the complexity is `O(N)`.
+
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/make_heap.qbk b/doc/reference/algorithm/make_heap.qbk
new file mode 100644
index 0000000..df47fac
--- /dev/null
+++ b/doc/reference/algorithm/make_heap.qbk
@@ -0,0 +1,56 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:make_heap make_heap]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& make_heap(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& make_heap(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class Compare>
+RandomAccessRange& make_heap(RandomAccessRange& rng, Compare pred);
+
+template<class RandomAccessRange, class Compare>
+const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`make_heap` turns `rng` into a heap.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/heap_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Complexity]
+
+Linear. At most `3 * distance(rng)` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/max_element.qbk b/doc/reference/algorithm/max_element.qbk
new file mode 100644
index 0000000..01101a5
--- /dev/null
+++ b/doc/reference/algorithm/max_element.qbk
@@ -0,0 +1,86 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:max_element max_element]
+
+[heading Prototype]
+
+``
+template<class ForwardRange>
+typename range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng);
+
+template<class ForwardRange>
+typename range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng, BinaryPredicate pred);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred);
+
+
+template<
+    range_return_value re,
+    class ForwardRange
+    >
+typename range_return<ForwardRange, re>::type
+max_element(ForwardRange& rng);
+
+template<
+    range_return_value_re,
+    class ForwardRange
+    >
+typename range_return<const ForwardRange, re>::type
+max_element(const ForwardRange& rng);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<ForwardRange, re>::type
+max_element(ForwardRange& rng, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<const ForwardRange, re>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `max_element` that return an iterator, return the iterator to the maximum value as determined by using `operator<` if a predicate is not supplied. Otherwise the predicate `pred` is used to determine the maximum value. The versions of `max_element` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/max_element.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange`'s value type is a model of the `LessThanComparableConcept`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Complexity]
+
+Linear. Zero comparisons if `empty(rng)`, otherwise `distance(rng) - 1` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/merge.qbk b/doc/reference/algorithm/merge.qbk
new file mode 100644
index 0000000..e838358
--- /dev/null
+++ b/doc/reference/algorithm/merge.qbk
@@ -0,0 +1,88 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:merge merge]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator
+    >
+OutputIterator merge(const SinglePassRange1& rng1,
+                     const SinglePassRange2& rng2,
+                     OutputIterator          out);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryPredicate
+    >
+OutputIterator merge(const SinglePassRange1& rng1,
+                     const SinglePassRange2& rng2,
+                     OutputIterator          out,
+                     BinaryPredicate         pred);
+``
+
+[heading Description]
+
+`merge` combines two sorted ranges `rng1` and `rng2` into a single sorted range by copying elements. `merge` is stable. The return value is `out + distance(rng1) + distance(rng2)`.
+
+The two versions of `merge` differ by how they compare the elements.
+
+The non-predicate version uses the `operator<()` for the range value type. The predicate version uses the predicate instead of `operator<()`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/merge.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate version:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `range_value<SinglePassRange1>::type` is the same as `range_value<SinglePassRange2>::type`.
+* `range_value<SinglePassRange1>::type` is a model of the `LessThanComparableConcept`.
+* The ordering on objects of `range_value<SinglePassRange1>::type` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* `range_value<SinglePassRange1>::type` is convertible to a type in `OutputIterator`'s set of value types.
+
+[*For the predicate version:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `range_value<SinglePassRange1>::type` is the same as `range_value<SinglePassRange2>::type`.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to both `BinaryPredicate`'s argument types.
+* `range_value<SinglePassRange1>::type` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+[heading For the non-predicate version:]
+
+* The elements of `rng1` are in ascending order. That is, for each adjacent element pair `[x,y]` of `rng1`, `y < x == false`.
+* The elements of `rng2` are in ascending order. That is, for each adjacent element pair `[x,y]` of `rng2`, `y < x == false`.
+* The ranges `rng1` and `[out, out + distance(rng1) + distance(rng2))` do not overlap.
+* The ranges `rng2` and `[out, out + distance(rng1) + distance(rng2))` do not overlap.
+* `[out, out + distance(rng1) + distance(rng2))` is a valid range.
+
+[heading For the predicate version:]
+
+* The elements of `rng1` are in ascending order. That is, for each adjacent element pair `[x,y]`, of `rng1`, `pred(y, x) == false`.
+* The elements of `rng2` are in ascending order. That is, for each adjacent element pair `[x,y]`, of `rng2`, `pred(y, x) == false`.
+* The ranges `rng1` and `[out, out + distance(rng1) + distance(rng2))` do not overlap.
+* The ranges `rng2` and `[out, out + distance(rng1) + distance(rng2))` do not overlap.
+* `[out, out + distance(rng1) + distance(rng2))` is a valid range.
+
+[heading Complexity]
+
+Linear. There are no comparisons if both `rng1` and `rng2` are empty, otherwise at most `distance(rng1) + distance(rng2) - 1` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/min_element.qbk b/doc/reference/algorithm/min_element.qbk
new file mode 100644
index 0000000..3895532
--- /dev/null
+++ b/doc/reference/algorithm/min_element.qbk
@@ -0,0 +1,86 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:min_element min_element]
+
+[heading Prototype]
+
+``
+template<class ForwardRange>
+typename range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng);
+
+template<class ForwardRange>
+typename range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng, BinaryPredicate pred);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred);
+
+
+template<
+    range_return_value re,
+    class ForwardRange
+    >
+typename range_return<ForwardRange, re>::type
+min_element(ForwardRange& rng);
+
+template<
+    range_return_value_re,
+    class ForwardRange
+    >
+typename range_return<const ForwardRange, re>::type
+min_element(const ForwardRange& rng);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<ForwardRange, re>::type
+min_element(ForwardRange& rng, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class BinaryPredicate
+    >
+typename range_return<const ForwardRange, re>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `min_element` that return an iterator, return the iterator to the minimum value as determined by using `operator<` if a predicate is not supplied. Otherwise the predicate `pred` is used to determine the minimum value. The versions of `min_element` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/min_element.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange`'s value type is a model of the `LessThanComparableConcept`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Complexity]
+
+Linear. Zero comparisons if `empty(rng)`, otherwise `distance(rng) - 1` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/mismatch.qbk b/doc/reference/algorithm/mismatch.qbk
new file mode 100644
index 0000000..3599733
--- /dev/null
+++ b/doc/reference/algorithm/mismatch.qbk
@@ -0,0 +1,119 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:mismatch mismatch]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange1, class SinglePassRange2>
+std::pair<
+    typename range_iterator<SinglePassRange1>::type,
+    typename range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2);
+
+template<class SinglePassRange1, class SinglePassRange2>
+std::pair<
+    typename range_iterator<const SinglePassRange1>::type,
+    typename range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2);
+
+template<class SinglePassRange1, class SinglePassRange2>
+std::pair<
+    typename range_iterator<SinglePassRange1>::type,
+    typename range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2);
+
+template<class SinglePassRange1, class SinglePassRange2>
+std::pair<
+    typename range_iterator<const SinglePassRange1>::type,
+    typename range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2);
+
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+std::pair<
+    typename range_iterator<SinglePassRange1>::type,
+    typename range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2,
+         BinaryPredicate pred);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+std::pair<
+    typename range_iterator<const SinglePassRange1>::type,
+    typename range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+         BinaryPredicate pred);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+std::pair<
+    typename range_iterator<SinglePassRange1>::type,
+    typename range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2,
+         BinaryPredicate pred);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryPredicate
+    >
+std::pair<
+    typename range_iterator<const SinglePassRange1>::type,
+    typename range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2,
+         BinaryPredicate pred);
+``
+
+[heading Description]
+
+`mismatch` finds the first position where the corresponding elements from the two ranges `rng1` and `rng2` are not equal.
+
+Equality is determined by `operator==` for non-predicate versions of `mismatch`, and by satisfying `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/mismatch.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1`'s value type is a model of the `EqualityComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `EqualityComparableConcept`.
+* `SinglePassRange1`s value type can be compared for equality with `SinglePassRange2`'s value type.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Precondition:]
+
+`distance(rng2) >= distance(rng1)`
+
+[heading Complexity]
+
+Linear. At most `distance(rng1)` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/next_permutation.qbk b/doc/reference/algorithm/next_permutation.qbk
new file mode 100644
index 0000000..4a8dc21
--- /dev/null
+++ b/doc/reference/algorithm/next_permutation.qbk
@@ -0,0 +1,56 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:next_permutation next_permutation]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange>
+bool next_permutation(BidirectionalRange& rng);
+
+template<class BidirectionalRange>
+bool next_permutation(const BidirectionalRange& rng);
+
+template<class BidirectionalRange, class Compare>
+bool next_permutation(BidirectionalRange& rng, Compare pred);
+
+template<class BidirectionalRange, class Compare>
+bool next_permutation(const BidirectionalRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`next_permutation` transforms the range of elements `rng` into the lexicographically next greater permutation of the elements if such a permutation exists. If one does not exist then the range is transformed into the lexicographically smallest permutation and `false` is returned. `true` is returned when the next greater permutation is successfully generated.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/permutation.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `BidirectionalRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `BidirectionalRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `BidirectionalRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Complexity]
+
+Linear. At most `distance(rng) / 2` swaps.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/nth_element.qbk b/doc/reference/algorithm/nth_element.qbk
new file mode 100644
index 0000000..9bd785e
--- /dev/null
+++ b/doc/reference/algorithm/nth_element.qbk
@@ -0,0 +1,67 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:nth_element nth_element]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& nth_element(
+    RandomAccessRange& rng,
+    typename range_iterator<RandomAccessRange>::type nth);
+
+template<class RandomAccessRange>
+const RandomAccessRange& nth_element(
+    const RandomAccessRange& rng,
+    typename range_iterator<const RandomAccessRange>::type nth);
+
+template<class RandomAccessRange>
+RandomAccessRange& nth_element(
+    RandomAccessRange& rng,
+    typename range_iterator<RandomAccessRange>::type nth,
+    BinaryPredicate sort_pred);
+
+template<class RandomAccessRange>
+const RandomAccessRange& nth_element(
+    const RandomAccessRange& rng,
+    typename range_iterator<const RandomAccessRange>::type nth,
+    BinaryPredicate sort_pred);
+``
+
+[heading Description]
+
+`nth_element` partially orders a range of elements. `nth_element` arranges the range `rng` such that the element corresponding with the iterator `nth` is the same as the element that would be in that position if `rng` has been sorted.
+
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/nth_element.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate version:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering relation on `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+
+[*For the predicate version:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+
+[heading Complexity]
+
+On average, linear in `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/partial_sort.qbk b/doc/reference/algorithm/partial_sort.qbk
new file mode 100644
index 0000000..e2b8876
--- /dev/null
+++ b/doc/reference/algorithm/partial_sort.qbk
@@ -0,0 +1,69 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:partial_sort partial_sort]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& partial_sort(
+    RandomAccessRange& rng,
+    typename range_iterator<RandomAccessRange>::type middle);
+
+template<class RandomAccessRange>
+const RandomAccessRange& partial_sort(
+    const RandomAccessRange& rng,
+    typename range_iterator<const RandomAccessRange>::type middle);
+
+template<class RandomAccessRange>
+RandomAccessRange& partial_sort(
+    RandomAccessRange& rng,
+    typename range_iterator<RandomAccessRange>::type middle,
+    BinaryPredicate sort_pred);
+
+template<class RandomAccessRange>
+const RandomAccessRange& partial_sort(
+    const RandomAccessRange& rng,
+    typename range_iterator<const RandomAccessRange>::type middle,
+    BinaryPredicate sort_pred);
+``
+
+[heading Description]
+
+`partial_sort` rearranges the elements in `rng`. It places the smallest `distance(begin(rng), middle)` elements, sorted in ascending order, into the range `[begin(rng), middle)`. The remaining elements are placed in an unspecified order into `[middle, last)`.
+
+The non-predicative versions of this function specify that one element is less than another by using `operator<()`. The predicate versions use the predicate instead.
+
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/partial_sort.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate version:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering relation on `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+
+[*For the predicate version:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+
+[heading Complexity]
+
+Approximately `distance(rng) * log(distance(begin(rng), middle))` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/partition.qbk b/doc/reference/algorithm/partition.qbk
new file mode 100644
index 0000000..a97a893
--- /dev/null
+++ b/doc/reference/algorithm/partition.qbk
@@ -0,0 +1,63 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:partition partition]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_iterator<ForwardRange>::type
+partition(ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_iterator<const ForwardRange>::type
+partition(const ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_return<ForwardRange, re>::type
+partition(ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_return<const ForwardRange, re>::type
+partition(const ForwardRange& rng, UnaryPredicate pred);
+``
+
+[heading Description]
+
+`partition` orders the elements in `rng` based on `pred`, such that the elements that satisfy `pred` precede the elements that do not. In the versions that return a single iterator, the return value is the middle iterator. In the versions that have a configurable range_return, `found` corresponds to the middle iterator.
+
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/partition.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept. For C++ versions prior to C++11 the underlying std::partition requires Bidirectional Iterators, hence the requirement for older library versions is for a __bidirectional_range__.
+* `UnaryPredicate` is a model of the `PredicateConcept`.
+* `ForwardRange`'s value type is convertible to `UnaryPredicate`'s argument type.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` applications of `pred`, and at most `distance(rng) / 2` swaps.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/pop_heap.qbk b/doc/reference/algorithm/pop_heap.qbk
new file mode 100644
index 0000000..9008de4
--- /dev/null
+++ b/doc/reference/algorithm/pop_heap.qbk
@@ -0,0 +1,61 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:pop_heap pop_heap]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& pop_heap(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& pop_heap(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class Compare>
+RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare pred);
+
+template<class RandomAccessRange, class Compare>
+const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`pop_heap` removes the largest element from the heap. It is assumed that `begin(rng), prior(end(rng))` is already a heap (and therefore the largest element is `*begin(rng)`).
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/heap_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Precondition:]
+
+* `!empty(rng)`
+* `rng` is a heap.
+
+[heading Complexity]
+
+Logarithmic. At most `2 * log(distance(rng))` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/prev_permutation.qbk b/doc/reference/algorithm/prev_permutation.qbk
new file mode 100644
index 0000000..6d20431
--- /dev/null
+++ b/doc/reference/algorithm/prev_permutation.qbk
@@ -0,0 +1,56 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:prev_permutation prev_permutation]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange>
+bool prev_permutation(BidirectionalRange& rng);
+
+template<class BidirectionalRange>
+bool prev_permutation(const BidirectionalRange& rng);
+
+template<class BidirectionalRange, class Compare>
+bool prev_permutation(BidirectionalRange& rng, Compare pred);
+
+template<class BidirectionalRange, class Compare>
+bool prev_permutation(const BidirectionalRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`prev_permutation` transforms the range of elements `rng` into the lexicographically next smaller permutation of the elements if such a permutation exists. If one does not exist then the range is transformed into the lexicographically largest permutation and `false` is returned. `true` is returned when the next smaller permutation is successfully generated.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/permutation.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `BidirectionalRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `BidirectionalRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `BidirectionalRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Complexity]
+
+Linear. At most `distance(rng) / 2` swaps.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/push_heap.qbk b/doc/reference/algorithm/push_heap.qbk
new file mode 100644
index 0000000..8aff8c2
--- /dev/null
+++ b/doc/reference/algorithm/push_heap.qbk
@@ -0,0 +1,61 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:push_heap push_heap]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& push_heap(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& push_heap(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class Compare>
+RandomAccessRange& push_heap(RandomAccessRange& rng, Compare pred);
+
+template<class RandomAccessRange, class Compare>
+const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`push_heap` adds an element to a heap. It is assumed that `begin(rng)`, `prior(end(rng))` is already a heap and that the element to be added is `*prior(end(rng))`.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/heap_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Precondition:]
+
+* `!empty(rng)`
+* `[begin(rng), prior(end(rng)))` is a heap.
+
+[heading Complexity]
+
+Logarithmic. At most `log(distance(rng))` comparisons.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/random_shuffle.qbk b/doc/reference/algorithm/random_shuffle.qbk
new file mode 100644
index 0000000..b092c36
--- /dev/null
+++ b/doc/reference/algorithm/random_shuffle.qbk
@@ -0,0 +1,55 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:random_shuffle random_shuffle]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& random_shuffle(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& random_shuffle(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class Generator>
+RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen);
+
+template<class RandomAccessRange, class Generator>
+const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen);
+``
+
+[heading Description]
+
+`random_shuffle` randomly rearranges the elements in `rng`. The versions of `random_shuffle` that do not specify a `Generator` use an internal random number generator. The versions of `random_shuffle` that do specify a `Generator` use this instead. Returns the shuffles range.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/random_shuffle.hpp`
+
+[heading Requirements]
+
+[*For the version without a Generator:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+
+[*For the version with a Generator:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `Generator` is a model of the `RandomNumberGeneratorConcept`.
+* `RandomAccessRange`'s distance type is convertible to `Generator`'s argument type.
+
+[heading Precondition:]
+
+* `distance(rng)` is less than `gen`'s maximum value.
+
+
+[heading Complexity]
+
+Linear. If `!empty(rng)`, exactly `distance(rng) - 1` swaps are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/remove.qbk b/doc/reference/algorithm/remove.qbk
new file mode 100644
index 0000000..f26b277
--- /dev/null
+++ b/doc/reference/algorithm/remove.qbk
@@ -0,0 +1,60 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove remove]
+[heading Prototype]
+
+``
+template<
+    class ForwardRange,
+    class Value
+    >
+typename range_iterator<ForwardRange>::type
+remove(ForwardRange& rng, const Value& val);
+
+template<
+    class ForwardRange,
+    class Value
+    >
+typename range_iterator<const ForwardRange>::type
+remove(const ForwardRange& rng, const Value& val);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value
+    >
+typename range_return<ForwardRange,re>::type
+remove(ForwardRange& rng, const Value& val);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value
+    >
+typename range_return<const ForwardRange,re>::type
+remove(const ForwardRange& rng, const Value& val);
+``
+
+[heading Description]
+
+`remove` removes from `rng` all of the elements `x` for which `x == val` is `true`. The versions of `remove` that return an iterator, return an iterator `new_last` such that the range `[begin(rng), new_last)` contains no elements equal to `val`. The `range_return` versions of `remove` defines `found` as the new last element. The iterators in the range `[new_last, end(rng))` are dereferenceable, but the elements are unspecified.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/remove.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is a model of the `EqualityComparableConcept`.
+* Objects of type `Value` can be compared for equality with objects of `ForwardRange`'s value type.
+
+[heading Complexity]
+
+Linear. `remove` performs exactly `distance(rng)` comparisons for equality.
+
+[endsect]
\ No newline at end of file
diff --git a/doc/reference/algorithm/remove_copy.qbk b/doc/reference/algorithm/remove_copy.qbk
new file mode 100644
index 0000000..b98da47
--- /dev/null
+++ b/doc/reference/algorithm/remove_copy.qbk
@@ -0,0 +1,39 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove_copy remove_copy]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Outputiterator, class Value>
+OutputIterator
+remove_copy(ForwardRange& rng, OutputIterator out, const Value& val);
+
+template<class ForwardRange, class OutputIterator, class Value>
+OutputIterator
+remove_copy(const ForwardRange& rng, OutputIterator out, const Value& val);
+``
+
+[heading Description]
+
+`remove_copy` copied all of the elements `x` from `rng` for which `x == val` is `false`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/remove_copy.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is a model of the `EqualityComparableConcept`.
+* Objects of type `Value` can be compared for equality with objects of `ForwardRange`'s value type.
+
+[heading Complexity]
+
+Linear. `remove_copy` performs exactly `distance(rng)` comparisons for equality.
+
+[endsect]
diff --git a/doc/reference/algorithm/remove_copy_if.qbk b/doc/reference/algorithm/remove_copy_if.qbk
new file mode 100644
index 0000000..d56647b
--- /dev/null
+++ b/doc/reference/algorithm/remove_copy_if.qbk
@@ -0,0 +1,38 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove_copy_if remove_copy_if]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Outputiterator, class UnaryPred>
+OutputIterator
+remove_copy_if(ForwardRange& rng, OutputIterator out, UnaryPred pred);
+
+template<class ForwardRange, class OutputIterator, class UnaryPred>
+OutputIterator
+remove_copy_if(const ForwardRange& rng, OutputIterator out, UnaryPred pred);
+``
+
+[heading Description]
+
+`remove_copy_if` copied all of the elements `x` from `rng` for which `pred(x)` is `false`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/remove_copy_if.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `UnaryPred` is a model of the `UnaryPredicateConcept`.
+
+[heading Complexity]
+
+Linear. `remove_copy_if` performs exactly `distance(rng)` comparisons with UnaryPred.
+
+[endsect]
diff --git a/doc/reference/algorithm/remove_if.qbk b/doc/reference/algorithm/remove_if.qbk
new file mode 100644
index 0000000..64b6ac3
--- /dev/null
+++ b/doc/reference/algorithm/remove_if.qbk
@@ -0,0 +1,63 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove_if remove_if]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_iterator<ForwardRange>::type
+remove(ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_iterator<const ForwardRange>::type
+remove(const ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_return<ForwardRange,re>::type
+remove(ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+    >
+typename range_return<const ForwardRange,re>::type
+remove(const ForwardRange& rng, UnaryPredicate pred);
+``
+
+[heading Description]
+
+`remove_if` removes from `rng` all of the elements `x` for which `pred(x)` is `true`. The versions of `remove_if` that return an iterator, return an iterator `new_last` such that the range `[begin(rng), new_last)` contains no elements where `pred(x)` is `true`. The iterators in the range `[new_last, end(rng))` are dereferenceable, but the elements are unspecified.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/remove_if.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `UnaryPredicate` is a model of the `PredicateConcept`.
+* `ForwardRange`'s value type is convertible to `UnaryPredicate`'s argument type.
+
+[heading Complexity]
+
+Linear. `remove_if` performs exactly `distance(rng)` applications of `pred`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/replace.qbk b/doc/reference/algorithm/replace.qbk
new file mode 100644
index 0000000..27b6c1b
--- /dev/null
+++ b/doc/reference/algorithm/replace.qbk
@@ -0,0 +1,46 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replace replace]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange,
+    class Value
+    >
+ForwardRange& replace(ForwardRange& rng, const Value& what, const Value& with_what);
+
+template<
+    class ForwardRange,
+    class UnaryPredicate
+    >
+const ForwardRange& replace(const ForwardRange& rng, const Value& what, const Value& with_what);
+``
+
+[heading Description]
+
+`replace` every element in `rng` equal to `what` with `with_what`. Return a reference to `rng`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/replace.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is convertible to `ForwardRange`'s value type.
+* `Value` is a model of the `AssignableConcept`.
+* `Value` is a model of the `EqualityComparableConcept`, and may be compared for equality with objects of `ForwardRange`'s value type.
+
+[heading Complexity]
+
+Linear. `replace` performs exactly `distance(rng)` comparisons for equality and at most `distance(rng)` assignments.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/replace_copy.qbk b/doc/reference/algorithm/replace_copy.qbk
new file mode 100644
index 0000000..e936fc0
--- /dev/null
+++ b/doc/reference/algorithm/replace_copy.qbk
@@ -0,0 +1,38 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replace_copy replace_copy]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class OutputIterator, class Value>
+OutputIterator replace_copy(const ForwardRange& rng, OutputIterator out,
+                            const Value& what, const Value& with_what);
+``
+
+[heading Description]
+
+`replace_copy` copy every element `x` in `rng` such that the corresponding element in the output range `y` is `x == what ? with_what : x`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/replace_copy.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is convertible to `ForwardRange`'s value type.
+* `Value` is a model of the `AssignableConcept`.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[heading Complexity]
+
+Linear. `replace_copy` performs exactly `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/replace_copy_if.qbk b/doc/reference/algorithm/replace_copy_if.qbk
new file mode 100644
index 0000000..13305a7
--- /dev/null
+++ b/doc/reference/algorithm/replace_copy_if.qbk
@@ -0,0 +1,39 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replace_copy_if replace_copy_if]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class OutputIterator, class UnaryPredicate, class Value>
+OutputIterator replace_copy_if(const ForwardRange& rng, OutputIterator out,
+                               UnaryPredicate pred, const Value& with_what);
+``
+
+[heading Description]
+
+`replace_copy_if` copy every element `x` in `rng` such that the corresponding element in the output range `y` is `pred(x) ? with_what : x`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/replace_copy_if.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `Value` is convertible to `ForwardRange`'s value type.
+* `Value` is a model of the `AssignableConcept`.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `UnaryPredicate` is a model of the `UnaryPredicateConcept`.
+
+[heading Complexity]
+
+Linear. `replace_copy_if` performs exactly `distance(rng)` evaluations of `pred`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/replace_if.qbk b/doc/reference/algorithm/replace_if.qbk
new file mode 100644
index 0000000..18480a9
--- /dev/null
+++ b/doc/reference/algorithm/replace_if.qbk
@@ -0,0 +1,41 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:replace_if replace_if]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class UnaryPredicate, class Value>
+ForwardRange& replace_if(ForwardRange& rng, UnaryPredicate pred, const Value& with_what);
+
+template<class ForwardRange, class UnaryPredicate, class Value>
+const ForwardRange& replace_if(const ForwardRange& rng, UnaryPredicate pred, const Value& with_what);
+``
+
+[heading Description]
+
+`replace_if` replaces every element `x` in `rng` for which `pred(x) == true` with `with_what`. Returns a reference to `rng`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/replace_if.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `UnaryPredicate` is a model of the `PredicateConcept`
+* `ForwardRange`'s value type is convertible to `UnaryPredicate`'s argument type.
+* `Value` is convertible to `ForwardRange`'s value type.
+* `Value` is a model of the `AssignableConcept`.
+
+[heading Complexity]
+
+Linear. `replace_if` performs exactly `distance(rng)` applications of `pred`, and at most `distance(rng)` assignments.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/reverse.qbk b/doc/reference/algorithm/reverse.qbk
new file mode 100644
index 0000000..6ecb31b
--- /dev/null
+++ b/doc/reference/algorithm/reverse.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:reverse reverse]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange>
+BidirectionalRange& reverse(BidirectionalRange& rng);
+
+template<class BidirectionalRange>
+const BidirectionalRange& reverse(const BidirectionalRange& rng);
+``
+
+[heading Description]
+
+`reverse` reverses a range. Returns a reference to the reversed range.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/reverse.hpp`
+
+[heading Requirements]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+
+[heading Complexity]
+
+Linear. `reverse` makes `distance(rng)/2` calls to `iter_swap`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/reverse_copy.qbk b/doc/reference/algorithm/reverse_copy.qbk
new file mode 100644
index 0000000..b19ed9f
--- /dev/null
+++ b/doc/reference/algorithm/reverse_copy.qbk
@@ -0,0 +1,36 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:reverse_copy reverse_copy]
+
+[heading Prototype]
+
+``
+template<class BidirectionalRange, class OutputIterator>
+OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out);
+``
+
+[heading Description]
+
+`reverse_copy` copies the elements from `rng` in reverse order to `out`.
+Returns the output iterator one passed the last copied element.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/reverse_copy.hpp`
+
+[heading Requirements]
+
+* `BidirectionalRange` is a model of the __bidirectional_range__ Concept.
+* `BidirectionalRange` is mutable.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[heading Complexity]
+
+Linear. `reverse_copy` makes `distance(rng)` copies.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/rotate.qbk b/doc/reference/algorithm/rotate.qbk
new file mode 100644
index 0000000..e28641b
--- /dev/null
+++ b/doc/reference/algorithm/rotate.qbk
@@ -0,0 +1,44 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:rotate rotate]
+
+[heading Prototype]
+
+``
+template<class ForwardRange>
+ForwardRange& rotate(ForwardRange& rng,
+                     typename range_iterator<ForwardRange>::type middle);
+
+template<class ForwardRange>
+const ForwardRange& rotate(const ForwardRange& rng,
+                           typename range_iterator<const ForwardRange>::type middle);
+``
+
+[heading Description]
+
+`rotate` rotates the elements in a range. It exchanges the two ranges `[begin(rng), middle)` and `[middle, end(rng))`. Returns a reference to `rng`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/rotate.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+
+[heading Precondition:]
+
+* `[begin(rng), middle)` is a valid range.
+* `[middle, end(rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. At most `distance(rng)` swaps are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/rotate_copy.qbk b/doc/reference/algorithm/rotate_copy.qbk
new file mode 100644
index 0000000..0f11bdc
--- /dev/null
+++ b/doc/reference/algorithm/rotate_copy.qbk
@@ -0,0 +1,43 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:rotate_copy rotate_copy]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class OutputIterator>
+OutputIterator rotate_copy(
+    const ForwardRange& rng,
+    typename range_iterator<ForwardRange>::type middle,
+    OutputIterator out);
+``
+
+[heading Description]
+
+`rotate_copy` rotates the elements in a range. It copies the two ranges `[begin(rng), middle)` and `[middle, end(rng))` to `out`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/rotate_copy.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[heading Precondition:]
+
+* `[begin(rng), middle)` is a valid range.
+* `[middle, end(rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` elements are copied.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/search.qbk b/doc/reference/algorithm/search.qbk
new file mode 100644
index 0000000..5c2c2a8
--- /dev/null
+++ b/doc/reference/algorithm/search.qbk
@@ -0,0 +1,106 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:search search]
+
+[heading Prototype]
+
+``
+template<class ForwardRange1, class ForwardRange2>
+typename range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<class ForwardRange1, class ForwardRange2>
+typename range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_iterator<ForwardRange1>::type,
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+
+template<
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, ForwardRange2& rng2, BinaryPredicate pred);
+
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2
+    >
+typename range_return<ForwardRange1, re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2
+    >
+typename range_return<const ForwardRange1, re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2);
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_return<ForwardRange1, re>::type,
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange1,
+    class ForwardRange2,
+    class BinaryPredicate
+    >
+typename range_return<const ForwardRange1, re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred);
+``
+
+[heading Description]
+
+The versions of `search` that return an iterator, return an iterator to the start of the first subsequence in `rng1` that is equal to the subsequence `rng2`. The `end(rng1)` is returned if no such subsequence exists in `rng1`.
+Equality is determined by `operator==` for non-predicate versions of `search`, and by satisfying `pred` in the predicate versions.
+
+The versions of `search` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+ 
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/search.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange1` is a model of the __forward_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `ForwardRange1`'s value type is a model of the `EqualityComparableConcept`.
+* `ForwardRange2`'s value type is a model of the `EqualityComparableConcept`.
+* `ForwardRange1`s value type can be compared for equality with `ForwardRange2`'s value type.
+
+[*For the predicate versions:]
+
+* `ForwardRange1` is a model of the __forward_range__ Concept.
+* `ForwardRange2` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `ForwardRange2`'s value type is convertible to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+Average complexity is Linear. Worst-case complexity is quadratic.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/search_n.qbk b/doc/reference/algorithm/search_n.qbk
new file mode 100644
index 0000000..ad8cbd2
--- /dev/null
+++ b/doc/reference/algorithm/search_n.qbk
@@ -0,0 +1,63 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:search_n search_n]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Integer, class Value>
+typename range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer n, const Value& value);
+
+template<class ForwardRange, class Integer, class Value>
+typename range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer n, const Value& value);
+
+template<class ForwardRange, class Integer, class Value, class BinaryPredicate>
+typename range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer n, const Value& value,
+         BinaryPredicate binary_pred);
+
+template<class ForwardRange, class Integer, class Value, class BinaryPredicate>
+typename range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer n, const Value& value,
+         BinaryPredicate binary_pred);
+``
+
+[heading Description]
+
+`search_n` searches `rng` for a sequence of length `n` equal to `value` where
+equality is determined by operator== in the non-predicate case, and by a
+predicate when one is supplied.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/search_n.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange`'s value type is a model of the `EqualityComparableConcept`.
+* `ForwardRange`s value type can be compared for equality with `Value`.
+* `Integer` is a model of the `IntegerConcept`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `Value` is convertible to `BinaryPredicate`'s second argument type.
+* `Integer` is a model of the `IntegerConcept`.
+
+[heading Complexity]
+
+Average complexity is Linear. Worst-case complexity is quadratic.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/set_difference.qbk b/doc/reference/algorithm/set_difference.qbk
new file mode 100644
index 0000000..8ab5091
--- /dev/null
+++ b/doc/reference/algorithm/set_difference.qbk
@@ -0,0 +1,81 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:set_difference set_difference]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator
+    >
+OutputIterator set_difference(const SinglePassRange1& rng1,
+                              const SinglePassRange2& rng2,
+                              OutputIterator          out);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryPredicate
+    >
+OutputIterator set_difference(const SinglePassRange1& rng1,
+                              const SinglePassRange2& rng2,
+                              OutputIterator          out,
+                              BinaryPredicate         pred);
+``
+
+[heading Description]
+
+`set_difference` constructs a sorted range that is the set difference of the sorted ranges `rng1` and `rng2`. The return value is the end of the output range.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+ 
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/set_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `SinglePassRange1`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* The ordering of objects of type `SinglePassRange2`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+Linear. `O(N)`, where `N` is `distance(rng1) + distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/set_intersection.qbk b/doc/reference/algorithm/set_intersection.qbk
new file mode 100644
index 0000000..3d46109
--- /dev/null
+++ b/doc/reference/algorithm/set_intersection.qbk
@@ -0,0 +1,81 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:set_intersection set_intersection]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator
+    >
+OutputIterator set_intersection(const SinglePassRange1& rng1,
+                                const SinglePassRange2& rng2,
+                                OutputIterator          out);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryPredicate
+    >
+OutputIterator set_intersection(const SinglePassRange1& rng1,
+                                const SinglePassRange2& rng2,
+                                OutputIterator          out,
+                                BinaryPredicate         pred);    
+``
+
+[heading Description]
+
+`set_intersection` constructs a sorted range that is the intersection of the sorted ranges `rng1` and `rng2`. The return value is the end of the output range.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+ 
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/set_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `SinglePassRange1`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* The ordering of objects of type `SinglePassRange2`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+Linear. `O(N)`, where `N` is `distance(rng1) + distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/set_symmetric_difference.qbk b/doc/reference/algorithm/set_symmetric_difference.qbk
new file mode 100644
index 0000000..9110cf0
--- /dev/null
+++ b/doc/reference/algorithm/set_symmetric_difference.qbk
@@ -0,0 +1,83 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:set_symmetric_difference set_symmetric_difference]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator
+    >
+OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryPredicate
+    >
+OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out,
+                         BinaryPredicate         pred);    
+``
+
+[heading Description]
+
+`set_symmetric_difference` constructs a sorted range that is the set symmetric difference of the sorted ranges `rng1` and `rng2`. The return value is the end of the output range.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions. 
+ 
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/set_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `SinglePassRange1`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* The ordering of objects of type `SinglePassRange2`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+Linear. `O(N)`, where `N` is `distance(rng1) + distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/set_union.qbk b/doc/reference/algorithm/set_union.qbk
new file mode 100644
index 0000000..679ec71
--- /dev/null
+++ b/doc/reference/algorithm/set_union.qbk
@@ -0,0 +1,80 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:set_union set_union]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator
+    >
+OutputIterator set_union(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryPredicate
+    >
+OutputIterator set_union(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out,
+                         BinaryPredicate         pred);    
+ ``
+
+[heading Description]
+
+`set_union` constructs a sorted range that is the union of the sorted ranges `rng1` and `rng2`. The return value is the end of the output range.
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions. 
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/set_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `SinglePassRange1`'s value type is a model of the `LessThanComparableConcept`.
+* `SinglePassRange2`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `SinglePassRange1`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* The ordering of objects of type `SinglePassRange2`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `SinglePassRange1` and `SinglePassRange2` have the same value type.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `SinglePassRange1`'s value type is convertible to `BinaryPredicate`'s first argument type.
+* `SinglePassRange2`'s value type is convertible to `BinaryPredicate`'s second argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng1` and `rng2` are sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+Linear. `O(N)`, where `N` is `distance(rng1) + distance(rng2)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/sort.qbk b/doc/reference/algorithm/sort.qbk
new file mode 100644
index 0000000..3027c89
--- /dev/null
+++ b/doc/reference/algorithm/sort.qbk
@@ -0,0 +1,58 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:sort sort]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& sort(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& sort(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class BinaryPredicate>
+RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred);
+
+template<class RandomAccessRange, class BinaryPredicate>
+const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`sort` sorts the elements in `rng` into ascending order. `sort` is not guaranteed to be stable. Returns the sorted range.
+
+For versions of the `sort` function without a predicate, ascending order is defined by `operator<()` such that for all adjacent elements `[x,y]`, `y < x == false`.
+
+For versions of the `sort` function with a predicate, ascending order is defined by `pred` such that for all adjacent elements `[x,y]`, `pred(y, x) == false`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/sort.hpp`
+
+[heading Requirements]
+
+[*For versions of sort without a predicate:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering relation on `RandomAccessRange`'s value type is a [*strict weak ordering], as defined in the `LessThanComparableConcept` requirements.
+
+[*For versions of sort with a predicate]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Complexity]
+
+`O(N log(N))` comparisons (both average and worst-case), where `N` is `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/sort_heap.qbk b/doc/reference/algorithm/sort_heap.qbk
new file mode 100644
index 0000000..b065ce5
--- /dev/null
+++ b/doc/reference/algorithm/sort_heap.qbk
@@ -0,0 +1,60 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:sort_heap sort_heap]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& sort_heap(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& sort_heap(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class Compare>
+RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare pred);
+
+template<class RandomAccessRange, class Compare>
+const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare pred);
+``
+
+[heading Description]
+
+`sort_heap` turns a heap into a sorted range.
+
+The ordering relationship is determined by using `operator<` in the non-predicate versions, and by evaluating `pred` in the predicate versions.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/heap_algorithm.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `RandomAccessRange`'s value type is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+
+[*For the predicate versions:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `Compare` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `Compare`'s argument types.
+
+[heading Precondition:]
+
+`rng` is a heap.
+
+[heading Complexity]
+
+At most `N * log(N)` comparisons, where `N` is `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/stable_partition.qbk b/doc/reference/algorithm/stable_partition.qbk
new file mode 100644
index 0000000..a820bcd
--- /dev/null
+++ b/doc/reference/algorithm/stable_partition.qbk
@@ -0,0 +1,61 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:stable_partition stable_partition]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class UnaryPredicate>
+typename range_iterator<ForwardRange>::type
+stable_partition(ForwardRange& rng, UnaryPredicate pred);
+
+template<class ForwardRange, class UnaryPredicate>
+typename range_iterator<const ForwardRange>::type
+stable_partition(const ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+>
+typename range_return<ForwardRange, re>::type
+stable_partition(ForwardRange& rng, UnaryPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class UnaryPredicate
+>
+typename range_return<const ForwardRange, re>::type
+stable_partition(const ForwardRange& rng, UnaryPredicate pred);
+``
+
+[heading Description]
+
+`stable_partition` reorders the elements in the range `rng` base on the function object `pred`. Once this function has completed all of the elements that satisfy `pred` appear before all of the elements that fail to satisfy it. `stable_partition` differs from `partition` because it preserves relative order. It is stable.
+
+For the versions that return an iterator, the return value is the iterator to the first element that fails to satisfy `pred`.
+
+For versions that return a `range_return`, the `found` iterator is the iterator to the first element that fails to satisfy `pred`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/stable_partition.hpp`
+
+[heading Requirements]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `UnaryPredicate` is a model of the `PredicateConcept`.
+
+[heading Complexity]
+
+Best case: `O(N)` where `N` is `distance(rng)`.
+Worst case: `N * log(N)` swaps, where `N` is `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/stable_sort.qbk b/doc/reference/algorithm/stable_sort.qbk
new file mode 100644
index 0000000..502551f
--- /dev/null
+++ b/doc/reference/algorithm/stable_sort.qbk
@@ -0,0 +1,59 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:stable_sort stable_sort]
+
+[heading Prototype]
+
+``
+template<class RandomAccessRange>
+RandomAccessRange& stable_sort(RandomAccessRange& rng);
+
+template<class RandomAccessRange>
+const RandomAccessRange& stable_sort(const RandomAccessRange& rng);
+
+template<class RandomAccessRange, class BinaryPredicate>
+RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate pred);
+
+template<class RandomAccessRange, class BinaryPredicate>
+const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`stable_sort` sorts the elements in `rng` into ascending order. `stable_sort` is guaranteed to be stable. The order is preserved for equivalent elements.
+
+For versions of the `stable_sort` function without a predicate ascending order is defined by `operator<()` such that for all adjacent elements `[x,y]`, `y < x == false`.
+
+For versions of the `stable_sort` function with a predicate, ascending order is designed by `pred` such that for all adjacent elements `[x,y]`, `pred(y,x) == false`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/stable_sort.hpp`
+
+[heading Requirements]
+
+[*For versions of stable_sort without a predicate]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `RandomAccessRange`'s value type is a model of the `LessThanComparableConcept`.
+* The ordering relation on `RandomAccessRange`'s value type is a [*strict weak ordering], as defined in the `LessThanComparableConcept` requirements.
+
+[*For versions of stable_sort with a predicate:]
+
+* `RandomAccessRange` is a model of the __random_access_range__ Concept.
+* `RandomAccessRange` is mutable.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `RandomAccessRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Complexity]
+
+Best case: `O(N)` where `N` is `distance(rng)`.
+Worst case: `O(N log(N)^2)` comparisons, where `N` is `distance(rng)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/swap_ranges.qbk b/doc/reference/algorithm/swap_ranges.qbk
new file mode 100644
index 0000000..9dcb764
--- /dev/null
+++ b/doc/reference/algorithm/swap_ranges.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:swap_ranges swap_ranges]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange1, class SinglePassRange2>
+SinglePassRange2& swap_ranges(SinglePassRange1& rng1, SinglePassRange& rng2);
+``
+
+[heading Description]
+
+`swap_ranges` swaps each element `x` in `rng1` with the corresponding element `y` in `rng2`.
+Returns a reference to `rng2`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/swap_ranges.hpp`
+
+[heading Requirements]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange1` is mutable.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is mutable.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng1)` elements are swapped.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/transform.qbk b/doc/reference/algorithm/transform.qbk
new file mode 100644
index 0000000..d1e5ac4
--- /dev/null
+++ b/doc/reference/algorithm/transform.qbk
@@ -0,0 +1,88 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:transform transform]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class OutputIterator,
+    class UnaryOperation
+>
+OutputIterator transform(const SinglePassRange1& rng,
+                         OutputIterator out,
+                         UnaryOperation fun);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class OutputIterator,
+    class BinaryOperation
+>
+OutputIterator transform(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator out,
+                         BinaryOperation fun);
+``
+
+[heading Description]
+
+[*UnaryOperation version:]
+
+`transform` assigns the value `y` to each element `[out, out + distance(rng)), y = fun(x)` where `x` is the corresponding value to `y` in `rng1`. The return value is `out + distance(rng)`.
+
+[*BinaryOperation version:]
+
+`transform` assigns the value `z` to each element `[out, out + min(distance(rng1), distance(rng2))), z = fun(x,y)` where `x` is the corresponding value in `rng1` and `y` is the corresponding value in `rng2`. This version of `transform` stops upon reaching either the end of `rng1`, or the end of `rng2`. Hence there isn't a requirement for `distance(rng1) == distance(rng2)` since there is a safe guaranteed behaviour, unlike with the iterator counterpart in the standard library.
+
+The return value is `out + min(distance(rng1), distance(rng2))`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/transform.hpp`
+
+[heading Requirements]
+
+[*For the unary versions of transform:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `UnaryOperation` is a model of the `UnaryFunctionConcept`.
+* `SinglePassRange1`'s value type must be convertible to `UnaryFunction`'s argument type.
+* `UnaryFunction`'s result type must be convertible to a type in `OutputIterator`'s set of value types.
+
+[*For the binary versions of transform:]
+
+* `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+* `BinaryOperation` is a model of the `BinaryFunctionConcept`.
+* `SinglePassRange1`'s value type must be convertible to `BinaryFunction`'s first argument type.
+* `SinglePassRange2`'s value type must be convertible to `BinaryFunction`'s second argument type.
+* `BinaryOperation`'s result type must be convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+[*For the unary version of transform:]
+
+* `out` is not an iterator within the range `[begin(rng1) + 1, end(rng1))`.
+* `[out, out + distance(rng1))` is a valid range.
+
+[*For the binary version of transform:]
+
+* `out` is not an iterator within the range `[begin(rng1) + 1, end(rng1))`.
+* `out` is not an iterator within the range `[begin(rng2) + 1, end(rng2))`.
+* `[out, out + min(distance(rng1), distance(rng2)))` is a valid range.
+
+
+[heading Complexity]
+
+Linear. The operation is applied exactly `distance(rng1)` for the unary version and `min(distance(rng1), distance(rng2))` for the binary version.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/unique.qbk b/doc/reference/algorithm/unique.qbk
new file mode 100644
index 0000000..bc2cdce
--- /dev/null
+++ b/doc/reference/algorithm/unique.qbk
@@ -0,0 +1,77 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:unique unique]
+
+[heading Prototype]
+
+``
+template<class ForwardRange>
+typename range_return<ForwardRange, return_begin_found>::type
+unique(ForwardRange& rng);
+
+template<class ForwardRange>
+typename range_return<const ForwardRange, return_begin_found>::type
+unique(const ForwardRange& rng);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_return<ForwardRange, return_begin_found>::type
+unique(ForwardRange& rng, BinaryPredicate pred);
+
+template<class ForwardRange, class BinaryPredicate>
+typename range_return<const ForwardRange, return_begin_found>::type
+unique(const ForwardRange& rng, BinaryPredicate pred);
+
+template<range_return_value re, class ForwardRange>
+typename range_return<ForwardRange, re>::type
+unique(ForwardRange& rng);
+
+template<range_return_value re, class ForwardRange>
+typename range_return<const ForwardRange, re>::type
+unique(const ForwardRange& rng);
+
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+typename range_return<ForwardRange, re>::type
+unique(ForwardRange& rng, BinaryPredicate pred);
+
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+typename range_return<const ForwardRange, re>::type
+unique(const ForwardRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`unique` removes all but the first element of each sequence of duplicate encountered in `rng`.
+
+Elements in the range `[new_last, end(rng))` are dereferenceable but undefined.
+
+Equality is determined by the predicate if one is supplied, or by `operator==()` for `ForwardRange`'s value type.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/unique.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions of unique:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `ForwardRange`'s value type is a model of the `EqualityComparableConcept`.
+
+[*For the predicate versions of unique:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `ForwardRange` is mutable.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `ForwardRange`'s value type is convertible to `BinaryPredicate`'s first argument type and to `BinaryPredicate`'s second argument type.
+
+[heading Complexity]
+
+Linear. `O(N)` where `N` is `distance(rng)`. Exactly `distance(rng)` comparisons are performed.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm/unique_copy.qbk b/doc/reference/algorithm/unique_copy.qbk
new file mode 100644
index 0000000..f10a85f
--- /dev/null
+++ b/doc/reference/algorithm/unique_copy.qbk
@@ -0,0 +1,49 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:unique_copy unique_copy]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class OutputIterator>
+OutputIterator unique_copy(const SinglePassRange& rng, OutputIterator out);
+
+template<class SinglePassRange, class OutputIterator, class BinaryPredicate>
+OutputIterator unique_copy(const SinglePassRange& rng, OutputIterator out, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`unique_copy` copies the first element of each sequence of duplicates encountered in `rng` to `out`.
+
+Equality is determined by the predicate if one is supplied, or by `operator==()` for `SinglePassRange`'s value type.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/unique_copy.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions of unique:]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange` is mutable.
+* `SinglePassRange`'s value type is a model of the `EqualityComparableConcept`.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[*For the predicate versions of unique:]
+
+* `SinglePassRange` is a model of the __single_pass_range__ Concept.
+* `SinglePassRange` is mutable.
+* `BinaryPredicate` is a model of the `BinaryPredicateConcept`.
+* `SinglePassRange`'s value type is convertible to `BinaryPredicate`'s first argument type and to `BinaryPredicate`'s second argument type.
+* `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[heading Complexity]
+
+Linear. `O(N)` where `N` is `distance(rng)`. Exactly `distance(rng)` comparisons are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm/upper_bound.qbk b/doc/reference/algorithm/upper_bound.qbk
new file mode 100644
index 0000000..d636a77
--- /dev/null
+++ b/doc/reference/algorithm/upper_bound.qbk
@@ -0,0 +1,90 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:upper_bound upper_bound]
+
+[heading Prototype]
+
+``
+template<
+    class ForwardRange, 
+    class Value
+    >
+typename range_iterator<ForwardRange>::type
+upper_bound(ForwardRange& rng, Value val);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value
+    >
+typename range_return<ForwardRange, re>::type
+upper_bound(ForwardRange& rng, Value val);
+
+template<
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+typename range_iterator<ForwardRange>::type
+upper_bound(ForwardRange& rng, Value val, SortPredicate pred);
+
+template<
+    range_return_value re,
+    class ForwardRange,
+    class Value,
+    class SortPredicate
+    >
+typename range_return<ForwardRange,re>::type
+upper_bound(ForwardRange& rng, Value val, SortPredicate pred);
+``
+
+[heading Description]
+
+The versions of `upper_bound` that return an iterator, returns the first iterator in the range `rng` such that:
+without predicate - `val < *i` is `true`,
+with predicate - `pred(val, *i)` is `true`.
+
+`end(rng)` is returned if no such iterator exists.
+
+The versions of `upper_bound` that return a `range_return`, defines `found` in the same manner as the returned iterator described above.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm/upper_bound.hpp`
+
+[heading Requirements]
+
+[*For the non-predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `Value` is a model of the `LessThanComparableConcept`.
+* The ordering of objects of type `Value` is a [*/strict weak ordering/], as defined in the `LessThanComparableConcept` requirements.
+* `ForwardRange`'s value type is the same type as `Value`.
+
+[*For the predicate versions:]
+
+* `ForwardRange` is a model of the __forward_range__ Concept.
+* `BinaryPredicate` is a model of the `StrictWeakOrderingConcept`.
+* `ForwardRange`'s value type is the same type as `Value`.
+* `ForwardRange`'s value type is convertible to both of `BinaryPredicate`'s argument types.
+
+[heading Precondition:]
+
+[*For the non-predicate versions:]
+
+`rng` is sorted in ascending order according to `operator<`.
+
+[*For the predicate versions:]
+
+`rng` is sorted in ascending order according to `pred`.
+
+[heading Complexity]
+
+For ranges that model the __random_access_range__ Concept the complexity is `O(log N)`, where `N` is `distance(rng)`. For all other range types the complexity is `O(N)`.
+
+[endsect]
+
+
diff --git a/doc/reference/algorithm_ext/copy_n.qbk b/doc/reference/algorithm_ext/copy_n.qbk
new file mode 100644
index 0000000..6b34c7b
--- /dev/null
+++ b/doc/reference/algorithm_ext/copy_n.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:copy_n copy_n]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange, class Size, class OutputIterator>
+OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out);
+``
+
+[heading Description]
+
+`copy_n` is provided to completely replicate the standard algorithm header,
+it is preferable to use Range Adaptors and the extension functions to achieve
+the same result with greater safety.
+
+`copy_n` copies elements from `[boost::begin(rng), boost::begin(rng) + n)` to the range `[out, out + n)`
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/copy_n.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Size` is a model of the `Integer` Concept.
+# `OutputIterator` is a model of the `OutputIteratorConcept`.
+
+[heading Complexity]
+
+Linear. Exactly `n` elements are copied.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/erase.qbk b/doc/reference/algorithm_ext/erase.qbk
new file mode 100644
index 0000000..5b640a2
--- /dev/null
+++ b/doc/reference/algorithm_ext/erase.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:erase erase]
+
+[heading Prototype]
+
+``
+template<class Container>
+Container& erase(
+    Container& target,
+    iterator_range<typename Container::iterator> to_erase);
+``
+
+[heading Description]
+
+`erase` the iterator range `to_erase` from the container `target`.
+
+`remove_erase` performs the frequently used combination equivalent to `target.erase(std::remove(target.begin(), target.end(), value), target.end());`
+
+`remove_erase_if` performs the frequently used combination equivalent to `target.erase(std::remove_if(target.begin(), target.end(), pred), target.end());`
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/erase.hpp`
+
+[heading Requirements]
+
+# `Container` supports erase of an iterator range.
+
+[heading Complexity]
+
+Linear. Proprotional to `distance(to_erase)`.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/for_each.qbk b/doc/reference/algorithm_ext/for_each.qbk
new file mode 100644
index 0000000..fdfcb99
--- /dev/null
+++ b/doc/reference/algorithm_ext/for_each.qbk
@@ -0,0 +1,73 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:for_each for_each]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryFunction
+    >
+BinaryFunction for_each(const SinglePassRange1& rng1,
+                        const SinglePassRange2& rng2,
+                        BinaryFunction fn);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryFunction
+    >
+BinaryFunction for_each(const SinglePassRange1& rng1,
+                        SinglePassRange2& rng2,
+                        BinaryFunction fn);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryFunction
+    >
+BinaryFunction for_each(SinglePassRange1& rng1,
+                        const SinglePassRange2& rng2,
+                        BinaryFunction fn);
+
+template<
+    class SinglePassRange1,
+    class SinglePassRange2,
+    class BinaryFunction
+    >
+BinaryFunction for_each(SinglePassRange1& rng1,
+                        SinglePassRange2& rng2,
+                        BinaryFunction fn);
+``
+
+[heading Description]
+
+`for_each` traverses forward through `rng1` and `rng2` simultaneously.
+For each iteration, the element `x` is used from `rng1` and the corresponding
+element `y` is used from `rng2` to invoke `fn(x,y)`.
+
+Iteration is stopped upon reaching the end of the shorter of `rng1`, or `rng2`.
+It is safe to call this function with unequal length ranges.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/for_each.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+# `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+# `BinaryFunction` is a model of the `BinaryFunctionConcept`.
+# `SinglePassRange1`'s value type is convertible to `BinaryFunction`'s first argument type.
+# `SinglepassRange2`'s value type is convertible to `BinaryFunction`'s second argument type.
+
+[heading Complexity]
+
+Linear. Exactly `min(distance(rng1), distance(rng2))` applications of `BinaryFunction`.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/insert.qbk b/doc/reference/algorithm_ext/insert.qbk
new file mode 100644
index 0000000..e9f48eb
--- /dev/null
+++ b/doc/reference/algorithm_ext/insert.qbk
@@ -0,0 +1,46 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:insert insert]
+
+[heading Prototype]
+
+``
+template<
+    class Container,
+    class SinglePassRange
+>
+Container& insert(Container& target,
+                  typename Container::iterator before,
+                  const SinglePassRange& from);
+
+// This overload is for target containers that do not require an insertion
+// position e.g. set/map
+template<
+    class Container,
+    class SinglePassRange
+>
+Container& insert(Container& target, const SinglePassRange& from);
+``
+
+[heading Description]
+
+`insert` all of the elements in the range `from` before the `before` iterator into `target`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/insert.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Container` supports insert at a specified position.
+# `SinglePassRange`'s value type is convertible to `Container`'s value type.
+
+[heading Complexity]
+
+Linear. `distance(from)` assignments are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/iota.qbk b/doc/reference/algorithm_ext/iota.qbk
new file mode 100644
index 0000000..0a5f799
--- /dev/null
+++ b/doc/reference/algorithm_ext/iota.qbk
@@ -0,0 +1,33 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:iota iota]
+
+[heading Prototype]
+
+``
+template<class ForwardRange, class Value>
+ForwardRange& iota(ForwardRange& rng, Value x);
+``
+
+[heading Description]
+
+`iota` traverses forward through `rng`, each element `y` in `rng` is assigned a value equivalent
+to `x + boost::distance(boost::begin(rng), it)`
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/iota.hpp`
+
+[heading Requirements]
+
+# `ForwardRange` is a model of the __forward_range__ Concept.
+# `Value` is a model of the `Incrementable` Concept.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)` assignments into `rng`.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/is_sorted.qbk b/doc/reference/algorithm_ext/is_sorted.qbk
new file mode 100644
index 0000000..f9c07b4
--- /dev/null
+++ b/doc/reference/algorithm_ext/is_sorted.qbk
@@ -0,0 +1,40 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:is_sorted is_sorted]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange>
+bool is_sorted(const SinglePassRange& rng);
+
+template<class SinglePassRange, class BinaryPredicate>
+bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred);
+``
+
+[heading Description]
+
+`is_sorted` determines if a range is sorted.
+For the non-predicate version the return value is `true` if and only if for
+each adjacent elements `[x,y]` the expression `x < y` is `true`.
+For the predicate version the return value is `true` is and only if for each
+adjacent elements `[x,y]` the expression `pred(x,y)` is `true`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/is_sorted.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `BinaryPredicate` is a model of the `BinaryPredicate` Concept.
+# The value type of `SinglePassRange` is convertible to both argument types of `BinaryPredicate`.
+
+[heading Complexity]
+
+Linear. A maximum of `distance(rng)` comparisons are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/overwrite.qbk b/doc/reference/algorithm_ext/overwrite.qbk
new file mode 100644
index 0000000..a265833
--- /dev/null
+++ b/doc/reference/algorithm_ext/overwrite.qbk
@@ -0,0 +1,39 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:overwrite overwrite]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange1,
+    class SinglePassRange2
+    >
+void overwrite(const SinglePassRange1& from,
+               SinglePassRange2& to);
+``
+
+[heading Description]
+
+`overwrite` assigns the values from the range `from` into the range `to`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/overwrite.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+# `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+# `SinglePassRange2` is mutable.
+# `distance(SinglePassRange1) <= distance(SinglePassRange2)`
+# `SinglePassRange1`'s value type is convertible to `SinglePassRange2`'s value type.
+
+[heading Complexity]
+
+Linear. `distance(rng1)` assignments are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/push_back.qbk b/doc/reference/algorithm_ext/push_back.qbk
new file mode 100644
index 0000000..ec46d0b
--- /dev/null
+++ b/doc/reference/algorithm_ext/push_back.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:push_back push_back]
+
+[heading Prototype]
+
+``
+template<
+    class Container,
+    class SinglePassRange
+    >
+Container& push_back(Container& target,
+                     const SinglePassRange& from);
+``
+
+[heading Description]
+
+`push_back` all of the elements in the range `from` to the back of the container `target`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/push_back.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Container` supports insert at `end()`.
+# `SinglePassRange`'s value type is convertible to `Container`'s value type.
+
+[heading Complexity]
+
+Linear. `distance(from)` assignments are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/push_front.qbk b/doc/reference/algorithm_ext/push_front.qbk
new file mode 100644
index 0000000..d9ca4fe
--- /dev/null
+++ b/doc/reference/algorithm_ext/push_front.qbk
@@ -0,0 +1,37 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:push_front push_front]
+
+[heading Prototype]
+
+``
+template<
+    class Container,
+    class SinglePassRange
+    >
+Container& push_front(Container& target,
+                      const SinglePassRange& from);
+``
+
+[heading Description]
+
+`push_front` all of the elements in the range `from` to the front of the container `target`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/push_front.hpp`
+
+[heading Requirements]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Container` supports insert at `begin()`.
+# `SinglePassRange`'s value type is convertible to `Container`'s value type.
+
+[heading Complexity]
+
+Linear. `distance(from)` assignments are performed.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/remove_erase.qbk b/doc/reference/algorithm_ext/remove_erase.qbk
new file mode 100644
index 0000000..eecc97b
--- /dev/null
+++ b/doc/reference/algorithm_ext/remove_erase.qbk
@@ -0,0 +1,33 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove_erase remove_erase]
+
+[heading Prototype]
+
+``
+template<class Container, class Value>
+Container& remove_erase(Container& target,
+                        const Value& value);
+``
+
+[heading Description]
+
+`remove_erase` actually eliminates the elements equal to `value` from the container. This
+is in contrast to the `remove` algorithm which merely rearranges elements.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/erase.hpp`
+
+[heading Requirements]
+
+# `Container` supports erase of an iterator range.
+
+[heading Complexity]
+
+Linear. Proportional to `distance(target)`s.
+
+[endsect]
diff --git a/doc/reference/algorithm_ext/remove_erase_if.qbk b/doc/reference/algorithm_ext/remove_erase_if.qbk
new file mode 100644
index 0000000..5eab446
--- /dev/null
+++ b/doc/reference/algorithm_ext/remove_erase_if.qbk
@@ -0,0 +1,34 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:remove_erase_if remove_erase_if]
+
+[heading Prototype]
+
+``
+template<class Container, class Pred>
+Container& remove_erase_if(Container& target,
+                           Pred pred);
+``
+
+[heading Description]
+
+`remove_erase_if` removes the elements `x` that satisfy `pred(x)` from the container.
+This is in contrast to the `erase` algorithm which merely rearranges elements.
+
+[heading Definition]
+
+Defined in the header file `boost/range/algorithm_ext/erase.hpp`
+
+[heading Requirements]
+
+# `Container` supports erase of an iterator range.
+# `Pred` is a model of the `Predicate` Concept.
+
+[heading Complexity]
+
+Linear. Proportional to `distance(target)`s.
+
+[endsect]
diff --git a/doc/reference/algorithms.qbk b/doc/reference/algorithms.qbk
new file mode 100644
index 0000000..8dcd848
--- /dev/null
+++ b/doc/reference/algorithms.qbk
@@ -0,0 +1,182 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:algorithms Range Algorithms]
+[section:introduction Introduction and motivation]
+In its most simple form a [*Range Algorithm] (or range-based algorithm) is simply an iterator-based algorithm where the /two/ iterator arguments have been replaced by /one/ range argument. For example, we may write
+
+``
+#include <boost/range/algorithm.hpp>
+#include <vector>
+
+std::vector<int> vec = ...;
+boost::sort(vec);
+``
+
+instead of
+
+``
+std::sort(vec.begin(), vec.end());
+``
+
+However, the return type of range algorithms is almost always different from that of existing iterator-based algorithms.
+
+One group of algorithms, like `boost::sort()`, will simply return the same range so that we can continue to pass the range around and/or further modify it. Because of this we may write
+``
+boost:unique(boost::sort(vec));
+``
+to first sort the range and then run `unique()` on the sorted range.
+
+Algorithms like `boost::unique()` fall into another group of algorithms that return (potentially) narrowed views of the original range. By default `boost::unique(rng)` returns the range `[boost::begin(rng), found)` where `found` denotes the iterator returned by `std::unique(boost::begin(rng), boost::end(rng))`
+
+Therefore exactly the unique values can be copied by writing
+``
+boost::copy(boost::unique(boost::sort(vec)),
+            std::ostream_iterator<int>(std::cout));
+``
+
+Algorithms like `boost::unique` usually return the range: `[boost::begin(rng), found)`.
+However, this behaviour may be changed by supplying a `range_return_value`
+as a template parameter to the algorithm:
+
+[table
+    [[Expression] [Return]]
+    [[`boost::unique<boost::return_found>(rng)`] [returns a single iterator like `std::unique`]]
+    [[`boost::unique<boost::return_begin_found>(rng)`] [returns the range `[boost::begin(rng), found)` (this is the default)]]
+    [[`boost::unique<boost::return_begin_next>(rng)`] [returns the range `[boost::begin(rng), boost::next(found))`]]
+    [[`boost::unique<boost::return_found_end>(rng)`] [returns the range `[found, boost::end(rng))`]]
+    [[`boost::unique<boost::return_next_end>(rng)`] [returns the range `[boost::next(found),boost::end(rng))`]]
+    [[`boost::unique<boost::return_begin_end>(rng)`] [returns the entire original range.]]
+]
+
+This functionality has the following advantages:
+
+# it allows for ['*seamless functional-style programming*] where you do not need to use named local variables to store intermediate results
+# it is very ['*safe*] because the algorithm can verify out-of-bounds conditions and handle tricky conditions that lead to empty ranges
+
+For example, consider how easy we may erase the duplicates in a sorted container:
+
+``
+std::vector<int> vec = ...;
+boost::erase(vec, boost::unique<boost::return_found_end>(boost::sort(vec)));
+``
+
+Notice the use of `boost::return_found_end`. What if we wanted to erase all the duplicates except one of them? In old-fashioned STL-programming we might write
+
+``
+// assume 'vec' is already sorted
+std::vector<int>::iterator i = std::unique(vec.begin(), vec.end());
+
+// remember this check or you get into problems
+if (i != vec.end())
+    ++i;
+
+vec.erase(i, vec.end());
+``
+
+The same task may be accomplished simply with
+``
+boost::erase(vec, boost::unique<boost::return_next_end>(vec));
+``
+and there is no need to worry about generating an invalid range. Furthermore, if the container is complex, calling `vec.end()` several times will be more expensive than using a range algorithm.
+
+[endsect]
+
+[section:mutating Mutating algorithms]
+[include algorithm/copy.qbk]
+[include algorithm/copy_backward.qbk]
+[include algorithm/fill.qbk]
+[include algorithm/fill_n.qbk]
+[include algorithm/generate.qbk]
+[include algorithm/inplace_merge.qbk]
+[include algorithm/merge.qbk]
+[include algorithm/nth_element.qbk]
+[include algorithm/partial_sort.qbk]
+[include algorithm/partition.qbk]
+[include algorithm/random_shuffle.qbk]
+[include algorithm/remove.qbk]
+[include algorithm/remove_copy.qbk]
+[include algorithm/remove_copy_if.qbk]
+[include algorithm/remove_if.qbk]
+[include algorithm/replace.qbk]
+[include algorithm/replace_copy.qbk]
+[include algorithm/replace_copy_if.qbk]
+[include algorithm/replace_if.qbk]
+[include algorithm/reverse.qbk]
+[include algorithm/reverse_copy.qbk]
+[include algorithm/rotate.qbk]
+[include algorithm/rotate_copy.qbk]
+[include algorithm/sort.qbk]
+[include algorithm/stable_partition.qbk]
+[include algorithm/stable_sort.qbk]
+[include algorithm/swap_ranges.qbk]
+[include algorithm/transform.qbk]
+[include algorithm/unique.qbk]
+[include algorithm/unique_copy.qbk]
+[endsect]
+
+[section:non_mutating Non-mutating algorithms]
+[include algorithm/adjacent_find.qbk]
+[include algorithm/binary_search.qbk]
+[include algorithm/count.qbk]
+[include algorithm/count_if.qbk]
+[include algorithm/equal.qbk]
+[include algorithm/equal_range.qbk]
+[include algorithm/for_each.qbk]
+[include algorithm/find.qbk]
+[include algorithm/find_end.qbk]
+[include algorithm/find_first_of.qbk]
+[include algorithm/find_if.qbk]
+[include algorithm/lexicographical_compare.qbk]
+[include algorithm/lower_bound.qbk]
+[include algorithm/max_element.qbk]
+[include algorithm/min_element.qbk]
+[include algorithm/mismatch.qbk]
+[include algorithm/search.qbk]
+[include algorithm/search_n.qbk]
+[include algorithm/upper_bound.qbk]
+[endsect]
+
+[section:set Set algorithms]
+[include algorithm/includes.qbk]
+[include algorithm/set_union.qbk]
+[include algorithm/set_intersection.qbk]
+[include algorithm/set_difference.qbk]
+[include algorithm/set_symmetric_difference.qbk]
+[endsect]
+
+[section:heap Heap algorithms]
+[include algorithm/push_heap.qbk]
+[include algorithm/pop_heap.qbk]
+[include algorithm/make_heap.qbk]
+[include algorithm/sort_heap.qbk]
+[endsect]
+
+[section:permutation Permutation algorithms]
+[include algorithm/next_permutation.qbk]
+[include algorithm/prev_permutation.qbk]
+[endsect]
+
+[section:new New algorithms]
+[include algorithm_ext/copy_n.qbk]
+[include algorithm_ext/erase.qbk]
+[include algorithm_ext/for_each.qbk]
+[include algorithm_ext/insert.qbk]
+[include algorithm_ext/iota.qbk]
+[include algorithm_ext/is_sorted.qbk]
+[include algorithm_ext/overwrite.qbk]
+[include algorithm_ext/push_back.qbk]
+[include algorithm_ext/push_front.qbk]
+[include algorithm_ext/remove_erase.qbk]
+[include algorithm_ext/remove_erase_if.qbk]
+[endsect]
+
+[section:numeric Numeric algorithms]
+[include numeric/accumulate.qbk]
+[include numeric/adjacent_difference.qbk]
+[include numeric/inner_product.qbk]
+[include numeric/partial_sum.qbk]
+[endsect]
+[endsect]
diff --git a/doc/reference/extending.qbk b/doc/reference/extending.qbk
new file mode 100644
index 0000000..46652d6
--- /dev/null
+++ b/doc/reference/extending.qbk
@@ -0,0 +1,328 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:extending Extending the library]
+
+[section:method_1 Method 1: provide member functions and nested types]
+
+This procedure assumes that you have control over the types that should be made conformant to a Range concept. If not, see [link range.reference.extending.method_2 method 2].
+
+The primary templates in this library are implemented such that standard containers will work automatically and so will __boost_array__. Below is given an overview of which member functions and member types a class must specify to be useable as a certain Range concept.
+
+[table
+  [[Member function] [Related concept      ]]
+  [[`begin()`      ] [__single_pass_range__]]
+  [[`end()`        ] [__single_pass_range__]]
+]
+
+Notice that `rbegin()` and `rend()` member functions are not needed even though the container can support bidirectional iteration.
+
+The required member types are:
+
+[table
+  [[Member type     ] [Related concept      ]]
+  [[`iterator`      ] [__single_pass_range__]]
+  [[`const_iterator`] [__single_pass_range__]]
+]
+
+Again one should notice that member types `reverse_iterator` and `const_reverse_iterator` are not needed.
+
+[endsect]
+
+[section:method_2 Method 2: provide free-standing functions and specialize metafunctions]
+
+This procedure assumes that you cannot (or do not wish to) change the types that should be made conformant to a Range concept. If this is not true, see [link range.reference.extending.method_1 method 1].
+
+The primary templates in this library are implemented such that certain functions are found via argument-dependent-lookup (ADL). Below is given an overview of which free-standing functions a class must specify to be useable as a certain Range concept. Let `x` be a variable (`const` or `mutable`) of the class in question.
+
+[table
+  [[Function              ] [Related concept      ]]
+  [[`range_begin(x)`] [__single_pass_range__]]
+  [[`range_end(x)`  ] [__single_pass_range__]]
+  [[`range_calculate_size(x)`] [ Optional. This can be used to specify a mechanism for constant-time computation of the size of a range. The default behaviour is to return `boost::end(x) - boost::begin(x)` for random access ranges, and to return `x.size()` for ranges with lesser traversal capability. This behaviour can be changed by implementing `range_calculate_size` in a manner that will be found via ADL. The ability to calculate size in O(1) is often possible even with ranges with traversal categories less than random access.]]
+]
+
+`range_begin()` and `range_end()` must be overloaded for both `const` and `mutable` reference arguments.
+
+You must also specialize two metafunctions for your type `X`:
+
+[table
+  [[Metafunction                 ] [Related concept      ]]
+  [[`boost::range_mutable_iterator`] [__single_pass_range__]]
+  [[`boost::range_const_iterator`] [__single_pass_range__]]
+]
+
+A complete example is given here:
+
+``
+    #include <boost/range.hpp>
+    #include <iterator>         // for std::iterator_traits, std::distance()
+
+    namespace Foo
+    {
+        //
+        // Our sample UDT. A 'Pair'
+        // will work as a range when the stored
+        // elements are iterators.
+        //
+        template< class T >
+        struct Pair
+        {
+            T first, last;
+        };
+
+    } // namespace 'Foo'
+
+    namespace boost
+    {
+        //
+        // Specialize metafunctions. We must include the range.hpp header.
+        // We must open the 'boost' namespace.
+        //
+
+    	template< class T >
+    	struct range_mutable_iterator< Foo::Pair<T> >
+    	{
+    		typedef T type;
+    	};
+
+    	template< class T >
+    	struct range_const_iterator< Foo::Pair<T> >
+    	{
+    		//
+    		// Remark: this is defined similar to 'range_iterator'
+    		//         because the 'Pair' type does not distinguish
+    		//         between an iterator and a const_iterator.
+    		//
+    		typedef T type;
+    	};
+
+    } // namespace 'boost'
+
+    namespace Foo
+    {
+    	//
+    	// The required functions. These should be defined in
+    	// the same namespace as 'Pair', in this case
+    	// in namespace 'Foo'.
+    	//
+
+    	template< class T >
+    	inline T range_begin( Pair<T>& x )
+    	{
+    		return x.first;
+    	}
+
+    	template< class T >
+    	inline T range_begin( const Pair<T>& x )
+    	{
+    		return x.first;
+    	}
+
+    	template< class T >
+    	inline T range_end( Pair<T>& x )
+    	{
+    		return x.last;
+    	}
+
+    	template< class T >
+    	inline T range_end( const Pair<T>& x )
+    	{
+    		return x.last;
+    	}
+
+    } // namespace 'Foo'
+
+    #include <vector>
+
+    int main(int argc, const char* argv[])
+    {
+    	typedef std::vector<int>::iterator  iter;
+    	std::vector<int>                    vec;
+    	Foo::Pair<iter>                     pair = { vec.begin(), vec.end() };
+    	const Foo::Pair<iter>&              cpair = pair;
+    	//
+    	// Notice that we call 'begin' etc with qualification.
+    	//
+    	iter i = boost::begin( pair );
+    	iter e = boost::end( pair );
+    	i      = boost::begin( cpair );
+    	e      = boost::end( cpair );
+    	boost::range_difference< Foo::Pair<iter> >::type s = boost::size( pair );
+    	s      = boost::size( cpair );
+    	boost::range_reverse_iterator< const Foo::Pair<iter> >::type
+    	ri     = boost::rbegin( cpair ),
+    	re     = boost::rend( cpair );
+
+    	return 0;
+    }
+``
+
+[endsect]
+
+[section:method_3 Method 3: provide range adaptor implementations]
+
+[section:method_3_1 Method 3.1: Implement a Range Adaptor without arguments]
+
+To implement a Range Adaptor without arguments (e.g. reversed) you need to:
+
+# Provide a range for your return type, for example:
+``
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+
+template< typename R >
+struct reverse_range :
+    boost::iterator_range<
+        boost::reverse_iterator<
+            typename boost::range_iterator<R>::type> >
+{
+private:
+    typedef boost::iterator_range<
+        boost::reverse_iterator<
+            typename boost::range_iterator<R>::type> > base;
+
+public:
+    typedef boost::reverse_iterator<
+        typename boost::range_iterator<R>::type > iterator;
+
+    reverse_range(R& r)
+        : base(iterator(boost::end(r)), iterator(boost::begin(r)))
+    { }
+};
+``
+
+# Provide a tag to uniquely identify your adaptor in the `operator|` function overload set
+``
+namespace detail {
+    struct reverse_forwarder {};
+}
+``
+
+# Implement `operator|`
+``
+template< class BidirectionalRng >
+inline reverse_range<BidirectionalRng>
+operator|( BidirectionalRng& r, detail::reverse_forwarder )
+{
+	return reverse_range<BidirectionalRng>( r );
+}
+
+template< class BidirectionalRng >
+inline reverse_range<const BidirectionalRng>
+operator|( const BidirectionalRng& r, detail::reverse_forwarder )
+{
+	return reverse_range<const BidirectionalRng>( r );
+}
+``
+
+# Declare the adaptor itself (it is a variable of the tag type).
+``
+namespace
+{
+    const detail::reverse_forwarder reversed = detail::reverse_forwarder();
+}
+``
+
+[endsect]
+
+[section:method_3_2 Method 3.2: Implement a Range Adaptor with arguments]
+
+# Provide a range for your return type, for example:
+``
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+
+template<typename Value>
+class replace_value
+{
+public:
+    typedef const Value& result_type;
+    typedef const Value& argument_type;
+
+    replace_value(const Value& from, const Value& to)
+        : m_from(from), m_to(to)
+    {
+    }
+
+    const Value& operator()(const Value& x) const
+    {
+        return (x == m_from) ? m_to : x;
+    }
+private:
+    Value m_from;
+    Value m_to;
+};
+
+template<typename Range>
+class replace_range
+: public boost::iterator_range<
+    boost::transform_iterator<
+        replace_value<typename boost::range_value<Range>::type>,
+        typename boost::range_iterator<Range>::type> >
+{
+private:
+    typedef typename boost::range_value<Range>::type value_type;
+    typedef typename boost::range_iterator<Range>::type iterator_base;
+    typedef replace_value<value_type> Fn;
+    typedef boost::transform_iterator<Fn, iterator_base> replaced_iterator;
+    typedef boost::iterator_range<replaced_iterator> base_t;
+
+public:
+    replace_range(Range& rng, value_type from, value_type to)
+        : base_t(replaced_iterator(boost::begin(rng), Fn(from,to)),
+                 replaced_iterator(boost::end(rng), Fn(from,to)))
+     {
+     }
+ };
+``
+
+# Implement a holder class to hold the arguments required to construct the RangeAdaptor.
+The holder combines multiple parameters into one that can be passed as the right operand of `operator|()`.
+``
+template<typename T>
+class replace_holder : public boost::range_detail::holder2<T>
+{
+public:
+    replace_holder(const T& from, const T& to)
+        : boost::range_detail::holder2<T>(from, to)
+    { }
+private:
+    void operator=(const replace_holder&);
+};
+``
+
+# Define an instance of the holder with the name of the adaptor
+``
+static boost::range_detail::forwarder2<replace_holder>
+replaced = boost::range_detail::forwarder2<replace_holder>();
+``
+
+# Define `operator|`
+``
+template<typename SinglePassRange>
+inline replace_range<SinglePassRange>
+operator|(SinglePassRange& rng,
+          const replace_holder<typename boost::range_value<SinglePassRange>::type>& f)
+{
+    return replace_range<SinglePassRange>(rng, f.val1, f.val2);
+}
+
+template<typename SinglePassRange>
+inline replace_range<const SinglePassRange>
+operator|(const SinglePassRange& rng,
+          const replace_holder<typename boost::range_value<SinglePassRange>::type>& f)
+{
+    return replace_range<const SinglePassRange>(rng, f.val1, f.val2);
+}
+``
+
+[endsect]
+
+[endsect]
+
+[endsect]
+
diff --git a/doc/reference/numeric/accumulate.qbk b/doc/reference/numeric/accumulate.qbk
new file mode 100644
index 0000000..e151e63
--- /dev/null
+++ b/doc/reference/numeric/accumulate.qbk
@@ -0,0 +1,61 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:accumulate accumulate]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange,
+    class Value
+    >
+Value accumulate(const SinglePassRange& source_rng,
+                 Value init);
+
+template<
+    class SinglePassRange,
+    class Value,
+    class BinaryOperation
+    >
+Value accumulate(const SinglePassRange& source_rng,
+                 Value init,
+                 BinaryOperation op);
+``
+
+[heading Description]
+
+`accumulate` is a generalisation of summation. It computes a binary operation (`operator+`
+in the non-predicate version) of `init` and all of the elements in `rng`.
+
+The return value is the resultant value of the above algorithm.
+
+[heading Definition]
+
+Defined in the header file `boost/range/numeric.hpp`
+
+[heading Requirements]
+
+[heading For the first version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Value` is a model of the `AssignableConcept`.
+# An `operator+` is defined for a left-hand operand of type `Value` and a right-hand operand of the `SinglePassRange` value type.
+# The return type of the above operator is convertible to `Value`.
+
+[heading For the second version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `Value` is a model of the `AssignableConcept`.
+# `BinaryOperation` is a model of the `BinaryFunctionConcept`.
+# `Value` is convertible to `BinaryOperation`'s first argument type.
+# `SinglePassRange`'s value type is convertible to `BinaryOperation`'s second argument type.
+# The return type of `BinaryOperation` is convertible to `Value`.
+
+[heading Complexity]
+
+Linear. Exactly `distance(source_rng)`.
+
+[endsect]
diff --git a/doc/reference/numeric/adjacent_difference.qbk b/doc/reference/numeric/adjacent_difference.qbk
new file mode 100644
index 0000000..7580036
--- /dev/null
+++ b/doc/reference/numeric/adjacent_difference.qbk
@@ -0,0 +1,68 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:adjacent_difference adjacent_difference]
+
+[heading Prototype]
+
+``
+template<
+    class SinglePassRange,
+    class OutputIterator
+    >
+OutputIterator adjacent_difference(
+    const SinglePassRange& source_rng,
+    OutputIterator out_it);
+
+template<
+    class SinglePassRange,
+    class OutputIterator,
+    class BinaryOperation
+    >
+OutputIterator adjacent_difference(
+    const SinglePassRange& source_rng,
+    OutputIterator out_it,
+    BinaryOperation op);
+``
+
+[heading Description]
+
+`adjacent_difference` calculates the differences of adjacent_elements in `rng`.
+
+The first version of `adjacent_difference` uses `operator-()` to calculate the differences.
+The second version uses `BinaryOperation` instead of `operator-()`.
+
+[heading Definition]
+
+Defined in the header file `boost/range/numeric.hpp`
+
+[heading Requirements]
+
+[heading For the first version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `OutputIterator` is a model of the `OutputIteratorConcept`.
+# If `x` and `y` are objects of `SinglePassRange`'s value type, then `x - y` is defined.
+# The value type of `SinglePassRange` is convertible to a type in `OutputIterator`'s set of value types.
+# The return type of `x - y` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading For the second version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `OutputIterator` is a model of the `OutputIteratorConcept`.
+# `BinaryOperation` is a model of the `BinaryFunctionConcept`.
+# The value type of `SinglePassRange` is convertible to `BinaryOperation`'s first and second argument types.
+# The value type of `SinglePassRange` is convertible to a type in `OutputIterator`'s set of value types.
+# The result type of `BinaryOperation` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+`[result, result + distance(rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. If `empty(rng)` then zero applications, otherwise `distance(rng) - 1` applications are performed.
+
+[endsect]
diff --git a/doc/reference/numeric/inner_product.qbk b/doc/reference/numeric/inner_product.qbk
new file mode 100644
index 0000000..bb4fc3c
--- /dev/null
+++ b/doc/reference/numeric/inner_product.qbk
@@ -0,0 +1,73 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:inner_product inner_product]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange1,
+         class SinglePassRange2,
+         class Value>
+    Value inner_product( const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         Value                   init );
+
+template<class SinglePassRange1,
+         class SinglePassRange2,
+         class Value,
+         class BinaryOperation1,
+         class BinaryOperation2>
+    Value inner_product( const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         Value                   init,
+                         BinaryOperation1        op1,
+                         BinaryOperation2        op2 );
+``
+
+[heading Description]
+
+`inner_product` calculates a generalised inner product of the range `rng1` and `rng2`.
+
+For further information on the `inner_product` algorithm please see __sgi_inner_product__.
+
+[heading Definition]
+
+Defined in the header file `boost/range/numeric.hpp`
+
+[heading Requirements]
+
+[heading For the first version]
+
+# `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+# `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+# `Value` is a model of the `AssignableConcept`.
+# If `x` is an object of type `Value`, `y` is an object of `SinglePassRange1`'s value
+type, and `z` is an object of `SinglePassRange2`'s value type, then `x + y * z`
+is defined.
+# The result type of the expression `x + y * z` is convertible to `Value`.
+
+[heading For the second version]
+
+# `SinglePassRange1` is a model of the __single_pass_range__ Concept.
+# `SinglePassRange2` is a model of the __single_pass_range__ Concept.
+# `Value` is a model of the `AssignableConcept`.
+# `BinaryOperation1` is a model of the `BinaryFunctionConcept`.
+# `BinaryOperation2` is a model of the `BinaryFunctionConcept`.
+# The value type of `SinglePassRange1` is convertible to the first argument type of `BinaryOperation2`.
+# The value type of `SinglePassRange2` is convertible to the second argument type of `BinaryOperation2`.
+# `Value` is convertible to the value type of `BinaryOperation1`.
+# The return type of `BinaryOperation2` is convertible to the second argument type of `BinaryOperation1`.
+# The return type of `BinaryOperation1` is convertible to `Value`.
+
+[heading Precondition:]
+
+`distance(rng2) >= distance(rng1)` is a valid range.
+
+[heading Complexity]
+
+Linear. Exactly `distance(rng)`.
+
+[endsect]
diff --git a/doc/reference/numeric/partial_sum.qbk b/doc/reference/numeric/partial_sum.qbk
new file mode 100644
index 0000000..f52e465
--- /dev/null
+++ b/doc/reference/numeric/partial_sum.qbk
@@ -0,0 +1,60 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:partial_sum partial_sum]
+
+[heading Prototype]
+
+``
+template<class SinglePassRange,
+         class OutputIterator>
+OutputIterator partial_sum(const SinglePassRange& rng,
+                           OutputIterator out_it);
+
+template<class SinglePassRange,
+         class OutputIterator,
+         class BinaryOperation>
+OutputIterator partial_sum(const SinglePassRange& rng,
+                           OutputIterator out_it,
+                           BinaryOperation op);
+``
+
+[heading Description]
+
+`partial_sum` calculates a generalised partial sum of `rng` in the same manner as
+`std::partial_sum(boost::begin(rng), boost::end(rng), out_it)`. See __sgi_partial_sum__.
+
+
+[heading Definition]
+
+Defined in the header file `boost/range/numeric.hpp`
+
+[heading Requirements]
+
+[heading For the first version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `OutputIterator` is a model of the `OutputIteratorConcept`.
+# If `x` and `y` are objects of `SinglePassRange`'s value type, then `x + y` is defined.
+# The return type of `x + y` is convertible to the value type of `SinglePassRange`.
+# The value type of `SinglePassRange` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading For the second version]
+
+# `SinglePassRange` is a model of the __single_pass_range__ Concept.
+# `OutputIterator` is a model of the `OutputIteratorConcept`.
+# `BinaryOperation` is a model of the `BinaryFunctionConcept`.
+# The result type of `BinaryOperation` is convertible to the value type of `SinglePassRange`.
+# The value type of `SinglePassRange` is convertible to a type in `OutputIterator`'s set of value types.
+
+[heading Precondition:]
+
+`[result, result + distance(rng))` is a valid range.
+
+[heading Complexity]
+
+Linear. If `empty(rng)` then zero applications, otherwise `distance(rng) - 1` applications are performed.
+
+[endsect]
diff --git a/doc/reference/overview.qbk b/doc/reference/overview.qbk
new file mode 100644
index 0000000..af7ef2c
--- /dev/null
+++ b/doc/reference/overview.qbk
@@ -0,0 +1,19 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:overview Overview]
+
+Three types of objects are currently supported by the library:
+
+* standard-like containers
+* `std::pair<iterator,iterator>`
+* built-in arrays
+
+Even though the behavior of the primary templates are exactly such that standard containers will be supported by default, the requirements are much lower than the standard container requirements. For example, the utility class __iterator_range__ implements the __minimal_interface__ required to make the class a __forward_range__.
+
+Please also see __range_concepts__ for more details.
+
+[endsect]
+
diff --git a/doc/reference/ranges.qbk b/doc/reference/ranges.qbk
new file mode 100644
index 0000000..5b853d5
--- /dev/null
+++ b/doc/reference/ranges.qbk
@@ -0,0 +1,14 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:ranges Provided Ranges]
+
+[include ranges/any_range.qbk]
+[include ranges/counting_range.qbk]
+[include ranges/istream_range.qbk]
+[include ranges/irange.qbk]
+
+[endsect]
+
diff --git a/doc/reference/ranges/any_range.qbk b/doc/reference/ranges/any_range.qbk
new file mode 100644
index 0000000..1888ed8
--- /dev/null
+++ b/doc/reference/ranges/any_range.qbk
@@ -0,0 +1,115 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:any_range any_range]
+
+[heading Description]
+
+`any_range` is a range that has the type information erased hence a `any_range<int, boost::forward_traversal_tag, int, std::ptrdiff_t>`
+can be used to represent a `std::vector<int>`, a `std::list<int>` or many other types.
+
+The __type_erasure_article__ covers the motivation and goals of type erasure in this context. Clearly
+my implementation is building upon a lot of prior art created by others. Thomas Becker's `any_iterator` was a strong
+influence. Adobe also have an `any_iterator` implementation, but this has very tight coupling to other parts of the
+library that precluded it from use in Boost.Range.
+Early development versions of this Range Adaptor directly used Thomas Becker's any_iterator implementation.
+Subsequently I discovered that the heap allocations of this and many other implementations cause poor
+speed performance particularly at the tails of the distribution. To solve this required a new design that
+incorporated the embedded buffer optimization.
+
+Despite the underlying `any_iterator` being the fastest available implementation, the performance overhead of `any_range` is still appreciable due to the cost of virtual function calls required to implement `increment`, `decrement`, `advance`, `equal` etc. Frequently a better design choice is to convert to a canonical form.
+
+Please see the __range_adaptors_type_erased__ for a Range Adaptor that returns `any_range` instances.
+
+[heading Synopsis]
+
+``
+template<
+    class Value
+  , class Traversal
+  , class Reference
+  , class Difference
+  , class Buffer = any_iterator_default_buffer
+>
+class any_range
+    : public iterator_range<
+        range_detail::any_iterator<
+            Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >
+    >
+{
+    typedef range_detail::any_iterator<
+        Value
+      , Traversal
+      , Reference
+      , Difference
+      , Buffer
+    > any_iterator_type;
+
+    typedef iterator_range<any_iterator_type> base_type;
+
+    struct enabler {};
+    struct disabler {};
+public:
+    typedef any_iterator_type iterator;
+    typedef any_iterator_type const_iterator;
+
+    any_range()
+    {
+    }
+
+    any_range(const any_range& other)
+        : base_type(other)
+    {
+    }
+
+    template<class WrappedRange>
+    any_range(WrappedRange& wrapped_range)
+    : base_type(boost::begin(wrapped_range),
+                boost::end(wrapped_range))
+    {
+    }
+
+    template<class WrappedRange>
+    any_range(const WrappedRange& wrapped_range)
+    : base_type(boost::begin(wrapped_range),
+                boost::end(wrapped_range))
+    {
+    }
+
+    template<
+        class OtherValue
+      , class OtherTraversal
+      , class OtherReference
+      , class OtherDifference
+    >
+    any_range(const any_range<
+                        OtherValue
+                      , OtherTraversal
+                      , OtherReference
+                      , OtherDifference
+                      , Buffer
+                    >& other)
+    : base_type(boost::begin(other), boost::end(other))
+    {
+    }
+
+    template<class Iterator>
+    any_range(Iterator first, Iterator last)
+        : base_type(first, last)
+    {
+    }
+};
+``
+
+[heading Definition]
+
+Defined in header file `boost/range/any_range.hpp`
+
+[endsect]
diff --git a/doc/reference/ranges/counting_range.qbk b/doc/reference/ranges/counting_range.qbk
new file mode 100644
index 0000000..31037a9
--- /dev/null
+++ b/doc/reference/ranges/counting_range.qbk
@@ -0,0 +1,36 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:counting_range counting_range]
+
+[heading Prototype]
+
+``
+template< class Incrementable > inline
+iterator_range< counting_iterator<Incrementable> >
+counting_range(Incrementable first, Incrementable last);
+
+template< class SinglePassRange > inline
+iterator_range< counting_iterator<typename range_iterator<SinglePassRange>::type >
+counting_range(const SinglePassRange& rng);
+
+template< class SinglePassRange > inline
+iterator_range< counting_iterator<typename range_iterator<SinglePassRange>::type >
+counting_range(SinglePassRange& rng);
+``
+
+[heading Description]
+
+`counting_range` is a function to generator that generates an `iterator_range` wrapping a `counting_iterator` (from Boost.Iterator).
+
+[heading Definition]
+
+Defined in header file `boost/range/counting_range.hpp`
+
+[heading Requirements]
+
+# `Incrementable` is a model of the `Incrementable` Concept.
+
+[endsect]
diff --git a/doc/reference/ranges/irange.qbk b/doc/reference/ranges/irange.qbk
new file mode 100644
index 0000000..1d4ae7e
--- /dev/null
+++ b/doc/reference/ranges/irange.qbk
@@ -0,0 +1,43 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:irange irange]
+
+[heading Prototype]
+
+``
+template<class Integer>
+iterator_range< range_detail::integer_iterator<Integer> >
+irange(Integer last);
+
+template<class Integer>
+iterator_range< range_detail::integer_iterator<Integer> >
+irange(Integer first, Integer last);
+
+template<class Integer, class StepSize>
+iterator_range< range_detail::integer_iterator_with_step<Integer, StepSize> >
+irange(Integer first, Integer last, StepSize step_size);
+``
+
+[heading Description]
+
+`irange` is a function to generate an Integer Range.
+
+`irange` allows treating integers as a model of the __random_access_range__ Concept. It should be noted that the `first` and `last` parameters denoted a half-open range.
+
+[heading Definition]
+
+Defined in the header file `boost/range/irange.hpp`
+
+[heading Requirements]
+
+# `Integer` is a model of the `Integer` Concept.
+# `StepSize` is a model of the `SignedInteger` Concept.
+
+[heading Complexity]
+
+Constant. Since this function generates a new range the most significant performance cost is incurred through the iteration of the generated range.
+
+[endsect]
diff --git a/doc/reference/ranges/istream_range.qbk b/doc/reference/ranges/istream_range.qbk
new file mode 100644
index 0000000..66a1e84
--- /dev/null
+++ b/doc/reference/ranges/istream_range.qbk
@@ -0,0 +1,24 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:istream_range istream_range]
+
+[heading Prototype]
+
+``
+template< class Type, class Elem, class Traits > inline
+iterator_range< std::istream_iterator<Type, Elem, Traits> >
+istream_range(std::basic_istream<Elem, Traits>& in);
+``
+
+[heading Description]
+
+`istream_range` is a function to generator that generates an `iterator_range` wrapping a `std::istream_iterator`.
+
+[heading Definition]
+
+Defined in header file `boost/range/istream_range.hpp`
+
+[endsect]
diff --git a/doc/reference/semantics.qbk b/doc/reference/semantics.qbk
new file mode 100644
index 0000000..c7cf8f4
--- /dev/null
+++ b/doc/reference/semantics.qbk
@@ -0,0 +1,200 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:semantics Semantics]
+
+[heading notation]
+
+[table
+  [[Type   ] [Object] [Describes                                ]]
+  [[`X`    ] [`x`   ] [any type                                 ]]
+  [[`T`    ] [`t`   ] [denotes behavior of the primary templates]]
+  [[`P`    ] [`p`   ] [denotes `std::pair<iterator,iterator>`   ]]
+  [[`A[sz]`] [`a`   ] [denotes an array of type `A` of size `sz`]]
+  [[`Char*`] [`s`   ] [denotes either `char*` or `wchar_t*`     ]]
+]
+
+[section Metafunctions]
+
+[table
+    [[Expression] [Return type] [Complexity]]
+    [
+        [`range_iterator<X>::type`]
+        [``
+            T::iterator
+            P::first_type
+            A*
+        ``]
+        [compile time]
+    ]
+    [
+        [`range_iterator<const X>::type`]
+        [``
+            T::const_iterator
+            P::first_type
+            const A*
+        ``]
+        [compile time]
+    ]
+    [
+        [`range_value<X>::type`]
+        [`boost::iterator_value<range_iterator<X>::type>::type`]
+        [compile time]
+    ]
+    [
+        [`range_reference<X>::type`]
+        [`boost::iterator_reference<range_iterator<X>::type>::type`]
+        [compile time]
+    ]
+    [
+        [`range_pointer<X>::type`]
+        [`boost::iterator_pointer<range_iterator<X>::type>::type`]
+        [compile time]
+    ]
+    [
+        [`range_category<X>::type`]
+        [`boost::iterator_category<range_iterator<X>::type>::type`]
+        [compile time]
+    ]
+    [
+        [`range_difference<X>::type`]
+        [`boost::iterator_difference<range_iterator<X>::type>::type`]
+        [compile time]
+    ]
+    [
+        [`range_reverse_iterator<X>::type`]
+        [`boost::reverse_iterator<range_iterator<X>::type>`]
+        [compile time]
+    ]
+    [
+        [`range_reverse_iterator<const X>::type`]
+        [`boost::reverse_iterator<range_iterator<const X>::type`]
+        [compile time]
+    ]
+    [
+        [`has_range_iterator<X>::type`]
+        [`mpl::true_` if `range_mutable_iterator<X>::type` is a valid expression, `mpl::false_` otherwise]
+        [compile time]
+    ]
+    [
+        [`has_range_const_iterator<X>::type`]
+        [`mpl::true_` if `range_const_iterator<X>::type` is a valid expression, `mpl::false_` otherwise]
+        [compile time]
+    ]
+]
+
+[endsect]
+
+[section Functions]
+
+[table
+    [[Expression] [Return type] [Returns] [Complexity]]
+
+    [
+        [`begin(x)`]
+        [`range_iterator<X>::type`]
+        [
+            `p.first` if `p` is of type `std::pair<T>`
+            `a` if `a` is an array
+            `range_begin(x)` if that expression would invoke a function found by ADL
+            `t.begin()` otherwise
+        ]
+        [constant time]
+    ]
+    [
+        [`end(x)`]
+        [`range_iterator<X>::type`]
+        [
+            `p.second` if `p` is of type `std::pair<T>`
+            `a + sz` if `a` is an array of size `sz`
+            `range_end(x)` if that expression would invoke a function found by ADL
+            `t.end()` otherwise
+        ]
+        [constant time]
+    ]
+    [
+        [`empty(x)`]
+        [`bool`]
+        [`boost::begin(x) == boost::end(x)`]
+        [constant time]
+    ]
+    [
+        [`distance(x)`]
+        [`range_difference<X>::type`]
+        [`std::distance(boost::begin(x),boost::end(x))`]
+        [-]
+    ]
+    [
+        [`size(x)`]
+        [`range_size<X>::type`]
+        [`range_calculate_size(x)` which by default is `boost::end(x) - boost::begin(x)`. Users may supply alternative implementations by implementing `range_calculate_size(x)` so that it will be found via ADL]
+        [constant time]
+    ]
+    [
+        [`rbegin(x)`]
+        [`range_reverse_iterator<X>::type`]
+        [`range_reverse_iterator<X>::type(boost::end(x))`]
+        [constant time]
+    ]
+    [
+        [`rend(x)`]
+        [`range_reverse_iterator<X>::type`]
+        [`range_reverse_iterator<X>::type(boost::begin(x))`]
+        [constant time]
+    ]
+    [
+        [`const_begin(x)`]
+        [`range_iterator<const X>::type`]
+        [`range_iterator<const X>::type(boost::begin(x))`]
+        [constant time]
+    ]
+    [
+        [`const_end(x)`]
+        [`range_iterator<const X>::type`]
+        [`range_iterator<const X>::type(boost::end(x))`]
+        [constant time]
+    ]
+    [
+        [`const_rbegin(x)`]
+        [`range_reverse_iterator<const X>::type`]
+        [`range_reverse_iterator<const X>::type(boost::rbegin(x))`]
+        [constant time]
+    ]
+    [
+        [`const_rend(x)`]
+        [`range_reverse_iterator<const X>::type`]
+        [`range_reverse_iterator<const X>::type(boost::rend(x))`]
+        [constant time]
+    ]
+    [
+        [`as_literal(x)`]
+        [`iterator_range<U>` where `U` is `Char*` if `x` is a pointer to a string and `U` is `range_iterator<X>::type` otherwise]
+        [
+            `[s,s + std::char_traits<X>::length(s))` if `s` is a `Char*` or an array of `Char` `[boost::begin(x),boost::end(x))` otherwise
+        ]
+        [
+            linear time for pointers to a string or arrays of `Char`, constant time otherwise
+        ]
+    ]
+    [
+        [`as_array(x)`]
+        [`iterator_range<X>`]
+        [`[boost::begin(x),boost::end(x))`]
+    ]
+]
+
+The special `const_`-named functions are useful when you want to document clearly that your code is read-only.
+
+`as_literal()` can be used ['*internally*] in string algorithm libraries such that arrays of characters are handled correctly.
+
+`as_array()` can be used with string algorithm libraries to make it clear that arrays of characters are handled like an array and not like a string.
+
+Notice that the above functions should always be called with qualification (`boost::`) to prevent ['*unintended*] Argument Dependent Lookup (ADL).
+
+[endsect]
+
+[endsect]
+
+
diff --git a/doc/reference/synopsis.qbk b/doc/reference/synopsis.qbk
new file mode 100644
index 0000000..26f9641
--- /dev/null
+++ b/doc/reference/synopsis.qbk
@@ -0,0 +1,144 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:synopsis Synopsis]
+
+``
+namespace boost
+{
+    //
+    // Single Pass Range metafunctions
+    //
+
+    template< class T, class Enabler=void >
+    struct range_iterator;
+
+    template< class T >
+    struct range_value;
+
+    template< class T >
+    struct range_reference;
+
+    template< class T >
+    struct range_pointer;
+
+    template< class T >
+    struct range_category;
+
+    //
+    // Forward Range metafunctions
+    //
+
+    template< class T >
+    struct range_difference;
+
+    //
+    // Bidirectional Range metafunctions
+    //
+
+    template< class T >
+    struct range_reverse_iterator;
+
+    //
+    // Single Pass Range functions
+    //
+
+    template< class T >
+    typename range_iterator<T>::type
+    begin( T& r );
+
+    template< class T >
+    typename range_iterator<const T>::type
+    begin( const T& r );
+
+    template< class T >
+    typename range_iterator<T>::type
+    end( T& r );
+
+    template< class T >
+    typename range_iterator<const T>::type
+    end( const T& r );
+
+    template< class T >
+    bool
+    empty( const T& r );
+
+    //
+    // Forward Range functions
+    //
+
+    template< class T >
+    typename range_difference<T>::type
+    distance( const T& r );
+
+    template< class T >
+    typename range_size<T>::type
+    size( const T& r );
+
+    //
+    // Bidirectional Range functions
+    //
+
+    template< class T >
+    typename range_reverse_iterator<T>::type
+    rbegin( T& r );
+
+    template< class T >
+    typename range_reverse_iterator<const T>::type
+    rbegin( const T& r );
+
+    template< class T >
+    typename range_reverse_iterator<T>::type
+    rend( T& r );
+
+    template< class T >
+    typename range_reverse_iterator<const T>::type
+    rend( const T& r );
+
+    //
+    // Special const Range functions
+    //
+
+    template< class T >
+    typename range_iterator<const T>::type
+    const_begin( const T& r );
+
+    template< class T >
+    typename range_iterator<const T>::type
+    const_end( const T& r );
+
+    template< class T >
+    typename range_reverse_iterator<const T>::type
+    const_rbegin( const T& r );
+
+    template< class T >
+    typename range_reverse_iterator<const T>::type
+    const_rend( const T& r );
+
+    //
+    // String utilities
+    //
+
+    template< class T >
+    iterator_range< ... see below ... >
+    as_literal( T& r );
+
+    template< class T >
+    iterator_range< ... see below ... >
+    as_literal( const T& r );
+
+    template< class T >
+    iterator_range< typename range_iterator<T>::type >
+    as_array( T& r );
+
+    template< class T >
+    iterator_range< typename range_iterator<const T>::type >
+    as_array( const T& r );
+
+} // namespace 'boost'
+``
+
+[endsect]
+
diff --git a/doc/reference/utilities.qbk b/doc/reference/utilities.qbk
new file mode 100644
index 0000000..8cbc34a
--- /dev/null
+++ b/doc/reference/utilities.qbk
@@ -0,0 +1,417 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:utilities Utilities]
+
+Having an abstraction that encapsulates a pair of iterators is very useful. The standard library uses `std::pair` in some circumstances, but that class is cumbersome to use because we need to specify two template arguments, and for all range algorithm purposes we must enforce the two template arguments to be the same. Moreover, `std::pair<iterator,iterator>` is hardly self-documenting whereas more domain specific class names are. Therefore these two classes are provided:
+
+* Class `iterator_range`
+* Class `sub_range`
+* Function `combine`
+* Function `join`
+
+The `iterator_range` class is templated on an __forward_traversal_iterator__ and should be used whenever fairly general code is needed. The `sub_range` class is templated on an __forward_range__ and it is less general, but a bit easier to use since its template argument is easier to specify. The biggest difference is, however, that a `sub_range` can propagate constness because it knows what a corresponding `const_iterator` is.
+
+Both classes can be used as ranges since they implement the __minimal_interface__ required for this to work automatically.
+
+[section:iterator_range Class `iterator_range`]
+
+The intention of the `iterator_range` class is to encapsulate two iterators so they fulfill the __forward_range__ concept. A few other functions are also provided for convenience.
+
+If the template argument is not a model of __forward_traversal_iterator__, one can still use a subset of the interface. In particular, `size()` requires Random Access Traversal Iterators whereas `empty()` only requires Single Pass Iterators.
+
+Recall that many default constructed iterators are [*/singular/] and hence can only be assigned, but not compared or incremented or anything. However, if one creates a default constructed `iterator_range`, then one can still call all its member functions. This design decision avoids the `iterator_range` imposing limitations upon ranges of iterators that are not singular. Any singularity limitation is simply propagated from the underlying iterator type.
+
+
+[h4 Synopsis]
+
+The core functionality is in the header file
+`<boost/range/iterator_range_core.hpp>` this includes all of the functionality
+except the `boost::hash_value` and `std::iostream` support.
+
+The `std::iostream` support is in the header `<boost/range/iterator_core.hpp>`
+while the `boost::hash_value` support is in
+`<boost/range/iterator_range_hash.hpp>`
+
+``
+namespace boost
+{
+    template< class ForwardTraversalIterator >
+    class iterator_range
+    {
+    public: // Forward Range types
+        typedef ForwardTraversalIterator   iterator;
+        typedef ForwardTraversalIterator   const_iterator;
+        typedef iterator_difference<iterator>::type difference_type;
+
+    public: // construction, assignment
+        template< class ForwardTraversalIterator2 >
+        iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
+
+        template< class ForwardRange >
+        iterator_range( ForwardRange& r );
+
+        template< class ForwardRange >
+        iterator_range( const ForwardRange& r );
+
+        template< class ForwardRange >
+        iterator_range& operator=( ForwardRange& r );
+
+        template< class ForwardRange >
+        iterator_range& operator=( const ForwardRange& r );
+
+    public: // Forward Range functions
+        iterator  begin() const;
+        iterator  end() const;
+
+    public: // convenience
+        operator    unspecified_bool_type() const;
+        bool        equal( const iterator_range& ) const;
+        value_type& front() const;
+        void        drop_front();
+        void        drop_front(difference_type n);
+        bool      empty() const;
+
+        iterator_range& advance_begin(difference_type n);
+        iterator_range& advance_end(difference_type n);
+
+        // for Bidirectional:
+        value_type& back() const;
+        void drop_back();
+        void drop_back(difference_type n);
+        // for Random Access only:
+        reference operator[]( difference_type at ) const;
+        value_type operator()( difference_type at ) const;
+        size_type size() const;
+    };
+
+    // stream output
+    template< class ForwardTraversalIterator, class T, class Traits >
+    std::basic_ostream<T,Traits>&
+    operator<<( std::basic_ostream<T,Traits>& Os,
+                const iterator_range<ForwardTraversalIterator>& r );
+
+    // comparison
+    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
+    bool operator==( const iterator_range<ForwardTraversalIterator>& l,
+                     const iterator_range<ForwardTraversalIterator2>& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator==( const iterator_range<ForwardTraversalIterator>& l,
+                     const ForwardRange& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator==( const ForwardRange& l,
+                     const iterator_range<ForwardTraversalIterator>& r );
+
+    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
+    bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
+                     const iterator_range<ForwardTraversalIterator2>& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
+                     const ForwardRange& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator!=( const ForwardRange& l,
+                     const iterator_range<ForwardTraversalIterator>& r );
+
+    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
+    bool operator<( const iterator_range<ForwardTraversalIterator>& l,
+                    const iterator_range<ForwardTraversalIterator2>& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator<( const iterator_range<ForwardTraversalIterator>& l,
+                    const ForwardRange& r );
+
+    template< class ForwardTraversalIterator, class ForwardRange >
+    bool operator<( const ForwardRange& l,
+                    const iterator_range<ForwardTraversalIterator>& r );
+
+    // external construction
+    template< class ForwardTraversalIterator >
+    iterator_range< ForwardTraversalIterator >
+    make_iterator_range( ForwardTraversalIterator Begin,
+                         ForwardTraversalIterator End );
+
+    // Make an iterator_range [first, boost::next(first, n) )
+    template< class ForwardTraversalIterator, class Integer >
+    iterator_range< ForwardTraversalIterator >
+    make_iterator_range_n( ForwardTraversalIterator first, Integer n );
+
+
+    template< class ForwardRange >
+    iterator_range< typename range_iterator<ForwardRange>::type >
+    make_iterator_range( ForwardRange& r );
+
+    template< class ForwardRange >
+    iterator_range< typename range_iterator<const ForwardRange>::type >
+    make_iterator_range( const ForwardRange& r );
+
+    template< class Range >
+    iterator_range< typename range_iterator<Range>::type >
+    make_iterator_range( Range& r,
+                         typename range_difference<Range>::type advance_begin,
+                         typename range_difference<Range>::type advance_end );
+
+    template< class Range >
+    iterator_range< typename range_iterator<const Range>::type >
+    make_iterator_range( const Range& r,
+                         typename range_difference<const Range>::type advance_begin,
+                         typename range_difference<const Range>::type advance_end );
+
+    // convenience
+    template< class Sequence, class ForwardRange >
+    Sequence copy_range( const ForwardRange& r );
+
+} // namespace 'boost'
+``
+
+If an instance of `iterator_range` is constructed by a client with two iterators, the client must ensure that the two iterators delimit a valid closed-open range [begin,end).
+
+It is worth noticing that the templated constructors and assignment operators allow conversion from `iterator_range<iterator>` to `iterator_range<const_iterator>`. Similarly, since the comparison operators have two template arguments, we can compare ranges whenever the iterators are comparable; for example when we are dealing with const and non-const iterators from the same container.
+
+[h4 Details member functions]
+
+`operator unspecified_bool_type() const;`
+
+[:['[*Returns]] `!empty();`]
+
+`bool equal( iterator_range& r ) const;`
+
+[:['[*Returns]] `begin() == r.begin() && end() == r.end();`]
+
+[h4 Details functions]
+
+`bool operator==( const ForwardRange1& l, const ForwardRange2& r );`
+
+[:['[*Returns]] `size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );`]
+
+`bool operator!=( const ForwardRange1& l, const ForwardRange2& r );`
+
+[:['[*Returns]] `!( l == r );`]
+
+`bool operator<( const ForwardRange1& l, const ForwardRange2& r );`
+
+[:['[*Returns]] `std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );`]
+
+``
+iterator_range make_iterator_range( Range& r,
+                                    typename range_difference<Range>::type advance_begin,
+                                    typename range_difference<Range>::type advance_end );
+``
+
+[:['[*Effects:]]]
+
+``
+    iterator new_begin = begin( r ),
+    iterator new_end   = end( r );
+    std::advance( new_begin, advance_begin );
+    std::advance( new_end, advance_end );
+    return make_iterator_range( new_begin, new_end );
+``
+
+`Sequence copy_range( const ForwardRange& r );`
+
+[:['[*Returns]] `Sequence( begin(r), end(r) );`]
+
+[endsect]
+
+[section:sub_range Class `sub_range`]
+
+The `sub_range` class inherits all its functionality from the __iterator_range__ class. The `sub_range` class is often easier to use because one must specify the __forward_range__ template argument instead of an iterator. Moreover, the `sub_range` class can propagate constness since it knows what a corresponding `const_iterator` is.
+
+[h4 Synopsis]
+
+``
+namespace boost
+{
+    template< class ForwardRange >
+    class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
+    {
+    public:
+        typedef typename range_value<ForwardRange>::type value_type;
+        typedef typename range_iterator<ForwardRange>::type iterator;
+        typedef typename range_iterator<const ForwardRange>::type  const_iterator;
+        typedef typename range_difference<ForwardRange>::type difference_type;
+        typedef typename range_size<ForwardRange>::type size_type;
+        typedef typename range_reference<ForwardRange>::type reference;
+        typedef typename range_reference<const ForwardRange>::type const_reference;
+
+    public: // construction, assignment
+        sub_range();
+
+        template< class ForwardTraversalIterator >
+        sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
+
+        template< class ForwardRange2 >
+        sub_range( ForwardRange2& r );
+
+        template< class ForwardRange2 >
+        sub_range( const Range2& r );
+
+        template< class ForwardRange2 >
+        sub_range& operator=( ForwardRange2& r );
+
+        template< class ForwardRange2 >
+        sub_range& operator=( const ForwardRange2& r );
+
+        // iterator accessors
+        const_iterator begin() const;
+        iterator begin();
+        const_iterator end() const;
+        iterator end();
+
+        reference front();
+        const_reference front() const;
+
+        sub_range& advance_begin(difference_type n);
+        sub_range& advance_end(difference_type n);
+
+        // If traversal >= bidirectional:
+        reference back();
+        const_reference back();
+
+        // If traversal >= random-access:
+        reference operator[](difference_type n);
+        const_reference operator[](difference_type n) const;
+
+    public:
+        // rest of interface inherited from iterator_range
+    };
+
+} // namespace 'boost'
+``
+
+The class should be trivial to use as seen below. Imagine that we have an algorithm that searches for a sub-string in a string. The result is an iterator_range, that delimits the match. We need to store the result from this algorithm. Here is an example of how we can do it with and without `sub_range`
+
+``
+std::string str("hello");
+iterator_range<std::string::iterator> ir = find_first( str, "ll" );
+sub_range<std::string>               sub = find_first( str, "ll" );
+``
+
+[endsect]
+
+[section:combine Function combine]
+
+The `combine` function is used to make one range from multiple ranges. The
+`combine` function returns a `combined_range` which is an `iterator_range` of
+a `zip_iterator` from the Boost.Iterator library.
+
+[h4 Synopsis]
+
+``
+namespace boost
+{
+    namespace range
+    {
+
+template<typename IterTuple>
+class combined_range
+    : public iterator_range<zip_iterator<IterTuple> >
+{
+public:
+    combined_range(IterTuple first, IterTuple last);
+};
+
+template<typename... Ranges>
+auto combine(Ranges&&... rngs) ->
+    combined_range<decltype(boost::make_tuple(boost::begin(rngs)...))>
+
+    } // namespace range
+} // namespace boost
+``
+
+* [*Precondition:] For each type `r` in `Ranges`, `r` is a model of
+__single_pass_range__ or better.
+* [*Return Type:] `combined_range<tuple<typename range_iterator<Ranges>::type...> >`
+* [*Returned Range Category:] The minimum of the range category of every range
+`r` in `Ranges`.
+
+[h4 Example]
+
+``
+#include <boost/range/combine.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <vector>
+#include <list>
+
+int main(int, const char*[])
+{
+    std::vector<int> v;
+    std::list<char> l;
+    for (int i = 0; i < 5; ++i)
+    {
+        v.push_back(i);
+        l.push_back(static_cast<char>(i) + 'a');
+    }
+
+    int ti;
+    char tc;
+    BOOST_FOREACH(boost::tie(ti, tc), boost::combine(v, l))
+    {
+        std::cout << '(' << ti << ',' << tv << ')' << '\n';
+    }
+
+    return 0;
+}
+``
+
+This produces the output:
+``
+(0,a)
+(1,b)
+(2,c)
+(3,d)
+(4,e)
+``
+
+[endsect]
+
+[section:join Function join]
+
+The intention of the `join` function is to join two ranges into one longer range.
+
+The resultant range will have the lowest common traversal of the two ranges supplied as parameters.
+
+Note that the joined range incurs a performance cost due to the need to check if the end of a range has been reached internally during traversal.
+
+[h4 Synopsis]
+
+``
+template<typename SinglePassRange1, typename SinglePassRange2>
+joined_range<const SinglePassRange1, const SinglePassRange2>
+join(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
+
+template<typename SinglePassRange1, typename SinglePassRange2>
+joined_range<SinglePassRange1, SinglePassRange2>
+join(SinglePassRange1& rng1, SinglePassRange2& rng2);
+``
+
+For the const version:
+
+* [*Precondition:] The `range_value<SinglePassRange2>::type` must be convertible to `range_value<SinglePassRange1>::type`. The `range_reference<const SinglePassRange2>::type` must be convertible to `range_reference<const SinglePassRange1>::type`.
+* [*Range Category:] Both `rng1` and `rng2` must be a model of __single_pass_range__ or better.
+* [*Range Return Type:] `joined_range<const SinglePassRange1, const SinglePassRange2>` which is a model of the lesser of the two range concepts passed.
+* [*Returned Range Category:] The minimum of the range category of `rng1` and `rng2`.
+
+For the mutable version:
+
+* [*Precondition:] The `range_value<SinglePassRange2>::type` must be convertible to `range_value<SinglePassRange1>::type`. The `range_reference<SinglePassRange2>::type` must be convertible to `range_reference<SinglePassRange1>::type`.
+* [*Range Category:] Both `rng1` and `rng2` must be a model of __single_pass_range__ or better.
+* [*Range Return Type:] `joined_range<SinglePassRange1, SinglePassRange2>` which is a model of the lesser of the two range concepts passed.
+* [*Returned Range Category:] The minimum of the range category of `rng1` and `rng2`.
+
+[h4 Example]
+
+The expression `join(irange(0,5), irange(5,10))` would evaluate to a range representing an integer range `[0,10)`
+
+
+[endsect]
+
+[endsect]
+
diff --git a/doc/style.qbk b/doc/style.qbk
new file mode 100644
index 0000000..2074ba6
--- /dev/null
+++ b/doc/style.qbk
@@ -0,0 +1,50 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:style_guide Terminology and style guidelines]
+
+The use of a consistent terminology is as important for __ranges__ and range-based algorithms as it is for iterators and iterator-based algorithms. If a conventional set of names are adopted, we can avoid misunderstandings and write generic function prototypes that are [*/self-documenting/].
+
+Since ranges are characterized by a specific underlying iterator type, we get a type of range for each type of iterator. Hence we can speak of the following types of ranges:
+
+* [*/Value access/] category:
+  * Readable Range
+  * Writeable Range
+  * Swappable Range
+  * Lvalue Range
+* [*/Traversal/] category:
+  * __single_pass_range__
+  * __forward_range__
+  * __bidirectional_range__
+  * __random_access_range__
+
+Notice how we have used the categories from the __new_style_iterators__.
+
+Notice that an iterator (and therefore an range) has one [*/traversal/] property and one or more properties from the [*/value access/] category. So in reality we will mostly talk about mixtures such as
+
+* Random Access Readable Writeable Range
+* Forward Lvalue Range
+
+By convention, we should always specify the [*/traversal/] property first as done above. This seems reasonable since there will only be one [*/traversal/] property, but perhaps many [*/value access/] properties.
+
+It might, however, be reasonable to specify only one category if the other category does not matter. For example, the __iterator_range__ can be constructed from a Forward Range. This means that we do not care about what [*/value access/] properties the Range has. Similarly, a Readable Range will be one that has the lowest possible [*/traversal/] property (Single Pass).
+
+As another example, consider how we specify the interface of `std::sort()`. Algorithms are usually more cumbersome to specify the interface of since both [*/traversal/] and [*/value access/] properties must be exactly defined. The iterator-based version looks like this:
+
+``
+   template< class RandomAccessTraversalReadableWritableIterator >
+   void sort( RandomAccessTraversalReadableWritableIterator first,
+              RandomAccessTraversalReadableWritableIterator last );
+``
+
+For ranges the interface becomes
+
+``
+   template< class RandomAccessReadableWritableRange >
+   void sort( RandomAccessReadableWritableRange& r );
+``
+
+[endsect]
+
diff --git a/doc/upgrade.qbk b/doc/upgrade.qbk
new file mode 100644
index 0000000..47fa8cb
--- /dev/null
+++ b/doc/upgrade.qbk
@@ -0,0 +1,67 @@
+[/
+    Copyright 2010 Neil Groves
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+/]
+[section:upgrade Upgrade version of Boost.Range]
+
+[section:upgrade_from_1_55 Upgrade from version 1.55]
+# __iterator_range__ is now implemented by implementing the member functions
+`size()`, `operator[]` via inheritance of base-classes specialized by the
+traversal type of the underlying iterator. This is normally requires no
+alteration of code. It does mean that types that derive from iterator_range may
+need to prefix `this->` to the various member functions. Additionally it has
+been noted that some calling code was relying on member functions such as
+`size()` being present despite the underlying iterators not being random-access
+due to `iterator_reference<Iter>::type` not being a reference. The suggested
+refactoring is to use `boost::size(rng)`.
+# The undocumented __iterator_range__ `pop_front()` has been deprecated and is
+replaced by `drop_front(). Similarly `pop_back()` has been replaced by
+`drop_back()`.
+
+[endsect]
+
+[section:upgrade_from_1_49 Upgrade from version 1.49]
+
+# __size__ now returns the type Rng::size_type if the range has size_type;
+otherwise range_size<Rng>::type is used. This is the distance type promoted to
+an unsigned type.
+
+[endsect]
+
+[section:upgrade_from_1_45 Upgrade from version 1.45]
+
+# __size__ in addition to supporting __random_access_range__ now also supports extensibility via calls to the unqualified `range_calculate_size(rng)` function.
+# __range_adaptors_strided__ now in addition to working with any RandomAccessRange additionally works for any SinglePassRange for which `boost::size(rng)` is valid.
+# __range_adaptors_strided__ no longer requires `distance(rng) % stride_size == 0` or `stride_size < distance(rng)`
+
+[endsect]
+
+[section:upgrade_from_1_42 Upgrade from version 1.42]
+
+New features:
+
+# __range_adaptors__
+# __range_algorithms__
+
+Removed:
+
+# `iterator_range` no longer has a `is_singular` member function. The singularity restrictions have been removed from the `iterator_range` class since this added restrictions to ranges of iterators whose default constructors were not singular. Previously the `is_singular` member function always returned `false` in release build configurations, hence it is not anticipated that this interface change will produce difficulty in upgrading.
+
+
+[endsect]
+
+[section:upgrade_from_1_34 Upgrade from version 1.34]
+
+Boost version 1.35 introduced some larger refactorings of the library:
+
+# Direct support for character arrays was abandoned in favor of uniform treatment of all arrays. Instead string algorithms can use the new function __as_literal__`()`.
+# __size__ now requires a __random_access_range__. The old behavior is provided as __distance__`()`.
+# `range_size<T>::type` has been completely removed in favor of `range_difference<T>::type`
+# `boost_range_begin()` and `boost_range_end()` have been renamed `range_begin()` and `range_end()` respectively.
+# `range_result_iterator<T>::type` and `range_reverse_result_iterator<T>::type` have been renamed `range_iterator<T>::type` and `range_reverse_iterator<T>::type`.
+# The procedure that makes a custom type work with the library has been greatly simplified. See __extending_for_udts__ for details.
+
+[endsect]
+
+[endsect]
diff --git a/include/boost/range.hpp b/include/boost/range.hpp
new file mode 100644
index 0000000..179ae22
--- /dev/null
+++ b/include/boost/range.hpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_HPP_27_07_04
+#define BOOST_RANGE_HPP_27_07_04
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/sub_range.hpp>
+
+#endif
diff --git a/include/boost/range/adaptor/adjacent_filtered.hpp b/include/boost/range/adaptor/adjacent_filtered.hpp
new file mode 100644
index 0000000..405fe7b
--- /dev/null
+++ b/include/boost/range/adaptor/adjacent_filtered.hpp
@@ -0,0 +1,237 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
+#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
+
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+#pragma warning( push )
+#pragma warning( disable : 4355 )
+#endif
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/next_prior.hpp>
+
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class Iter, class Pred, bool default_pass >
+        class skip_iterator
+          : public boost::iterator_adaptor<
+                    skip_iterator<Iter,Pred,default_pass>,
+                    Iter,
+                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
+                    boost::forward_traversal_tag,
+                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
+                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
+                >
+          , private Pred
+        {
+        private:
+            typedef boost::iterator_adaptor<
+                        skip_iterator<Iter,Pred,default_pass>,
+                        Iter,
+                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
+                        boost::forward_traversal_tag,
+                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
+                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
+                    > base_t;
+
+        public:
+            typedef Pred pred_t;
+            typedef Iter iter_t;
+
+            skip_iterator() : m_last() {}
+
+            skip_iterator(iter_t it, iter_t last, const Pred& pred)
+                : base_t(it)
+                , pred_t(pred)
+                , m_last(last)
+            {
+            }
+
+            template<class OtherIter>
+            skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
+            : base_t(other.base())
+            , pred_t(other)
+            , m_last(other.m_last)
+            {
+            }
+
+            void increment()
+            {
+                iter_t& it = this->base_reference();
+                BOOST_ASSERT( it != m_last );
+                pred_t& bi_pred = *this;
+                iter_t prev = it;
+                ++it;
+                if (it != m_last)
+                {
+                    if (default_pass)
+                    {
+                        while (it != m_last && !bi_pred(*prev, *it))
+                        {
+                            ++it;
+                            ++prev;
+                        }
+                    }
+                    else
+                    {
+                        for (; it != m_last; ++it, ++prev)
+                        {
+                            if (bi_pred(*prev, *it))
+                            {
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+
+            iter_t m_last;
+        };
+
+        template< class P, class R, bool default_pass >
+        struct adjacent_filtered_range
+            : iterator_range< skip_iterator<
+                                BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
+                                P,
+                                default_pass
+                            >
+                        >
+        {
+        private:
+            typedef skip_iterator<
+                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
+                        P,
+                        default_pass
+                     >
+                skip_iter;
+
+            typedef iterator_range<skip_iter>
+                base_range;
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
+
+        public:
+            adjacent_filtered_range( const P& p, R& r )
+            : base_range(skip_iter(boost::begin(r), boost::end(r), p),
+                         skip_iter(boost::end(r), boost::end(r), p))
+            {
+            }
+        };
+
+        template< class T >
+        struct adjacent_holder : holder<T>
+        {
+            adjacent_holder( T r ) : holder<T>(r)
+            { }
+        };
+
+        template< class T >
+        struct adjacent_excl_holder : holder<T>
+        {
+            adjacent_excl_holder( T r ) : holder<T>(r)
+            { }
+        };
+
+        template< class ForwardRng, class BinPredicate >
+        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
+        operator|( ForwardRng& r,
+                   const adjacent_holder<BinPredicate>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
+
+            return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
+        }
+
+        template< class ForwardRng, class BinPredicate >
+        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
+        operator|( const ForwardRng& r,
+                   const adjacent_holder<BinPredicate>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
+
+            return adjacent_filtered_range<BinPredicate,
+                                           const ForwardRng, true>( f.val, r );
+        }
+
+        template< class ForwardRng, class BinPredicate >
+        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
+        operator|( ForwardRng& r,
+                   const adjacent_excl_holder<BinPredicate>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
+            return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
+        }
+
+        template< class ForwardRng, class BinPredicate >
+        inline adjacent_filtered_range<BinPredicate, const ForwardRng, false>
+        operator|( const ForwardRng& r,
+                   const adjacent_excl_holder<BinPredicate>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
+            return adjacent_filtered_range<BinPredicate,
+                                           const ForwardRng, false>( f.val, r );
+        }
+
+    } // 'range_detail'
+
+    // Bring adjacent_filter_range into the boost namespace so that users of
+    // this library may specify the return type of the '|' operator and
+    // adjacent_filter()
+    using range_detail::adjacent_filtered_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::forwarder<range_detail::adjacent_holder>
+                adjacent_filtered =
+                   range_detail::forwarder<range_detail::adjacent_holder>();
+
+            const range_detail::forwarder<range_detail::adjacent_excl_holder>
+                adjacent_filtered_excl =
+                    range_detail::forwarder<range_detail::adjacent_excl_holder>();
+        }
+
+        template<class ForwardRng, class BinPredicate>
+        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
+        adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
+            return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
+        }
+
+        template<class ForwardRng, class BinPredicate>
+        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
+        adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
+            return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
+        }
+
+    } // 'adaptors'
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning( pop )
+#endif
+
+#endif
diff --git a/include/boost/range/adaptor/argument_fwd.hpp b/include/boost/range/adaptor/argument_fwd.hpp
new file mode 100644
index 0000000..fbfd40c
--- /dev/null
+++ b/include/boost/range/adaptor/argument_fwd.hpp
@@ -0,0 +1,80 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
+#define BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#endif
+
+namespace boost
+{
+    namespace range_detail
+    {  
+        template< class T >
+        struct holder
+        {
+            T val;
+            holder( T t ) : val(t)
+            { }
+        };
+
+        template< class T >
+        struct holder2
+        {
+            T val1, val2;
+            holder2( T t, T u ) : val1(t), val2(u)
+            { }
+        };
+        
+        template< template<class> class Holder >
+        struct forwarder
+        {
+            template< class T >
+            Holder<T> operator()( T t ) const
+            {
+                return Holder<T>(t);
+            }
+        };
+
+        template< template<class> class Holder >
+        struct forwarder2
+        {
+            template< class T >
+            Holder<T> operator()( T t, T u ) const
+            {
+                return Holder<T>(t,u);
+            }
+        };
+
+        template< template<class,class> class Holder >
+        struct forwarder2TU
+        {
+            template< class T, class U >
+            Holder<T, U> operator()( T t, U u ) const
+            {
+                return Holder<T, U>(t, u);
+            }
+        };
+
+
+    } 
+        
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/boost/range/adaptor/copied.hpp b/include/boost/range/adaptor/copied.hpp
new file mode 100644
index 0000000..f7dfbcd
--- /dev/null
+++ b/include/boost/range/adaptor/copied.hpp
@@ -0,0 +1,68 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_COPIED_HPP
+#define BOOST_RANGE_ADAPTOR_COPIED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+
+namespace boost
+{
+    namespace adaptors
+    {
+        struct copied
+        {
+            copied(std::size_t t_, std::size_t u_)
+                : t(t_), u(u_) {}
+
+            std::size_t t;
+            std::size_t u;
+        };
+
+        template<class CopyableRandomAccessRange>
+        inline CopyableRandomAccessRange
+        operator|(const CopyableRandomAccessRange& r, const copied& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<const CopyableRandomAccessRange>));
+
+            iterator_range<
+                BOOST_DEDUCED_TYPENAME range_iterator<
+                    const CopyableRandomAccessRange
+                >::type
+            > temp(adaptors::slice(r, f.t, f.u));
+
+            return CopyableRandomAccessRange(temp.begin(), temp.end());
+        }
+
+        template<class CopyableRandomAccessRange>
+        inline CopyableRandomAccessRange
+        copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<const CopyableRandomAccessRange>));
+
+            iterator_range<
+                BOOST_DEDUCED_TYPENAME range_iterator<
+                    const CopyableRandomAccessRange
+                >::type
+            > temp(adaptors::slice(rng, t, u));
+
+            return CopyableRandomAccessRange( temp.begin(), temp.end() );
+        }
+    } // 'adaptors'
+
+}
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/define_adaptor.hpp b/include/boost/range/adaptor/define_adaptor.hpp
new file mode 100644
index 0000000..b228df3
--- /dev/null
+++ b/include/boost/range/adaptor/define_adaptor.hpp
@@ -0,0 +1,109 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
+#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
+
+#include <boost/tuple/tuple.hpp>
+
+#define BOOST_DEFINE_RANGE_ADAPTOR( adaptor_name, range_adaptor ) \
+    struct adaptor_name##_forwarder {}; \
+    \
+    template<typename Range> range_adaptor <Range> \
+        operator|(Range& rng, adaptor_name##_forwarder) \
+    { \
+        return range_adaptor <Range>( rng ); \
+    } \
+    \
+    template<typename Range> range_adaptor <const Range> \
+        operator|(const Range& rng, adaptor_name##_forwarder) \
+    { \
+        return range_adaptor <const Range>( rng ); \
+    } \
+    \
+    static adaptor_name##_forwarder adaptor_name = adaptor_name##_forwarder(); \
+    \
+    template<typename Range> \
+    range_adaptor <Range> \
+    make_##adaptor_name(Range& rng) \
+    { \
+        return range_adaptor <Range>(rng); \
+    } \
+    \
+    template<typename Range> \
+    range_adaptor <const Range> \
+    make_##adaptor_name(const Range& rng) \
+    { \
+        return range_adaptor <const Range>(rng); \
+    }
+
+#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \
+    struct adaptor_name \
+    { \
+        explicit adaptor_name (arg1_type arg1_) \
+            : arg1(arg1_) {} \
+        arg1_type arg1; \
+    }; \
+    \
+    template<typename Range> range_adaptor <Range> \
+        operator|(Range& rng, adaptor_name args) \
+    { \
+        return range_adaptor <Range>(rng, args.arg1); \
+    } \
+    \
+    template<typename Range> range_adaptor <const Range> \
+        operator|(const Range& rng, adaptor_name args) \
+    { \
+        return range_adaptor <const Range>(rng, args.arg1); \
+    } \
+    \
+    template<typename Range> \
+    range_adaptor <Range> \
+    make_##adaptor_name(Range& rng, arg1_type arg1) \
+    { \
+        return range_adaptor <Range>(rng, arg1); \
+    } \
+    \
+    template<typename Range> \
+    range_adaptor <const Range> \
+    make_##adaptor_name(const Range& rng, arg1_type arg1) \
+    { \
+        return range_adaptor <const Range>(rng, arg1); \
+    }
+
+#define BOOST_RANGE_ADAPTOR_2( adaptor_name, range_adaptor, arg1_type, arg2_type ) \
+    struct adaptor_name \
+    { \
+        explicit adaptor_name (arg1_type arg1_, arg2_type arg2_) \
+            : arg1(arg1_), arg2(arg2_) {} \
+        arg1_type arg1; \
+        arg2_type arg2; \
+    }; \
+    \
+    template<typename Range> range_adaptor <Range> \
+    operator|(Range& rng, adaptor_name args) \
+    { \
+        return range_adaptor <Range>(rng, args.arg1, args.arg2); \
+    } \
+    template<typename Range> \
+    range_adaptor <Range> \
+    make_##adaptor_name(Range& rng, arg1_type arg1, arg2_type arg2) \
+    { \
+        return range_adaptor <Range>(rng, arg1, arg2); \
+    } \
+    template<typename Range> \
+    range_adaptor <const Range> \
+    make_##adaptor_name(const Range& rng, arg1_type arg1, arg2_type arg2) \
+    { \
+        return range_adaptor <const Range>(rng, arg1, arg2); \
+    }
+
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/filtered.hpp b/include/boost/range/adaptor/filtered.hpp
new file mode 100644
index 0000000..1fb778e
--- /dev/null
+++ b/include/boost/range/adaptor/filtered.hpp
@@ -0,0 +1,121 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_FILTERED_HPP
+#define BOOST_RANGE_ADAPTOR_FILTERED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/detail/default_constructible_unary_fn.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class P, class R >
+        struct filtered_range :
+            boost::iterator_range<
+                boost::filter_iterator<
+                    typename default_constructible_unary_fn_gen<P, bool>::type,
+                    typename range_iterator<R>::type
+                >
+            >
+        {
+        private:
+            typedef boost::iterator_range<
+                boost::filter_iterator<
+                    typename default_constructible_unary_fn_gen<P, bool>::type,
+                    typename range_iterator<R>::type
+                >
+            > base;
+        public:
+            typedef typename default_constructible_unary_fn_gen<P, bool>::type
+                pred_t;
+
+            filtered_range(P p, R& r)
+            : base(make_filter_iterator(pred_t(p),
+                                        boost::begin(r), boost::end(r)),
+                   make_filter_iterator(pred_t(p),
+                                        boost::end(r), boost::end(r)))
+            { }
+        };
+
+        template< class T >
+        struct filter_holder : holder<T>
+        {
+            filter_holder( T r ) : holder<T>(r)
+            { }
+        };
+
+        template< class SinglePassRange, class Predicate >
+        inline filtered_range<Predicate, SinglePassRange>
+        operator|(SinglePassRange& r,
+                  const filter_holder<Predicate>& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
+            return filtered_range<Predicate, SinglePassRange>( f.val, r );
+        }
+
+        template< class SinglePassRange, class Predicate >
+        inline filtered_range<Predicate, const SinglePassRange>
+        operator|(const SinglePassRange& r,
+                  const filter_holder<Predicate>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+            return filtered_range<Predicate, const SinglePassRange>( f.val, r );
+        }
+
+    } // 'range_detail'
+
+    // Unusual use of 'using' is intended to bring filter_range into the boost namespace
+    // while leaving the mechanics of the '|' operator in range_detail and maintain
+    // argument dependent lookup.
+    // filter_range logically needs to be in the boost namespace to allow user of
+    // the library to define the return type for filter()
+    using range_detail::filtered_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::forwarder<range_detail::filter_holder>
+                    filtered =
+                       range_detail::forwarder<range_detail::filter_holder>();
+        }
+
+        template<class SinglePassRange, class Predicate>
+        inline filtered_range<Predicate, SinglePassRange>
+        filter(SinglePassRange& rng, Predicate filter_pred)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return range_detail::filtered_range<
+                Predicate, SinglePassRange>( filter_pred, rng );
+        }
+
+        template<class SinglePassRange, class Predicate>
+        inline filtered_range<Predicate, const SinglePassRange>
+        filter(const SinglePassRange& rng, Predicate filter_pred)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return range_detail::filtered_range<
+                Predicate, const SinglePassRange>( filter_pred, rng );
+        }
+    } // 'adaptors'
+
+}
+
+#endif
diff --git a/include/boost/range/adaptor/formatted.hpp b/include/boost/range/adaptor/formatted.hpp
new file mode 100644
index 0000000..f31f1bc
--- /dev/null
+++ b/include/boost/range/adaptor/formatted.hpp
@@ -0,0 +1,229 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/remove_extent.hpp>
+#include <ostream>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<typename Sep, typename Prefix, typename Postfix>
+struct formatted_holder
+{
+    typedef typename boost::mpl::if_<
+        boost::is_array<Sep>,
+        const typename boost::remove_extent<Sep>::type*,
+        Sep
+    >::type separator_t;
+
+    typedef typename boost::mpl::if_<
+        boost::is_array<Prefix>,
+        const typename boost::remove_extent<Prefix>::type*,
+        Prefix
+    >::type prefix_t;
+
+    typedef typename boost::mpl::if_<
+        boost::is_array<Postfix>,
+        const typename boost::remove_extent<Postfix>::type*,
+        Postfix
+    >::type postfix_t;
+
+    formatted_holder(
+        const separator_t& sep,
+        const prefix_t& prefix,
+        const postfix_t& postfix)
+        : m_sep(sep)
+        , m_prefix(prefix)
+        , m_postfix(postfix)
+    {
+    }
+
+    separator_t m_sep;
+    prefix_t m_prefix;
+    postfix_t m_postfix;
+};
+
+template<typename Iter, typename Sep, typename Prefix, typename Postfix>
+class formatted_range
+        : public boost::iterator_range<Iter>
+{
+    typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
+public:
+    formatted_range(Iter first, Iter last, const holder_t& holder)
+        : boost::iterator_range<Iter>(first, last)
+        , m_holder(holder)
+    {
+    }
+
+    template<typename OStream>
+    void write(OStream& out) const
+    {
+        Iter it(this->begin());
+        out << m_holder.m_prefix;
+        if (it != this->end())
+        {
+            out << *it;
+            for (++it; it != this->end(); ++it)
+            {
+                out << m_holder.m_sep << *it;
+            }
+        }
+        out << m_holder.m_postfix;
+    }
+
+private:
+    holder_t m_holder;
+};
+
+template<
+    typename SinglePassRange,
+    typename Sep,
+    typename Prefix,
+    typename Postfix
+>
+inline range_detail::formatted_range<
+    typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
+>
+operator|(
+    const SinglePassRange& rng,
+    const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
+)
+{
+    typedef typename range_iterator<const SinglePassRange>::type iterator;
+    return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
+        boost::begin(rng), boost::end(rng), holder);
+}
+
+template<typename Char, typename Traits, typename Iter, typename Sep,
+    typename Prefix, typename Postfix>
+std::basic_ostream<Char, Traits>&
+operator<<(
+        std::basic_ostream<Char, Traits>& out,
+        const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
+{
+    writer.write(out);
+    return out;
+}
+
+    } // namespace range_detail
+
+    namespace adaptors
+    {
+
+template<typename Sep, typename Prefix, typename Postfix>
+range_detail::formatted_holder<Sep, Prefix, Postfix>
+formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
+{
+    return range_detail::formatted_holder<Sep,Prefix,Postfix>(
+                sep, prefix, postfix);
+}
+
+template<typename Sep, typename Prefix>
+range_detail::formatted_holder<Sep, Prefix, char>
+formatted(const Sep& sep, const Prefix& prefix)
+{
+    return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
+}
+
+template<typename Sep>
+range_detail::formatted_holder<Sep, char, char>
+formatted(const Sep& sep)
+{
+    return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
+}
+
+inline range_detail::formatted_holder<char, char, char>
+formatted()
+{
+    return range_detail::formatted_holder<char, char, char>(',', '{', '}');
+}
+
+using range_detail::formatted_range;
+
+template<typename SinglePassRange, typename Sep, typename Prefix,
+         typename Postfix>
+inline boost::range_detail::formatted_range<
+    typename boost::range_iterator<const SinglePassRange>::type,
+    Sep, Prefix, Postfix
+>
+format(
+    const SinglePassRange& rng,
+    const Sep& sep,
+    const Prefix& prefix,
+    const Postfix& postfix
+)
+{
+    typedef typename boost::range_iterator<const SinglePassRange>::type
+                iterator_t;
+
+    typedef boost::range_detail::formatted_range<
+                iterator_t, Sep, Prefix, Postfix>       result_t;
+
+    typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
+                holder_t;
+
+    return result_t(boost::begin(rng), boost::end(rng),
+                    holder_t(sep, prefix, postfix));
+}
+
+template<typename SinglePassRange, typename Sep, typename Prefix>
+inline boost::range_detail::formatted_range<
+    typename boost::range_iterator<const SinglePassRange>::type,
+    Sep, Prefix, char
+>
+format(
+    const SinglePassRange& rng,
+    const Sep& sep,
+    const Prefix& prefix)
+{
+    return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
+}
+
+template<typename SinglePassRange, typename Sep>
+inline boost::range_detail::formatted_range<
+    typename boost::range_iterator<const SinglePassRange>::type,
+    Sep, char, char
+>
+format(const SinglePassRange& rng, const Sep& sep)
+{
+    return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
+}
+
+template<typename SinglePassRange>
+inline boost::range_detail::formatted_range<
+    typename boost::range_iterator<const SinglePassRange>::type,
+    char, char, char
+>
+format(const SinglePassRange& rng)
+{
+    return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
+}
+
+    } // namespace adaptors
+
+    namespace range
+    {
+        using boost::range_detail::formatted_range;
+    } // namespace range
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/indexed.hpp b/include/boost/range/adaptor/indexed.hpp
new file mode 100644
index 0000000..a426bd6
--- /dev/null
+++ b/include/boost/range/adaptor/indexed.hpp
@@ -0,0 +1,370 @@
+//  Copyright 2014 Neil Groves
+//
+//  Copyright (c) 2010 Ilya Murav'jov
+// 
+//  Use, modification and distribution is subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// Credits:
+//  My (Neil's) first indexed adaptor was hindered by having the underlying
+//  iterator return the same reference as the wrapped iterator. This meant that
+//  to obtain the index one had to get to the index_iterator and call the
+//  index() function on it. Ilya politely pointed out that this was useless in
+//  a number of scenarios since one naturally hides the use of iterators in
+//  good range-based code. Ilya provided a new interface (which has remained)
+//  and a first implementation. Much of this original implementation has
+//  been simplified and now supports more compilers and platforms.
+//
+#ifndef BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/traversal.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+namespace boost
+{
+    namespace adaptors
+    {
+
+struct indexed
+{
+    explicit indexed(std::ptrdiff_t x = 0)
+        : val(x)
+    {
+    }
+    std::ptrdiff_t val;
+};
+
+    } // namespace adaptors
+
+    namespace range
+    {
+
+// Why yet another "pair" class:
+// - std::pair can't store references
+// - no need for typing for index type (default to "std::ptrdiff_t"); this is
+// useful in BOOST_FOREACH() expressions that have pitfalls with commas
+//   ( see http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/pitfalls.html )
+// - meaningful access functions index(), value()
+template<class T, class Indexable = std::ptrdiff_t>
+class index_value
+    : public tuple<Indexable, T>
+{
+    typedef tuple<Indexable, T> base_t;
+
+    template<int N>
+    struct iv_types
+    {
+        typedef typename tuples::element<N, base_t>::type n_type;
+
+        typedef typename tuples::access_traits<n_type>::non_const_type non_const_type;
+        typedef typename tuples::access_traits<n_type>::const_type const_type;
+    };
+
+public:
+    typedef typename iv_types<0>::non_const_type index_type;
+    typedef typename iv_types<0>::const_type const_index_type;
+    typedef typename iv_types<1>::non_const_type value_type;
+    typedef typename iv_types<1>::const_type const_value_type;
+
+    index_value()
+    {
+    }
+
+    index_value(typename tuples::access_traits<Indexable>::parameter_type t0,
+                typename tuples::access_traits<T>::parameter_type t1)
+        : base_t(t0, t1)
+    {
+    }
+
+    // member functions index(), value() (non-const and const)
+    index_type index()
+    {
+        return boost::tuples::get<0>(*this);
+    }
+
+    const_index_type index() const
+    {
+        return boost::tuples::get<0>(*this);
+    }
+
+    value_type value()
+    {
+        return boost::tuples::get<1>(*this);
+    }
+
+    const_value_type value() const
+    {
+        return boost::tuples::get<1>(*this);
+    }
+};
+
+    } // namespace range
+
+namespace range_detail
+{
+
+template<typename Iter>
+struct indexed_iterator_value_type
+{
+    typedef ::boost::range::index_value<
+        typename iterator_reference<Iter>::type,
+        typename iterator_difference<Iter>::type
+    > type;
+};
+
+// Meta-function to get the traversal for the range and therefore iterator
+// returned by the indexed adaptor for a specified iterator type.
+//
+// Random access -> Random access
+// Bidirectional -> Forward
+// Forward -> Forward
+// SinglePass -> SinglePass
+//
+// The rationale for demoting a Bidirectional input to Forward is that the end
+// iterator cannot cheaply have an index computed for it. Therefore I chose to
+// demote to forward traversal. I can maintain the ability to traverse randomly
+// when the input is Random Access since the index for the end iterator is cheap
+// to compute.
+template<typename Iter>
+struct indexed_traversal
+{
+private:
+    typedef typename iterator_traversal<Iter>::type wrapped_traversal;
+
+public:
+
+    typedef typename mpl::if_<
+        is_convertible<wrapped_traversal, random_access_traversal_tag>,
+        random_access_traversal_tag,
+        typename mpl::if_<
+            is_convertible<wrapped_traversal, bidirectional_traversal_tag>,
+            forward_traversal_tag,
+            wrapped_traversal
+        >::type
+    >::type type;
+};
+
+template<typename Iter>
+class indexed_iterator
+    : public iterator_facade<
+            indexed_iterator<Iter>,
+            typename indexed_iterator_value_type<Iter>::type,
+            typename indexed_traversal<Iter>::type,
+            typename indexed_iterator_value_type<Iter>::type,
+            typename iterator_difference<Iter>::type
+        >
+{
+public:
+    typedef Iter wrapped;
+
+private:
+    typedef iterator_facade<
+        indexed_iterator<wrapped>,
+        typename indexed_iterator_value_type<wrapped>::type,
+        typename indexed_traversal<wrapped>::type,
+        typename indexed_iterator_value_type<wrapped>::type,
+        typename iterator_difference<wrapped>::type
+    > base_t;
+
+public:
+    typedef typename base_t::difference_type difference_type;
+    typedef typename base_t::reference reference;
+    typedef typename base_t::difference_type index_type;
+
+    indexed_iterator()
+        : m_it()
+        , m_index()
+    {
+    }
+
+    template<typename OtherWrapped>
+    indexed_iterator(
+        const indexed_iterator<OtherWrapped>& other,
+        typename enable_if<is_convertible<OtherWrapped, wrapped> >::type* = 0
+    )
+        : m_it(other.get())
+        , m_index(other.get_index())
+    {
+    }
+
+    explicit indexed_iterator(wrapped it, index_type index)
+        : m_it(it)
+        , m_index(index)
+    {
+    }
+
+    wrapped get() const
+    {
+        return m_it;
+    }
+
+    index_type get_index() const
+    {
+        return m_index;
+    }
+
+ private:
+    friend class boost::iterator_core_access;
+
+    reference dereference() const
+    {
+        return reference(m_index, *m_it);
+    }
+
+    bool equal(const indexed_iterator& other) const
+    {
+        return m_it == other.m_it;
+    }
+
+    void increment()
+    {
+        ++m_index;
+        ++m_it;
+    }
+
+    void decrement()
+    {
+        BOOST_ASSERT_MSG(m_index > 0, "indexed Iterator out of bounds");
+        --m_index;
+        --m_it;
+    }
+
+    void advance(index_type n)
+    {
+        m_index += n;
+        BOOST_ASSERT_MSG(m_index >= 0, "indexed Iterator out of bounds");
+        m_it += n;
+    }
+
+    difference_type distance_to(const indexed_iterator& other) const
+    {
+        return other.m_it - m_it;
+    }
+
+    wrapped m_it;
+    index_type m_index;
+};
+
+template<typename SinglePassRange>
+struct indexed_range
+    : iterator_range<
+        indexed_iterator<
+            typename range_iterator<SinglePassRange>::type
+        >
+    >
+{
+    typedef iterator_range<
+        indexed_iterator<
+            typename range_iterator<SinglePassRange>::type
+        >
+    > base_t;
+
+    BOOST_RANGE_CONCEPT_ASSERT((
+        boost::SinglePassRangeConcept<SinglePassRange>));
+public:
+    typedef indexed_iterator<
+        typename range_iterator<SinglePassRange>::type
+    > iterator;
+
+    // Constructor for non-random access iterators.
+    // This sets the end iterator index to i despite this being incorrect it
+    // is never observable since bidirectional iterators are demoted to
+    // forward iterators.
+    indexed_range(
+        typename base_t::difference_type i,
+        SinglePassRange& r,
+        single_pass_traversal_tag
+        )
+        : base_t(iterator(boost::begin(r), i),
+                 iterator(boost::end(r), i))
+    {
+    }
+
+    indexed_range(
+        typename base_t::difference_type i,
+        SinglePassRange& r,
+        random_access_traversal_tag
+        )
+        : base_t(iterator(boost::begin(r), i),
+                 iterator(boost::end(r), i + boost::size(r)))
+    {
+    }
+};
+
+    } // namespace range_detail 
+
+    using range_detail::indexed_range;
+
+    namespace adaptors
+    {
+
+template<class SinglePassRange>
+inline indexed_range<SinglePassRange>
+operator|(SinglePassRange& r, indexed e)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((
+        boost::SinglePassRangeConcept<SinglePassRange>
+    ));
+    return indexed_range<SinglePassRange>(
+                e.val, r,
+                typename range_traversal<SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<const SinglePassRange>
+operator|(const SinglePassRange& r, indexed e)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((
+        boost::SinglePassRangeConcept<const SinglePassRange>
+    ));
+    return indexed_range<const SinglePassRange>(
+                e.val, r,
+                typename range_traversal<const SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<SinglePassRange>
+index(
+    SinglePassRange& rng,
+    typename range_difference<SinglePassRange>::type index_value = 0)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((
+        boost::SinglePassRangeConcept<SinglePassRange>
+    ));
+    return indexed_range<SinglePassRange>(
+                index_value, rng,
+                typename range_traversal<SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<const SinglePassRange>
+index(
+    const SinglePassRange& rng,
+    typename range_difference<const SinglePassRange>::type index_value = 0)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((
+        boost::SinglePassRangeConcept<SinglePassRange>
+    ));
+    return indexed_range<const SinglePassRange>(
+                index_value, rng,
+                typename range_traversal<const SinglePassRange>::type());
+}
+
+    } // namespace adaptors
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/indirected.hpp b/include/boost/range/adaptor/indirected.hpp
new file mode 100644
index 0000000..e741f17
--- /dev/null
+++ b/include/boost/range/adaptor/indirected.hpp
@@ -0,0 +1,100 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
+#define BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class R >
+        struct indirected_range :
+            public boost::iterator_range<
+                        boost::indirect_iterator<
+                            BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+                        >
+                    >
+        {
+        private:
+            typedef boost::iterator_range<
+                        boost::indirect_iterator<
+                            BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+                        >
+                    >
+                base;
+
+        public:
+            explicit indirected_range( R& r )
+                : base( r )
+            { }
+        };
+
+        struct indirect_forwarder {};
+
+        template< class SinglePassRange >
+        inline indirected_range<SinglePassRange>
+        operator|( SinglePassRange& r, indirect_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return indirected_range<SinglePassRange>( r );
+        }
+
+        template< class SinglePassRange >
+        inline indirected_range<const SinglePassRange>
+        operator|( const SinglePassRange& r, indirect_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return indirected_range<const SinglePassRange>( r );
+        }
+
+    } // 'range_detail'
+
+    using range_detail::indirected_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::indirect_forwarder indirected =
+                                            range_detail::indirect_forwarder();
+        }
+
+        template<class SinglePassRange>
+        inline indirected_range<SinglePassRange>
+        indirect(SinglePassRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+            return indirected_range<SinglePassRange>(rng);
+        }
+
+        template<class SinglePassRange>
+        inline indirected_range<const SinglePassRange>
+        indirect(const SinglePassRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return indirected_range<const SinglePassRange>(rng);
+        }
+    } // 'adaptors'
+
+}
+
+#endif
diff --git a/include/boost/range/adaptor/map.hpp b/include/boost/range/adaptor/map.hpp
new file mode 100644
index 0000000..2d922ea
--- /dev/null
+++ b/include/boost/range/adaptor/map.hpp
@@ -0,0 +1,204 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_MAP_HPP
+#define BOOST_RANGE_ADAPTOR_MAP_HPP
+
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/concepts.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        struct map_keys_forwarder {};
+        struct map_values_forwarder {};
+
+        template< class Map >
+        struct select_first
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
+            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.first;
+            }
+        };
+
+        template< class Map >
+        struct select_second_mutable
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type;
+            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.second;
+            }
+        };
+
+        template< class Map >
+        struct select_second_const
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
+            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.second;
+            }
+        };
+
+        template<class StdPairRng>
+        class select_first_range
+            : public transformed_range<
+                        select_first<StdPairRng>,
+                        const StdPairRng>
+        {
+            typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base;
+        public:
+            typedef select_first<StdPairRng> transform_fn_type;
+            typedef const StdPairRng source_range_type;
+
+            select_first_range(transform_fn_type fn, source_range_type& rng)
+                : base(fn, rng)
+            {
+            }
+
+            select_first_range(const base& other) : base(other) {}
+        };
+
+        template<class StdPairRng>
+        class select_second_mutable_range
+            : public transformed_range<
+                        select_second_mutable<StdPairRng>,
+                        StdPairRng>
+        {
+            typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base;
+        public:
+            typedef select_second_mutable<StdPairRng> transform_fn_type;
+            typedef StdPairRng source_range_type;
+
+            select_second_mutable_range(transform_fn_type fn, source_range_type& rng)
+                : base(fn, rng)
+            {
+            }
+
+            select_second_mutable_range(const base& other) : base(other) {}
+        };
+
+        template<class StdPairRng>
+        class select_second_const_range
+            : public transformed_range<
+                        select_second_const<StdPairRng>,
+                        const StdPairRng>
+        {
+            typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base;
+        public:
+            typedef select_second_const<StdPairRng> transform_fn_type;
+            typedef const StdPairRng source_range_type;
+
+            select_second_const_range(transform_fn_type fn, source_range_type& rng)
+                : base(fn, rng)
+            {
+            }
+
+            select_second_const_range(const base& other) : base(other) {}
+        };
+
+        template< class StdPairRng >
+        inline select_first_range<StdPairRng>
+        operator|( const StdPairRng& r, map_keys_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const StdPairRng>));
+
+            return operator|( r,
+                boost::adaptors::transformed( select_first<StdPairRng>() ) );
+        }
+
+        template< class StdPairRng >
+        inline select_second_mutable_range<StdPairRng>
+        operator|( StdPairRng& r, map_values_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRng>));
+
+            return operator|( r,
+                boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
+        }
+
+        template< class StdPairRng >
+        inline select_second_const_range<StdPairRng>
+        operator|( const StdPairRng& r, map_values_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const StdPairRng>));
+
+            return operator|( r,
+                boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
+        }
+
+    } // 'range_detail'
+
+    using range_detail::select_first_range;
+    using range_detail::select_second_mutable_range;
+    using range_detail::select_second_const_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::map_keys_forwarder map_keys =
+                                            range_detail::map_keys_forwarder();
+
+            const range_detail::map_values_forwarder map_values =
+                                           range_detail::map_values_forwarder();
+        }
+
+        template<class StdPairRange>
+        inline select_first_range<StdPairRange>
+        keys(const StdPairRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const StdPairRange>));
+
+            return select_first_range<StdPairRange>(
+                range_detail::select_first<StdPairRange>(), rng );
+        }
+
+        template<class StdPairRange>
+        inline select_second_const_range<StdPairRange>
+        values(const StdPairRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const StdPairRange>));
+
+            return select_second_const_range<StdPairRange>(
+                range_detail::select_second_const<StdPairRange>(), rng );
+        }
+
+        template<class StdPairRange>
+        inline select_second_mutable_range<StdPairRange>
+        values(StdPairRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRange>));
+
+            return select_second_mutable_range<StdPairRange>(
+                range_detail::select_second_mutable<StdPairRange>(), rng );
+        }
+    } // 'adaptors'
+
+}
+
+#endif
diff --git a/include/boost/range/adaptor/ref_unwrapped.hpp b/include/boost/range/adaptor/ref_unwrapped.hpp
new file mode 100644
index 0000000..71af483
--- /dev/null
+++ b/include/boost/range/adaptor/ref_unwrapped.hpp
@@ -0,0 +1,102 @@
+// Boost.Range library
+//
+//  Copyright Robin Eckert 2015.
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
+#define BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
+
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <utility>
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE)
+
+namespace boost
+{
+    namespace range_detail
+    {
+        struct ref_unwrapped_forwarder {};
+
+        template<class SinglePassRange>
+        struct unwrap_ref
+        {
+            typedef BOOST_DEDUCED_TYPENAME
+                          range_reference<SinglePassRange>::type argument_type;
+
+            using result_type = decltype(std::declval<argument_type>().get() );
+
+            result_type operator()( argument_type &&r ) const
+            {
+                return r.get();
+            }
+        };
+
+
+        template<class SinglePassRange>
+        class unwrap_ref_range
+            : public transformed_range<unwrap_ref<SinglePassRange>,
+                                       SinglePassRange>
+        {
+            using base = transformed_range<unwrap_ref<SinglePassRange>,
+                                           SinglePassRange>;
+        public:
+            using transform_fn_type = unwrap_ref<SinglePassRange>;
+            using source_range_type = SinglePassRange;
+
+            unwrap_ref_range(transform_fn_type fn, source_range_type &rng)
+                : base(fn, rng)
+            {
+            }
+
+            unwrap_ref_range(const base &other) : base(other) {}
+        };
+
+        template<class SinglePassRange>
+        inline unwrap_ref_range<SinglePassRange>
+        operator|(SinglePassRange& r, ref_unwrapped_forwarder)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return operator|( r,
+                boost::adaptors::transformed(unwrap_ref<SinglePassRange>()));
+        }
+
+    }
+
+    using range_detail::unwrap_ref_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::ref_unwrapped_forwarder ref_unwrapped =
+                                       range_detail::ref_unwrapped_forwarder();
+        }
+
+        template<class SinglePassRange>
+        inline unwrap_ref_range<SinglePassRange>
+        ref_unwrap(SinglePassRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return unwrap_ref_range<SinglePassRange>(
+                range_detail::unwrap_ref<SinglePassRange>(), rng );
+        }
+    } // 'adaptors'
+
+}
+
+#endif
+
+#endif
diff --git a/include/boost/range/adaptor/replaced.hpp b/include/boost/range/adaptor/replaced.hpp
new file mode 100644
index 0000000..42eb52a
--- /dev/null
+++ b/include/boost/range/adaptor/replaced.hpp
@@ -0,0 +1,159 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2007. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/optional/optional.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class Value >
+        class replace_value
+        {
+        public:
+            typedef const Value& result_type;
+            typedef const Value& first_argument_type;
+
+            // Rationale:
+            // The default constructor is required to allow the transform
+            // iterator to properly model the iterator concept.
+            replace_value()
+            {
+            }
+
+            replace_value(const Value& from, const Value& to)
+                :   m_impl(data(from, to))
+            {
+            }
+
+            const Value& operator()(const Value& x) const
+            {
+                return (x == m_impl->m_from) ? m_impl->m_to : x;
+            }
+
+        private:
+            struct data
+            {
+                data(const Value& from, const Value& to)
+                    : m_from(from)
+                    , m_to(to)
+                {
+                }
+
+                Value m_from;
+                Value m_to;
+            };
+            boost::optional<data> m_impl;
+        };
+
+        template< class R >
+        class replaced_range :
+            public boost::iterator_range<
+                boost::transform_iterator<
+                    replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
+        {
+        private:
+            typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
+
+            typedef boost::iterator_range<
+                boost::transform_iterator<
+                    replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
+
+        public:
+            typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
+
+            replaced_range( R& r, value_type from, value_type to )
+                : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
+                          make_transform_iterator( boost::end(r), Fn(from, to) ) )
+            { }
+        };
+
+        template< class T >
+        class replace_holder : public holder2<T>
+        {
+        public:
+            replace_holder( const T& from, const T& to )
+                : holder2<T>(from, to)
+            { }
+        private:
+            // not assignable
+            void operator=(const replace_holder&);
+        };
+
+        template< class SinglePassRange, class Value >
+        inline replaced_range<SinglePassRange>
+        operator|(SinglePassRange& r, const replace_holder<Value>& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return replaced_range<SinglePassRange>(r, f.val1, f.val2);
+        }
+
+        template< class SinglePassRange, class Value >
+        inline replaced_range<const SinglePassRange>
+        operator|(const SinglePassRange& r, const replace_holder<Value>& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
+        }
+    } // 'range_detail'
+
+    using range_detail::replaced_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::forwarder2<range_detail::replace_holder>
+                replaced =
+                    range_detail::forwarder2<range_detail::replace_holder>();
+        }
+
+        template< class SinglePassRange, class Value >
+        inline replaced_range<SinglePassRange>
+        replace(SinglePassRange& rng, Value from, Value to)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return replaced_range<SinglePassRange>(rng, from, to);
+        }
+
+        template< class SinglePassRange, class Value >
+        inline replaced_range<const SinglePassRange>
+        replace(const SinglePassRange& rng, Value from, Value to)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return replaced_range<const SinglePassRange>(rng, from ,to);
+        }
+
+    } // 'adaptors'
+} // 'boost'
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/replaced_if.hpp b/include/boost/range/adaptor/replaced_if.hpp
new file mode 100644
index 0000000..83d3ec8
--- /dev/null
+++ b/include/boost/range/adaptor/replaced_if.hpp
@@ -0,0 +1,165 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2007. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/optional/optional.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class Pred, class Value >
+        class replace_value_if
+        {
+        public:
+            typedef const Value& result_type;
+            typedef const Value& first_argument_type;
+
+            // Rationale:
+            // required to allow the iterator to be default constructible.
+            replace_value_if()
+            {
+            }
+
+            replace_value_if(const Pred& pred, const Value& to)
+                : m_impl(data(pred, to))
+            {
+            }
+
+            const Value& operator()(const Value& x) const
+            {
+                return m_impl->m_pred(x) ? m_impl->m_to : x;
+            }
+
+        private:
+            struct data
+            {
+                data(const Pred& p, const Value& t)
+                    : m_pred(p), m_to(t)
+                {
+                }
+
+                Pred  m_pred;
+                Value m_to;
+            };
+            boost::optional<data> m_impl;
+        };
+
+        template< class Pred, class R >
+        class replaced_if_range :
+            public boost::iterator_range<
+                boost::transform_iterator<
+                    replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
+        {
+        private:
+            typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
+
+            typedef boost::iterator_range<
+                boost::transform_iterator<
+                    replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
+
+        public:
+            typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
+
+            replaced_if_range( R& r, const Pred& pred, value_type to )
+                : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
+                          make_transform_iterator( boost::end(r), Fn(pred, to) ) )
+            { }
+        };
+
+        template< class Pred, class T >
+        class replace_if_holder
+        {
+        public:
+            replace_if_holder( const Pred& pred, const T& to )
+                : m_pred(pred), m_to(to)
+            { }
+
+            const Pred& pred() const { return m_pred; }
+            const T& to() const { return m_to; }
+
+        private:
+            Pred m_pred;
+            T m_to;
+        };
+
+        template< class Pred, class SinglePassRange, class Value >
+        inline replaced_if_range<Pred, SinglePassRange>
+        operator|(SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return replaced_if_range<Pred, SinglePassRange>(
+                r, f.pred(), f.to());
+        }
+
+        template< class Pred, class SinglePassRange, class Value >
+        inline replaced_if_range<Pred, const SinglePassRange>
+        operator|(const SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return replaced_if_range<Pred, const SinglePassRange>(
+                r, f.pred(), f.to());
+        }
+    } // 'range_detail'
+
+    using range_detail::replaced_if_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::forwarder2TU<range_detail::replace_if_holder>
+                replaced_if =
+                    range_detail::forwarder2TU<range_detail::replace_if_holder>();
+        }
+
+        template< class Pred, class SinglePassRange, class Value >
+        inline replaced_if_range<Pred, SinglePassRange>
+        replace_if(SinglePassRange& rng, Pred pred, Value to)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return range_detail::replaced_if_range<Pred, SinglePassRange>(
+                rng, pred, to);
+        }
+
+        template< class Pred, class SinglePassRange, class Value >
+        inline replaced_if_range<Pred, const SinglePassRange>
+        replace_if(const SinglePassRange& rng, Pred pred, Value to)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return range_detail::replaced_if_range<Pred, const SinglePassRange>(
+                rng, pred, to);
+        }
+    } // 'adaptors'
+
+} // 'boost'
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/reversed.hpp b/include/boost/range/adaptor/reversed.hpp
new file mode 100644
index 0000000..944fbff
--- /dev/null
+++ b/include/boost/range/adaptor/reversed.hpp
@@ -0,0 +1,103 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REVERSED_HPP
+#define BOOST_RANGE_ADAPTOR_REVERSED_HPP
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class R >
+        struct reversed_range : 
+            public boost::iterator_range< 
+                      boost::reverse_iterator<
+                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
+                                              >
+                                         >
+        {
+        private:
+            typedef boost::iterator_range< 
+                      boost::reverse_iterator<
+                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
+                                              >
+                                         >
+                base;
+            
+        public:
+            typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator;
+
+            explicit reversed_range( R& r ) 
+                : base( iterator(boost::end(r)), iterator(boost::begin(r)) )
+            { }
+        };
+
+        struct reverse_forwarder {};
+        
+        template< class BidirectionalRange >
+        inline reversed_range<BidirectionalRange> 
+        operator|( BidirectionalRange& r, reverse_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                BidirectionalRangeConcept<BidirectionalRange>));
+
+            return reversed_range<BidirectionalRange>( r );
+        }
+
+        template< class BidirectionalRange >
+        inline reversed_range<const BidirectionalRange> 
+        operator|( const BidirectionalRange& r, reverse_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                BidirectionalRangeConcept<const BidirectionalRange>));
+
+            return reversed_range<const BidirectionalRange>( r ); 
+        }
+        
+    } // 'range_detail'
+    
+    using range_detail::reversed_range;
+
+    namespace adaptors
+    { 
+        namespace
+        {
+            const range_detail::reverse_forwarder reversed = 
+                                            range_detail::reverse_forwarder();
+        }
+        
+        template<class BidirectionalRange>
+        inline reversed_range<BidirectionalRange>
+        reverse(BidirectionalRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                BidirectionalRangeConcept<BidirectionalRange>));
+
+            return reversed_range<BidirectionalRange>(rng);
+        }
+        
+        template<class BidirectionalRange>
+        inline reversed_range<const BidirectionalRange>
+        reverse(const BidirectionalRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                BidirectionalRangeConcept<const BidirectionalRange>));
+
+            return reversed_range<const BidirectionalRange>(rng);
+        }
+    } // 'adaptors'
+    
+} // 'boost'
+
+#endif
diff --git a/include/boost/range/adaptor/sliced.hpp b/include/boost/range/adaptor/sliced.hpp
new file mode 100644
index 0000000..f8d9612
--- /dev/null
+++ b/include/boost/range/adaptor/sliced.hpp
@@ -0,0 +1,97 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_SLICED_HPP
+#define BOOST_RANGE_ADAPTOR_SLICED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/next_prior.hpp>
+
+namespace boost
+{
+    namespace adaptors
+    {
+        struct sliced
+        {
+            sliced(std::size_t t_, std::size_t u_)
+                : t(t_), u(u_) {}
+            std::size_t t;
+            std::size_t u;
+        };
+
+        template< class RandomAccessRange >
+        class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
+        {
+            typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
+        public:
+            template<typename Rng, typename T, typename U>
+            sliced_range(Rng& rng, T t, U u)
+                : base_t(boost::next(boost::begin(rng), t),
+                         boost::next(boost::begin(rng), u))
+            {
+            }
+        };
+
+        template< class RandomAccessRange >
+        inline sliced_range<RandomAccessRange>
+        slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<RandomAccessRange>));
+
+            BOOST_ASSERT( t <= u && "error in slice indices" );
+            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
+                          "second slice index out of bounds" );
+
+            return sliced_range<RandomAccessRange>(rng, t, u);
+        }
+
+        template< class RandomAccessRange >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
+        slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<const RandomAccessRange>));
+
+            BOOST_ASSERT( t <= u && "error in slice indices" );
+            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
+                          "second slice index out of bounds" );
+
+            return sliced_range<const RandomAccessRange>(rng, t, u);
+        }
+
+        template< class RandomAccessRange >
+        inline sliced_range<RandomAccessRange>
+        operator|( RandomAccessRange& r, const sliced& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<RandomAccessRange>));
+
+            return sliced_range<RandomAccessRange>( r, f.t, f.u );
+        }
+
+        template< class RandomAccessRange >
+        inline sliced_range<const RandomAccessRange>
+        operator|( const RandomAccessRange& r, const sliced& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                RandomAccessRangeConcept<const RandomAccessRange>));
+
+            return sliced_range<const RandomAccessRange>( r, f.t, f.u );
+        }
+
+    } // namespace adaptors
+    using adaptors::sliced_range;
+} // namespace boost
+
+#endif
diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp
new file mode 100644
index 0000000..560b820
--- /dev/null
+++ b/include/boost/range/adaptor/strided.hpp
@@ -0,0 +1,697 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2007. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <iterator>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // strided_iterator for wrapping a forward traversal iterator
+        template<class BaseIterator, class Category>
+        class strided_iterator
+            : public iterator_facade<
+                strided_iterator<BaseIterator, Category>
+                , typename iterator_value<BaseIterator>::type
+                , forward_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            >
+        {
+            friend class ::boost::iterator_core_access;
+
+            typedef iterator_facade<
+                strided_iterator<BaseIterator, Category>
+                , typename iterator_value<BaseIterator>::type
+                , forward_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            > super_t;
+
+        public:
+            typedef typename super_t::difference_type difference_type;
+            typedef typename super_t::reference reference;
+            typedef BaseIterator base_iterator;
+            typedef std::forward_iterator_tag iterator_category;
+
+            strided_iterator()
+                : m_it()
+                , m_last()
+                , m_stride()
+            {
+            }
+
+            strided_iterator(base_iterator   it,
+                             base_iterator   last,
+                             difference_type stride)
+                : m_it(it)
+                , m_last(last)
+                , m_stride(stride)
+            {
+            }
+
+            template<class OtherIterator>
+            strided_iterator(
+                const strided_iterator<OtherIterator, Category>& other,
+                typename enable_if_convertible<
+                    OtherIterator,
+                    base_iterator
+                >::type* = 0
+            )
+                : m_it(other.base())
+                , m_last(other.base_end())
+                , m_stride(other.get_stride())
+            {
+            }
+
+            base_iterator base() const
+            {
+                return m_it;
+            }
+
+            base_iterator base_end() const
+            {
+                return m_last;
+            }
+
+            difference_type get_stride() const
+            {
+                return m_stride;
+            }
+
+        private:
+            void increment()
+            {
+                for (difference_type i = 0;
+                        (m_it != m_last) && (i < m_stride); ++i)
+                {
+                    ++m_it;
+                }
+            }
+
+            reference dereference() const
+            {
+                return *m_it;
+            }
+
+            template<class OtherIterator>
+            bool equal(
+                const strided_iterator<OtherIterator, Category>& other,
+                typename enable_if_convertible<
+                    OtherIterator,
+                    base_iterator
+                >::type* = 0) const
+            {
+                return m_it == other.m_it;
+            }
+
+            base_iterator m_it;
+            base_iterator m_last;
+            difference_type m_stride;
+        };
+
+        // strided_iterator for wrapping a bidirectional iterator
+        template<class BaseIterator>
+        class strided_iterator<BaseIterator, bidirectional_traversal_tag>
+            : public iterator_facade<
+                strided_iterator<BaseIterator, bidirectional_traversal_tag>
+                , typename iterator_value<BaseIterator>::type
+                , bidirectional_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            >
+        {
+            friend class ::boost::iterator_core_access;
+
+            typedef iterator_facade<
+                strided_iterator<BaseIterator, bidirectional_traversal_tag>
+                , typename iterator_value<BaseIterator>::type
+                , bidirectional_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            > super_t;
+        public:
+            typedef typename super_t::difference_type difference_type;
+            typedef typename super_t::reference reference;
+            typedef BaseIterator base_iterator;
+            typedef typename boost::make_unsigned<difference_type>::type
+                        size_type;
+            typedef std::bidirectional_iterator_tag iterator_category;
+
+            strided_iterator()
+                : m_it()
+                , m_offset()
+                , m_index()
+                , m_stride()
+            {
+            }
+
+            strided_iterator(base_iterator   it,
+                             size_type       index,
+                             difference_type stride)
+                : m_it(it)
+                , m_offset()
+                , m_index(index)
+                , m_stride(stride)
+            {
+                if (stride && ((m_index % stride) != 0))
+                    m_index += (stride - (m_index % stride));
+            }
+
+            template<class OtherIterator>
+            strided_iterator(
+                const strided_iterator<
+                    OtherIterator,
+                    bidirectional_traversal_tag
+                >& other,
+                typename enable_if_convertible<
+                    OtherIterator,
+                    base_iterator
+                >::type* = 0
+            )
+                : m_it(other.base())
+                , m_offset(other.get_offset())
+                , m_index(other.get_index())
+                , m_stride(other.get_stride())
+            {
+            }
+
+            base_iterator base() const
+            {
+                return m_it;
+            }
+
+            difference_type get_offset() const
+            {
+                return m_offset;
+            }
+
+            size_type get_index() const
+            {
+                return m_index;
+            }
+
+            difference_type get_stride() const
+            {
+                return m_stride;
+            }
+
+        private:
+            void increment()
+            {
+                m_offset += m_stride;
+            }
+
+            void decrement()
+            {
+                m_offset -= m_stride;
+            }
+
+            reference dereference() const
+            {
+                update();
+                return *m_it;
+            }
+
+            void update() const
+            {
+                std::advance(m_it, m_offset);
+                m_index += m_offset;
+                m_offset = 0;
+            }
+
+            template<class OtherIterator>
+            bool equal(
+                const strided_iterator<
+                    OtherIterator,
+                    bidirectional_traversal_tag
+                >& other,
+                typename enable_if_convertible<
+                    OtherIterator,
+                    base_iterator
+                >::type* = 0) const
+            {
+                return (m_index + m_offset) ==
+                            (other.get_index() + other.get_offset());
+            }
+
+            mutable base_iterator m_it;
+            mutable difference_type m_offset;
+            mutable size_type m_index;
+            difference_type m_stride;
+        };
+
+        // strided_iterator implementation for wrapping a random access iterator
+        template<class BaseIterator>
+        class strided_iterator<BaseIterator, random_access_traversal_tag>
+            : public iterator_facade<
+                strided_iterator<BaseIterator, random_access_traversal_tag>
+                , typename iterator_value<BaseIterator>::type
+                , random_access_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            >
+        {
+            friend class ::boost::iterator_core_access;
+
+            typedef iterator_facade<
+                strided_iterator<BaseIterator, random_access_traversal_tag>
+                , typename iterator_value<BaseIterator>::type
+                , random_access_traversal_tag
+                , typename iterator_reference<BaseIterator>::type
+                , typename iterator_difference<BaseIterator>::type
+            > super_t;
+        public:
+            typedef typename super_t::difference_type difference_type;
+            typedef typename super_t::reference reference;
+            typedef BaseIterator base_iterator;
+            typedef std::random_access_iterator_tag iterator_category;
+
+            strided_iterator()
+                : m_it()
+                , m_first()
+                , m_index(0)
+                , m_stride()
+            {
+            }
+
+            strided_iterator(
+                base_iterator   first,
+                base_iterator   it,
+                difference_type stride
+            )
+                : m_it(it)
+                , m_first(first)
+                , m_index(stride ? (it - first) : difference_type())
+                , m_stride(stride)
+            {
+                if (stride && ((m_index % stride) != 0))
+                    m_index += (stride - (m_index % stride));
+            }
+
+            template<class OtherIterator>
+            strided_iterator(
+                const strided_iterator<
+                    OtherIterator,
+                    random_access_traversal_tag
+                >& other,
+                typename enable_if_convertible<
+                    OtherIterator,
+                    base_iterator
+                >::type* = 0
+            )
+                : m_it(other.base())
+                , m_first(other.base_begin())
+                , m_index(other.get_index())
+                , m_stride(other.get_stride())
+            {
+            }
+
+            base_iterator base_begin() const
+            {
+                return m_first;
+            }
+
+            base_iterator base() const
+            {
+                return m_it;
+            }
+
+            difference_type get_stride() const
+            {
+                return m_stride;
+            }
+
+            difference_type get_index() const
+            {
+                return m_index;
+            }
+
+        private:
+            void increment()
+            {
+                m_index += m_stride;
+            }
+
+            void decrement()
+            {
+                m_index -= m_stride;
+            }
+
+            void advance(difference_type offset)
+            {
+                m_index += (m_stride * offset);
+            }
+
+            // Implementation detail: only update the actual underlying iterator
+            // at the point of dereference. This is done so that the increment
+            // and decrement can overshoot the valid sequence as is required
+            // by striding. Since we can do all comparisons just with the index
+            // simply, and all dereferences must be within the valid range.
+            void update() const
+            {
+                m_it = m_first + m_index;
+            }
+
+            template<class OtherIterator>
+            difference_type distance_to(
+                const strided_iterator<
+                    OtherIterator,
+                    random_access_traversal_tag
+                >& other,
+                typename enable_if_convertible<
+                            OtherIterator, base_iterator>::type* = 0) const
+            {
+                BOOST_ASSERT((other.m_index - m_index) % m_stride == difference_type());
+                return (other.m_index - m_index) / m_stride;
+            }
+
+            template<class OtherIterator>
+            bool equal(
+                const strided_iterator<
+                    OtherIterator,
+                    random_access_traversal_tag
+                >& other,
+                typename enable_if_convertible<
+                            OtherIterator, base_iterator>::type* = 0) const
+            {
+                return m_index == other.m_index;
+            }
+
+            reference dereference() const
+            {
+                update();
+                return *m_it;
+            }
+
+        private:
+            mutable base_iterator m_it;
+            base_iterator m_first;
+            difference_type m_index;
+            difference_type m_stride;
+        };
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            forward_traversal_tag
+        >
+        make_begin_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            forward_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                forward_traversal_tag
+            >(boost::begin(rng), boost::end(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            forward_traversal_tag
+        >
+        make_begin_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            forward_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                forward_traversal_tag
+            >(boost::begin(rng), boost::end(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            forward_traversal_tag
+        >
+        make_end_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            forward_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                forward_traversal_tag
+            >(boost::end(rng), boost::end(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            forward_traversal_tag
+        >
+        make_end_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            forward_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                forward_traversal_tag
+            >(boost::end(rng), boost::end(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            bidirectional_traversal_tag
+        >
+        make_begin_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            bidirectional_traversal_tag)
+        {
+            typedef typename range_difference<Rng>::type difference_type;
+
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                bidirectional_traversal_tag
+            >(boost::begin(rng), difference_type(), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            bidirectional_traversal_tag
+        >
+        make_begin_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            bidirectional_traversal_tag)
+        {
+            typedef typename range_difference<const Rng>::type difference_type;
+
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                bidirectional_traversal_tag
+            >(boost::begin(rng), difference_type(), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            bidirectional_traversal_tag
+        >
+        make_end_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            bidirectional_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                bidirectional_traversal_tag
+            >(boost::end(rng), boost::size(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            bidirectional_traversal_tag
+        >
+        make_end_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            bidirectional_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                bidirectional_traversal_tag
+            >(boost::end(rng), boost::size(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            random_access_traversal_tag
+        >
+        make_begin_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            random_access_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                random_access_traversal_tag
+            >(boost::begin(rng), boost::begin(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            random_access_traversal_tag
+        >
+        make_begin_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            random_access_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                random_access_traversal_tag
+            >(boost::begin(rng), boost::begin(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<Rng>::type,
+            random_access_traversal_tag
+        >
+        make_end_strided_iterator(
+            Rng& rng,
+            Difference stride,
+            random_access_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<Rng>::type,
+                random_access_traversal_tag
+            >(boost::begin(rng), boost::end(rng), stride);
+        }
+
+        template<class Rng, class Difference> inline
+        strided_iterator<
+            typename range_iterator<const Rng>::type,
+            random_access_traversal_tag
+        >
+        make_end_strided_iterator(
+            const Rng& rng,
+            Difference stride,
+            random_access_traversal_tag)
+        {
+            return strided_iterator<
+                typename range_iterator<const Rng>::type,
+                random_access_traversal_tag
+            >(boost::begin(rng), boost::end(rng), stride);
+        }
+
+        template<
+            class Rng,
+            class Category =
+                typename iterators::pure_iterator_traversal<
+                    typename range_iterator<Rng>::type
+                >::type
+        >
+        class strided_range
+            : public iterator_range<
+                range_detail::strided_iterator<
+                    typename range_iterator<Rng>::type,
+                    Category
+                >
+            >
+        {
+            typedef range_detail::strided_iterator<
+                typename range_iterator<Rng>::type,
+                Category
+            > iter_type;
+            typedef iterator_range<iter_type> super_t;
+        public:
+            template<class Difference>
+            strided_range(Difference stride, Rng& rng)
+                : super_t(
+                    range_detail::make_begin_strided_iterator(
+                        rng, stride,
+                        typename iterator_traversal<
+                            typename range_iterator<Rng>::type
+                        >::type()),
+                    range_detail::make_end_strided_iterator(
+                        rng, stride,
+                        typename iterator_traversal<
+                            typename range_iterator<Rng>::type
+                        >::type()))
+            {
+                BOOST_ASSERT( stride >= 0 );
+            }
+        };
+
+        template<class Difference>
+        class strided_holder : public holder<Difference>
+        {
+        public:
+            explicit strided_holder(Difference value)
+                : holder<Difference>(value)
+            {
+            }
+        };
+
+        template<class Rng, class Difference>
+        inline strided_range<Rng>
+        operator|(Rng& rng, const strided_holder<Difference>& stride)
+        {
+            return strided_range<Rng>(stride.val, rng);
+        }
+
+        template<class Rng, class Difference>
+        inline strided_range<const Rng>
+        operator|(const Rng& rng, const strided_holder<Difference>& stride)
+        {
+            return strided_range<const Rng>(stride.val, rng);
+        }
+
+    } // namespace range_detail
+
+    using range_detail::strided_range;
+
+    namespace adaptors
+    {
+
+        namespace
+        {
+            const range_detail::forwarder<range_detail::strided_holder>
+                strided = range_detail::forwarder<
+                            range_detail::strided_holder>();
+        }
+
+        template<class Range, class Difference>
+        inline strided_range<Range>
+        stride(Range& rng, Difference step)
+        {
+            return strided_range<Range>(step, rng);
+        }
+
+        template<class Range, class Difference>
+        inline strided_range<const Range>
+        stride(const Range& rng, Difference step)
+        {
+            return strided_range<const Range>(step, rng);
+        }
+
+    } // namespace 'adaptors'
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/adaptor/tokenized.hpp b/include/boost/range/adaptor/tokenized.hpp
new file mode 100644
index 0000000..f0aa12e
--- /dev/null
+++ b/include/boost/range/adaptor/tokenized.hpp
@@ -0,0 +1,137 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
+#define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
+
+#include <boost/regex.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+        template< class R >
+        struct tokenized_range : 
+            public boost::iterator_range< 
+                      boost::regex_token_iterator< 
+                          BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
+                                              >
+                                         >
+        {
+        private:
+            typedef           
+                boost::regex_token_iterator< 
+                          BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
+                                            >
+                regex_iter;
+            
+            typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type 
+                regex_type;
+        
+            typedef boost::iterator_range<regex_iter> 
+                base;
+
+        public:
+            template< class Regex, class Submatch, class Flag >
+            tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f )
+              : base( regex_iter( boost::begin(r), boost::end(r), 
+                                  regex_type(re), sub, f ),
+                      regex_iter() )
+            { }
+        };
+
+        template< class T, class U, class V >
+        struct regex_holder
+        {
+            T  re;
+            U  sub;
+            V  f;
+
+            regex_holder( const T& rex, const U& subm, V flag ) :
+                re(rex), sub(subm), f(flag)
+            { }
+        private:
+            // Not assignable
+            void operator=(const regex_holder&);
+        };
+
+        struct regex_forwarder
+        {           
+            template< class Regex >
+            regex_holder<Regex,int,regex_constants::match_flag_type>
+            operator()( const Regex& re, 
+                        int submatch = 0,    
+                        regex_constants::match_flag_type f = 
+                            regex_constants::match_default ) const
+            {
+                return regex_holder<Regex,int,
+                           regex_constants::match_flag_type>( re, submatch, f );
+            }
+             
+            template< class Regex, class Submatch >
+            regex_holder<Regex,Submatch,regex_constants::match_flag_type> 
+            operator()( const Regex& re, 
+                        const Submatch& sub, 
+                        regex_constants::match_flag_type f = 
+                            regex_constants::match_default ) const
+            {
+                return regex_holder<Regex,Submatch,
+                           regex_constants::match_flag_type>( re, sub, f ); 
+            }
+        };
+        
+        template< class BidirectionalRng, class R, class S, class F >
+        inline tokenized_range<BidirectionalRng> 
+        operator|( BidirectionalRng& r, 
+                   const regex_holder<R,S,F>& f )
+        {
+            return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );   
+        }
+
+        template< class BidirectionalRng, class R, class S, class F  >
+        inline tokenized_range<const BidirectionalRng> 
+        operator|( const BidirectionalRng& r, 
+                   const regex_holder<R,S,F>& f )
+        {
+            return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
+        }
+        
+    } // 'range_detail'
+
+    using range_detail::tokenized_range;
+
+    namespace adaptors
+    { 
+        namespace
+        {
+            const range_detail::regex_forwarder tokenized = 
+                    range_detail::regex_forwarder();
+        }
+        
+        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
+        inline tokenized_range<BidirectionalRange>
+        tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
+        {
+            return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
+        }
+        
+        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
+        inline tokenized_range<const BidirectionalRange>
+        tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
+        {
+            return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
+        }
+    } // 'adaptors'
+    
+}
+
+#endif
diff --git a/include/boost/range/adaptor/transformed.hpp b/include/boost/range/adaptor/transformed.hpp
new file mode 100644
index 0000000..428ff4b
--- /dev/null
+++ b/include/boost/range/adaptor/transformed.hpp
@@ -0,0 +1,137 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
+#define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/detail/default_constructible_unary_fn.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/utility/result_of.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // A type generator to produce the transform_iterator type conditionally
+        // including a wrapped predicate as appropriate.
+        template<typename P, typename It>
+        struct transform_iterator_gen
+        {
+            typedef transform_iterator<
+                typename default_constructible_unary_fn_gen<
+                    P,
+                    typename transform_iterator<P, It>::reference
+                >::type,
+                It
+            > type;
+        };
+
+        template< class F, class R >
+        struct transformed_range :
+            public boost::iterator_range<
+                typename transform_iterator_gen<
+                    F, typename range_iterator<R>::type>::type>
+        {
+        private:
+            typedef typename transform_iterator_gen<
+                F, typename range_iterator<R>::type>::type transform_iter_t;
+
+            typedef boost::iterator_range<transform_iter_t> base;
+
+        public:
+            typedef typename default_constructible_unary_fn_gen<
+                F,
+                typename transform_iterator<
+                    F,
+                    typename range_iterator<R>::type
+                >::reference
+            >::type transform_fn_type;
+
+            typedef R source_range_type;
+
+            transformed_range(transform_fn_type f, R& r)
+                : base(transform_iter_t(boost::begin(r), f),
+                       transform_iter_t(boost::end(r), f))
+            {
+            }
+        };
+
+        template< class T >
+        struct transform_holder : holder<T>
+        {
+            transform_holder( T r ) : holder<T>(r)
+            {
+            }
+        };
+
+        template< class SinglePassRange, class UnaryFunction >
+        inline transformed_range<UnaryFunction,SinglePassRange>
+        operator|( SinglePassRange& r,
+                   const transform_holder<UnaryFunction>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return transformed_range<UnaryFunction,SinglePassRange>( f.val, r );
+        }
+
+        template< class SinglePassRange, class UnaryFunction >
+        inline transformed_range<UnaryFunction, const SinglePassRange>
+        operator|( const SinglePassRange& r,
+                   const transform_holder<UnaryFunction>& f )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+           return transformed_range<UnaryFunction, const SinglePassRange>(
+               f.val, r);
+        }
+
+    } // 'range_detail'
+
+    using range_detail::transformed_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::forwarder<range_detail::transform_holder>
+                    transformed =
+                      range_detail::forwarder<range_detail::transform_holder>();
+        }
+
+        template<class UnaryFunction, class SinglePassRange>
+        inline transformed_range<UnaryFunction, SinglePassRange>
+        transform(SinglePassRange& rng, UnaryFunction fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            return transformed_range<UnaryFunction, SinglePassRange>(fn, rng);
+        }
+
+        template<class UnaryFunction, class SinglePassRange>
+        inline transformed_range<UnaryFunction, const SinglePassRange>
+        transform(const SinglePassRange& rng, UnaryFunction fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            return transformed_range<UnaryFunction, const SinglePassRange>(
+                fn, rng);
+        }
+    } // 'adaptors'
+
+}
+
+#endif
diff --git a/include/boost/range/adaptor/type_erased.hpp b/include/boost/range/adaptor/type_erased.hpp
new file mode 100644
index 0000000..ba5b159
--- /dev/null
+++ b/include/boost/range/adaptor/type_erased.hpp
@@ -0,0 +1,196 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
+
+#include <boost/range/reference.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/any_range.hpp>
+#include <boost/range/concepts.hpp>
+
+namespace boost
+{
+    namespace adaptors
+    {
+        template<
+            class Value = use_default
+          , class Traversal = use_default
+          , class Reference = use_default
+          , class Difference = use_default
+          , class Buffer = use_default
+        >
+        struct type_erased
+        {
+        };
+
+        template<
+            class SinglePassRange
+          , class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        typename any_range_type_generator<
+            SinglePassRange
+          , Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >::type
+        operator|(SinglePassRange& rng,
+                  type_erased<
+                        Value
+                      , Traversal
+                      , Reference
+                      , Difference
+                      , Buffer
+                    >)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            typedef typename any_range_type_generator<
+                SinglePassRange
+              , Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >::type range_type;
+            return range_type(boost::begin(rng), boost::end(rng));
+        }
+
+        template<
+            class SinglePassRange
+          , class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        typename any_range_type_generator<
+            const SinglePassRange
+          , Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >::type
+        operator|(const SinglePassRange& rng,
+                  type_erased<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                    >)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            typedef typename any_range_type_generator<
+                const SinglePassRange
+              , Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >::type range_type;
+            return range_type(boost::begin(rng), boost::end(rng));
+        }
+
+        template<
+            class SinglePassRange
+          , class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        typename any_range_type_generator<
+            SinglePassRange
+          , Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >::type
+        type_erase(SinglePassRange& rng
+                 , type_erased<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                    > = type_erased<>()
+                )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<SinglePassRange>));
+
+            typedef typename any_range_type_generator<
+                SinglePassRange
+              , Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >::type range_type;
+
+            return range_type(boost::begin(rng), boost::end(rng));
+        }
+
+        template<
+            class SinglePassRange
+          , class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        typename any_range_type_generator<
+            const SinglePassRange
+          , Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >::type
+        type_erase(const SinglePassRange& rng
+                 , type_erased<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                    > = type_erased<>()
+                )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+            typedef typename any_range_type_generator<
+                const SinglePassRange
+              , Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >::type range_type;
+
+            return range_type(boost::begin(rng), boost::end(rng));
+        }
+    }
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/uniqued.hpp b/include/boost/range/adaptor/uniqued.hpp
new file mode 100644
index 0000000..29101d3
--- /dev/null
+++ b/include/boost/range/adaptor/uniqued.hpp
@@ -0,0 +1,97 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
+#define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
+
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+#include <boost/range/concepts.hpp>
+
+namespace boost
+{
+
+    namespace range_detail
+    {
+        struct unique_forwarder { };
+
+        struct unique_not_equal_to
+        {
+            typedef bool result_type;
+
+            template< class T >
+            bool operator()( const T& l, const T& r ) const
+            {
+                return !(l == r);
+            }
+        };
+
+        template<class ForwardRng>
+        class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
+        {
+            typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
+        public:
+            explicit uniqued_range(ForwardRng& rng)
+                : base(unique_not_equal_to(), rng)
+            {
+            }
+        };
+
+        template< class ForwardRng >
+        inline uniqued_range<ForwardRng>
+        operator|( ForwardRng& r,
+                   unique_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
+            return uniqued_range<ForwardRng>(r);
+        }
+
+        template< class ForwardRng >
+        inline uniqued_range<const ForwardRng>
+        operator|( const ForwardRng& r,
+                   unique_forwarder )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
+            return uniqued_range<const ForwardRng>(r);
+        }
+
+    } // 'range_detail'
+
+    using range_detail::uniqued_range;
+
+    namespace adaptors
+    {
+        namespace
+        {
+            const range_detail::unique_forwarder uniqued =
+                       range_detail::unique_forwarder();
+        }
+
+        template<class ForwardRange>
+        inline uniqued_range<ForwardRange>
+        unique(ForwardRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+            return uniqued_range<ForwardRange>(rng);
+        }
+
+        template<class ForwardRange>
+        inline uniqued_range<const ForwardRange>
+        unique(const ForwardRange& rng)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT((
+                ForwardRangeConcept<const ForwardRange>));
+
+            return uniqued_range<const ForwardRange>(rng);
+        }
+    } // 'adaptors'
+
+}
+
+#endif
diff --git a/include/boost/range/adaptors.hpp b/include/boost/range/adaptors.hpp
new file mode 100644
index 0000000..0530c4d
--- /dev/null
+++ b/include/boost/range/adaptors.hpp
@@ -0,0 +1,31 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2007.
+//  Copyright Thorsten Ottosen 2006.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTORS_HPP
+#define BOOST_RANGE_ADAPTORS_HPP
+
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+#include <boost/range/adaptor/copied.hpp>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/adaptor/formatted.hpp>
+#include <boost/range/adaptor/indexed.hpp>
+#include <boost/range/adaptor/indirected.hpp>
+#include <boost/range/adaptor/map.hpp>
+#include <boost/range/adaptor/replaced.hpp>
+#include <boost/range/adaptor/replaced_if.hpp>
+#include <boost/range/adaptor/reversed.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/adaptor/strided.hpp>
+#include <boost/range/adaptor/tokenized.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/adaptor/uniqued.hpp>
+
+#endif
diff --git a/include/boost/range/algorithm.hpp b/include/boost/range/algorithm.hpp
new file mode 100644
index 0000000..30dc583
--- /dev/null
+++ b/include/boost/range/algorithm.hpp
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file algorithm.hpp
+///   Includes the range-based versions of the algorithms in the
+///   C++ standard header file <algorithm>
+//
+/////////////////////////////////////////////////////////////////////////////
+
+// Copyright 2009 Neil Groves.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// This code uses combinations of ideas, techniques and code snippets
+// from: Thorsten Ottosen, Eric Niebler, Jeremy Siek,
+// and Vladimir Prus'
+//
+// The original mutating algorithms that served as the first version
+// were originally written by Vladimir Prus'
+// <ghost@cs.msu.su> code from Boost Wiki
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#ifndef BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
+#define BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
+
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/next_prior.hpp>
+#include <algorithm>
+
+// Non-mutating algorithms
+#include <boost/range/algorithm/adjacent_find.hpp>
+#include <boost/range/algorithm/count.hpp>
+#include <boost/range/algorithm/count_if.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/algorithm/for_each.hpp>
+#include <boost/range/algorithm/find.hpp>
+#include <boost/range/algorithm/find_end.hpp>
+#include <boost/range/algorithm/find_first_of.hpp>
+#include <boost/range/algorithm/find_if.hpp>
+#include <boost/range/algorithm/lexicographical_compare.hpp>
+#include <boost/range/algorithm/mismatch.hpp>
+#include <boost/range/algorithm/search.hpp>
+#include <boost/range/algorithm/search_n.hpp>
+
+// Mutating algorithms
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/range/algorithm/copy_backward.hpp>
+#include <boost/range/algorithm/fill.hpp>
+#include <boost/range/algorithm/fill_n.hpp>
+#include <boost/range/algorithm/generate.hpp>
+#include <boost/range/algorithm/inplace_merge.hpp>
+#include <boost/range/algorithm/merge.hpp>
+#include <boost/range/algorithm/nth_element.hpp>
+#include <boost/range/algorithm/partial_sort.hpp>
+#include <boost/range/algorithm/partial_sort_copy.hpp>
+#include <boost/range/algorithm/partition.hpp>
+#include <boost/range/algorithm/random_shuffle.hpp>
+#include <boost/range/algorithm/remove.hpp>
+#include <boost/range/algorithm/remove_copy.hpp>
+#include <boost/range/algorithm/remove_copy_if.hpp>
+#include <boost/range/algorithm/remove_if.hpp>
+#include <boost/range/algorithm/replace.hpp>
+#include <boost/range/algorithm/replace_copy.hpp>
+#include <boost/range/algorithm/replace_copy_if.hpp>
+#include <boost/range/algorithm/replace_if.hpp>
+#include <boost/range/algorithm/reverse.hpp>
+#include <boost/range/algorithm/reverse_copy.hpp>
+#include <boost/range/algorithm/rotate.hpp>
+#include <boost/range/algorithm/rotate_copy.hpp>
+#include <boost/range/algorithm/sort.hpp>
+#include <boost/range/algorithm/stable_partition.hpp>
+#include <boost/range/algorithm/stable_sort.hpp>
+#include <boost/range/algorithm/transform.hpp>
+#include <boost/range/algorithm/unique.hpp>
+#include <boost/range/algorithm/unique_copy.hpp>
+
+// Binary search
+#include <boost/range/algorithm/binary_search.hpp>
+#include <boost/range/algorithm/equal_range.hpp>
+#include <boost/range/algorithm/lower_bound.hpp>
+#include <boost/range/algorithm/upper_bound.hpp>
+
+// Set operations of sorted ranges
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+// Heap operations
+#include <boost/range/algorithm/heap_algorithm.hpp>
+
+// Minimum and Maximum
+#include <boost/range/algorithm/max_element.hpp>
+#include <boost/range/algorithm/min_element.hpp>
+
+// Permutations
+#include <boost/range/algorithm/permutation.hpp>
+
+#endif // include guard
+
diff --git a/include/boost/range/algorithm/adjacent_find.hpp b/include/boost/range/algorithm/adjacent_find.hpp
new file mode 100644
index 0000000..1b88dae
--- /dev/null
+++ b/include/boost/range/algorithm/adjacent_find.hpp
@@ -0,0 +1,125 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function adjacent_find
+///
+/// range-based version of the adjacent_find std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< typename ForwardRange >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        typename range_value<ForwardRange>::type,
+        typename range_value<ForwardRange>::type>));
+    return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        typename range_value<const ForwardRange>::type,
+        typename range_value<const ForwardRange>::type>));
+    return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+//  range_return overloads
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange & rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return range_return<ForwardRange,re>::
+        pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return range_return<const ForwardRange,re>::
+        pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        typename range_value<ForwardRange>::type,
+        typename range_value<ForwardRange>::type>));
+    return range_return<ForwardRange,re>::
+        pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return range_return<const ForwardRange,re>::
+        pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+             rng);
+}
+
+    } // namespace range
+    using range::adjacent_find;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/binary_search.hpp b/include/boost/range/algorithm/binary_search.hpp
new file mode 100644
index 0000000..bb64ec8
--- /dev/null
+++ b/include/boost/range/algorithm/binary_search.hpp
@@ -0,0 +1,49 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function binary_search
+///
+/// range-based version of the binary_search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline bool binary_search(const ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::binary_search(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class BinaryPredicate>
+inline bool binary_search(const ForwardRange& rng, const Value& val,
+                          BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::binary_search(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+    } // namespace range
+    using range::binary_search;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/copy.hpp b/include/boost/range/algorithm/copy.hpp
new file mode 100644
index 0000000..f15b31f
--- /dev/null
+++ b/include/boost/range/algorithm/copy.hpp
@@ -0,0 +1,41 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function copy
+///
+/// range-based version of the copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator copy(const SinglePassRange& rng, OutputIterator out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::copy(boost::begin(rng),boost::end(rng),out);
+}
+
+    } // namespace range
+    using range::copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/copy_backward.hpp b/include/boost/range/algorithm/copy_backward.hpp
new file mode 100644
index 0000000..c95c6f1
--- /dev/null
+++ b/include/boost/range/algorithm/copy_backward.hpp
@@ -0,0 +1,43 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function copy_backward
+///
+/// range-based version of the copy_backwards std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the BidirectionalIteratorConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the WriteableIteratorConcept
+template< class BidirectionalRange, class BidirectionalTraversalWriteableIterator >
+inline BidirectionalTraversalWriteableIterator
+copy_backward(const BidirectionalRange& rng,
+              BidirectionalTraversalWriteableIterator out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::copy_backward(boost::begin(rng), boost::end(rng), out);
+}
+
+    } // namespace range
+    using range::copy_backward;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/count.hpp b/include/boost/range/algorithm/count.hpp
new file mode 100644
index 0000000..8316ce0
--- /dev/null
+++ b/include/boost/range/algorithm/count.hpp
@@ -0,0 +1,50 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function count
+///
+/// range-based version of the count std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
+count(SinglePassRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
+count(const SinglePassRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+    } // namespace range
+    using range::count;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/count_if.hpp b/include/boost/range/algorithm/count_if.hpp
new file mode 100644
index 0000000..ae17b0e
--- /dev/null
+++ b/include/boost/range/algorithm/count_if.hpp
@@ -0,0 +1,51 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function count_if
+///
+/// range-based version of the count_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
+count_if(SinglePassRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
+count_if(const SinglePassRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+    } // namespace range
+    using range::count_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/equal.hpp b/include/boost/range/algorithm/equal.hpp
new file mode 100644
index 0000000..2b44f3b
--- /dev/null
+++ b/include/boost/range/algorithm/equal.hpp
@@ -0,0 +1,200 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <iterator>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // An implementation of equality comparison that is optimized for iterator
+        // traversal categories less than RandomAccessTraversal.
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2,
+                  class IteratorCategoryTag1,
+                  class IteratorCategoryTag2 >
+        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+                                SinglePassTraversalReadableIterator1 last1,
+                                SinglePassTraversalReadableIterator2 first2,
+                                SinglePassTraversalReadableIterator2 last2,
+                                IteratorCategoryTag1,
+                                IteratorCategoryTag2 )
+        {
+            for (;;)
+            {
+                // If we have reached the end of the left range then this is
+                // the end of the loop. They are equal if and only if we have
+                // simultaneously reached the end of the right range.
+                if (first1 == last1)
+                    return first2 == last2;
+
+                // If we have reached the end of the right range at this line
+                // it indicates that the right range is shorter than the left
+                // and hence the result is false.
+                if (first2 == last2)
+                    return false;
+
+                // continue looping if and only if the values are equal
+                if (*first1 != *first2)
+                    break;
+
+                ++first1;
+                ++first2;
+            }
+
+            // Reaching this line in the algorithm indicates that a value
+            // inequality has been detected.
+            return false;
+        }
+
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2,
+                  class IteratorCategoryTag1,
+                  class IteratorCategoryTag2,
+                  class BinaryPredicate >
+        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+                                SinglePassTraversalReadableIterator1 last1,
+                                SinglePassTraversalReadableIterator2 first2,
+                                SinglePassTraversalReadableIterator2 last2,
+                                BinaryPredicate                      pred,
+                                IteratorCategoryTag1,
+                                IteratorCategoryTag2 )
+        {
+            for (;;)
+            {
+                // If we have reached the end of the left range then this is
+                // the end of the loop. They are equal if and only if we have
+                // simultaneously reached the end of the right range.
+                if (first1 == last1)
+                    return first2 == last2;
+
+                // If we have reached the end of the right range at this line
+                // it indicates that the right range is shorter than the left
+                // and hence the result is false.
+                if (first2 == last2)
+                    return false;
+
+                // continue looping if and only if the values are equal
+                if (!pred(*first1, *first2))
+                    break;
+
+                ++first1;
+                ++first2;
+            }
+
+            // Reaching this line in the algorithm indicates that a value
+            // inequality has been detected.
+            return false;
+        }
+
+        // An implementation of equality comparison that is optimized for
+        // random access iterators.
+        template< class RandomAccessTraversalReadableIterator1,
+                  class RandomAccessTraversalReadableIterator2 >
+        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+                                RandomAccessTraversalReadableIterator1 last1,
+                                RandomAccessTraversalReadableIterator2 first2,
+                                RandomAccessTraversalReadableIterator2 last2,
+                                std::random_access_iterator_tag,
+                                std::random_access_iterator_tag )
+        {
+            return ((last1 - first1) == (last2 - first2))
+                && std::equal(first1, last1, first2);
+        }
+
+        template< class RandomAccessTraversalReadableIterator1,
+                  class RandomAccessTraversalReadableIterator2,
+                  class BinaryPredicate >
+        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+                                RandomAccessTraversalReadableIterator1 last1,
+                                RandomAccessTraversalReadableIterator2 first2,
+                                RandomAccessTraversalReadableIterator2 last2,
+                                BinaryPredicate                        pred,
+                                std::random_access_iterator_tag,
+                                std::random_access_iterator_tag )
+        {
+            return ((last1 - first1) == (last2 - first2))
+                && std::equal(first1, last1, first2, pred);
+        }
+
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2 >
+        inline bool equal( SinglePassTraversalReadableIterator1 first1,
+                           SinglePassTraversalReadableIterator1 last1,
+                           SinglePassTraversalReadableIterator2 first2,
+                           SinglePassTraversalReadableIterator2 last2 )
+        {
+            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+            return equal_impl(first1, last1, first2, last2, tag1, tag2);
+        }
+
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2,
+                  class BinaryPredicate >
+        inline bool equal( SinglePassTraversalReadableIterator1 first1,
+                           SinglePassTraversalReadableIterator1 last1,
+                           SinglePassTraversalReadableIterator2 first2,
+                           SinglePassTraversalReadableIterator2 last2,
+                           BinaryPredicate                      pred )
+        {
+            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+            return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
+        }
+
+    } // namespace range_detail
+
+    namespace range
+    {
+
+        /// \brief template function equal
+        ///
+        /// range-based version of the equal std algorithm
+        ///
+        /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+        /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+        /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+        template< class SinglePassRange1, class SinglePassRange2 >
+        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+            return ::boost::range_detail::equal(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2) );
+        }
+
+        /// \overload
+        template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+                           BinaryPredicate pred )
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+            return ::boost::range_detail::equal(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2),
+                pred);
+        }
+
+    } // namespace range
+    using ::boost::range::equal;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/equal_range.hpp b/include/boost/range/algorithm/equal_range.hpp
new file mode 100644
index 0000000..4aa4a54
--- /dev/null
+++ b/include/boost/range/algorithm/equal_range.hpp
@@ -0,0 +1,80 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function equal_range
+///
+/// range-based version of the equal_range std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre SortPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline std::pair<
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+       >
+equal_range(ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value>
+inline std::pair<
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+       >
+equal_range(const ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+       >
+equal_range(ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+       >
+equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+    } // namespace range
+    using range::equal_range;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/fill.hpp b/include/boost/range/algorithm/fill.hpp
new file mode 100644
index 0000000..95231a8
--- /dev/null
+++ b/include/boost/range/algorithm/fill.hpp
@@ -0,0 +1,49 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function fill
+///
+/// range-based version of the fill std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange& fill(ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    std::fill(boost::begin(rng), boost::end(rng), val);
+    return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange& fill(const ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    std::fill(boost::begin(rng), boost::end(rng), val);
+    return rng;
+}
+
+    } // namespace range
+    using range::fill;
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/fill_n.hpp b/include/boost/range/algorithm/fill_n.hpp
new file mode 100644
index 0000000..02a0c2a
--- /dev/null
+++ b/include/boost/range/algorithm/fill_n.hpp
@@ -0,0 +1,53 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function fill_n
+///
+/// range-based version of the fill_n std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre n <= std::distance(boost::begin(rng), boost::end(rng))
+template< class ForwardRange, class Size, class Value >
+inline ForwardRange& fill_n(ForwardRange& rng, Size n, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+    std::fill_n(boost::begin(rng), n, val);
+    return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Size, class Value >
+inline const ForwardRange& fill_n(const ForwardRange& rng, Size n, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+    std::fill_n(boost::begin(rng), n, val);
+    return rng;
+}
+
+    } // namespace range
+    using range::fill_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find.hpp b/include/boost/range/algorithm/find.hpp
new file mode 100644
index 0000000..72c5cf1
--- /dev/null
+++ b/include/boost/range/algorithm/find.hpp
@@ -0,0 +1,80 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function find
+///
+/// range-based version of the find std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange>,
+    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return range_return<SinglePassRange,re>::
+        pack(std::find(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return range_return<const SinglePassRange,re>::
+        pack(std::find(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+    } // namespace range
+    using range::find;
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_end.hpp b/include/boost/range/algorithm/find_end.hpp
new file mode 100644
index 0000000..757e999
--- /dev/null
+++ b/include/boost/range/algorithm/find_end.hpp
@@ -0,0 +1,152 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function find_end
+///
+/// range-based version of the find_end std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange1>,
+    BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_end(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type
+find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_end(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange1>,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_end(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_end(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange1>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<ForwardRange1,re>::
+        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+                           boost::begin(rng2), boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<const ForwardRange1,re>::
+        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+                           boost::begin(rng2), boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange1>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<ForwardRange1,re>::
+        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+                           boost::begin(rng2), boost::end(rng2), pred),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<const ForwardRange1,re>::
+        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+                           boost::begin(rng2), boost::end(rng2), pred),
+             rng1);
+}
+
+    } // namespace range
+    using range::find_end;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_first_of.hpp b/include/boost/range/algorithm/find_first_of.hpp
new file mode 100644
index 0000000..4cb5989
--- /dev/null
+++ b/include/boost/range/algorithm/find_first_of.hpp
@@ -0,0 +1,155 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function find_first_of
+///
+/// range-based version of the find_first_of std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange1>,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+                              boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+                              boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange1>,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+                              boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+                              boost::begin(rng2),boost::end(rng2),pred);
+}
+
+// range return overloads
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange1>,
+    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<SinglePassRange1,re>::
+        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+                                boost::begin(rng2), boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<const SinglePassRange1,re>::
+        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+                                boost::begin(rng2), boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange1>,
+    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2,
+              BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<SinglePassRange1,re>::
+        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+                                boost::begin(rng2), boost::end(rng2), pred),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2,
+              BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+    return range_return<const SinglePassRange1,re>::
+        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+                                boost::begin(rng2), boost::end(rng2), pred),
+             rng1);
+}
+
+    } // namespace range
+    using range::find_first_of;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_if.hpp b/include/boost/range/algorithm/find_if.hpp
new file mode 100644
index 0000000..2d1926d
--- /dev/null
+++ b/include/boost/range/algorithm/find_if.hpp
@@ -0,0 +1,81 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function find_if
+///
+/// range-based version of the find_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<SinglePassRange>,
+    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    return range_return<SinglePassRange,re>::
+        pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return range_return<const SinglePassRange,re>::
+        pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+             rng);
+}
+
+    } // namespace range
+    using range::find_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/for_each.hpp b/include/boost/range/algorithm/for_each.hpp
new file mode 100644
index 0000000..ea731b2
--- /dev/null
+++ b/include/boost/range/algorithm/for_each.hpp
@@ -0,0 +1,110 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/ref.hpp>
+#include <algorithm>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+#include <xutility>
+#endif
+
+namespace boost
+{
+    namespace range
+    {
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+        namespace for_each_detail
+        {
+            template<typename Iterator, typename UnaryFunction>
+            inline UnaryFunction
+            for_each_impl(Iterator first, Iterator last, UnaryFunction fun,
+                          typename ::boost::enable_if<
+                            is_reference_wrapper<UnaryFunction>,
+                            void
+                          >::type* = 0)
+            {
+                    typedef typename std::_Get_unchecked_type<Iterator>::type
+                                unchecked_iterator;
+
+                    unchecked_iterator unchecked_last = std::_Unchecked(last);
+                    for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first)
+                            fun.get()(*unchecked_first);
+
+                    return fun;
+            }
+
+            template<typename Iterator, typename UnaryFunction>
+            inline UnaryFunction
+            for_each_impl(Iterator first, Iterator last, UnaryFunction fn,
+                          typename disable_if<
+                            is_reference_wrapper<UnaryFunction>,
+                            void
+                          >::type* = 0)
+            {
+                return std::for_each<Iterator, UnaryFunction>(first, last, fn);
+            }
+        }
+#endif
+
+/// \brief template function for_each
+///
+/// range-based version of the for_each std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryFunction is a model of the UnaryFunctionConcept
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+    
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+        return for_each_detail::for_each_impl<
+                typename range_iterator<SinglePassRange>::type,
+                UnaryFunction
+        >(boost::begin(rng), boost::end(rng), fun);
+#else
+    return std::for_each<
+        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
+        UnaryFunction
+    >(boost::begin(rng),boost::end(rng),fun);
+#endif    
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+        return for_each_detail::for_each_impl<
+                typename range_iterator<const SinglePassRange>::type,
+                UnaryFunction
+        >(boost::begin(rng), boost::end(rng), fun);
+#else    
+    return std::for_each<
+        BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type,
+        UnaryFunction
+    >(boost::begin(rng), boost::end(rng), fun);
+#endif    
+}
+
+    } // namespace range
+    using range::for_each;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/generate.hpp b/include/boost/range/algorithm/generate.hpp
new file mode 100644
index 0000000..324412c
--- /dev/null
+++ b/include/boost/range/algorithm/generate.hpp
@@ -0,0 +1,49 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+/// \brief template function generate
+///
+/// range-based version of the generate std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template< class ForwardRange, class Generator >
+inline ForwardRange& generate( ForwardRange& rng, Generator gen )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    std::generate(boost::begin(rng), boost::end(rng), gen);
+    return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Generator >
+inline const ForwardRange& generate( const ForwardRange& rng, Generator gen )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    std::generate(boost::begin(rng), boost::end(rng), gen);
+    return rng;
+}
+
+    } // namespace range
+    using range::generate;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/heap_algorithm.hpp b/include/boost/range/algorithm/heap_algorithm.hpp
new file mode 100644
index 0000000..584920d
--- /dev/null
+++ b/include/boost/range/algorithm/heap_algorithm.hpp
@@ -0,0 +1,194 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function push_heap
+///
+/// range-based version of the push_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::push_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::push_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \brief template function pop_heap
+///
+/// range-based version of the pop_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::pop_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::pop_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \brief template function make_heap
+///
+/// range-based version of the make_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::make_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::make_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \brief template function sort_heap
+///
+/// range-based version of the sort_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::sort_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::sort_heap(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::push_heap;
+    using range::pop_heap;
+    using range::make_heap;
+    using range::sort_heap;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/inplace_merge.hpp b/include/boost/range/algorithm/inplace_merge.hpp
new file mode 100644
index 0000000..dfadbaa
--- /dev/null
+++ b/include/boost/range/algorithm/inplace_merge.hpp
@@ -0,0 +1,74 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function inplace_merge
+///
+/// range-based version of the inplace_merge std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+    BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+    BOOST_DEDUCED_TYPENAME boost::range_iterator<BidirectionalRange>::type middle,
+    BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+    return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+    BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle,
+    BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::inplace_merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/lexicographical_compare.hpp b/include/boost/range/algorithm/lexicographical_compare.hpp
new file mode 100644
index 0000000..c6e4bc8
--- /dev/null
+++ b/include/boost/range/algorithm/lexicographical_compare.hpp
@@ -0,0 +1,58 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function lexicographic_compare
+///
+/// range-based version of the lexicographic_compare std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+                                    const SinglePassRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::lexicographical_compare(
+        boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class BinaryPredicate>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+                                    const SinglePassRange2& rng2,
+                                    BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::lexicographical_compare(
+        boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2), pred);
+}
+
+    } // namespace range
+    using range::lexicographical_compare;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/lower_bound.hpp b/include/boost/range/algorithm/lower_bound.hpp
new file mode 100644
index 0000000..cb5e639
--- /dev/null
+++ b/include/boost/range/algorithm/lower_bound.hpp
@@ -0,0 +1,124 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function lower_bound
+///
+/// range-based version of the lower_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+             rng);
+}
+
+    } // namespace range
+    using range::lower_bound;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/max_element.hpp b/include/boost/range/algorithm/max_element.hpp
new file mode 100644
index 0000000..dd2b9cb
--- /dev/null
+++ b/include/boost/range/algorithm/max_element.hpp
@@ -0,0 +1,115 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function max_element
+///
+/// range-based version of the max_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return boost::first_max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return boost::first_max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        boost::first_max_element(boost::begin(rng), boost::end(rng)),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        boost::first_max_element(boost::begin(rng), boost::end(rng)),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+    } // namespace range
+    using range::max_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/merge.hpp b/include/boost/range/algorithm/merge.hpp
new file mode 100644
index 0000000..c81b8c7
--- /dev/null
+++ b/include/boost/range/algorithm/merge.hpp
@@ -0,0 +1,61 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function merge
+///
+/// range-based version of the merge std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+///
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+                            const SinglePassRange2& rng2,
+                            OutputIterator          out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::merge(boost::begin(rng1), boost::end(rng1),
+                      boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator, class BinaryPredicate>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+                            const SinglePassRange2& rng2,
+                            OutputIterator          out,
+                            BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::merge(boost::begin(rng1), boost::end(rng1),
+                      boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+    } // namespace range
+    using range::merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/min_element.hpp b/include/boost/range/algorithm/min_element.hpp
new file mode 100644
index 0000000..339f56a
--- /dev/null
+++ b/include/boost/range/algorithm/min_element.hpp
@@ -0,0 +1,115 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function min_element
+///
+/// range-based version of the min_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return boost::first_min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return boost::first_min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        boost::first_min_element(boost::begin(rng), boost::end(rng)),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        boost::first_min_element(boost::begin(rng), boost::end(rng)),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+    } // namespace range
+    using range::min_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/mismatch.hpp b/include/boost/range/algorithm/mismatch.hpp
new file mode 100644
index 0000000..2819c33
--- /dev/null
+++ b/include/boost/range/algorithm/mismatch.hpp
@@ -0,0 +1,195 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2 >
+        inline std::pair<SinglePassTraversalReadableIterator1,
+                         SinglePassTraversalReadableIterator2>
+        mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+                      SinglePassTraversalReadableIterator1 last1,
+                      SinglePassTraversalReadableIterator2 first2,
+                      SinglePassTraversalReadableIterator2 last2)
+        {
+            while (first1 != last1 && first2 != last2 && *first1 == *first2)
+            {
+                ++first1;
+                ++first2;
+            }
+            return std::pair<SinglePassTraversalReadableIterator1,
+                             SinglePassTraversalReadableIterator2>(first1, first2);
+        }
+
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2,
+                  class BinaryPredicate >
+        inline std::pair<SinglePassTraversalReadableIterator1,
+                         SinglePassTraversalReadableIterator2>
+        mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+                      SinglePassTraversalReadableIterator1 last1,
+                      SinglePassTraversalReadableIterator2 first2,
+                      SinglePassTraversalReadableIterator2 last2,
+                      BinaryPredicate pred)
+        {
+            while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
+            {
+                ++first1;
+                ++first2;
+            }
+            return std::pair<SinglePassTraversalReadableIterator1,
+                             SinglePassTraversalReadableIterator2>(first1, first2);
+        }
+    } // namespace range_detail
+
+    namespace range
+    {
+/// \brief template function mismatch
+///
+/// range-based version of the mismatch std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return ::boost::range_detail::mismatch_impl(
+        ::boost::begin(rng1), ::boost::end(rng1),
+        ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+    } // namespace range
+    using range::mismatch;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/nth_element.hpp b/include/boost/range/algorithm/nth_element.hpp
new file mode 100644
index 0000000..a605595
--- /dev/null
+++ b/include/boost/range/algorithm/nth_element.hpp
@@ -0,0 +1,74 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function nth_element
+///
+/// range-based version of the nth_element std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::nth_element(boost::begin(rng), nth, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::nth_element(boost::begin(rng), nth, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth,
+    BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth,
+    BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::nth_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partial_sort.hpp b/include/boost/range/algorithm/partial_sort.hpp
new file mode 100644
index 0000000..d7044cd
--- /dev/null
+++ b/include/boost/range/algorithm/partial_sort.hpp
@@ -0,0 +1,76 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function partial_sort
+///
+/// range-based version of the partial_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
+    BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+                        sort_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
+    BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+                        sort_pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::partial_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partial_sort_copy.hpp b/include/boost/range/algorithm/partial_sort_copy.hpp
new file mode 100644
index 0000000..9129389
--- /dev/null
+++ b/include/boost/range/algorithm/partial_sort_copy.hpp
@@ -0,0 +1,82 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function partial_sort_copy
+///
+/// range-based version of the partial_sort_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre RandomAccessRange is a model of the Mutable_RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+         class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2,
+    BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+         class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2,
+    BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2), pred);
+}
+
+    } // namespace range
+    using range::partial_sort_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partition.hpp b/include/boost/range/algorithm/partition.hpp
new file mode 100644
index 0000000..b814a24
--- /dev/null
+++ b/include/boost/range/algorithm/partition.hpp
@@ -0,0 +1,74 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function partition
+///
+/// range-based version of the partition std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+          class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return boost::range_return<ForwardRange,re>::
+        pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+          class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return boost::range_return<const ForwardRange,re>::
+        pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+    } // namespace range
+    using range::partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/permutation.hpp b/include/boost/range/algorithm/permutation.hpp
new file mode 100644
index 0000000..75388cc
--- /dev/null
+++ b/include/boost/range/algorithm/permutation.hpp
@@ -0,0 +1,108 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function next_permutation
+///
+/// range-based version of the next_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool next_permutation(BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool next_permutation(const BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return std::next_permutation(boost::begin(rng), boost::end(rng),
+                                 comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(const BidirectionalRange& rng,
+                             Compare                   comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::next_permutation(boost::begin(rng), boost::end(rng),
+                                 comp_pred);
+}
+
+/// \brief template function prev_permutation
+///
+/// range-based version of the prev_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool prev_permutation(BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool prev_permutation(const BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return std::prev_permutation(boost::begin(rng), boost::end(rng),
+                                 comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(const BidirectionalRange& rng,
+                             Compare                   comp_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::prev_permutation(boost::begin(rng), boost::end(rng),
+                                 comp_pred);
+}
+
+    } // namespace range
+    using range::next_permutation;
+    using range::prev_permutation;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/random_shuffle.hpp b/include/boost/range/algorithm/random_shuffle.hpp
new file mode 100644
index 0000000..2475173
--- /dev/null
+++ b/include/boost/range/algorithm/random_shuffle.hpp
@@ -0,0 +1,141 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
+#include <cstdlib>
+#endif
+
+namespace boost
+{
+    namespace range
+    {
+
+        namespace detail
+        {
+#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
+
+// wrap std::rand as UniformRandomBitGenerator
+struct wrap_rand
+{
+    typedef unsigned int result_type;
+
+    static result_type (min)()
+    {
+        return 0;
+    }
+
+    static result_type (max)()
+    {
+        return RAND_MAX;
+    }
+
+    result_type operator()()
+    {
+        return std::rand();
+    }
+};
+
+template< class RandomIt >
+inline void random_shuffle(RandomIt first, RandomIt last)
+{
+    std::shuffle(first, last, wrap_rand());
+}
+
+// wrap Generator as UniformRandomBitGenerator
+template< class Generator >
+struct wrap_generator
+{
+    typedef unsigned int result_type;
+    static const int max_arg = ((0u - 1u) >> 2) + 1;
+    Generator& g;
+
+    wrap_generator(Generator& gen) : g(gen) {}
+
+    static result_type (min)()
+    {
+        return 0;
+    }
+
+    static result_type (max)()
+    {
+        return max_arg - 1;
+    }
+
+    result_type operator()()
+    {
+        return static_cast<result_type>(g(max_arg));
+    }
+};
+
+template< class RandomIt, class Generator >
+inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen)
+{
+    std::shuffle(first, last, wrap_generator< Generator >(gen));
+}
+
+#else
+    
+using std::random_shuffle;
+
+#endif  
+        } // namespace detail
+
+/// \brief template function random_shuffle
+///
+/// range-based version of the random_shuffle std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    detail::random_shuffle(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    detail::random_shuffle(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+    return rng;
+}
+
+    } // namespace range
+    using range::random_shuffle;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove.hpp b/include/boost/range/algorithm/remove.hpp
new file mode 100644
index 0000000..699a7cd
--- /dev/null
+++ b/include/boost/range/algorithm/remove.hpp
@@ -0,0 +1,74 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function remove
+///
+/// range-based version of the remove std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+remove(ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove(ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        std::remove(boost::begin(rng), boost::end(rng), val),
+        rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        std::remove(boost::begin(rng), boost::end(rng), val),
+        rng);
+}
+
+    } // namespace range
+    using range::remove;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_copy.hpp b/include/boost/range/algorithm/remove_copy.hpp
new file mode 100644
index 0000000..b65747e
--- /dev/null
+++ b/include/boost/range/algorithm/remove_copy.hpp
@@ -0,0 +1,44 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function remove_copy
+///
+/// range-based version of the remove_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre Objects of type Value can be compared for equality with objects of
+/// InputIterator's value type.
+template< class SinglePassRange, class OutputIterator, class Value >
+inline OutputIterator
+remove_copy(const SinglePassRange& rng, OutputIterator out_it, const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::remove_copy(boost::begin(rng), boost::end(rng), out_it, val);
+}
+
+    } // namespace range
+    using range::remove_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_copy_if.hpp b/include/boost/range/algorithm/remove_copy_if.hpp
new file mode 100644
index 0000000..8d9c37b
--- /dev/null
+++ b/include/boost/range/algorithm/remove_copy_if.hpp
@@ -0,0 +1,38 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    /// \brief template function remove_copy_if
+    ///
+    /// range-based version of the remove_copy_if std algorithm
+    ///
+    /// \pre SinglePassRange is a model of the SinglePassRangeConcept
+    /// \pre OutputIterator is a model of the OutputIteratorConcept
+    /// \pre Predicate is a model of the PredicateConcept
+    /// \pre InputIterator's value type is convertible to Predicate's argument type
+    /// \pre out_it is not an iterator in the range rng
+    template< class SinglePassRange, class OutputIterator, class Predicate >
+    inline OutputIterator
+    remove_copy_if(const SinglePassRange& rng, OutputIterator out_it, Predicate pred)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+        return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred);
+    }
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_if.hpp b/include/boost/range/algorithm/remove_if.hpp
new file mode 100644
index 0000000..a965df0
--- /dev/null
+++ b/include/boost/range/algorithm/remove_if.hpp
@@ -0,0 +1,75 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function remove_if
+///
+/// range-based version of the remove_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::pack(
+        std::remove_if(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::pack(
+        std::remove_if(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+    } // namespace range
+    using range::remove_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace.hpp b/include/boost/range/algorithm/replace.hpp
new file mode 100644
index 0000000..44d3e4c
--- /dev/null
+++ b/include/boost/range/algorithm/replace.hpp
@@ -0,0 +1,53 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function replace
+///
+/// range-based version of the replace std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange&
+replace(ForwardRange& rng, const Value& what,
+        const Value& with_what)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+    return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange&
+replace(const ForwardRange& rng, const Value& what,
+        const Value& with_what)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+    return rng;
+}
+
+    } // namespace range
+    using range::replace;
+} // namespace boost;
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_copy.hpp b/include/boost/range/algorithm/replace_copy.hpp
new file mode 100644
index 0000000..0c02005
--- /dev/null
+++ b/include/boost/range/algorithm/replace_copy.hpp
@@ -0,0 +1,42 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function replace_copy
+///
+/// range-based version of the replace_copy std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class OutputIterator, class Value >
+inline OutputIterator
+replace_copy(const ForwardRange& rng, OutputIterator out_it, const Value& what,
+        const Value& with_what)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
+        what, with_what);
+}
+
+    } // namespace range
+    using range::replace_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_copy_if.hpp b/include/boost/range/algorithm/replace_copy_if.hpp
new file mode 100644
index 0000000..d313151
--- /dev/null
+++ b/include/boost/range/algorithm/replace_copy_if.hpp
@@ -0,0 +1,46 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function replace_copy_if
+///
+/// range-based version of the replace_copy_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Predicate is a model of the PredicateConcept
+/// \pre Value is convertible to Predicate's argument type
+/// \pre Value is Assignable
+/// \pre Value is convertible to a type in OutputIterator's set of value types.
+template< class ForwardRange, class OutputIterator, class Predicate, class Value >
+inline OutputIterator
+replace_copy_if(const ForwardRange& rng, OutputIterator out_it, Predicate pred,
+        const Value& with_what)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::replace_copy_if(boost::begin(rng), boost::end(rng), out_it,
+        pred, with_what);
+}
+
+    } // namespace range
+    using range::replace_copy_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_if.hpp b/include/boost/range/algorithm/replace_if.hpp
new file mode 100644
index 0000000..93d5a1f
--- /dev/null
+++ b/include/boost/range/algorithm/replace_if.hpp
@@ -0,0 +1,54 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function replace_if
+///
+/// range-based version of the replace_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline ForwardRange&
+    replace_if(ForwardRange& rng, UnaryPredicate pred,
+               const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+    return rng;
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline const ForwardRange&
+    replace_if(const ForwardRange& rng, UnaryPredicate pred,
+               const Value& val)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+    return rng;
+}
+
+    } // namespace range
+    using range::replace_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/reverse.hpp b/include/boost/range/algorithm/reverse.hpp
new file mode 100644
index 0000000..20a7eb1
--- /dev/null
+++ b/include/boost/range/algorithm/reverse.hpp
@@ -0,0 +1,50 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function reverse
+///
+/// range-based version of the reverse std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& reverse(BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    std::reverse(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& reverse(const BidirectionalRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    std::reverse(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+    } // namespace range
+    using range::reverse;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/reverse_copy.hpp b/include/boost/range/algorithm/reverse_copy.hpp
new file mode 100644
index 0000000..f1990ad
--- /dev/null
+++ b/include/boost/range/algorithm/reverse_copy.hpp
@@ -0,0 +1,40 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function reverse_copy
+///
+/// range-based version of the reverse_copy std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange, class OutputIterator>
+inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::reverse_copy(boost::begin(rng), boost::end(rng), out);
+}
+
+    } // namespace range
+    using range::reverse_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/rotate.hpp b/include/boost/range/algorithm/rotate.hpp
new file mode 100644
index 0000000..ca4b223
--- /dev/null
+++ b/include/boost/range/algorithm/rotate.hpp
@@ -0,0 +1,51 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function rotate
+///
+/// range-based version of the rotate std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template<class ForwardRange>
+inline ForwardRange& rotate(ForwardRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    std::rotate(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class ForwardRange>
+inline const ForwardRange& rotate(const ForwardRange& rng,
+    BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    std::rotate(boost::begin(rng), middle, boost::end(rng));
+    return rng;
+}
+
+    } // namespace range
+    using range::rotate;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/rotate_copy.hpp b/include/boost/range/algorithm/rotate_copy.hpp
new file mode 100644
index 0000000..0409ac5
--- /dev/null
+++ b/include/boost/range/algorithm/rotate_copy.hpp
@@ -0,0 +1,44 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+    /// \brief template function rotate
+    ///
+    /// range-based version of the rotate std algorithm
+    ///
+    /// \pre Rng meets the requirements for a Forward range
+    template<typename ForwardRange, typename OutputIterator>
+    inline OutputIterator rotate_copy(
+        const ForwardRange&                                             rng,
+        BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle,
+        OutputIterator                                                  target
+        )
+    {
+        BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+        return std::rotate_copy(boost::begin(rng), middle, boost::end(rng), target);
+    }
+
+    } // namespace range
+    using range::rotate_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/search.hpp b/include/boost/range/algorithm/search.hpp
new file mode 100644
index 0000000..28cc6e6
--- /dev/null
+++ b/include/boost/range/algorithm/search.hpp
@@ -0,0 +1,134 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return std::search(boost::begin(rng1),boost::end(rng1),
+                       boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return std::search(boost::begin(rng1), boost::end(rng1),
+                       boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return std::search(boost::begin(rng1),boost::end(rng1),
+                       boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return std::search(boost::begin(rng1), boost::end(rng1),
+                       boost::begin(rng2), boost::end(rng2), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return range_return<ForwardRange1,re>::
+        pack(std::search(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return range_return<const ForwardRange1,re>::
+        pack(std::search(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2)),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return range_return<ForwardRange1,re>::
+        pack(std::search(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2),pred),
+             rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+    return range_return<const ForwardRange1,re>::
+        pack(std::search(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2),pred),
+             rng1);
+}
+
+    } // namespace range
+    using range::search;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/search_n.hpp b/include/boost/range/algorithm/search_n.hpp
new file mode 100644
index 0000000..ccfb27a
--- /dev/null
+++ b/include/boost/range/algorithm/search_n.hpp
@@ -0,0 +1,360 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <boost/range/value_type.hpp>
+#include <iterator>
+#include <algorithm>
+
+namespace boost
+{
+
+namespace range_detail
+{
+    // Rationale: search_n is implemented rather than delegate to
+    // the standard library implementation because some standard
+    // library implementations are broken eg. MSVC.
+
+    // search_n forward iterator version
+    template<typename ForwardIterator, typename Integer, typename Value>
+    inline ForwardIterator
+    search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
+                  const Value& value, std::forward_iterator_tag)
+    {
+        first = std::find(first, last, value);
+        while (first != last)
+        {
+            typename std::iterator_traits<ForwardIterator>::difference_type n = count;
+            ForwardIterator i = first;
+            ++i;
+            while (i != last && n != 1 && *i==value)
+            {
+                ++i;
+                --n;
+            }
+            if (n == 1)
+                return first;
+            if (i == last)
+                return last;
+            first = std::find(++i, last, value);
+        }
+        return last;
+    }
+
+    // search_n random-access iterator version
+    template<typename RandomAccessIterator, typename Integer, typename Value>
+    inline RandomAccessIterator
+    search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
+                  Integer count, const Value& value,
+                  std::random_access_iterator_tag)
+    {
+        typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+        difference_t tail_size = last - first;
+        const difference_t pattern_size = count;
+
+        if (tail_size < pattern_size)
+            return last;
+
+        const difference_t skip_offset = pattern_size - 1;
+        RandomAccessIterator look_ahead = first + skip_offset;
+        tail_size -= pattern_size;
+
+        while (1)
+        {
+            // look_ahead here is pointing to the last element of the
+            // next possible match
+            while (!(*look_ahead == value)) // skip loop...
+            {
+                if (tail_size < pattern_size)
+                    return last; // no match
+                look_ahead += pattern_size;
+                tail_size -= pattern_size;
+            }
+            difference_t remainder = skip_offset;
+            for (RandomAccessIterator back_track = look_ahead - 1;
+                    *back_track == value; --back_track)
+            {
+                if (--remainder == 0)
+                {
+                    return look_ahead - skip_offset; // matched
+                }
+            }
+            if (remainder > tail_size)
+                return last; // no match
+            look_ahead += remainder;
+            tail_size -= remainder;
+        }
+
+        return last;
+    }
+
+    // search_n for forward iterators using a binary predicate
+    // to determine a match
+    template<typename ForwardIterator, typename Integer, typename Value,
+             typename BinaryPredicate>
+    inline ForwardIterator
+    search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+                       Integer count, const Value& value,
+                       BinaryPredicate pred, std::forward_iterator_tag)
+    {
+        typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
+
+        while (first != last && !static_cast<bool>(pred(*first, value)))
+            ++first;
+
+        while (first != last)
+        {
+            difference_t n = count;
+            ForwardIterator i = first;
+            ++i;
+            while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
+            {
+                ++i;
+                --n;
+            }
+            if (n == 1)
+                return first;
+            if (i == last)
+                return last;
+            first = ++i;
+            while (first != last && !static_cast<bool>(pred(*first, value)))
+                ++first;
+        }
+        return last;
+    }
+
+    // search_n for random-access iterators using a binary predicate
+    // to determine a match
+    template<typename RandomAccessIterator, typename Integer,
+             typename Value, typename BinaryPredicate>
+    inline RandomAccessIterator
+    search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
+                       Integer count, const Value& value,
+                       BinaryPredicate pred, std::random_access_iterator_tag)
+    {
+        typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+        difference_t tail_size = last - first;
+        const difference_t pattern_size = count;
+
+        if (tail_size < pattern_size)
+            return last;
+
+        const difference_t skip_offset = pattern_size - 1;
+        RandomAccessIterator look_ahead = first + skip_offset;
+        tail_size -= pattern_size;
+
+        while (1)
+        {
+            // look_ahead points to the last element of the next
+            // possible match
+            while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
+            {
+                if (tail_size < pattern_size)
+                    return last; // no match
+                look_ahead += pattern_size;
+                tail_size -= pattern_size;
+            }
+            difference_t remainder = skip_offset;
+            for (RandomAccessIterator back_track = look_ahead - 1;
+                    pred(*back_track, value); --back_track)
+            {
+                if (--remainder == 0)
+                    return look_ahead -= skip_offset; // success
+            }
+            if (remainder > tail_size)
+            {
+                return last; // no match
+            }
+            look_ahead += remainder;
+            tail_size -= remainder;
+        }
+    }
+
+    template<typename ForwardIterator, typename Integer, typename Value>
+    inline ForwardIterator
+    search_n_impl(ForwardIterator first, ForwardIterator last,
+                  Integer count, const Value& value)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+        BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
+        BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
+        //BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
+
+        typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+        if (count <= 0)
+            return first;
+        if (count == 1)
+            return std::find(first, last, value);
+        return range_detail::search_n_impl(first, last, count, value, cat_t());
+    }
+
+    template<typename ForwardIterator, typename Integer, typename Value,
+             typename BinaryPredicate>
+    inline ForwardIterator
+    search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+                       Integer count, const Value& value,
+                       BinaryPredicate pred)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+        BOOST_RANGE_CONCEPT_ASSERT((
+            BinaryPredicateConcept<
+                BinaryPredicate,
+                typename std::iterator_traits<ForwardIterator>::value_type,
+                Value>
+            ));
+
+        typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+        if (count <= 0)
+            return first;
+        if (count == 1)
+        {
+            while (first != last && !static_cast<bool>(pred(*first, value)))
+                ++first;
+            return first;
+        }
+        return range_detail::search_n_pred_impl(first, last, count,
+                                                value, pred, cat_t());
+    }
+} // namespace range_detail
+
+namespace range {
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Integer is an integral type
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
+/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+    return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+         BinaryPredicate binary_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
+    return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+        count, value, binary_pred);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+          class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+         BinaryPredicate binary_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
+    return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+        count, value, binary_pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+          class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    return range_return<ForwardRange,re>::
+        pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
+                           count, value),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+          class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+    return range_return<const ForwardRange,re>::
+        pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
+                           count, value),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+          class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+         BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
+        const Value&>));
+    return range_return<ForwardRange,re>::
+        pack(range_detail::search_n_pred_impl(boost::begin(rng),
+                                              boost::end(rng),
+                           count, value, pred),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+          class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+         BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+        BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
+        const Value&>));
+    return range_return<const ForwardRange,re>::
+        pack(range_detail::search_n_pred_impl(boost::begin(rng),
+                                              boost::end(rng),
+                           count, value, pred),
+             rng);
+}
+
+    } // namespace range
+    using range::search_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/set_algorithm.hpp b/include/boost/range/algorithm/set_algorithm.hpp
new file mode 100644
index 0000000..82ef8ec
--- /dev/null
+++ b/include/boost/range/algorithm/set_algorithm.hpp
@@ -0,0 +1,198 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function includes
+///
+/// range-based version of the includes std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool includes(const SinglePassRange1& rng1,
+                     const SinglePassRange2& rng2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::includes(boost::begin(rng1),boost::end(rng1),
+                         boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class BinaryPredicate>
+inline bool includes(const SinglePassRange1& rng1,
+                     const SinglePassRange2& rng2,
+                     BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::includes(boost::begin(rng1), boost::end(rng1),
+                         boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \brief template function set_union
+///
+/// range-based version of the set_union std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+                                const SinglePassRange2& rng2,
+                                OutputIterator          out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_union(boost::begin(rng1), boost::end(rng1),
+                          boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+                                const SinglePassRange2& rng2,
+                                OutputIterator          out,
+                                BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_union(boost::begin(rng1), boost::end(rng1),
+                          boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_intersection
+///
+/// range-based version of the set_intersection std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+                                       const SinglePassRange2& rng2,
+                                       OutputIterator          out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+                                 boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+                                       const SinglePassRange2& rng2,
+                                       OutputIterator          out,
+                                       BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+                                 boost::begin(rng2), boost::end(rng2),
+                                 out, pred);
+}
+
+/// \brief template function set_difference
+///
+/// range-based version of the set_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+                                     const SinglePassRange2& rng2,
+                                     OutputIterator out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_difference(boost::begin(rng1), boost::end(rng1),
+                               boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+                                     const SinglePassRange2& rng2,
+                                     OutputIterator          out,
+                                     BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_difference(
+        boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_symmetric_difference
+///
+/// range-based version of the set_symmetric_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
+                                         boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+         class OutputIterator, class BinaryPredicate>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+                         const SinglePassRange2& rng2,
+                         OutputIterator          out,
+                         BinaryPredicate         pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+    return std::set_symmetric_difference(
+        boost::begin(rng1), boost::end(rng1),
+        boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+    } // namespace range
+    using range::includes;
+    using range::set_union;
+    using range::set_intersection;
+    using range::set_difference;
+    using range::set_symmetric_difference;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/sort.hpp b/include/boost/range/algorithm/sort.hpp
new file mode 100644
index 0000000..45eecde
--- /dev/null
+++ b/include/boost/range/algorithm/sort.hpp
@@ -0,0 +1,68 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function sort
+///
+/// range-based version of the sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::sort(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::sort(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::sort(boost::begin(rng), boost::end(rng), pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::sort(boost::begin(rng), boost::end(rng), pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/stable_partition.hpp b/include/boost/range/algorithm/stable_partition.hpp
new file mode 100644
index 0000000..24febfc
--- /dev/null
+++ b/include/boost/range/algorithm/stable_partition.hpp
@@ -0,0 +1,73 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function stable_partition
+///
+/// range-based version of the stable_partition std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return std::stable_partition(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const BidirectionalRange>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return std::stable_partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<BidirectionalRange,re>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+    return range_return<BidirectionalRange,re>::pack(
+        std::stable_partition(boost::begin(rng), boost::end(rng), pred),
+        rng);
+}
+
+/// \overload
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const BidirectionalRange,re>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+    return range_return<const BidirectionalRange,re>::pack(
+        std::stable_partition(boost::begin(rng),boost::end(rng),pred),
+        rng);
+}
+
+    } // namespace range
+    using range::stable_partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/stable_sort.hpp b/include/boost/range/algorithm/stable_sort.hpp
new file mode 100644
index 0000000..d18da4d
--- /dev/null
+++ b/include/boost/range/algorithm/stable_sort.hpp
@@ -0,0 +1,68 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function stable_sort
+///
+/// range-based version of the stable_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::stable_sort(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::stable_sort(boost::begin(rng), boost::end(rng));
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+    std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+    return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+    std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+    return rng;
+}
+
+    } // namespace range
+    using range::stable_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/swap_ranges.hpp b/include/boost/range/algorithm/swap_ranges.hpp
new file mode 100644
index 0000000..52b0162
--- /dev/null
+++ b/include/boost/range/algorithm/swap_ranges.hpp
@@ -0,0 +1,132 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template<class Iterator1, class Iterator2>
+        void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+                              Iterator2 it2, Iterator2 last2,
+                              single_pass_traversal_tag,
+                              single_pass_traversal_tag)
+        {
+            ignore_unused_variable_warning(last2);
+            for (; it1 != last1; ++it1, ++it2)
+            {
+                BOOST_ASSERT( it2 != last2 );
+                std::iter_swap(it1, it2);
+            }
+        }
+
+        template<class Iterator1, class Iterator2>
+        void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+                              Iterator2 it2, Iterator2 last2,
+                              random_access_traversal_tag,
+                              random_access_traversal_tag)
+        {
+            ignore_unused_variable_warning(last2);
+            BOOST_ASSERT( last2 - it2 >= last1 - it1 );
+            std::swap_ranges(it1, last1, it2);
+        }
+
+        template<class Iterator1, class Iterator2>
+        void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
+                              Iterator2 first2, Iterator2 last2)
+        {
+            swap_ranges_impl(first1, last1, first2, last2,
+                BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
+                BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
+        }
+    } // namespace range_detail
+
+    namespace range
+    {
+
+/// \brief template function swap_ranges
+///
+/// range-based version of the swap_ranges std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+    boost::range_detail::swap_ranges_impl(
+        boost::begin(range1), boost::end(range1),
+        boost::begin(range2), boost::end(range2));
+
+    return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+    boost::range_detail::swap_ranges_impl(
+        boost::begin(range1), boost::end(range1),
+        boost::begin(range2), boost::end(range2));
+
+    return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+    boost::range_detail::swap_ranges_impl(
+        boost::begin(range1), boost::end(range1),
+        boost::begin(range2), boost::end(range2));
+
+    return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+    boost::range_detail::swap_ranges_impl(
+        boost::begin(range1), boost::end(range1),
+        boost::begin(range2), boost::end(range2));
+
+    return range2;
+}
+
+    } // namespace range
+    using range::swap_ranges;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/transform.hpp b/include/boost/range/algorithm/transform.hpp
new file mode 100644
index 0000000..ade147a
--- /dev/null
+++ b/include/boost/range/algorithm/transform.hpp
@@ -0,0 +1,96 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+        /// \brief template function transform
+        ///
+        /// range-based version of the transform std algorithm
+        ///
+        /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+        /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+        /// \pre OutputIterator is a model of the OutputIteratorConcept
+        /// \pre UnaryOperation is a model of the UnaryFunctionConcept
+        /// \pre BinaryOperation is a model of the BinaryFunctionConcept
+        template< class SinglePassRange1,
+                  class OutputIterator,
+                  class UnaryOperation >
+        inline OutputIterator
+        transform(const SinglePassRange1& rng,
+                  OutputIterator          out,
+                  UnaryOperation          fun)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            return std::transform(boost::begin(rng),boost::end(rng),out,fun);
+        }
+
+    } // namespace range
+
+    namespace range_detail
+    {
+        template< class SinglePassTraversalReadableIterator1,
+                  class SinglePassTraversalReadableIterator2,
+                  class OutputIterator,
+                  class BinaryFunction >
+        inline OutputIterator
+        transform_impl(SinglePassTraversalReadableIterator1 first1,
+                       SinglePassTraversalReadableIterator1 last1,
+                       SinglePassTraversalReadableIterator2 first2,
+                       SinglePassTraversalReadableIterator2 last2,
+                       OutputIterator                       out,
+                       BinaryFunction                       fn)
+        {
+            for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+            {
+                *out = fn(*first1, *first2);
+                ++out;
+            }
+            return out;
+        }
+    }
+
+    namespace range
+    {
+
+        /// \overload
+        template< class SinglePassRange1,
+                  class SinglePassRange2,
+                  class OutputIterator,
+                  class BinaryOperation >
+        inline OutputIterator
+        transform(const SinglePassRange1& rng1,
+                  const SinglePassRange2& rng2,
+                  OutputIterator          out,
+                  BinaryOperation         fun)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+            return boost::range_detail::transform_impl(
+                        boost::begin(rng1), boost::end(rng1),
+                        boost::begin(rng2), boost::end(rng2),
+                        out, fun);
+        }
+
+    } // namespace range
+    using range::transform;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/unique.hpp b/include/boost/range/algorithm/unique.hpp
new file mode 100644
index 0000000..8017a83
--- /dev/null
+++ b/include/boost/range/algorithm/unique.hpp
@@ -0,0 +1,107 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function unique
+///
+/// range-based version of the unique std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack( std::unique( boost::begin(rng),
+                           boost::end(rng)), rng );
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack( std::unique( boost::begin(rng),
+                           boost::end(rng)), rng );
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+             rng);
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+             rng);
+}
+
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
+unique( const ForwardRange& rng )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return ::boost::range::unique<return_begin_found>(rng, pred);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return ::boost::range::unique<return_begin_found>(rng, pred);
+}
+
+    } // namespace range
+    using range::unique;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/unique_copy.hpp b/include/boost/range/algorithm/unique_copy.hpp
new file mode 100644
index 0000000..0682d74
--- /dev/null
+++ b/include/boost/range/algorithm/unique_copy.hpp
@@ -0,0 +1,51 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function unique_copy
+///
+/// range-based version of the unique_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::unique_copy(boost::begin(rng), boost::end(rng), out_it);
+}
+/// \overload
+template< class SinglePassRange, class OutputIterator, class BinaryPredicate >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it,
+             BinaryPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    return std::unique_copy(boost::begin(rng), boost::end(rng), out_it, pred);
+}
+
+    } // namespace range
+    using range::unique_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/upper_bound.hpp b/include/boost/range/algorithm/upper_bound.hpp
new file mode 100644
index 0000000..c8acbc6
--- /dev/null
+++ b/include/boost/range/algorithm/upper_bound.hpp
@@ -0,0 +1,127 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function upper_bound
+///
+/// range-based version of the upper_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline
+BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+          class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+    is_const<ForwardRange>,
+    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    return range_return<ForwardRange,re>::
+        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+             rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+          class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    return range_return<const ForwardRange,re>::
+        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+             rng);
+}
+
+    } // namespace range
+    using range::upper_bound;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext.hpp b/include/boost/range/algorithm_ext.hpp
new file mode 100644
index 0000000..783d38a
--- /dev/null
+++ b/include/boost/range/algorithm_ext.hpp
@@ -0,0 +1,28 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2007. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_HPP
+#define BOOST_RANGE_ALGORITHM_EXT_HPP
+
+#include <boost/range/algorithm_ext/copy_n.hpp>
+#include <boost/range/algorithm_ext/for_each.hpp>
+#include <boost/range/algorithm_ext/is_sorted.hpp>
+#include <boost/range/algorithm_ext/iota.hpp>
+#include <boost/range/algorithm_ext/overwrite.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/range/algorithm_ext/push_front.hpp>
+#include <boost/range/algorithm_ext/insert.hpp>
+#include <boost/range/algorithm_ext/erase.hpp>
+
+#endif
diff --git a/include/boost/range/algorithm_ext/copy_n.hpp b/include/boost/range/algorithm_ext/copy_n.hpp
new file mode 100644
index 0000000..f855441
--- /dev/null
+++ b/include/boost/range/algorithm_ext/copy_n.hpp
@@ -0,0 +1,53 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function copy
+///
+/// range-based version of the copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre 0 <= n <= distance(rng)
+template< class SinglePassRange, class Size, class OutputIterator >
+inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+    BOOST_ASSERT( n <= static_cast<Size>(::boost::distance(rng)) );
+    BOOST_ASSERT( n >= static_cast<Size>(0) );
+
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = ::boost::begin(rng);
+
+    for (Size i = 0; i < n; ++i, ++out, ++source)
+        *out = *source;
+
+    return out;
+}
+
+    } // namespace range
+    using ::boost::range::copy_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/erase.hpp b/include/boost/range/algorithm_ext/erase.hpp
new file mode 100644
index 0000000..107d32b
--- /dev/null
+++ b/include/boost/range/algorithm_ext/erase.hpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class Container >
+inline Container& erase( Container& on,
+      iterator_range<BOOST_DEDUCED_TYPENAME Container::iterator> to_erase )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+    on.erase( boost::begin(to_erase), boost::end(to_erase) );
+    return on;
+}
+
+template< class Container, class T >
+inline Container& remove_erase( Container& on, const T& val )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+    on.erase(
+        std::remove(boost::begin(on), boost::end(on), val),
+        boost::end(on));
+    return on;
+}
+
+template< class Container, class Pred >
+inline Container& remove_erase_if( Container& on, Pred pred )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+    on.erase(
+        std::remove_if(boost::begin(on), boost::end(on), pred),
+        boost::end(on));
+    return on;
+}
+
+    } // namespace range
+    using range::erase;
+    using range::remove_erase;
+    using range::remove_erase_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/for_each.hpp b/include/boost/range/algorithm_ext/for_each.hpp
new file mode 100644
index 0000000..a470e2b
--- /dev/null
+++ b/include/boost/range/algorithm_ext/for_each.hpp
@@ -0,0 +1,86 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template<class InputIterator1, class InputIterator2, class Fn2>
+        inline Fn2 for_each_impl(InputIterator1 first1, InputIterator1 last1,
+                                 InputIterator2 first2, InputIterator2 last2,
+                                 Fn2 fn)
+        {
+            for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+            {
+                fn(*first1, *first2);
+            }
+            return fn;
+        }
+    }
+
+    namespace range
+    {
+        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+        inline Fn2 for_each(const SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+            return ::boost::range_detail::for_each_impl(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2), fn);
+        }
+
+        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+        inline Fn2 for_each(const SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+            return ::boost::range_detail::for_each_impl(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2), fn);
+        }
+
+        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+        inline Fn2 for_each(SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+            return ::boost::range_detail::for_each_impl(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2), fn);
+        }
+
+        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+        inline Fn2 for_each(SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+            return ::boost::range_detail::for_each_impl(
+                ::boost::begin(rng1), ::boost::end(rng1),
+                ::boost::begin(rng2), ::boost::end(rng2), fn);
+        }
+    } // namespace range
+    using range::for_each;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/insert.hpp b/include/boost/range/algorithm_ext/insert.hpp
new file mode 100644
index 0000000..51f1b8e
--- /dev/null
+++ b/include/boost/range/algorithm_ext/insert.hpp
@@ -0,0 +1,49 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class Container, class Range >
+inline Container& insert( Container& on,
+                          BOOST_DEDUCED_TYPENAME Container::iterator before,
+                          const Range& from )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
+    on.insert( before, boost::begin(from), boost::end(from) );
+    return on;
+}
+
+template< class Container, class Range >
+inline Container& insert( Container& on, const Range& from )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
+    on.insert(boost::begin(from), boost::end(from));
+    return on;
+}
+
+    } // namespace range
+    using range::insert;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/iota.hpp b/include/boost/range/algorithm_ext/iota.hpp
new file mode 100644
index 0000000..f7af446
--- /dev/null
+++ b/include/boost/range/algorithm_ext/iota.hpp
@@ -0,0 +1,54 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class ForwardRange, class Value >
+inline ForwardRange& iota( ForwardRange& rng, Value x )
+{
+    BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
+
+    iterator_t last_target = ::boost::end(rng);
+    for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
+        *target = x;
+
+    return rng;
+}
+
+template< class ForwardRange, class Value >
+inline const ForwardRange& iota( const ForwardRange& rng, Value x )
+{
+    BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type iterator_t;
+    
+    iterator_t last_target = ::boost::end(rng);
+    for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
+        *target = x;
+    
+    return rng;
+}
+
+    } // namespace range
+    using range::iota;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/is_sorted.hpp b/include/boost/range/algorithm_ext/is_sorted.hpp
new file mode 100644
index 0000000..3d00729
--- /dev/null
+++ b/include/boost/range/algorithm_ext/is_sorted.hpp
@@ -0,0 +1,57 @@
+//  Copyright Bryce Lelbach 2010
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/detail/is_sorted.hpp>
+#include <algorithm>
+
+namespace boost
+{
+    namespace range
+    {
+
+/// \brief template function is_sorted
+///
+/// range-based version of the is_sorted std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template<class SinglePassRange>
+inline bool is_sorted(const SinglePassRange& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME
+      range_value<const SinglePassRange>::type>));
+    return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class SinglePassRange, class BinaryPredicate>
+inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred)
+{
+    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+      BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type,
+      BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>));
+    return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred);
+}
+
+    } // namespace range
+
+using range::is_sorted;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/overwrite.hpp b/include/boost/range/algorithm_ext/overwrite.hpp
new file mode 100644
index 0000000..f84f6ea
--- /dev/null
+++ b/include/boost/range/algorithm_ext/overwrite.hpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class SinglePassRange1, class SinglePassRange2 >
+inline void overwrite( const SinglePassRange1& from, SinglePassRange2& to )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+        i = boost::begin(from), e = boost::end(from);
+
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
+        out = boost::begin(to);
+
+#ifndef NDEBUG
+    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
+        last_out = boost::end(to);
+#endif
+
+    for( ; i != e; ++out, ++i )
+    {
+#ifndef NDEBUG
+        BOOST_ASSERT( out != last_out
+            && "out of bounds in boost::overwrite()" );
+#endif
+        *out = *i;
+    }
+}
+
+template< class SinglePassRange1, class SinglePassRange2 >
+inline void overwrite( const SinglePassRange1& from, const SinglePassRange2& to )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+        i = boost::begin(from), e = boost::end(from);
+
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
+        out = boost::begin(to);
+
+#ifndef NDEBUG
+    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
+        last_out = boost::end(to);
+#endif
+
+    for( ; i != e; ++out, ++i )
+    {
+#ifndef NDEBUG
+        BOOST_ASSERT( out != last_out
+            && "out of bounds in boost::overwrite()" );
+#endif
+        *out = *i;
+    }
+}
+
+    } // namespace range
+    using range::overwrite;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/push_back.hpp b/include/boost/range/algorithm_ext/push_back.hpp
new file mode 100644
index 0000000..6fb9b9b
--- /dev/null
+++ b/include/boost/range/algorithm_ext/push_back.hpp
@@ -0,0 +1,41 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class Container, class Range >
+inline Container& push_back( Container& on, const Range& from )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
+    BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from),
+        "cannot copy from a container to itself");
+    on.insert( on.end(), boost::begin(from), boost::end(from) );
+    return on;
+}
+
+    } // namespace range
+    using range::push_back;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm_ext/push_front.hpp b/include/boost/range/algorithm_ext/push_front.hpp
new file mode 100644
index 0000000..e893098
--- /dev/null
+++ b/include/boost/range/algorithm_ext/push_front.hpp
@@ -0,0 +1,41 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template< class Container, class Range >
+inline Container& push_front( Container& on, const Range& from )
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
+    BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from),
+        "cannot copy from a container to itself");
+    on.insert( on.begin(), boost::begin(from), boost::end(from) );
+    return on;
+}
+
+    } // namespace range
+    using range::push_front;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/any_range.hpp b/include/boost/range/any_range.hpp
new file mode 100644
index 0000000..1cb5996
--- /dev/null
+++ b/include/boost/range/any_range.hpp
@@ -0,0 +1,204 @@
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/range/detail/any_iterator.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // If T is use_default, return the result of Default, otherwise
+        // return T.
+        //
+        // This is an implementation artifact used to pick intelligent default
+        // values when the user specified boost::use_default as a template
+        // parameter.
+        template<
+            class T,
+            class Default
+        >
+        struct any_range_default_help
+            : mpl::eval_if<
+                is_same<T, use_default>
+              , Default
+              , mpl::identity<T>
+            >
+        {
+        };
+
+        template<
+            class WrappedRange
+          , class Value
+          , class Reference
+        >
+        struct any_range_value_type
+        {
+# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+            typedef typename any_range_default_help<
+                    Value
+                  , mpl::eval_if<
+                        is_same<Reference, use_default>
+                      , range_value<
+                            typename remove_const<WrappedRange>
+                        ::type>
+                      , remove_reference<Reference>
+                    >
+                >::type type;
+# else
+            typedef typename any_range_default_help<
+                Value
+              , range_value<
+                    typename remove_const<WrappedRange>
+                ::type>
+            >::type type;
+# endif
+        };
+
+        template<
+            class Value
+          , class Traversal
+          , class Reference = Value&
+          , class Difference = std::ptrdiff_t
+          , class Buffer = use_default
+        >
+        class any_range
+            : public iterator_range<
+                        any_iterator<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , typename any_range_default_help<
+                                Buffer
+                              , mpl::identity<any_iterator_default_buffer>
+                            >::type
+                        >
+                    >
+        {
+            typedef iterator_range<
+                        any_iterator<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , typename any_range_default_help<
+                                Buffer
+                              , mpl::identity<any_iterator_default_buffer>
+                            >::type
+                        >
+                    > base_type;
+
+            struct enabler {};
+            struct disabler {};
+        public:
+            any_range()
+            {
+            }
+
+            any_range(const any_range& other)
+                : base_type(other)
+            {
+            }
+
+            template<class WrappedRange>
+            any_range(WrappedRange& wrapped_range)
+            : base_type(boost::begin(wrapped_range),
+                        boost::end(wrapped_range))
+            {
+            }
+
+            template<class WrappedRange>
+            any_range(const WrappedRange& wrapped_range)
+            : base_type(boost::begin(wrapped_range),
+                        boost::end(wrapped_range))
+            {
+            }
+
+            template<
+                class OtherValue
+              , class OtherTraversal
+              , class OtherReference
+              , class OtherDifference
+            >
+            any_range(const any_range<
+                                OtherValue
+                              , OtherTraversal
+                              , OtherReference
+                              , OtherDifference
+                              , Buffer
+                            >& other)
+            : base_type(boost::begin(other), boost::end(other))
+            {
+            }
+
+            template<class Iterator>
+            any_range(Iterator first, Iterator last)
+                : base_type(first, last)
+            {
+            }
+        };
+
+        template<
+            class WrappedRange
+          , class Value = use_default
+          , class Traversal = use_default
+          , class Reference = use_default
+          , class Difference = use_default
+          , class Buffer = use_default
+        >
+        struct any_range_type_generator
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> ));
+            typedef any_range<
+                typename any_range_value_type<
+                    WrappedRange
+                  , Value
+                  , typename any_range_default_help<
+                        Reference
+                      , range_reference<WrappedRange>
+                    >::type
+                >::type
+              , typename any_range_default_help<
+                            Traversal
+                          , iterator_traversal<
+                                typename range_iterator<WrappedRange>::type
+                            >
+                        >::type
+              , typename any_range_default_help<
+                    Reference
+                  , range_reference<WrappedRange>
+                >::type
+              , typename any_range_default_help<
+                    Difference
+                  , range_difference<WrappedRange>
+                >::type
+              , typename any_range_default_help<
+                    Buffer
+                  , mpl::identity<any_iterator_default_buffer>
+                >::type
+            > type;
+        };
+    } // namespace range_detail
+
+    using range_detail::any_range;
+    using range_detail::any_range_type_generator;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/as_array.hpp b/include/boost/range/as_array.hpp
new file mode 100644
index 0000000..69a1580
--- /dev/null
+++ b/include/boost/range/as_array.hpp
@@ -0,0 +1,45 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_AS_ARRAY_HPP
+#define BOOST_RANGE_AS_ARRAY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/detail/str_types.hpp>
+
+namespace boost
+{
+
+    template< class R >
+    inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type > 
+    as_array( R& r )
+    {
+        return boost::make_iterator_range( r );
+    }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+    template< class Range >
+    inline boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type > 
+    as_array( const Range& r )
+    {
+        return boost::make_iterator_range( r );
+    }
+    
+#endif
+    
+}
+
+#endif
+
diff --git a/include/boost/range/as_literal.hpp b/include/boost/range/as_literal.hpp
new file mode 100644
index 0000000..3bca1a8
--- /dev/null
+++ b/include/boost/range/as_literal.hpp
@@ -0,0 +1,170 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_AS_LITERAL_HPP
+#define BOOST_RANGE_AS_LITERAL_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/as_literal.hpp>
+#else
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/detail/str_types.hpp>
+
+#include <boost/detail/workaround.hpp>
+
+#include <cstring>
+
+#if !defined(BOOST_NO_CXX11_CHAR16_T) || !defined(BOOST_NO_CXX11_CHAR32_T)
+#include <string>  // for std::char_traits
+#endif
+
+#ifndef BOOST_NO_CWCHAR
+#include <cwchar>
+#endif
+
+namespace boost
+{
+    namespace range_detail
+    {
+        inline std::size_t length( const char* s )
+        {
+            return strlen( s );
+        }
+
+#ifndef BOOST_NO_CXX11_CHAR16_T
+        inline std::size_t length( const char16_t* s )
+        {
+            return std::char_traits<char16_t>::length( s );
+        }
+#endif
+
+#ifndef BOOST_NO_CXX11_CHAR32_T
+        inline std::size_t length( const char32_t* s )
+        {
+            return std::char_traits<char32_t>::length( s );
+        }
+#endif
+
+#ifndef BOOST_NO_CWCHAR
+        inline std::size_t length( const wchar_t* s )
+        {
+            return wcslen( s );
+        }
+#endif
+
+        //
+        // Remark: the compiler cannot choose between T* and T[sz]
+        // overloads, so we must put the T* internal to the
+        // unconstrained version.
+        //
+
+        inline bool is_char_ptr( char* )
+        {
+            return true;
+        }
+
+        inline bool is_char_ptr( const char* )
+        {
+            return true;
+        }
+
+#ifndef BOOST_NO_CXX11_CHAR16_T
+        inline bool is_char_ptr( char16_t* )
+        {
+            return true;
+        }
+
+        inline bool is_char_ptr( const char16_t* )
+        {
+            return true;
+        }
+#endif
+
+#ifndef BOOST_NO_CXX11_CHAR32_T
+        inline bool is_char_ptr( char32_t* )
+        {
+            return true;
+        }
+
+        inline bool is_char_ptr( const char32_t* )
+        {
+            return true;
+        }
+#endif
+
+#ifndef BOOST_NO_CWCHAR
+        inline bool is_char_ptr( wchar_t* )
+        {
+            return true;
+        }
+
+        inline bool is_char_ptr( const wchar_t* )
+        {
+            return true;
+        }
+#endif
+
+        template< class T >
+        inline long is_char_ptr( const T& /* r */ )
+        {
+            return 0L;
+        }
+
+        template< class T >
+        inline iterator_range<T*>
+        make_range( T* const r, bool )
+        {
+            return iterator_range<T*>( r, r + length(r) );
+        }
+
+        template< class T >
+        inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type>
+        make_range( T& r, long )
+        {
+            return boost::make_iterator_range( r );
+        }
+
+    }
+
+    template< class Range >
+    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
+    as_literal( Range& r )
+    {
+        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
+    }
+
+    template< class Range >
+    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type>
+    as_literal( const Range& r )
+    {
+        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
+    }
+
+    template< class Char, std::size_t sz >
+    inline iterator_range<Char*> as_literal( Char (&arr)[sz] )
+    {
+        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
+    }
+
+    template< class Char, std::size_t sz >
+    inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] )
+    {
+        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
+    }
+}
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+#endif
diff --git a/include/boost/range/atl.hpp b/include/boost/range/atl.hpp
new file mode 100644
index 0000000..e6500e5
--- /dev/null
+++ b/include/boost/range/atl.hpp
@@ -0,0 +1,724 @@
+#ifndef BOOST_RANGE_ATL_HPP
+#define BOOST_RANGE_ATL_HPP
+
+
+
+
+// Boost.Range ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <atldef.h> // _ATL_VER
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+    #if (_ATL_VER < 0x0700)
+        #define BOOST_RANGE_ATL_NO_COLLECTIONS
+    #endif
+#endif
+
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+    #if (_ATL_VER < 0x0700) // dubious
+        #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX
+    #endif
+#endif
+
+
+// forward declarations
+//
+
+
+#include <basetyps.h> // IID
+
+
+namespace ATL {
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+    // arrays
+    //
+    template< class E, class ETraits >
+    class CAtlArray;
+
+    template< class E >
+    class CAutoPtrArray;
+
+    template< class I, const IID *piid >
+    class CInterfaceArray;
+
+
+    // lists
+    //
+    template< class E, class ETraits >
+    class CAtlList;
+
+    template< class E >
+    class CAutoPtrList;
+
+    template< class E, class Allocator >
+    class CHeapPtrList;
+
+    template< class I, const IID *piid >
+    class CInterfaceList;
+
+
+    // maps
+    //
+    template< class K, class V, class KTraits, class VTraits >
+    class CAtlMap;
+
+    template< class K, class V, class KTraits, class VTraits >
+    class CRBTree;
+
+    template< class K, class V, class KTraits, class VTraits >
+    class CRBMap;
+
+    template< class K, class V, class KTraits, class VTraits >
+    class CRBMultiMap;
+
+
+    // strings
+    //
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
+    template< class BaseType, bool t_bMFCDLL >
+    class CSimpleStringT;
+#else
+    template< class BaseType >
+    class CSimpleStringT;
+#endif
+
+    template< class BaseType, class StringTraits >
+    class CStringT;
+
+    template< class StringType, int t_nChars >
+    class CFixedStringT;
+
+    template< class BaseType, const int t_nSize >
+    class CStaticString;
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+    // simples
+    //
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+    template< class T, class TEqual >
+    class CSimpleArray;
+
+    template< class TKey, class TVal, class TEqual >
+    class CSimpleMap;
+
+#else
+
+    template< class T >
+    class CSimpleArray;
+
+    template< class T >
+    class CSimpleValArray;
+
+    template< class TKey, class TVal >
+    class CSimpleMap;
+
+#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+    // pointers
+    //
+    template< class E >
+    class CAutoPtr;
+
+    template< class T >
+    class CComPtr;
+
+    template< class T, const IID *piid >
+    class CComQIPtr;
+
+    template< class E, class Allocator >
+    class CHeapPtr;
+
+    template< class T >
+    class CAdapt;
+
+
+} // namespace ATL
+
+
+
+
+// indirect_iterator customizations
+//
+
+
+#include <boost/mpl/identity.hpp>
+#include <boost/pointee.hpp>
+
+
+namespace boost {
+
+
+    template< class E >
+    struct pointee< ATL::CAutoPtr<E> > :
+        mpl::identity<E>
+    { };
+
+    template< class T >
+    struct pointee< ATL::CComPtr<T> > :
+        mpl::identity<T>
+    { };
+
+    template< class T, const IID *piid >
+    struct pointee< ATL::CComQIPtr<T, piid> > :
+        mpl::identity<T>
+    { };
+
+    template< class E, class Allocator >
+    struct pointee< ATL::CHeapPtr<E, Allocator> > :
+        mpl::identity<E>
+    { };
+
+    template< class T >
+    struct pointee< ATL::CAdapt<T> > :
+        pointee<T>
+    { };
+
+
+} // namespace boost
+
+
+
+
+// extended customizations
+//
+
+
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+#include <boost/range/detail/microsoft.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <atlbase.h> // CComBSTR
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+    // arrays
+    //
+
+    struct atl_array_functions :
+        array_functions
+    {
+        template< class Iterator, class X >
+        Iterator end(X& x) // redefine
+        {
+            return x.GetData() + x.GetCount(); // no 'GetSize()'
+        }
+    };
+
+
+    template< class E, class ETraits >
+    struct customization< ATL::CAtlArray<E, ETraits> > :
+        atl_array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef E val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< class E >
+    struct customization< ATL::CAutoPtrArray<E> > :
+        atl_array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            // ATL::CAutoPtr/CHeapPtr is no assignable.
+            typedef ATL::CAutoPtr<E> val_t;
+            typedef val_t *miter_t;
+            typedef val_t const *citer_t;
+
+            typedef indirect_iterator<miter_t> mutable_iterator;
+            typedef indirect_iterator<citer_t> const_iterator;
+        };
+    };
+
+
+    template< class I, const IID *piid >
+    struct customization< ATL::CInterfaceArray<I, piid> > :
+        atl_array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ATL::CComQIPtr<I, piid> val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< class E, class ETraits >
+    struct customization< ATL::CAtlList<E, ETraits> > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef E val_t;
+
+            typedef list_iterator<X, val_t> mutable_iterator;
+            typedef list_iterator<X const, val_t const> const_iterator;
+        };
+    };
+
+
+    struct indirected_list_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            typedef typename Iterator::base_type base_t; // == list_iterator
+            return Iterator(base_t(x, x.GetHeadPosition()));
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            typedef typename Iterator::base_type base_t;
+            return Iterator(base_t(x, POSITION(0)));
+        }
+    };
+
+
+    template< class E >
+    struct customization< ATL::CAutoPtrList<E> > :
+        indirected_list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ATL::CAutoPtr<E> val_t;
+            typedef list_iterator<X, val_t> miter_t;
+            typedef list_iterator<X const, val_t const> citer_t;
+
+            typedef indirect_iterator<miter_t> mutable_iterator;
+            typedef indirect_iterator<citer_t> const_iterator;
+        };
+    };
+
+
+    template< class E, class Allocator >
+    struct customization< ATL::CHeapPtrList<E, Allocator> > :
+        indirected_list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ATL::CHeapPtr<E, Allocator> val_t;
+            typedef list_iterator<X, val_t> miter_t;
+            typedef list_iterator<X const, val_t const> citer_t;
+
+            typedef indirect_iterator<miter_t> mutable_iterator;
+            typedef indirect_iterator<citer_t> const_iterator;
+        };
+    };
+
+
+    template< class I, const IID *piid >
+    struct customization< ATL::CInterfaceList<I, piid> > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ATL::CComQIPtr<I, piid> val_t;
+
+            typedef list_iterator<X, val_t> mutable_iterator;
+            typedef list_iterator<X const, val_t const> const_iterator;
+        };
+    };
+
+
+    // maps
+    //
+
+    struct atl_rb_tree_tag
+    { };
+
+    template< >
+    struct customization< atl_rb_tree_tag > :
+        indirected_list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef typename X::CPair val_t;
+
+            typedef list_iterator<X, val_t *, val_t *> miter_t;
+            typedef list_iterator<X const, val_t const *, val_t const *> citer_t;
+            
+            typedef indirect_iterator<miter_t> mutable_iterator;
+            typedef indirect_iterator<citer_t> const_iterator;
+        };
+    };
+
+
+    template< class K, class V, class KTraits, class VTraits >
+    struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > :
+        customization< atl_rb_tree_tag >
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x) // redefine
+        {
+            typedef typename Iterator::base_type base_t; // == list_iterator
+            return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition'
+        }
+    };
+
+
+    // strings
+    //
+
+    struct atl_string_tag
+    { };
+
+    template< >
+    struct customization< atl_string_tag >
+    {
+        template< class X >
+        struct meta
+        {
+            typedef typename X::PXSTR mutable_iterator;
+            typedef typename X::PCXSTR const_iterator;
+        };
+
+        template< class Iterator, class X >
+        typename mutable_<Iterator, X>::type begin(X& x)
+        {
+            return x.GetBuffer(0);
+        }
+
+        template< class Iterator, class X >
+        Iterator begin(X const& x)
+        {
+            return x.GetString();
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return begin<Iterator>(x) + x.GetLength();
+        }
+    };
+
+
+    template< class BaseType, const int t_nSize >
+    struct customization< ATL::CStaticString<BaseType, t_nSize> >
+    {
+        template< class X >
+        struct meta
+        {
+            typedef BaseType const *mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+
+        template< class Iterator, class X >
+        Iterator begin(X const& x)
+        {
+            return x;
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X const& x)
+        {
+            return begin<Iterator>(x) + X::GetLength();
+        }
+    };
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+    template< >
+    struct customization< ATL::CComBSTR >
+    {
+        template< class X >
+        struct meta
+        {
+            typedef OLECHAR *mutable_iterator;
+            typedef OLECHAR const *const_iterator;
+        };
+
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return x.operator BSTR();
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return begin<Iterator>(x) + x.Length();
+        }
+    };
+
+
+    // simples
+    //
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+    template< class T, class TEqual >
+    struct customization< ATL::CSimpleArray<T, TEqual> > :
+#else
+    template< class T >
+    struct customization< ATL::CSimpleArray<T> > :
+#endif
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef T val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+    template< class T >
+    struct customization< ATL::CSimpleValArray<T> > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef T val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+    template< class TKey, class TVal, class TEqual >
+    struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> >
+#else
+    template< class TKey, class TVal >
+    struct customization< ATL::CSimpleMap<TKey, TVal> >
+#endif
+    {
+        template< class X >
+        struct meta
+        {
+            typedef TKey k_val_t;
+            typedef k_val_t *k_miter_t;
+            typedef k_val_t const *k_citer_t;
+
+            typedef TVal v_val_t;
+            typedef v_val_t *v_miter_t;
+            typedef v_val_t const *v_citer_t;
+
+            // Topic:
+            // 'std::pair' can't contain references
+            // because of reference to reference problem.
+
+            typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator;
+            typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator;
+        };
+
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal));
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize()));
+        }
+    };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// range customizations
+//
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+    // arrays
+    //
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CAtlArray, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CAutoPtrArray, 1
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *)
+    )
+
+
+    // lists
+    //
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CAtlList, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CAutoPtrList, 1
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CHeapPtrList, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *)
+    )
+
+
+    //maps
+    //
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CAtlMap, 4
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::atl_rb_tree_tag,
+        (ATL, BOOST_PP_NIL), CRBTree, 4
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::atl_rb_tree_tag,
+        (ATL, BOOST_PP_NIL), CRBMap, 4
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::atl_rb_tree_tag,
+        (ATL, BOOST_PP_NIL), CRBMultiMap, 4
+    )
+
+
+    // strings
+    //
+    #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+            boost::range_detail_microsoft::atl_string_tag,
+            (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool)
+        )
+    #else
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+            boost::range_detail_microsoft::atl_string_tag,
+            (ATL, BOOST_PP_NIL), CSimpleStringT, 1
+        )
+    #endif
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::atl_string_tag,
+        (ATL, BOOST_PP_NIL), CStringT, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::atl_string_tag,
+        (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int)
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CStaticString, (class)(const int)
+    )
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    (ATL, BOOST_PP_NIL), CComBSTR
+)
+
+
+// simples
+//
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CSimpleArray, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CSimpleMap, 3
+    )
+
+#else
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CSimpleArray, 1
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CSimpleMap, 2
+    )
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        (ATL, BOOST_PP_NIL), CSimpleValArray, 1
+    )
+
+#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+
+
+#endif
diff --git a/include/boost/range/begin.hpp b/include/boost/range/begin.hpp
new file mode 100644
index 0000000..0d7d3db
--- /dev/null
+++ b/include/boost/range/begin.hpp
@@ -0,0 +1,135 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_BEGIN_HPP
+#define BOOST_RANGE_BEGIN_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/begin.hpp>
+#else
+
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+namespace range_detail
+{
+#endif
+
+    //////////////////////////////////////////////////////////////////////
+    // primary template
+    //////////////////////////////////////////////////////////////////////
+
+    template< typename C >
+    BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
+    range_begin( C& c )
+    {
+        //
+        // If you get a compile-error here, it is most likely because
+        // you have not implemented range_begin() properly in
+        // the namespace of C
+        //
+        return c.begin();
+    }
+
+    //////////////////////////////////////////////////////////////////////
+    // pair
+    //////////////////////////////////////////////////////////////////////
+
+    template< typename Iterator >
+    BOOST_CONSTEXPR inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
+    {
+        return p.first;
+    }
+
+    template< typename Iterator >
+    BOOST_CONSTEXPR inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
+    {
+        return p.first;
+    }
+
+    //////////////////////////////////////////////////////////////////////
+    // array
+    //////////////////////////////////////////////////////////////////////
+
+    //
+    // May this be discarded? Or is it needed for bad compilers?
+    //
+    template< typename T, std::size_t sz >
+    BOOST_CONSTEXPR inline const T* range_begin( const T (&a)[sz] ) BOOST_NOEXCEPT
+    {
+        return a;
+    }
+
+    template< typename T, std::size_t sz >
+    BOOST_CONSTEXPR inline T* range_begin( T (&a)[sz] ) BOOST_NOEXCEPT
+    {
+        return a;
+    }
+
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+} // namespace 'range_detail'
+#endif
+
+// Use a ADL namespace barrier to avoid ambiguity with other unqualified
+// calls. This is particularly important with C++0x encouraging
+// unqualified calls to begin/end.
+namespace range_adl_barrier
+{
+
+template< class T >
+BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    using namespace range_detail;
+#endif
+    return range_begin( r );
+}
+
+template< class T >
+BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    using namespace range_detail;
+#endif
+    return range_begin( r );
+}
+
+    } // namespace range_adl_barrier
+} // namespace boost
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+namespace boost
+{
+    namespace range_adl_barrier
+    {
+        template< class T >
+        inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
+        const_begin( const T& r )
+        {
+            return boost::range_adl_barrier::begin( r );
+        }
+    } // namespace range_adl_barrier
+
+    using namespace range_adl_barrier;
+} // namespace boost
+
+#endif
+
diff --git a/include/boost/range/category.hpp b/include/boost/range/category.hpp
new file mode 100644
index 0000000..f5431ad
--- /dev/null
+++ b/include/boost/range/category.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CATEGORY_HPP
+#define BOOST_RANGE_CATEGORY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+    template< class T >
+    struct range_category : iterator_category< typename range_iterator<T>::type >
+    { };
+}
+
+#endif
diff --git a/include/boost/range/combine.hpp b/include/boost/range/combine.hpp
new file mode 100644
index 0000000..26cef9a
--- /dev/null
+++ b/include/boost/range/combine.hpp
@@ -0,0 +1,45 @@
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_COMBINE_HPP
+#define BOOST_RANGE_COMBINE_HPP
+
+#include <boost/config.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+
+template<typename IterTuple>
+class combined_range
+        : public iterator_range<zip_iterator<IterTuple> >
+{
+    typedef iterator_range<zip_iterator<IterTuple> > base;
+public:
+    combined_range(IterTuple first, IterTuple last)
+        : base(first, last)
+    {
+    }
+};
+
+    } // namespace range
+} // namespace boost
+
+#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \
+    defined(BOOST_NO_CXX11_DECLTYPE) || \
+    defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
+    defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#   include <boost/range/detail/combine_cxx03.hpp>
+#else
+#   include <boost/range/detail/combine_cxx11.hpp>
+#endif
+
+#endif
diff --git a/include/boost/range/concepts.hpp b/include/boost/range/concepts.hpp
new file mode 100644
index 0000000..f6f9f41
--- /dev/null
+++ b/include/boost/range/concepts.hpp
@@ -0,0 +1,388 @@
+// Boost.Range library concept checks
+//
+//  Copyright Neil Groves 2009. Use, modification and distribution
+//  are subject to the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  Copyright Daniel Walker 2006. Use, modification and distribution
+//  are subject to the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONCEPTS_HPP
+#define BOOST_RANGE_CONCEPTS_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/detail/misc_concept.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <iterator>
+
+/*!
+ * \file
+ * \brief Concept checks for the Boost Range library.
+ *
+ * The structures in this file may be used in conjunction with the
+ * Boost Concept Check library to insure that the type of a function
+ * parameter is compatible with a range concept. If not, a meaningful
+ * compile time error is generated. Checks are provided for the range
+ * concepts related to iterator traversal categories. For example, the
+ * following line checks that the type T models the ForwardRange
+ * concept.
+ *
+ * \code
+ * BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
+ * \endcode
+ *
+ * A different concept check is required to ensure writeable value
+ * access. For example to check for a ForwardRange that can be written
+ * to, the following code is required.
+ *
+ * \code
+ * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
+ * \endcode
+ *
+ * \see http://www.boost.org/libs/range/doc/range.html for details
+ * about range concepts.
+ * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
+ * for details about iterator concepts.
+ * \see http://www.boost.org/libs/concept_check/concept_check.htm for
+ * details about concept checks.
+ */
+
+namespace boost {
+
+    namespace range_detail {
+
+#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+
+// List broken compiler versions here:
+#ifndef __clang__
+    #ifdef __GNUC__
+        // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
+        // hence the least disruptive approach is to turn-off the concept checking for
+        // this version of the compiler.
+        #if __GNUC__ == 4 && __GNUC_MINOR__ == 2
+            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+        #endif
+    #endif
+
+    #ifdef __GCCXML__
+        // GCC XML, unsurprisingly, has the same issues
+        #if __GCCXML_GNUC__ == 4 && __GCCXML_GNUC_MINOR__ == 2
+            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+        #endif
+    #endif
+#endif
+
+    #ifdef __BORLANDC__
+        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+    #endif
+
+    #ifdef __PATHCC__
+        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+    #endif
+
+// Default to using the concept asserts unless we have defined it off
+// during the search for black listed compilers.
+    #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
+    #endif
+
+#endif
+
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+    #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
+#else
+    #define BOOST_RANGE_CONCEPT_ASSERT( x )
+#endif
+
+        // Rationale for the inclusion of redefined iterator concept
+        // classes:
+        //
+        // The Range algorithms often do not require that the iterators are
+        // Assignable or default constructable, but the correct standard
+        // conformant iterators do require the iterators to be a model of the
+        // Assignable concept.
+        // Iterators that contains a functor that is not assignable therefore
+        // are not correct models of the standard iterator concepts,
+        // despite being adequate for most algorithms. An example of this
+        // use case is the combination of the boost::adaptors::filtered
+        // class with a boost::lambda::bind generated functor.
+        // Ultimately modeling the range concepts using composition
+        // with the Boost.Iterator concepts would render the library
+        // incompatible with many common Boost.Lambda expressions.
+        template<class Iterator>
+        struct IncrementableIteratorConcept : CopyConstructible<Iterator>
+        {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+            typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
+
+            BOOST_RANGE_CONCEPT_ASSERT((
+                Convertible<
+                    traversal_category,
+                    incrementable_traversal_tag
+                >));
+
+            BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
+            {
+                ++i;
+                (void)i++;
+            }
+        private:
+            Iterator i;
+#endif
+        };
+
+        template<class Iterator>
+        struct SinglePassIteratorConcept
+            : IncrementableIteratorConcept<Iterator>
+            , EqualityComparable<Iterator>
+        {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+            BOOST_RANGE_CONCEPT_ASSERT((
+                Convertible<
+                    BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
+                    single_pass_traversal_tag
+                >));
+
+            BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
+            {
+                Iterator i2(++i);
+                boost::ignore_unused_variable_warning(i2);
+
+                // deliberately we are loose with the postfix version for the single pass
+                // iterator due to the commonly poor adherence to the specification means that
+                // many algorithms would be unusable, whereas actually without the check they
+                // work
+                (void)(i++);
+
+                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r1(*i);
+                boost::ignore_unused_variable_warning(r1);
+
+                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r2(*(++i));
+                boost::ignore_unused_variable_warning(r2);
+            }
+        private:
+            Iterator i;
+#endif
+        };
+
+        template<class Iterator>
+        struct ForwardIteratorConcept
+            : SinglePassIteratorConcept<Iterator>
+            , DefaultConstructible<Iterator>
+        {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+            typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::difference_type difference_type;
+
+            BOOST_MPL_ASSERT((is_integral<difference_type>));
+            BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
+
+            BOOST_RANGE_CONCEPT_ASSERT((
+                Convertible<
+                    BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
+                    forward_traversal_tag
+                >));
+
+            BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
+            {
+                // See the above note in the SinglePassIteratorConcept about the handling of the
+                // postfix increment. Since with forward and better iterators there is no need
+                // for a proxy, we can sensibly require that the dereference result
+                // is convertible to reference.
+                Iterator i2(i++);
+                boost::ignore_unused_variable_warning(i2);
+                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r(*(i++));
+                boost::ignore_unused_variable_warning(r);
+            }
+        private:
+            Iterator i;
+#endif
+         };
+
+         template<class Iterator>
+         struct BidirectionalIteratorConcept
+             : ForwardIteratorConcept<Iterator>
+         {
+ #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+             BOOST_RANGE_CONCEPT_ASSERT((
+                 Convertible<
+                     BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
+                     bidirectional_traversal_tag
+                 >));
+
+             BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
+             {
+                 --i;
+                 (void)i--;
+             }
+         private:
+             Iterator i;
+ #endif
+         };
+
+         template<class Iterator>
+         struct RandomAccessIteratorConcept
+             : BidirectionalIteratorConcept<Iterator>
+         {
+ #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+             BOOST_RANGE_CONCEPT_ASSERT((
+                 Convertible<
+                     BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
+                     random_access_traversal_tag
+                 >));
+
+             BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
+             {
+                 i += n;
+                 i = i + n;
+                 i = n + i;
+                 i -= n;
+                 i = i - n;
+                 n = i - j;
+             }
+         private:
+             BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept<Iterator>::difference_type n;
+             Iterator i;
+             Iterator j;
+ #endif
+         };
+
+    } // namespace range_detail
+
+    //! Check if a type T models the SinglePassRange range concept.
+    template<class T>
+    struct SinglePassRangeConcept
+    {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        // A few compilers don't like the rvalue reference T types so just
+        // remove it.
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type Rng;
+
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<
+            Rng const
+        >::type const_iterator;
+
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type iterator;
+
+        BOOST_RANGE_CONCEPT_ASSERT((
+                range_detail::SinglePassIteratorConcept<iterator>));
+
+        BOOST_RANGE_CONCEPT_ASSERT((
+                range_detail::SinglePassIteratorConcept<const_iterator>));
+
+        BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
+        {
+            // This has been modified from assigning to this->i
+            // (where i was a member variable) to improve
+            // compatibility with Boost.Lambda
+            iterator i1 = boost::begin(*m_range);
+            iterator i2 = boost::end(*m_range);
+
+            boost::ignore_unused_variable_warning(i1);
+            boost::ignore_unused_variable_warning(i2);
+
+            const_constraints(*m_range);
+        }
+
+    private:
+        void const_constraints(const Rng& const_range)
+        {
+            const_iterator ci1 = boost::begin(const_range);
+            const_iterator ci2 = boost::end(const_range);
+
+            boost::ignore_unused_variable_warning(ci1);
+            boost::ignore_unused_variable_warning(ci2);
+        }
+
+       // Rationale:
+       // The type of m_range is T* rather than T because it allows
+       // T to be an abstract class. The other obvious alternative of
+       // T& produces a warning on some compilers.
+       Rng* m_range;
+#endif
+    };
+
+    //! Check if a type T models the ForwardRange range concept.
+    template<class T>
+    struct ForwardRangeConcept : SinglePassRangeConcept<T>
+    {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
+#endif
+    };
+
+    template<class T>
+    struct WriteableRangeConcept
+    {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type iterator;
+
+        BOOST_CONCEPT_USAGE(WriteableRangeConcept)
+        {
+            *i = v;
+        }
+    private:
+        iterator i;
+        BOOST_DEDUCED_TYPENAME range_value<T>::type v;
+#endif
+    };
+
+    //! Check if a type T models the WriteableForwardRange range concept.
+    template<class T>
+    struct WriteableForwardRangeConcept
+        : ForwardRangeConcept<T>
+        , WriteableRangeConcept<T>
+    {
+    };
+
+    //! Check if a type T models the BidirectionalRange range concept.
+    template<class T>
+    struct BidirectionalRangeConcept : ForwardRangeConcept<T>
+    {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
+#endif
+    };
+
+    //! Check if a type T models the WriteableBidirectionalRange range concept.
+    template<class T>
+    struct WriteableBidirectionalRangeConcept
+        : BidirectionalRangeConcept<T>
+        , WriteableRangeConcept<T>
+    {
+    };
+
+    //! Check if a type T models the RandomAccessRange range concept.
+    template<class T>
+    struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
+    {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
+        BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
+#endif
+    };
+
+    //! Check if a type T models the WriteableRandomAccessRange range concept.
+    template<class T>
+    struct WriteableRandomAccessRangeConcept
+        : RandomAccessRangeConcept<T>
+        , WriteableRangeConcept<T>
+    {
+    };
+
+} // namespace boost
+
+#endif // BOOST_RANGE_CONCEPTS_HPP
diff --git a/include/boost/range/config.hpp b/include/boost/range/config.hpp
new file mode 100644
index 0000000..7600a5f
--- /dev/null
+++ b/include/boost/range/config.hpp
@@ -0,0 +1,56 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONFIG_HPP
+#define BOOST_RANGE_CONFIG_HPP
+
+#include <boost/detail/workaround.hpp>
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_RANGE_DEDUCED_TYPENAME
+#error "macro already defined!"
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# define BOOST_RANGE_DEDUCED_TYPENAME typename
+#else
+#define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
+#endif
+
+#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
+#error "macro already defined!"
+#endif
+
+#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
+#define BOOST_RANGE_NO_ARRAY_SUPPORT 1
+#endif
+
+#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
+#define BOOST_RANGE_ARRAY_REF() (boost_range_array)
+#define BOOST_RANGE_NO_STATIC_ASSERT
+#else
+#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
+#  define BOOST_RANGE_UNUSED __attribute__((unused))
+#else
+#  define BOOST_RANGE_UNUSED
+#endif
+
+
+
+#endif
+
diff --git a/include/boost/range/const_iterator.hpp b/include/boost/range/const_iterator.hpp
new file mode 100644
index 0000000..727fdad
--- /dev/null
+++ b/include/boost/range/const_iterator.hpp
@@ -0,0 +1,76 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONST_ITERATOR_HPP
+#define BOOST_RANGE_CONST_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#include <boost/range/range_fwd.hpp>
+#include <boost/range/detail/extract_optional_type.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+    //////////////////////////////////////////////////////////////////////////
+    // default
+    //////////////////////////////////////////////////////////////////////////
+    
+    namespace range_detail
+    {
+
+BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator )
+
+template< typename C >
+struct range_const_iterator_helper
+        : extract_const_iterator<C>
+{};
+
+//////////////////////////////////////////////////////////////////////////
+// pair
+//////////////////////////////////////////////////////////////////////////
+
+template< typename Iterator >
+struct range_const_iterator_helper<std::pair<Iterator,Iterator> >
+{
+    typedef Iterator type;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// array
+//////////////////////////////////////////////////////////////////////////
+
+template< typename T, std::size_t sz >
+struct range_const_iterator_helper< T[sz] >
+{
+    typedef const T* type;
+};
+
+    } // namespace range_detail
+
+template<typename C, typename Enabler=void>
+struct range_const_iterator
+        : range_detail::range_const_iterator_helper<
+            BOOST_DEDUCED_TYPENAME remove_reference<C>::type
+        >
+{
+};
+
+} // namespace boost
+
+
+#endif
diff --git a/include/boost/range/const_reverse_iterator.hpp b/include/boost/range/const_reverse_iterator.hpp
new file mode 100644
index 0000000..bfe1615
--- /dev/null
+++ b/include/boost/range/const_reverse_iterator.hpp
@@ -0,0 +1,35 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
+#define BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/reverse_iterator.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost
+{
+    //
+    // This interface is deprecated, use range_reverse_iterator<const T>
+    //
+    
+    template< typename C >
+    struct range_const_reverse_iterator
+            : range_reverse_iterator<
+                const BOOST_DEDUCED_TYPENAME remove_reference<C>::type>
+    { };
+    
+} // namespace boost
+
+#endif
diff --git a/include/boost/range/counting_range.hpp b/include/boost/range/counting_range.hpp
new file mode 100644
index 0000000..d886a21
--- /dev/null
+++ b/include/boost/range/counting_range.hpp
@@ -0,0 +1,76 @@
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#if BOOST_MSVC >= 1400
+#pragma warning(push)
+#pragma warning(disable : 4244)
+#endif
+
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+
+namespace boost
+{
+    template<class Value>
+    inline iterator_range<counting_iterator<Value> >
+    counting_range(Value first, Value last)
+    {
+        typedef counting_iterator<Value> counting_iterator_t;
+        typedef iterator_range<counting_iterator_t> result_t;
+        return result_t(counting_iterator_t(first),
+                        counting_iterator_t(last));
+    }
+
+    template<class Range>
+    inline iterator_range<
+        counting_iterator<
+            BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type
+        >
+    >
+    counting_range(const Range& rng)
+    {
+        typedef counting_iterator<
+            BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type
+        > counting_iterator_t;
+
+        typedef iterator_range<counting_iterator_t> result_t;
+
+        return result_t(counting_iterator_t(boost::begin(rng)),
+                        counting_iterator_t(boost::end(rng)));
+    }
+
+    template<class Range>
+    inline iterator_range<
+        counting_iterator<
+            BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
+        >
+    >
+    counting_range(Range& rng)
+    {
+        typedef counting_iterator<
+            BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
+        > counting_iterator_t;
+
+        typedef iterator_range<counting_iterator_t> result_t;
+
+        return result_t(counting_iterator_t(boost::begin(rng)),
+                        counting_iterator_t(boost::end(rng)));
+    }
+} // namespace boost
+
+#if BOOST_MSVC >= 1400
+#pragma warning(pop)
+#endif
+
+#endif // include guard
diff --git a/include/boost/range/detail/any_iterator.hpp b/include/boost/range/detail/any_iterator.hpp
new file mode 100644
index 0000000..044237c
--- /dev/null
+++ b/include/boost/range/detail/any_iterator.hpp
@@ -0,0 +1,589 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
+
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/range/detail/any_iterator_buffer.hpp>
+#include <boost/range/detail/any_iterator_interface.hpp>
+#include <boost/range/detail/any_iterator_wrapper.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // metafunction to determine if T is a const reference
+        template<class T>
+        struct is_const_reference
+        {
+            typedef typename mpl::and_<
+                typename is_reference<T>::type,
+                typename is_const<
+                    typename remove_reference<T>::type
+                >::type
+            >::type type;
+        };
+
+        // metafunction to determine if T is a mutable reference
+        template<class T>
+        struct is_mutable_reference
+        {
+            typedef typename mpl::and_<
+                typename is_reference<T>::type,
+                typename mpl::not_<
+                    typename is_const<
+                        typename remove_reference<T>::type
+                    >::type
+                >::type
+            >::type type;
+        };
+
+        // metafunction to evaluate if a source 'reference' can be
+        // converted to a target 'reference' as a value.
+        //
+        // This is true, when the target reference type is actually
+        // not a reference, and the source reference is convertible
+        // to the target type.
+        template<class SourceReference, class TargetReference>
+        struct is_convertible_to_value_as_reference
+        {
+            typedef typename mpl::and_<
+                typename mpl::not_<
+                    typename is_reference<TargetReference>::type
+                >::type
+              , typename is_convertible<
+                    SourceReference
+                  , TargetReference
+                >::type
+            >::type type;
+        };
+
+        template<
+            class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer = any_iterator_default_buffer
+        >
+        class any_iterator;
+
+        // metafunction to determine if SomeIterator is an
+        // any_iterator.
+        //
+        // This is the general implementation which evaluates to false.
+        template<class SomeIterator>
+        struct is_any_iterator
+            : mpl::bool_<false>
+        {
+        };
+
+        // specialization of is_any_iterator to return true for
+        // any_iterator classes regardless of template parameters.
+        template<
+            class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct is_any_iterator<
+            any_iterator<
+                Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >
+        >
+            : mpl::bool_<true>
+        {
+        };
+    } // namespace range_detail
+
+    namespace iterators
+    {
+    namespace detail
+    {
+        // Rationale:
+        // These are specialized since the iterator_facade versions lack
+        // the requisite typedefs to allow wrapping to determine the types
+        // if a user copy constructs from a postfix increment.
+
+        template<
+            class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        class postfix_increment_proxy<
+                    range_detail::any_iterator<
+                        Value
+                      , Traversal
+                      , Reference
+                      , Difference
+                      , Buffer
+                    >
+                >
+        {
+            typedef range_detail::any_iterator<
+                Value
+              , Traversal
+              , Reference
+              , Difference
+              , Buffer
+            > any_iterator_type;
+
+        public:
+            typedef Value value_type;
+            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
+            typedef Difference difference_type;
+            typedef typename iterator_pointer<any_iterator_type>::type pointer;
+            typedef Reference reference;
+
+            explicit postfix_increment_proxy(any_iterator_type const& x)
+                : stored_value(*x)
+            {}
+
+            value_type&
+            operator*() const
+            {
+                return this->stored_value;
+            }
+        private:
+            mutable value_type stored_value;
+        };
+
+        template<
+            class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        class writable_postfix_increment_proxy<
+                    range_detail::any_iterator<
+                        Value
+                      , Traversal
+                      , Reference
+                      , Difference
+                      , Buffer
+                    >
+                >
+        {
+            typedef range_detail::any_iterator<
+                        Value
+                      , Traversal
+                      , Reference
+                      , Difference
+                      , Buffer
+                    > any_iterator_type;
+         public:
+            typedef Value value_type;
+            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
+            typedef Difference difference_type;
+            typedef typename iterator_pointer<any_iterator_type>::type pointer;
+            typedef Reference reference;
+
+            explicit writable_postfix_increment_proxy(any_iterator_type const& x)
+              : stored_value(*x)
+              , stored_iterator(x)
+            {}
+
+            // Dereferencing must return a proxy so that both *r++ = o and
+            // value_type(*r++) can work.  In this case, *r is the same as
+            // *r++, and the conversion operator below is used to ensure
+            // readability.
+            writable_postfix_increment_proxy const&
+            operator*() const
+            {
+                return *this;
+            }
+
+            // Provides readability of *r++
+            operator value_type&() const
+            {
+                return stored_value;
+            }
+
+            // Provides writability of *r++
+            template <class T>
+            T const& operator=(T const& x) const
+            {
+                *this->stored_iterator = x;
+                return x;
+            }
+
+            // This overload just in case only non-const objects are writable
+            template <class T>
+            T& operator=(T& x) const
+            {
+                *this->stored_iterator = x;
+                return x;
+            }
+
+            // Provides X(r++)
+            operator any_iterator_type const&() const
+            {
+                return stored_iterator;
+            }
+
+         private:
+            mutable value_type stored_value;
+            any_iterator_type stored_iterator;
+        };
+
+    } //namespace detail
+    } //namespace iterators
+
+    namespace range_detail
+    {
+        template<
+            class Value
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        class any_iterator
+            : public iterator_facade<
+                        any_iterator<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                        >
+                    , Value
+                    , Traversal
+                    , Reference
+                    , Difference
+                >
+        {
+            template<
+                class OtherValue
+              , class OtherTraversal
+              , class OtherReference
+              , class OtherDifference
+              , class OtherBuffer
+            >
+            friend class any_iterator;
+
+            struct enabler {};
+            struct disabler {};
+
+            typedef typename any_iterator_interface_type_generator<
+                Traversal
+              , Reference
+              , Difference
+              , Buffer
+            >::type abstract_base_type;
+
+            typedef iterator_facade<
+                        any_iterator<
+                            Value
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                        >
+                      , Value
+                      , Traversal
+                      , Reference
+                      , Difference
+                  > base_type;
+
+            typedef Buffer buffer_type;
+
+        public:
+            typedef typename base_type::value_type value_type;
+            typedef typename base_type::reference reference;
+            typedef typename base_type::difference_type difference_type;
+
+            // Default constructor
+            any_iterator()
+                : m_impl(0) {}
+
+            // Simple copy construction without conversion
+            any_iterator(const any_iterator& other)
+                : base_type(other)
+                , m_impl(other.m_impl
+                            ? other.m_impl->clone(m_buffer)
+                            : 0)
+            {
+            }
+
+            // Simple assignment operator without conversion
+            any_iterator& operator=(const any_iterator& other)
+            {
+                if (this != &other)
+                {
+                    if (m_impl)
+                        m_impl->~abstract_base_type();
+                    m_buffer.deallocate();
+                    m_impl = 0;
+                    if (other.m_impl)
+                        m_impl = other.m_impl->clone(m_buffer);
+                }
+                return *this;
+            }
+
+            // Implicit conversion from another any_iterator where the
+            // conversion is from a non-const reference to a const reference
+            template<
+                class OtherValue
+              , class OtherTraversal
+              , class OtherReference
+              , class OtherDifference
+            >
+            any_iterator(const any_iterator<
+                                OtherValue,
+                                OtherTraversal,
+                                OtherReference,
+                                OtherDifference,
+                                Buffer
+                            >& other,
+                         typename ::boost::enable_if<
+                            typename mpl::and_<
+                                typename is_mutable_reference<OtherReference>::type,
+                                typename is_const_reference<Reference>::type
+                            >::type,
+                            enabler
+                        >::type* = 0
+                    )
+                : m_impl(other.m_impl
+                            ? other.m_impl->clone_const_ref(m_buffer)
+                         : 0
+                        )
+            {
+            }
+
+            // Implicit conversion from another any_iterator where the
+            // reference types of the source and the target are references
+            // that are either both const, or both non-const.
+            template<
+                class OtherValue
+              , class OtherTraversal
+              , class OtherReference
+              , class OtherDifference
+            >
+            any_iterator(const any_iterator<
+                                OtherValue
+                              , OtherTraversal
+                              , OtherReference
+                              , OtherDifference
+                              , Buffer
+                            >& other,
+                         typename ::boost::enable_if<
+                            typename mpl::or_<
+                                typename mpl::and_<
+                                    typename is_mutable_reference<OtherReference>::type,
+                                    typename is_mutable_reference<Reference>::type
+                                >::type,
+                                typename mpl::and_<
+                                    typename is_const_reference<OtherReference>::type,
+                                    typename is_const_reference<Reference>::type
+                                >::type
+                            >::type,
+                            enabler
+                        >::type* = 0
+                        )
+                : m_impl(other.m_impl
+                            ? other.m_impl->clone(m_buffer)
+                         : 0
+                        )
+            {
+            }
+
+            // Implicit conversion to an any_iterator that uses a value for
+            // the reference type.
+            template<
+                class OtherValue
+              , class OtherTraversal
+              , class OtherReference
+              , class OtherDifference
+            >
+            any_iterator(const any_iterator<
+                                OtherValue
+                              , OtherTraversal
+                              , OtherReference
+                              , OtherDifference
+                              , Buffer
+                            >& other,
+                        typename ::boost::enable_if<
+                            typename is_convertible_to_value_as_reference<
+                                        OtherReference
+                                      , Reference
+                                    >::type,
+                            enabler
+                        >::type* = 0
+                        )
+                : m_impl(other.m_impl
+                            ? other.m_impl->clone_reference_as_value(m_buffer)
+                            : 0
+                            )
+            {
+            }
+
+            any_iterator clone() const
+            {
+                any_iterator result;
+                if (m_impl)
+                    result.m_impl = m_impl->clone(result.m_buffer);
+                return result;
+            }
+
+            any_iterator<
+                Value
+              , Traversal
+              , typename abstract_base_type::const_reference
+              , Difference
+              , Buffer
+            >
+            clone_const_ref() const
+            {
+                typedef any_iterator<
+                    Value
+                  , Traversal
+                  , typename abstract_base_type::const_reference
+                  , Difference
+                  , Buffer
+                > result_type;
+
+                result_type result;
+
+                if (m_impl)
+                    result.m_impl = m_impl->clone_const_ref(result.m_buffer);
+
+                return result;
+            }
+
+            // implicit conversion and construction from type-erasure-compatible
+            // iterators
+            template<class WrappedIterator>
+            explicit any_iterator(
+                const WrappedIterator& wrapped_iterator,
+                typename disable_if<
+                    typename is_any_iterator<WrappedIterator>::type
+                  , disabler
+                >::type* = 0
+                )
+            {
+                typedef typename any_iterator_wrapper_type_generator<
+                            WrappedIterator
+                          , Traversal
+                          , Reference
+                          , Difference
+                          , Buffer
+                        >::type wrapper_type;
+
+                void* ptr = m_buffer.allocate(sizeof(wrapper_type));
+                m_impl = new(ptr) wrapper_type(wrapped_iterator);
+            }
+
+            ~any_iterator()
+            {
+                // manually run the destructor, the deallocation is automatically
+                // handled by the any_iterator_small_buffer base class.
+                if (m_impl)
+                    m_impl->~abstract_base_type();
+            }
+
+        private:
+            friend class ::boost::iterator_core_access;
+
+            Reference dereference() const
+            {
+                BOOST_ASSERT( m_impl );
+                return m_impl->dereference();
+            }
+
+            bool equal(const any_iterator& other) const
+            {
+                return (m_impl == other.m_impl)
+                    || (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
+            }
+
+            void increment()
+            {
+                BOOST_ASSERT( m_impl );
+                m_impl->increment();
+            }
+
+            void decrement()
+            {
+                BOOST_ASSERT( m_impl );
+                m_impl->decrement();
+            }
+
+            Difference distance_to(const any_iterator& other) const
+            {
+                return m_impl && other.m_impl
+                    ? m_impl->distance_to(*other.m_impl)
+                    : 0;
+            }
+
+            void advance(Difference offset)
+            {
+                BOOST_ASSERT( m_impl );
+                m_impl->advance(offset);
+            }
+
+            any_iterator& swap(any_iterator& other)
+            {
+                BOOST_ASSERT( this != &other );
+                // grab a temporary copy of the other iterator
+                any_iterator tmp(other);
+
+                // deallocate the other iterator, taking care to obey the
+                // class-invariants in-case of exceptions later
+                if (other.m_impl)
+                {
+                    other.m_impl->~abstract_base_type();
+                    other.m_buffer.deallocate();
+                    other.m_impl = 0;
+                }
+
+                // If this is a non-null iterator then we need to put
+                // a clone of this iterators implementation into the other
+                // iterator.
+                // We can't just swap because of the small buffer optimization.
+                if (m_impl)
+                {
+                    other.m_impl = m_impl->clone(other.m_buffer);
+                    m_impl->~abstract_base_type();
+                    m_buffer.deallocate();
+                    m_impl = 0;
+                }
+
+                // assign to this instance a clone of the temporarily held
+                // tmp which represents the input other parameter at the
+                // start of execution of this function.
+                if (tmp.m_impl)
+                    m_impl = tmp.m_impl->clone(m_buffer);
+
+                return *this;
+            }
+
+            buffer_type m_buffer;
+            abstract_base_type* m_impl;
+        };
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/any_iterator_buffer.hpp b/include/boost/range/detail/any_iterator_buffer.hpp
new file mode 100644
index 0000000..2bb5d53
--- /dev/null
+++ b/include/boost/range/detail/any_iterator_buffer.hpp
@@ -0,0 +1,117 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
+
+#include <boost/array.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace boost
+{
+    template<std::size_t StackBufferSize>
+    class any_iterator_buffer
+        : noncopyable
+    {
+        BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
+    public:
+        any_iterator_buffer()
+            : m_ptr()
+        {
+        }
+
+        ~any_iterator_buffer()
+        {
+            delete [] m_ptr;
+        }
+
+        void* allocate(std::size_t bytes)
+        {
+            BOOST_ASSERT( !m_ptr );
+            if (bytes <= StackBufferSize)
+                return m_buffer.data();
+
+            m_ptr = new char[bytes];
+            return m_ptr;
+        }
+
+        void deallocate()
+        {
+            delete [] m_ptr;
+            m_ptr = 0;
+        }
+
+    private:
+        // Rationale:
+        // Do not use inheritance from noncopyable because this causes
+        // the concepts to erroneous detect the derived any_iterator
+        // as noncopyable.
+        any_iterator_buffer(const any_iterator_buffer&);
+        void operator=(const any_iterator_buffer&);
+
+        char* m_ptr;
+        boost::array<char, StackBufferSize> m_buffer;
+    };
+
+    class any_iterator_heap_only_buffer
+        : noncopyable
+    {
+    public:
+        any_iterator_heap_only_buffer()
+            : m_ptr()
+        {
+        }
+
+        ~any_iterator_heap_only_buffer()
+        {
+            delete [] m_ptr;
+        }
+
+        void* allocate(std::size_t bytes)
+        {
+            BOOST_ASSERT( !m_ptr );
+            m_ptr = new char[bytes];
+            return m_ptr;
+        }
+
+        void deallocate()
+        {
+            delete [] m_ptr;
+            m_ptr = 0;
+        }
+
+    private:
+        char* m_ptr;
+    };
+
+    template<std::size_t StackBufferSize>
+    class any_iterator_stack_only_buffer
+    {
+        BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
+    public:
+        void* allocate(std::size_t bytes)
+        {
+            BOOST_ASSERT( bytes <= m_buffer.size() );
+            return m_buffer.data();
+        }
+
+        void deallocate()
+        {
+        }
+
+    private:
+        boost::array<char, StackBufferSize> m_buffer;
+    };
+
+    typedef any_iterator_buffer<64> any_iterator_default_buffer;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/any_iterator_interface.hpp b/include/boost/range/detail/any_iterator_interface.hpp
new file mode 100644
index 0000000..cd56714
--- /dev/null
+++ b/include/boost/range/detail/any_iterator_interface.hpp
@@ -0,0 +1,277 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
+
+#include <boost/range/detail/any_iterator_buffer.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template<class T>
+        struct const_reference_type_generator
+        {
+            typedef typename mpl::if_<
+                typename is_reference<T>::type,
+                typename add_const<
+                    typename remove_reference<T>::type
+                >::type&,
+                T
+            >::type type;
+        };
+
+        template<class T>
+        struct mutable_reference_type_generator
+        {
+            typedef typename mpl::if_<
+                typename mpl::and_<
+                    typename is_const<T>::type,
+                    typename mpl::not_<typename is_reference<T>::type>::type
+                >::type,
+                T,
+                typename add_reference<T>::type
+            >::type type;
+        };
+
+        template<
+            class Reference
+          , class Buffer
+        >
+        struct any_incrementable_iterator_interface
+        {
+            typedef typename mutable_reference_type_generator<
+                Reference
+            >::type reference;
+
+            typedef typename const_reference_type_generator<
+                Reference
+            >::type const_reference;
+
+            typedef typename remove_const<
+                typename remove_reference<Reference>::type
+            >::type reference_as_value_type;
+
+            typedef Buffer buffer_type;
+
+            virtual ~any_incrementable_iterator_interface() {}
+
+            virtual any_incrementable_iterator_interface*
+                        clone(buffer_type& buffer) const = 0;
+
+            virtual any_incrementable_iterator_interface<const_reference, Buffer>*
+                        clone_const_ref(buffer_type& buffer) const = 0;
+
+            virtual any_incrementable_iterator_interface<reference_as_value_type, Buffer>*
+                        clone_reference_as_value(buffer_type& buffer) const = 0;
+
+            virtual void increment() = 0;
+        };
+
+        template<
+            class Reference
+          , class Buffer
+        >
+        struct any_single_pass_iterator_interface
+            : any_incrementable_iterator_interface<Reference, Buffer>
+        {
+            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference reference;
+            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::const_reference const_reference;
+            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+            virtual any_single_pass_iterator_interface*
+                        clone(buffer_type& buffer) const = 0;
+
+            virtual any_single_pass_iterator_interface<const_reference, Buffer>*
+                        clone_const_ref(buffer_type& buffer) const = 0;
+
+            virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
+                        clone_reference_as_value(buffer_type& buffer) const = 0;
+
+            virtual reference dereference() const = 0;
+
+            virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
+        };
+
+        template<
+            class Reference
+          , class Buffer
+        >
+        struct any_forward_iterator_interface
+            : any_single_pass_iterator_interface<Reference, Buffer>
+        {
+            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference reference;
+            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::const_reference const_reference;
+            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+            virtual any_forward_iterator_interface*
+                        clone(buffer_type& buffer) const = 0;
+
+            virtual any_forward_iterator_interface<const_reference, Buffer>*
+                        clone_const_ref(buffer_type& buffer) const = 0;
+
+            virtual any_forward_iterator_interface<reference_as_value_type, Buffer>*
+                        clone_reference_as_value(buffer_type& buffer) const = 0;
+        };
+
+        template<
+            class Reference
+          , class Buffer
+        >
+        struct any_bidirectional_iterator_interface
+            : any_forward_iterator_interface<Reference, Buffer>
+        {
+            typedef typename any_forward_iterator_interface<Reference, Buffer>::reference reference;
+            typedef typename any_forward_iterator_interface<Reference, Buffer>::const_reference const_reference;
+            typedef typename any_forward_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+            typedef typename any_forward_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+            virtual any_bidirectional_iterator_interface*
+                        clone(buffer_type& buffer) const = 0;
+
+            virtual any_bidirectional_iterator_interface<const_reference, Buffer>*
+                        clone_const_ref(buffer_type& buffer) const = 0;
+
+            virtual any_bidirectional_iterator_interface<reference_as_value_type, Buffer>*
+                        clone_reference_as_value(buffer_type& buffer) const = 0;
+
+            virtual void decrement() = 0;
+        };
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_random_access_iterator_interface
+            : any_bidirectional_iterator_interface<
+                    Reference
+                  , Buffer
+                >
+        {
+            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference reference;
+            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::const_reference const_reference;
+            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+            typedef Difference difference_type;
+
+            virtual any_random_access_iterator_interface*
+                        clone(buffer_type& buffer) const = 0;
+
+            virtual any_random_access_iterator_interface<const_reference, Difference, Buffer>*
+                        clone_const_ref(buffer_type& buffer) const = 0;
+
+            virtual any_random_access_iterator_interface<reference_as_value_type, Difference, Buffer>*
+                        clone_reference_as_value(buffer_type& buffer) const = 0;
+
+            virtual void advance(Difference offset) = 0;
+
+            virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0;
+        };
+
+        template<
+            class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator;
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator<
+                    incrementable_traversal_tag
+                  , Reference
+                  , Difference
+                  , Buffer
+                >
+        {
+            typedef any_incrementable_iterator_interface<Reference, Buffer> type;
+        };
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator<
+                    single_pass_traversal_tag
+                  , Reference
+                  , Difference
+                  , Buffer
+                >
+        {
+            typedef any_single_pass_iterator_interface<Reference, Buffer> type;
+        };
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator<
+                    forward_traversal_tag
+                  , Reference
+                  , Difference
+                  , Buffer
+                >
+        {
+            typedef any_forward_iterator_interface<Reference, Buffer> type;
+        };
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator<
+                    bidirectional_traversal_tag
+                  , Reference
+                  , Difference
+                  , Buffer
+                >
+        {
+            typedef any_bidirectional_iterator_interface<Reference, Buffer> type;
+        };
+
+        template<
+            class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_interface_type_generator<
+                    random_access_traversal_tag
+                  , Reference
+                  , Difference
+                  , Buffer
+                >
+        {
+            typedef any_random_access_iterator_interface<
+                        Reference
+                      , Difference
+                      , Buffer
+                    > type;
+        };
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/any_iterator_wrapper.hpp b/include/boost/range/detail/any_iterator_wrapper.hpp
new file mode 100644
index 0000000..c542d39
--- /dev/null
+++ b/include/boost/range/detail/any_iterator_wrapper.hpp
@@ -0,0 +1,640 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
+
+#include <boost/cast.hpp>
+#include <boost/range/config.hpp>
+#include <boost/range/detail/any_iterator_interface.hpp>
+#include <boost/range/concepts.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template<typename TargetT, typename SourceT>
+        TargetT& polymorphic_ref_downcast(SourceT& source)
+        {
+#ifdef BOOST_NO_RTTI
+            return static_cast<TargetT&>(source);
+#else
+            return *boost::polymorphic_downcast<TargetT*>(&source);
+#endif
+        }
+
+        template<class Reference, class T>
+        Reference dereference_cast(T& x)
+        {
+            return static_cast<Reference>(x);
+        }
+        template<class Reference, class T>
+        Reference dereference_cast(const T& x)
+        {
+            return static_cast<Reference>(const_cast<T&>(x));
+        }
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Buffer
+        >
+        class any_incrementable_iterator_wrapper
+            : public any_incrementable_iterator_interface<
+                        Reference
+                      , Buffer
+                    >
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> ));
+        public:
+            typedef WrappedIterator wrapped_type;
+
+            BOOST_STATIC_ASSERT(( is_convertible<
+                                    typename iterator_reference<WrappedIterator>::type
+                                  , Reference
+                                  >::value ));
+
+            any_incrementable_iterator_wrapper()
+                : m_it()
+            {}
+
+            explicit any_incrementable_iterator_wrapper(wrapped_type it)
+                : m_it(it)
+            {}
+
+        // any_incrementable_iterator implementation
+            virtual any_incrementable_iterator_wrapper* clone(
+                typename any_incrementable_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                return new (buffer.allocate(sizeof(*this)))
+                                any_incrementable_iterator_wrapper(m_it);
+            }
+
+            virtual any_incrementable_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_incrementable_iterator_wrapper::const_reference
+                      , Buffer
+                    >* clone_const_ref(
+                        typename any_incrementable_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                typedef any_incrementable_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_incrementable_iterator_wrapper::const_reference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual any_incrementable_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_incrementable_iterator_wrapper::reference_as_value_type
+                      , Buffer
+                    >* clone_reference_as_value(
+                        typename any_incrementable_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                typedef any_incrementable_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_incrementable_iterator_wrapper::reference_as_value_type
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual void increment()
+            {
+                ++m_it;
+            }
+
+         private:
+            wrapped_type m_it;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Buffer
+        >
+        class any_single_pass_iterator_wrapper
+            : public any_single_pass_iterator_interface<
+                        Reference
+                      , Buffer
+                    >
+        {
+            struct disabler {};
+            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
+            typedef any_single_pass_iterator_interface<
+                Reference,
+                Buffer
+            > base_type;
+
+        public:
+            typedef typename base_type::reference reference;
+
+            any_single_pass_iterator_wrapper()
+                : m_it()
+            {}
+
+            explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
+                : m_it(it)
+            {}
+        // any_single_pass_iterator_interface<Reference> implementation
+            virtual any_single_pass_iterator_wrapper* clone(
+                typename any_single_pass_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                return new (buffer.allocate(sizeof(*this)))
+                            any_single_pass_iterator_wrapper(m_it);
+            }
+
+            virtual any_single_pass_iterator_wrapper<
+                WrappedIterator
+              , typename any_single_pass_iterator_wrapper::const_reference
+              , Buffer
+            >* clone_const_ref(
+                   typename any_single_pass_iterator_wrapper::buffer_type& buffer
+                   ) const
+            {
+                typedef any_single_pass_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_single_pass_iterator_wrapper::const_reference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual any_single_pass_iterator_wrapper<
+                WrappedIterator
+              , typename any_single_pass_iterator_wrapper::reference_as_value_type
+              , Buffer
+            >* clone_reference_as_value(
+                typename any_single_pass_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                typedef any_single_pass_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_single_pass_iterator_wrapper::reference_as_value_type
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual void increment()
+            {
+                ++m_it;
+            }
+
+            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+            {
+                return m_it == range_detail::polymorphic_ref_downcast<const any_single_pass_iterator_wrapper>(other).m_it;
+            }
+
+            virtual reference dereference() const
+            {
+                return dereference_cast<reference>(*m_it);
+            }
+
+        private:
+            WrappedIterator m_it;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Buffer
+        >
+        class any_forward_iterator_wrapper
+            : public any_forward_iterator_interface<
+                        Reference
+                      , Buffer
+                    >
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
+            typedef any_forward_iterator_interface<
+                Reference,
+                Buffer
+            > base_type;
+
+        public:
+            typedef typename base_type::reference reference;
+
+            any_forward_iterator_wrapper()
+                : m_it()
+            {}
+
+            explicit any_forward_iterator_wrapper(const WrappedIterator& it)
+                : m_it(it)
+            {}
+
+            // any_forward_iterator_interface<Reference> implementation
+            virtual any_forward_iterator_wrapper* clone(
+                typename any_forward_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                return new (buffer.allocate(sizeof(*this)))
+                                any_forward_iterator_wrapper(m_it);
+            }
+
+            virtual any_forward_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_forward_iterator_wrapper::const_reference
+                      , Buffer
+                    >* clone_const_ref(
+                            typename any_forward_iterator_wrapper::buffer_type& buffer
+                        ) const
+            {
+                typedef any_forward_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_forward_iterator_wrapper::const_reference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual any_forward_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_forward_iterator_wrapper::reference_as_value_type
+                      , Buffer
+                    >* clone_reference_as_value(
+                            typename any_forward_iterator_wrapper::buffer_type& buffer
+                    ) const
+            {
+                typedef any_forward_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_forward_iterator_wrapper::reference_as_value_type
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual void increment()
+            {
+                ++m_it;
+            }
+
+            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+            {
+                return m_it == range_detail::polymorphic_ref_downcast<const any_forward_iterator_wrapper>(other).m_it;
+            }
+
+            virtual reference dereference() const
+            {
+                return dereference_cast<reference>(*m_it);
+            }
+        private:
+            WrappedIterator m_it;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Buffer
+        >
+        class any_bidirectional_iterator_wrapper
+            : public any_bidirectional_iterator_interface<
+                        Reference
+                      , Buffer
+                    >
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
+            typedef any_bidirectional_iterator_interface<
+                Reference,
+                Buffer
+            > base_type;
+
+        public:
+            typedef typename base_type::reference reference;
+
+            any_bidirectional_iterator_wrapper()
+                : m_it()
+            {
+            }
+
+            explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
+                : m_it(it)
+            {
+            }
+
+            virtual any_bidirectional_iterator_wrapper* clone(
+                typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                return new (buffer.allocate(sizeof(*this)))
+                            any_bidirectional_iterator_wrapper(*this);
+            }
+
+            virtual any_bidirectional_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_bidirectional_iterator_wrapper::const_reference
+                      , Buffer
+                    >* clone_const_ref(
+                           typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+                       ) const
+            {
+                typedef any_bidirectional_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_bidirectional_iterator_wrapper::const_reference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual any_bidirectional_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_bidirectional_iterator_wrapper::reference_as_value_type
+                      , Buffer
+                    >* clone_reference_as_value(
+                           typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+                       ) const
+            {
+                typedef any_bidirectional_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_bidirectional_iterator_wrapper::reference_as_value_type
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual void increment()
+            {
+                ++m_it;
+            }
+
+            virtual void decrement()
+            {
+                --m_it;
+            }
+
+            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+            {
+                return m_it == range_detail::polymorphic_ref_downcast<const any_bidirectional_iterator_wrapper>(other).m_it;
+            }
+
+            virtual reference dereference() const
+            {
+                return dereference_cast<reference>(*m_it);
+            }
+
+        private:
+            WrappedIterator m_it;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        class any_random_access_iterator_wrapper
+            : public any_random_access_iterator_interface<
+                            Reference
+                          , Difference
+                          , Buffer
+                        >
+        {
+            BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
+            typedef any_random_access_iterator_interface<
+                Reference,
+                Difference,
+                Buffer
+            > base_type;
+
+        public:
+            typedef typename base_type::reference reference;
+            typedef Difference difference_type;
+
+            any_random_access_iterator_wrapper()
+                : m_it()
+            {
+            }
+
+            explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
+                : m_it(other)
+            {
+            }
+
+            virtual any_random_access_iterator_wrapper* clone(
+                    typename any_random_access_iterator_wrapper::buffer_type& buffer
+                ) const
+            {
+                return new (buffer.allocate(sizeof(*this)))
+                                any_random_access_iterator_wrapper(*this);
+            }
+
+            virtual any_random_access_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_random_access_iterator_wrapper::const_reference
+                      , Difference
+                      , Buffer
+                    >* clone_const_ref(
+                           typename any_random_access_iterator_wrapper::buffer_type& buffer
+                           ) const
+            {
+                typedef any_random_access_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_random_access_iterator_wrapper::const_reference
+                          , Difference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual any_random_access_iterator_wrapper<
+                        WrappedIterator
+                      , typename any_random_access_iterator_wrapper::reference_as_value_type
+                      , Difference
+                      , Buffer
+                    >* clone_reference_as_value(
+                           typename any_random_access_iterator_wrapper::buffer_type& buffer
+                           ) const
+            {
+                typedef any_random_access_iterator_wrapper<
+                            WrappedIterator
+                          , typename any_random_access_iterator_wrapper::reference_as_value_type
+                          , Difference
+                          , Buffer
+                        > result_type;
+
+                return new (buffer.allocate(sizeof(result_type)))
+                            result_type(m_it);
+            }
+
+            virtual void increment()
+            {
+                ++m_it;
+            }
+
+            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+            {
+                return m_it == range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it;
+            }
+
+            virtual void decrement()
+            {
+                --m_it;
+            }
+
+            virtual void advance(Difference offset)
+            {
+                m_it += offset;
+            }
+
+            virtual reference dereference() const
+            {
+                return dereference_cast<reference>(*m_it);
+            }
+
+            virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
+            {
+                return range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it - m_it;
+            }
+
+        private:
+            WrappedIterator m_it;
+        };
+
+        template<
+            class WrappedIterator
+          , class Traversal
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator;
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator<
+            WrappedIterator
+          , incrementable_traversal_tag
+          , Reference
+          , Difference
+          , Buffer
+        >
+        {
+            typedef any_incrementable_iterator_wrapper<
+                        WrappedIterator
+                      , Reference
+                      , Buffer
+                    > type;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator<
+            WrappedIterator
+          , single_pass_traversal_tag
+          , Reference
+          , Difference
+          , Buffer
+        >
+        {
+            typedef any_single_pass_iterator_wrapper<
+                        WrappedIterator
+                      , Reference
+                      , Buffer
+                > type;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator<
+            WrappedIterator
+          , forward_traversal_tag
+          , Reference
+          , Difference
+          , Buffer
+        >
+        {
+            typedef any_forward_iterator_wrapper<
+                WrappedIterator
+              , Reference
+              , Buffer
+            > type;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator<
+            WrappedIterator
+          , bidirectional_traversal_tag
+          , Reference
+          , Difference
+          , Buffer
+        >
+        {
+            typedef any_bidirectional_iterator_wrapper<
+                WrappedIterator
+              , Reference
+              , Buffer
+            > type;
+        };
+
+        template<
+            class WrappedIterator
+          , class Reference
+          , class Difference
+          , class Buffer
+        >
+        struct any_iterator_wrapper_type_generator<
+            WrappedIterator
+          , random_access_traversal_tag
+          , Reference
+          , Difference
+          , Buffer
+        >
+        {
+            typedef any_random_access_iterator_wrapper<
+                WrappedIterator
+              , Reference
+              , Difference
+              , Buffer
+            > type;
+        };
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/as_literal.hpp b/include/boost/range/detail/as_literal.hpp
new file mode 100644
index 0000000..8b219ea
--- /dev/null
+++ b/include/boost/range/detail/as_literal.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_AS_LITERAL_HPP
+#define BOOST_RANGE_DETAIL_AS_LITERAL_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/detail/detail_str.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+    template< class Range >
+    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type> 
+    as_literal( Range& r )
+    {
+        return ::boost::make_iterator_range( ::boost::range_detail::str_begin(r),
+                                             ::boost::range_detail::str_end(r) );
+    }
+
+}
+
+#endif
diff --git a/include/boost/range/detail/begin.hpp b/include/boost/range/detail/begin.hpp
new file mode 100644
index 0000000..efadaa6
--- /dev/null
+++ b/include/boost/range/detail/begin.hpp
@@ -0,0 +1,83 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_BEGIN_HPP
+#define BOOST_RANGE_DETAIL_BEGIN_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/detail/workaround.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/detail/common.hpp>
+
+namespace boost
+{
+
+    namespace range_detail
+    {
+        template< typename T >
+        struct range_begin;
+
+        //////////////////////////////////////////////////////////////////////
+        // default
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_begin<std_container_>
+        {
+            template< typename C >
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type fun( C& c )
+            {
+                return c.begin();
+            };
+        };
+
+        //////////////////////////////////////////////////////////////////////
+        // pair
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_begin<std_pair_>
+        {
+            template< typename P >
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type fun( const P& p )
+            {
+                return p.first;
+            }
+        };
+
+        //////////////////////////////////////////////////////////////////////
+        // array
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_begin<array_>
+        {
+            template<typename T>
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_value<T>::type* fun(T& t)
+            {
+                return t;
+            }
+        };
+
+    } // namespace 'range_detail'
+
+    namespace range_adl_barrier
+    {
+        template< typename C >
+        BOOST_CONSTEXPR inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+        begin( C& c )
+        {
+            return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+        }
+    }
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/detail/collection_traits.hpp b/include/boost/range/detail/collection_traits.hpp
new file mode 100644
index 0000000..823c0af
--- /dev/null
+++ b/include/boost/range/detail/collection_traits.hpp
@@ -0,0 +1,265 @@
+//  Boost string_algo library collection_traits.hpp header file  -------------//
+
+//  Copyright Pavol Droba 2002-2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// (C) Copyright Thorsten Ottosen 2002-2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// (C) Copyright Jeremy Siek 2001. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+//  Original idea of container traits was proposed by Jeremy Siek and
+//  Thorsten Ottosen. This implementation is lightweighted version
+//  of container_traits adapter for usage with string_algo library
+
+#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
+#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
+
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/mpl/eval_if.hpp>
+
+// Implementation
+#include <boost/range/detail/collection_traits_detail.hpp>
+
+/*! \file
+    Defines collection_traits class and related free-standing functions.
+    This facility is used to unify the access to different types of collections.
+    It allows the algorithms in the library to work with STL collections, c-style
+    array, null-terminated c-strings (and more) using the same interface.
+*/
+
+namespace boost {
+    namespace algorithm {
+
+//  collection_traits template class -----------------------------------------//
+        
+        //! collection_traits class
+        /*!
+            Collection traits provide uniform access to different types of 
+            collections. This functionality allows to write generic algorithms
+            which work with several different kinds of collections.
+
+            Currently following collection types are supported:
+                - containers with STL compatible container interface ( see ContainerConcept )
+                    ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... )
+                - c-style array 
+                   ( \c char[10], \c int[15] ... )
+                - null-terminated c-strings
+                    ( \c char*, \c wchar_T* )
+                - std::pair of iterators 
+                    ( i.e \c std::pair<vector<int>::iterator,vector<int>::iterator> )
+
+            Collection traits provide an external collection interface operations.
+            All are accessible using free-standing functions.
+
+            The following operations are supported:
+                - \c size()
+                - \c empty()
+                - \c begin()
+                - \c end()
+
+            Container traits have somewhat limited functionality on compilers not
+            supporting partial template specialization and partial template ordering.
+        */
+        template< typename T >
+        struct collection_traits
+        {
+        private:
+            typedef typename ::boost::mpl::eval_if<
+                    ::boost::algorithm::detail::is_pair<T>, 
+                        detail::pair_container_traits_selector<T>,
+                        typename ::boost::mpl::eval_if<
+                        ::boost::is_array<T>, 
+                            detail::array_container_traits_selector<T>,
+                            typename ::boost::mpl::eval_if<
+                            ::boost::is_pointer<T>,
+                                detail::pointer_container_traits_selector<T>,
+                                detail::default_container_traits_selector<T>
+                            >
+                        > 
+                >::type container_helper_type;
+        public:
+            //! Function type       
+            typedef container_helper_type function_type;        
+            //! Value type
+            typedef typename
+                container_helper_type::value_type value_type;
+            //! Size type
+            typedef typename
+                container_helper_type::size_type size_type;
+            //! Iterator type
+            typedef typename
+                container_helper_type::iterator iterator;
+            //! Const iterator type
+            typedef typename
+                container_helper_type::const_iterator const_iterator;
+            //! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
+            typedef typename
+                container_helper_type::result_iterator result_iterator;
+            //! Difference type
+            typedef typename
+                container_helper_type::difference_type difference_type;
+
+        }; // 'collection_traits'
+
+//  collection_traits metafunctions -----------------------------------------//
+
+        //! Container value_type trait
+        /*!
+            Extract the type of elements contained in a container
+        */
+        template< typename C >
+        struct value_type_of
+        {
+            typedef typename collection_traits<C>::value_type type;
+        };
+        
+        //! Container difference trait
+        /*!
+            Extract the container's difference type
+        */
+        template< typename C >
+        struct difference_type_of
+        {
+            typedef typename collection_traits<C>::difference_type type;
+        };
+
+        //! Container iterator trait
+        /*!
+            Extract the container's iterator type
+        */
+        template< typename C >
+        struct iterator_of
+        {
+            typedef typename collection_traits<C>::iterator type;
+        };
+
+        //! Container const_iterator trait
+        /*!
+            Extract the container's const_iterator type
+        */
+        template< typename C >
+        struct const_iterator_of
+        {
+            typedef typename collection_traits<C>::const_iterator type;
+        };
+
+
+        //! Container result_iterator
+        /*!
+            Extract the container's result_iterator type. This type maps to \c C::iterator
+            for mutable container and \c C::const_iterator for const containers.
+        */
+        template< typename C >
+        struct result_iterator_of
+        {
+            typedef typename collection_traits<C>::result_iterator type;
+        };
+
+//  collection_traits related functions -----------------------------------------//
+
+        //! Free-standing size() function
+        /*!
+            Get the size of the container. Uses collection_traits.
+        */
+        template< typename C >
+        inline typename collection_traits<C>::size_type
+        size( const C& c )
+        {
+            return collection_traits<C>::function_type::size( c ); 
+        }
+
+        //! Free-standing empty() function
+        /*!
+            Check whether the container is empty. Uses container traits.
+        */
+        template< typename C >
+        inline bool empty( const C& c )
+        {
+            return collection_traits<C>::function_type::empty( c );
+        }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        //! Free-standing begin() function
+        /*!
+            Get the begin iterator of the container. Uses collection_traits.
+        */
+        template< typename C >
+        inline typename collection_traits<C>::iterator
+        begin( C& c )
+        {
+            return collection_traits<C>::function_type::begin( c ); 
+        }
+
+        //! Free-standing begin() function
+        /*!
+            \overload
+        */
+        template< typename C >
+        inline typename collection_traits<C>::const_iterator
+        begin( const C& c )
+        {
+            return collection_traits<C>::function_type::begin( c ); 
+        }
+
+        //! Free-standing end() function
+        /*!
+            Get the begin iterator of the container. Uses collection_traits.
+        */
+        template< typename C >
+        inline typename collection_traits<C>::iterator
+        end( C& c )
+        {
+            return collection_traits<C>::function_type::end( c );
+        }
+
+        //! Free-standing end() function
+        /*!
+            \overload           
+        */
+        template< typename C >
+        inline typename collection_traits<C>::const_iterator
+        end( const C& c )
+        {
+            return collection_traits<C>::function_type::end( c );
+        }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        //! Free-standing begin() function
+        /*!
+            \overload
+        */
+        template< typename C >
+        inline typename collection_traits<C>::result_iterator
+        begin( C& c )
+        {
+            return collection_traits<C>::function_type::begin( c );
+        }
+
+        //! Free-standing end() function
+        /*!
+            \overload
+        */
+        template< typename C >
+        inline typename collection_traits<C>::result_iterator
+        end( C& c )
+        {
+            return collection_traits<C>::function_type::end( c );
+        }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+    } // namespace algorithm
+} // namespace boost
+
+#endif // BOOST_STRING_COLLECTION_TRAITS_HPP
diff --git a/include/boost/range/detail/collection_traits_detail.hpp b/include/boost/range/detail/collection_traits_detail.hpp
new file mode 100644
index 0000000..1545997
--- /dev/null
+++ b/include/boost/range/detail/collection_traits_detail.hpp
@@ -0,0 +1,502 @@
+//  Boost string_algo library collection_traits.hpp header file  -----------------------//
+
+//  Copyright Pavol Droba 2002-2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
+#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
+
+#include <cstddef>
+#include <string>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/detail/iterator.hpp>
+
+// Container traits implementation ---------------------------------------------------------
+
+namespace boost {
+    namespace algorithm {
+        namespace detail {
+
+// Default collection traits -----------------------------------------------------------------
+
+            // Default collection helper 
+            /*
+                Wraps std::container compliant containers
+            */
+            template< typename ContainerT >     
+            struct default_container_traits
+            {
+                typedef typename ContainerT::value_type value_type;
+                typedef typename ContainerT::iterator iterator;
+                typedef typename ContainerT::const_iterator const_iterator;
+                typedef typename
+                    ::boost::mpl::if_< ::boost::is_const<ContainerT>,
+                        const_iterator,
+                        iterator 
+                    >::type result_iterator;
+                typedef typename ContainerT::difference_type difference_type;
+                typedef typename ContainerT::size_type size_type;
+                
+                // static operations
+                template< typename C >
+                static size_type size( const C& c )
+                {
+                    return c.size();
+                }
+
+                template< typename C >
+                static bool empty( const C& c )
+                {
+                    return c.empty();
+                }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename C >
+                static iterator begin( C& c )
+                {
+                    return c.begin();
+                }
+
+                template< typename C >
+                static const_iterator begin( const C& c )
+                {
+                    return c.begin();
+                }
+
+                template< typename C >
+                static iterator end( C& c )
+                {
+                    return c.end();
+                }
+
+                template< typename C >
+                static const_iterator end( const C& c )
+                {
+                    return c.end();
+                }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename C >
+                static result_iterator begin( C& c )
+                {
+                    return c.begin();
+                }
+
+                template< typename C >
+                static result_iterator end( C& c )
+                {
+                    return c.end();
+                }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
+
+            }; 
+
+            template<typename T>
+            struct default_container_traits_selector
+            {
+                typedef default_container_traits<T> type;
+            };
+
+// Pair container traits ---------------------------------------------------------------------
+
+            typedef double yes_type;
+            typedef char no_type;
+
+            // pair selector
+            template< typename T, typename U >
+            yes_type is_pair_impl( const std::pair<T,U>* );
+            no_type is_pair_impl( ... );
+
+            template<typename T> struct is_pair
+            {
+            private:
+                static T* t;
+            public:
+                BOOST_STATIC_CONSTANT( bool, value=
+                    sizeof(is_pair_impl(t))==sizeof(yes_type) );
+            };
+
+            // pair helper
+            template< typename PairT >
+            struct pair_container_traits
+            {
+                typedef typename PairT::first_type element_type;
+
+                typedef typename ::boost::detail::
+                    iterator_traits<element_type>::value_type value_type;
+                typedef std::size_t size_type;
+                typedef typename ::boost::detail::
+                    iterator_traits<element_type>::difference_type difference_type;
+
+                typedef element_type iterator;
+                typedef element_type const_iterator;
+                typedef element_type result_iterator;
+
+                // static operations
+                template< typename P >
+                static size_type size( const P& p )
+                {
+                    difference_type diff = std::distance( p.first, p.second );
+                    if ( diff < 0 ) 
+                        return 0;
+                    else
+                        return diff;
+                }
+
+                template< typename P >
+                static bool empty( const P& p )
+                {
+                    return p.first==p.second;
+                }
+
+                template< typename P > 
+                static const_iterator begin( const P& p )
+                {
+                    return p.first;
+                }
+
+                template< typename P >
+                static const_iterator end( const P& p )
+                {
+                    return p.second;
+                }
+            }; // 'pair_container_helper'
+
+            template<typename T>
+            struct pair_container_traits_selector
+            {
+                typedef pair_container_traits<T> type;
+            };
+
+// Array container traits ---------------------------------------------------------------
+
+            // array traits ( partial specialization )
+            template< typename T >
+            struct array_traits;
+
+            template< typename T, std::size_t sz >
+            struct array_traits<T[sz]>
+            {
+                // typedef
+                typedef T* iterator;
+                typedef const T* const_iterator;
+                typedef T value_type;
+                typedef std::size_t size_type;
+                typedef std::ptrdiff_t difference_type;
+
+                // size of the array ( static );
+                BOOST_STATIC_CONSTANT( size_type, array_size = sz );
+            };
+
+            
+            // array length resolving
+            /*
+                Lenght of string contained in a static array could
+                be different from the size of the array.
+                For string processing we need the length without
+                terminating 0.
+
+                Therefore, the length is calculated for char and wchar_t
+                using char_traits, rather then simply returning
+                the array size.
+            */
+            template< typename T >
+            struct array_length_selector
+            {
+                template< typename TraitsT >
+                struct array_length
+                {
+                    typedef typename
+                        TraitsT::size_type size_type;
+
+                    BOOST_STATIC_CONSTANT(
+                        size_type,
+                        array_size=TraitsT::array_size );
+
+                    template< typename A >
+                    static size_type length( const A& )
+                    {
+                        return array_size;
+                    }
+
+                    template< typename A >
+                    static bool empty( const A& )
+                    {
+                        return array_size==0;
+                    }
+                };
+            };
+
+            // specialization for char
+            template<>
+            struct array_length_selector<char>
+            {
+                template< typename TraitsT >
+                struct array_length
+                {
+                    typedef typename
+                        TraitsT::size_type size_type;
+
+                    template< typename A >
+                    static size_type length( const A& a )
+                    {
+                        if ( a==0 ) 
+                            return 0;
+                        else
+                            return std::char_traits<char>::length(a);
+                    }
+                    
+                    template< typename A >
+                    static bool empty( const A& a )
+                    {
+                        return a==0 || a[0]==0;
+                    }
+                };
+            };
+
+            // specialization for wchar_t
+            template<>
+            struct array_length_selector<wchar_t>
+            {
+                template< typename TraitsT >
+                struct array_length
+                {
+                    typedef typename
+                        TraitsT::size_type size_type;
+
+                    template< typename A >
+                    static size_type length( const A& a )
+                    {
+                        if ( a==0 ) 
+                            return 0;
+                        else
+                            return std::char_traits<wchar_t>::length(a);
+                    }
+
+                    template< typename A >
+                    static bool empty( const A& a )
+                    {
+                        return a==0 || a[0]==0;
+                    }
+                };
+            };
+
+            template< typename T >
+            struct array_container_traits
+            {
+            private:
+                // resolve array traits
+                typedef array_traits<T> traits_type;
+
+            public:
+                typedef typename
+                    traits_type::value_type value_type;
+                typedef typename
+                    traits_type::iterator iterator;
+                typedef typename
+                    traits_type::const_iterator const_iterator;
+                typedef typename
+                    traits_type::size_type size_type;
+                typedef typename
+                    traits_type::difference_type difference_type;
+
+                typedef typename
+                    ::boost::mpl::if_< ::boost::is_const<T>,
+                        const_iterator,
+                        iterator 
+                    >::type result_iterator;
+                
+            private:
+                // resolve array size
+                typedef typename
+                    ::boost::remove_cv<value_type>::type char_type;
+                typedef typename
+                    array_length_selector<char_type>::
+                        BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
+
+            public:
+                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
+
+                // static operations
+                template< typename A >
+                static size_type size( const A& a )
+                {
+                    return array_length_type::length(a);
+                }
+
+                template< typename A >
+                static bool empty( const A& a )
+                {
+                    return array_length_type::empty(a);
+                }
+                
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename A >
+                static iterator begin( A& a )
+                {
+                    return a;
+                }
+
+                template< typename A >
+                static const_iterator begin( const A& a )
+                {
+                    return a;
+                }
+
+                template< typename A >
+                static iterator end( A& a )
+                {
+                    return a+array_length_type::length(a);
+                }
+
+                template< typename A >
+                static const_iterator end( const A& a )
+                {
+                    return a+array_length_type::length(a);
+                }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename A >
+                static result_iterator begin( A& a )
+                {
+                    return a;
+                }
+
+                template< typename A >
+                static result_iterator end( A& a )
+                {
+                    return a+array_length_type::length(a);
+                }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
+
+            }; 
+
+            template<typename T>
+            struct array_container_traits_selector
+            {
+                typedef array_container_traits<T> type;
+            };
+
+// Pointer container traits ---------------------------------------------------------------
+
+            template<typename T>
+            struct pointer_container_traits
+            {
+                typedef typename
+                    ::boost::remove_pointer<T>::type value_type;
+
+                typedef typename
+                    ::boost::remove_cv<value_type>::type char_type;
+                typedef ::std::char_traits<char_type> char_traits;
+
+                typedef value_type* iterator;
+                typedef const value_type* const_iterator;
+                typedef std::ptrdiff_t difference_type;
+                typedef std::size_t size_type;
+
+                typedef typename
+                    ::boost::mpl::if_< ::boost::is_const<T>,
+                        const_iterator,
+                        iterator 
+                    >::type result_iterator;
+
+                // static operations
+                template< typename P >
+                static size_type size( const P& p )
+                {
+                    if ( p==0 ) 
+                        return 0;
+                    else
+                        return char_traits::length(p);
+                }
+
+                template< typename P >
+                static bool empty( const P& p )
+                {
+                    return p==0 || p[0]==0;
+                }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename P >
+                static iterator begin( P& p )
+                {
+                    return p;
+                }
+
+                template< typename P >
+                static const_iterator begin( const P& p )
+                {
+                    return p;
+                }
+
+                template< typename P >
+                static iterator end( P& p )
+                {
+                    if ( p==0 )
+                        return p;
+                    else
+                        return p+char_traits::length(p);
+                }
+
+                template< typename P >
+                static const_iterator end( const P& p )
+                {
+                    if ( p==0 )
+                        return p;
+                    else
+                        return p+char_traits::length(p);
+                }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+                template< typename P >
+                static result_iterator begin( P& p )
+                {
+                    return p;
+                }
+
+                template< typename P >
+                static result_iterator end( P& p )
+                {
+                    if ( p==0 )
+                        return p;
+                    else
+                        return p+char_traits::length(p);
+                }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
+            }; 
+
+            template<typename T>
+            struct pointer_container_traits_selector
+            {
+                typedef pointer_container_traits<T> type;
+            };
+
+        } // namespace detail
+    } // namespace algorithm
+} // namespace boost
+
+
+#endif  // BOOST_STRING_DETAIL_COLLECTION_HPP
diff --git a/include/boost/range/detail/combine_cxx03.hpp b/include/boost/range/detail/combine_cxx03.hpp
new file mode 100644
index 0000000..47da6a6
--- /dev/null
+++ b/include/boost/range/detail/combine_cxx03.hpp
@@ -0,0 +1,131 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP
+#define BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP
+
+#ifndef BOOST_RANGE_MIN_COMBINE_ARGS
+#define BOOST_RANGE_MIN_COMBINE_ARGS 2
+#endif
+
+#ifndef BOOST_RANGE_MAX_COMBINE_ARGS
+#define BOOST_RANGE_MAX_COMBINE_ARGS 5
+#endif
+
+#include <boost/config.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/arithmetic/div.hpp>
+#include <boost/preprocessor/arithmetic/mul.hpp>
+#include <boost/preprocessor/control.hpp>
+#include <boost/preprocessor/control/while.hpp>
+#include <boost/preprocessor/facilities/empty.hpp>
+#include <boost/preprocessor/facilities/identity.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <vector>
+#include <list>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<typename F, typename T, int SIZE>
+struct combined_result_impl;
+
+template<typename F, typename T>
+struct combined_result
+    : combined_result_impl<F, T, tuples::length<T>::value>
+{
+};
+
+#define BOOST_RANGE_combined_element(z, n, data) \
+    typename tuples::element<n, T>::type
+
+#define BOOST_RANGE_combined_result(z, n, data) \
+    template<typename F, typename T> \
+    struct combined_result_impl <F,T,n> \
+        : result_of<F(BOOST_PP_ENUM(n, BOOST_RANGE_combined_element, ~))> \
+    { \
+    };
+
+#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_result(~,n,~)
+
+#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
+                               BOOST_RANGE_MAX_COMBINE_ARGS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#define BOOST_RANGE_combined_get(z, n, data) get<n>(tuple)
+
+#define BOOST_RANGE_combined_unpack(z, n, data) \
+    template<typename F, typename T> inline \
+    typename combined_result<F,T>::type \
+    unpack_(mpl::int_<n>, F f, const T& tuple) \
+    { \
+        return f(BOOST_PP_ENUM(n, BOOST_RANGE_combined_get, ~)); \
+    }
+
+#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_unpack(~,n,~)
+#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
+                               BOOST_RANGE_MAX_COMBINE_ARGS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+} // namespace range_detail
+
+namespace range
+{
+
+#define BOOST_RANGE_combined_seq(z, n, data) boost::data(BOOST_PP_CAT(r,n))
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/range/detail/combine_no_rvalue.hpp>
+
+#else // by using rvalue references we avoid requiring 2^n overloads.
+
+#include <boost/range/detail/combine_rvalue.hpp>
+
+#endif
+
+#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combine(~,n,~)
+#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
+                               BOOST_RANGE_MAX_COMBINE_ARGS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+    } // namespace range
+
+    using boost::range::combine;
+
+} // namespace boost
+
+#endif // include guard
+
+#undef BOOST_RANGE_combined_element
+#undef BOOST_RANGE_combined_result
+#undef BOOST_RANGE_combined_get
+#undef BOOST_RANGE_combined_unpack
+#undef BOOST_RANGE_combined_seq
+#undef BOOST_RANGE_combined_exp_pred
+#undef BOOST_RANGE_combined_exp_op
+#undef BOOST_RANGE_combined_exp
+#undef BOOST_RANGE_combined_bitset_pred
+#undef BOOST_RANGE_combined_bitset_op
+#undef BOOST_RANGE_combined_bitset
+#undef BOOST_RANGE_combined_range_iterator
+#undef BOOST_RANGE_combined_args
+#undef BOOST_RANGE_combine_impl
+#undef BOOST_RANGE_combine
diff --git a/include/boost/range/detail/combine_cxx11.hpp b/include/boost/range/detail/combine_cxx11.hpp
new file mode 100644
index 0000000..a7fa5b1
--- /dev/null
+++ b/include/boost/range/detail/combine_cxx11.hpp
@@ -0,0 +1,40 @@
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP
+#define BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP
+
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+
+#include <fstream>
+
+namespace boost
+{
+    namespace range
+    {
+
+template<typename... Ranges>
+auto combine(Ranges&&... rngs) ->
+    combined_range<decltype(boost::make_tuple(boost::begin(rngs)...))>
+{
+    return combined_range<decltype(boost::make_tuple(boost::begin(rngs)...))>(
+                boost::make_tuple(boost::begin(rngs)...),
+                boost::make_tuple(boost::end(rngs)...));
+}
+
+    } // namespace range
+
+using range::combine;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/combine_no_rvalue.hpp b/include/boost/range/detail/combine_no_rvalue.hpp
new file mode 100644
index 0000000..bdb3950
--- /dev/null
+++ b/include/boost/range/detail/combine_no_rvalue.hpp
@@ -0,0 +1,73 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#define BOOST_RANGE_combined_exp_pred(d, data) BOOST_PP_TUPLE_ELEM(3, 0, data)
+
+#define BOOST_RANGE_combined_exp_op(d, data) \
+ ( \
+    BOOST_PP_DEC( \
+       BOOST_PP_TUPLE_ELEM(3, 0, data) \
+    ), \
+    BOOST_PP_TUPLE_ELEM(3, 1, data), \
+    BOOST_PP_MUL_D( \
+       d, \
+       BOOST_PP_TUPLE_ELEM(3, 2, data), \
+       BOOST_PP_TUPLE_ELEM(3, 1, data) \
+    ) \
+ )
+
+#define BOOST_RANGE_combined_exp(x, n) \
+  BOOST_PP_TUPLE_ELEM(3, 2, \
+  BOOST_PP_WHILE(BOOST_RANGE_combined_exp_pred, \
+                 BOOST_RANGE_combined_exp_op, (n, x, 1)))
+
+#define BOOST_RANGE_combined_bitset_pred(n, state) \
+    BOOST_PP_TUPLE_ELEM(2,1,state)
+
+#define BOOST_RANGE_combined_bitset_op(d, state) \
+    (BOOST_PP_DIV_D(d, BOOST_PP_TUPLE_ELEM(2,0,state), 2), \
+     BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2,1,state)))
+
+#define BOOST_RANGE_combined_bitset(i, n) \
+BOOST_PP_MOD(BOOST_PP_TUPLE_ELEM(2, 0, \
+      BOOST_PP_WHILE(BOOST_RANGE_combined_bitset_pred, \
+                     BOOST_RANGE_combined_bitset_op, (i,n))), 2)
+
+#define BOOST_RANGE_combined_range_iterator(z, n, i) \
+  typename range_iterator< \
+      BOOST_PP_CAT(R,n)          \
+      BOOST_PP_IF( \
+          BOOST_RANGE_combined_bitset(i,n), \
+          BOOST_PP_IDENTITY(const), \
+          BOOST_PP_EMPTY)() \
+  >::type
+
+#define BOOST_RANGE_combined_args(z, n, i) \
+  BOOST_PP_CAT(R, n) \
+  BOOST_PP_IF(BOOST_RANGE_combined_bitset(i,n), const&, &)  \
+  BOOST_PP_CAT(r, n)
+
+#define BOOST_RANGE_combine_impl(z, i, n)\
+    template<BOOST_PP_ENUM_PARAMS(n, typename R)> \
+    inline range::combined_range< \
+        boost::tuple<BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i)> \
+    > \
+    combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, i)) \
+    { \
+        typedef tuple< \
+            BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i) \
+        > rng_tuple_t;   \
+        return range::combined_range<rng_tuple_t>( \
+            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \
+            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \
+    }
+
+
+#define BOOST_RANGE_combine(z, n, data) \
+  BOOST_PP_REPEAT(BOOST_RANGE_combined_exp(2,n), BOOST_RANGE_combine_impl, n)
diff --git a/include/boost/range/detail/combine_rvalue.hpp b/include/boost/range/detail/combine_rvalue.hpp
new file mode 100644
index 0000000..2e323b7
--- /dev/null
+++ b/include/boost/range/detail/combine_rvalue.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#define BOOST_RANGE_combined_args(z, n, i) \
+    BOOST_PP_CAT(R, n)&& BOOST_PP_CAT(r, n)
+
+#define BOOST_RANGE_combined_range_iterator(z, n, i) \
+    typename range_iterator< \
+        typename remove_reference<BOOST_PP_CAT(R,n)>::type \
+  >::type
+
+
+#define BOOST_RANGE_combine(z, n, data) \
+    template <BOOST_PP_ENUM_PARAMS(n, typename R)> \
+    inline range::combined_range< \
+        tuple<BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~)> \
+    > \
+    combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, ~)) \
+    { \
+        typedef tuple< \
+            BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~) \
+        > rng_tuple_t; \
+        return range::combined_range<rng_tuple_t>( \
+            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \
+            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \
+    }
diff --git a/include/boost/range/detail/common.hpp b/include/boost/range/detail/common.hpp
new file mode 100644
index 0000000..2cbc554
--- /dev/null
+++ b/include/boost/range/detail/common.hpp
@@ -0,0 +1,116 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_COMMON_HPP
+#define BOOST_RANGE_DETAIL_COMMON_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/detail/sfinae.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
+#include <cstddef>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization  workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost 
+{
+    namespace range_detail 
+    {        
+        // 1 = std containers
+        // 2 = std::pair
+        // 3 = const std::pair
+        // 4 = array
+        // 5 = const array
+        // 6 = char array
+        // 7 = wchar_t array
+        // 8 = char*
+        // 9 = const char*
+        // 10 = whar_t*
+        // 11 = const wchar_t*
+        // 12 = string
+        
+        typedef mpl::int_<1>::type    std_container_;
+        typedef mpl::int_<2>::type    std_pair_;
+        typedef mpl::int_<3>::type    const_std_pair_;
+        typedef mpl::int_<4>::type    array_;
+        typedef mpl::int_<5>::type    const_array_;
+        typedef mpl::int_<6>::type    char_array_;
+        typedef mpl::int_<7>::type    wchar_t_array_;
+        typedef mpl::int_<8>::type    char_ptr_;
+        typedef mpl::int_<9>::type    const_char_ptr_;
+        typedef mpl::int_<10>::type   wchar_t_ptr_;
+        typedef mpl::int_<11>::type   const_wchar_t_ptr_;
+        typedef mpl::int_<12>::type   string_;
+        
+        template< typename C >
+        struct range_helper
+        {
+            static C* c;
+            static C  ptr;
+
+            BOOST_STATIC_CONSTANT( bool, is_pair_                = sizeof( boost::range_detail::is_pair_impl( c ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_char_ptr_            = sizeof( boost::range_detail::is_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_const_char_ptr_      = sizeof( boost::range_detail::is_const_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_wchar_t_ptr_         = sizeof( boost::range_detail::is_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_   = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_char_array_          = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_       = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
+            BOOST_STATIC_CONSTANT( bool, is_string_              = (is_const_char_ptr_ || is_const_wchar_t_ptr_));
+            BOOST_STATIC_CONSTANT( bool, is_array_               = boost::is_array<C>::value );
+            
+        };
+        
+        template< typename C >
+        class range
+        {
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_pair_,
+                                                                  boost::range_detail::std_pair_,
+                                                                  void >::type pair_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_array_,
+                                                                    boost::range_detail::array_,
+                                                                    pair_t >::type array_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_string_,
+                                                                    boost::range_detail::string_,
+                                                                    array_t >::type string_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_char_ptr_,
+                                                                    boost::range_detail::const_char_ptr_,
+                                                                    string_t >::type const_char_ptr_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_ptr_,
+                                                                    boost::range_detail::char_ptr_,
+                                                                    const_char_ptr_t >::type char_ptr_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_wchar_t_ptr_,
+                                                                    boost::range_detail::const_wchar_t_ptr_,
+                                                                    char_ptr_t >::type const_wchar_ptr_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_ptr_,
+                                                                    boost::range_detail::wchar_t_ptr_,
+                                                                    const_wchar_ptr_t >::type wchar_ptr_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_array_,
+                                                                    boost::range_detail::wchar_t_array_,
+                                                                    wchar_ptr_t >::type wchar_array_t;
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_array_,
+                                                                    boost::range_detail::char_array_,
+                                                                    wchar_array_t >::type char_array_t;
+        public:
+            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::is_void<char_array_t>::value,
+                                                                    boost::range_detail::std_container_,
+                                                                    char_array_t >::type type;  
+        }; // class 'range' 
+    }
+}
+        
+#endif
+
diff --git a/include/boost/range/detail/default_constructible_unary_fn.hpp b/include/boost/range/detail/default_constructible_unary_fn.hpp
new file mode 100644
index 0000000..9729e3c
--- /dev/null
+++ b/include/boost/range/detail/default_constructible_unary_fn.hpp
@@ -0,0 +1,81 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED
+
+#include <boost/optional/optional.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<typename F, typename R>
+class default_constructible_unary_fn_wrapper
+{
+public:
+    typedef R result_type;
+
+    default_constructible_unary_fn_wrapper()
+    {
+    }
+    default_constructible_unary_fn_wrapper(const F& source)
+        : m_impl(source)
+    {
+    }
+    default_constructible_unary_fn_wrapper(const default_constructible_unary_fn_wrapper& source)
+        : m_impl(source.m_impl)
+    {
+    }
+    default_constructible_unary_fn_wrapper& operator=(const default_constructible_unary_fn_wrapper& source)
+    {
+        if (source.m_impl)
+        {
+            // Lambda are not copy/move assignable.
+            m_impl.emplace(*source.m_impl);
+        }
+        else
+        {
+            m_impl.reset();
+        }
+        return *this;
+    }
+    template<typename Arg>
+    R operator()(const Arg& arg) const
+    {
+        BOOST_ASSERT(m_impl);
+        return (*m_impl)(arg);
+    }
+    template<typename Arg>
+    R operator()(Arg& arg) const
+    {
+        BOOST_ASSERT(m_impl);
+        return (*m_impl)(arg);
+    }
+private:
+    boost::optional<F> m_impl;
+};
+
+template<typename F, typename R>
+struct default_constructible_unary_fn_gen
+{
+    typedef typename boost::mpl::if_<
+        boost::has_trivial_default_constructor<F>,
+        F,
+        default_constructible_unary_fn_wrapper<F,R>
+    >::type type;
+};
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/demote_iterator_traversal_tag.hpp b/include/boost/range/detail/demote_iterator_traversal_tag.hpp
new file mode 100644
index 0000000..6d65720
--- /dev/null
+++ b/include/boost/range/detail/demote_iterator_traversal_tag.hpp
@@ -0,0 +1,91 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// aschoedl supplied a fix to supply the level of interoperability I had
+// originally intended, but failed to implement.
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
+
+#include <boost/iterator/iterator_categories.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<class IteratorTraversalTag1, class IteratorTraversalTag2>
+struct inner_demote_iterator_traversal_tag
+{
+};
+
+#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \
+template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \
+{ \
+    typedef ResultTag type; \
+};
+
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, no_traversal_tag,            no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, incrementable_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, single_pass_traversal_tag,   no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, forward_traversal_tag,       no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, bidirectional_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, random_access_traversal_tag, no_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, no_traversal_tag,            no_traversal_tag            )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, single_pass_traversal_tag,   incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, forward_traversal_tag,       incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, bidirectional_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, random_access_traversal_tag, incrementable_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, no_traversal_tag,            no_traversal_tag            )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, forward_traversal_tag,       single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, bidirectional_traversal_tag, single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, random_access_traversal_tag, single_pass_traversal_tag   )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, no_traversal_tag,            no_traversal_tag            )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, bidirectional_traversal_tag, forward_traversal_tag       )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, random_access_traversal_tag, forward_traversal_tag       )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, no_traversal_tag,            no_traversal_tag            )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, random_access_traversal_tag, bidirectional_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, no_traversal_tag,            no_traversal_tag            )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal_tag, random_access_traversal_tag )
+
+#undef BOOST_DEMOTE_TRAVERSAL_TAG
+
+template<class IteratorTraversalTag1, class IteratorTraversalTag2>
+struct demote_iterator_traversal_tag
+    : inner_demote_iterator_traversal_tag<
+        typename boost::iterators::pure_traversal_tag< IteratorTraversalTag1 >::type,
+        typename boost::iterators::pure_traversal_tag< IteratorTraversalTag2 >::type
+      >
+{
+};
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/detail_str.hpp b/include/boost/range/detail/detail_str.hpp
new file mode 100644
index 0000000..5ef7a34
--- /dev/null
+++ b/include/boost/range/detail/detail_str.hpp
@@ -0,0 +1,376 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_DETAIL_STR_HPP
+#define BOOST_RANGE_DETAIL_DETAIL_STR_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/range/iterator.hpp>
+
+namespace boost 
+{
+    
+    namespace range_detail
+    {
+        //
+        // iterator
+        //
+        
+        template<>
+        struct range_iterator_<char_array_>
+        { 
+            template< typename T >
+            struct pts
+            {
+                 typedef BOOST_RANGE_DEDUCED_TYPENAME 
+                    remove_extent<T>::type* type;
+            };
+        };
+
+        template<>
+        struct range_iterator_<char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef char* type; 
+            };         
+        };
+
+        template<>
+        struct range_iterator_<const_char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef const char* type;
+            };         
+        };
+
+        template<>
+        struct range_iterator_<wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef wchar_t* type; 
+            };         
+        };
+
+        template<>
+        struct range_iterator_<const_wchar_t_ptr_>
+        {
+             template< typename S >
+             struct pts
+             {
+                 typedef const wchar_t* type; 
+             };         
+        };
+
+
+        //
+        // const iterator
+        //
+
+        template<>
+        struct range_const_iterator_<char_array_>
+        { 
+            template< typename T >
+            struct pts
+            {
+                typedef const BOOST_RANGE_DEDUCED_TYPENAME 
+                    remove_extent<T>::type* type;
+            };
+        };
+
+        template<>
+        struct range_const_iterator_<char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef const char* type; 
+            };         
+        };
+
+        template<>
+        struct range_const_iterator_<const_char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef const char* type; 
+            };         
+        };
+
+        template<>
+        struct range_const_iterator_<wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef const wchar_t* type; 
+            };         
+        };
+
+        template<>
+        struct range_const_iterator_<const_wchar_t_ptr_>
+        {
+             template< typename S >
+             struct pts
+             {
+                 typedef const wchar_t* type; 
+             };         
+        };
+    }
+}
+
+#include <boost/range/detail/begin.hpp>
+#include <boost/range/detail/end.hpp>
+#include <boost/range/detail/size_type.hpp>
+#include <boost/range/detail/value_type.hpp>
+#include <boost/range/detail/common.hpp>
+
+namespace boost 
+{
+    
+    namespace range_detail
+    {
+        //
+        // str_begin()
+        //
+        template<>
+        struct range_begin<char_ptr_>
+        {
+            static char* fun( char* s )
+            {
+                return s;
+            }
+        };
+
+        template<>
+        struct range_begin<const_char_ptr_>
+        {
+            static const char* fun( const char* s )
+            {
+                return s;
+            }
+        };
+        
+        template<>
+        struct range_begin<wchar_t_ptr_>
+        {
+            
+            static wchar_t* fun( wchar_t* s )
+            {
+                return s;
+            }
+        };
+
+        template<>
+        struct range_begin<const_wchar_t_ptr_>
+        {
+            static const wchar_t* fun( const wchar_t* s )
+            {
+                return s;
+            }
+        };
+        
+        template< typename C >
+        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type 
+        str_begin( C& c )
+        {
+            return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME 
+                range_detail::range<C>::type >::fun( c );
+        }
+
+        //
+        // str_end()
+        //
+
+        template<>
+        struct range_end<char_array_>
+        {
+            template< typename T, std::size_t sz >
+            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+            {
+                return boost::range_detail::array_end( boost_range_array );
+            }
+        };
+        
+        template<>
+        struct range_end<wchar_t_array_>
+        {
+            template< typename T, std::size_t sz >
+            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+            {
+                return boost::range_detail::array_end( boost_range_array );
+            }
+        };
+        
+        template<>
+        struct range_end<char_ptr_>
+        {
+            static char* fun( char* s )
+            {
+                return boost::range_detail::str_end( s );
+            }
+        };
+
+        template<>
+        struct range_end<const_char_ptr_>
+        {
+            static const char* fun( const char* s )
+            {
+                return boost::range_detail::str_end( s );
+            }
+        };
+
+        template<>
+        struct range_end<wchar_t_ptr_>
+        {
+            static wchar_t* fun( wchar_t* s )
+            {
+                return boost::range_detail::str_end( s );
+            }
+        };
+
+
+        template<>
+        struct range_end<const_wchar_t_ptr_>
+        {
+            static const wchar_t* fun( const wchar_t* s )
+            {
+                return boost::range_detail::str_end( s );
+            }
+        };
+
+        template< typename C >
+        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type 
+        str_end( C& c )
+        {
+            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME 
+                range_detail::range<C>::type >::fun( c );
+        }
+
+        //
+        // size_type
+        //
+
+        template<>
+        struct range_size_type_<char_array_>
+        { 
+            template< typename A >
+            struct pts
+            {
+                typedef std::size_t type;
+            };
+        };
+
+        template<>
+        struct range_size_type_<char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::size_t type;
+            };         
+        };
+        
+        template<>
+        struct range_size_type_<const_char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::size_t type;
+            };         
+        };
+        
+        template<>
+        struct range_size_type_<wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::size_t type;
+            };         
+        };
+        
+        template<>
+        struct range_size_type_<const_wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::size_t type;
+            };         
+        };  
+
+        //
+        // value_type
+        //
+        
+        template<>
+        struct range_value_type_<char_array_>
+        { 
+            template< typename T >
+            struct pts
+            {
+                typedef char type;
+            };
+        };
+
+        template<>
+        struct range_value_type_<char_ptr_>
+        {
+             template< typename S >
+             struct pts
+             {
+                 typedef char type; 
+             };         
+        };
+        
+        template<>
+        struct range_value_type_<const_char_ptr_>
+        {
+             template< typename S >
+             struct pts
+             {
+                 typedef const char type;
+             };         
+        };
+        
+        template<>
+        struct range_value_type_<wchar_t_ptr_>
+        {
+             template< typename S >
+             struct pts
+             {
+                 typedef wchar_t type;
+             };         
+        };
+        
+        template<>
+        struct range_value_type_<const_wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef const wchar_t type;
+            };         
+        };
+
+    } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/detail/difference_type.hpp b/include/boost/range/detail/difference_type.hpp
new file mode 100644
index 0000000..c641516
--- /dev/null
+++ b/include/boost/range/detail/difference_type.hpp
@@ -0,0 +1,121 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization  workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost 
+{
+    namespace range_detail 
+    {        
+        template< typename T >
+        struct range_difference_type_;
+
+        template<>
+        struct range_difference_type_<std_container_>
+        {
+            template< typename C >
+            struct pts
+            {
+                typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
+            };
+        };
+
+        template<>
+        struct range_difference_type_<std_pair_>
+        {
+            template< typename P >
+            struct pts
+            {
+                typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;                
+            };
+        };
+
+        template<>
+        struct range_difference_type_<array_>
+        {
+            template< typename A >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };
+        };
+
+        template<>
+        struct range_difference_type_<char_array_>
+        { 
+            template< typename A >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };
+        };
+
+        template<>
+        struct range_difference_type_<char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };         
+        };
+        
+        template<>
+        struct range_difference_type_<const_char_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };         
+        };
+        
+        template<>
+        struct range_difference_type_<wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };         
+        };
+        
+        template<>
+        struct range_difference_type_<const_wchar_t_ptr_>
+        {
+            template< typename S >
+            struct pts
+            {
+                typedef std::ptrdiff_t type;
+            };         
+        };
+        
+    } 
+    
+    template< typename C >
+    class range_difference
+    {
+        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+    public:
+        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
+    };
+
+}
+
+#endif
+
diff --git a/include/boost/range/detail/empty.hpp b/include/boost/range/detail/empty.hpp
new file mode 100644
index 0000000..b098705
--- /dev/null
+++ b/include/boost/range/detail/empty.hpp
@@ -0,0 +1,120 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_EMPTY_HPP
+#define BOOST_RANGE_DETAIL_EMPTY_HPP
+
+#include <boost/range/detail/common.hpp>
+
+namespace boost 
+{
+    namespace range_detail
+    {
+        template< typename T >
+        struct range_empty;
+
+        //////////////////////////////////////////////////////////////////////
+        // default
+        //////////////////////////////////////////////////////////////////////
+        
+        template<>
+        struct range_empty<std_container_>
+        {
+            template< typename C >
+            static bool fun( C& c )
+            {
+                return c.empty();
+            };
+        };
+                    
+        //////////////////////////////////////////////////////////////////////
+        // pair
+        //////////////////////////////////////////////////////////////////////
+        
+        template<>
+        struct range_empty<std_pair_>
+        {
+            template< typename P >
+            static bool fun( const P& p )
+            {
+                return p.first == p.second;
+            }
+        };
+ 
+        //////////////////////////////////////////////////////////////////////
+        // array
+        //////////////////////////////////////////////////////////////////////
+        
+        template<>
+        struct range_empty<array_>
+        {
+            template< typename T, std::size_t sz >
+            static bool fun( T BOOST_ARRAY_REF[sz] )
+            {
+                if( boost_range_array == 0 )
+                    return true;
+                return false;
+            }
+        };
+
+        //////////////////////////////////////////////////////////////////////
+        // string
+        //////////////////////////////////////////////////////////////////////
+        
+        template<>
+        struct range_empty<char_ptr_>
+        {
+            static bool fun( const char* s )
+            {
+                return s == 0 || s[0] == 0;
+            }
+        };
+
+        template<>
+        struct range_empty<const_char_ptr_>
+        {
+            static bool fun( const char* s )
+            {
+                return  s == 0 || s[0] == 0;
+            }
+        };
+
+        template<>
+        struct range_empty<wchar_t_ptr_>
+        {
+            static bool fun( const wchar_t* s )
+            {
+                return  s == 0 || s[0] == 0;
+            }
+        };
+        
+        template<>
+        struct range_empty<const_wchar_t_ptr_>
+        {
+            static bool fun( const wchar_t* s )
+            {
+                return  s == 0 || s[0] == 0;
+            }
+        };
+
+    } // namespace 'range_detail'
+    
+        
+    template< typename C >
+    inline bool 
+    empty( const C& c )
+    {
+        return range_detail::range_empty<  BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+    }
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/detail/end.hpp b/include/boost/range/detail/end.hpp
new file mode 100644
index 0000000..7622921
--- /dev/null
+++ b/include/boost/range/detail/end.hpp
@@ -0,0 +1,86 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_END_HPP
+#define BOOST_RANGE_DETAIL_END_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/detail/workaround.hpp>
+
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/detail/common.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< typename T >
+        struct range_end;
+
+        //////////////////////////////////////////////////////////////////////
+        // default
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_end<std_container_>
+        {
+            template< typename C >
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+            fun( C& c )
+            {
+                return c.end();
+            };
+        };
+
+        //////////////////////////////////////////////////////////////////////
+        // pair
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_end<std_pair_>
+        {
+            template< typename P >
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
+            fun( const P& p )
+            {
+                return p.second;
+            }
+        };
+
+        //////////////////////////////////////////////////////////////////////
+        // array
+        //////////////////////////////////////////////////////////////////////
+
+        template<>
+        struct range_end<array_>
+        {
+            template<typename T>
+            BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t)
+            {
+                return t + remove_extent<T>::size;
+            }
+        };
+
+    } // namespace 'range_detail'
+
+    namespace range_adl_barrier
+    {
+        template< typename C >
+        BOOST_CONSTEXPR inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+        end( C& c )
+        {
+            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+        }
+    } // namespace range_adl_barrier
+
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/detail/extract_optional_type.hpp b/include/boost/range/detail/extract_optional_type.hpp
new file mode 100644
index 0000000..0381434
--- /dev/null
+++ b/include/boost/range/detail/extract_optional_type.hpp
@@ -0,0 +1,48 @@
+// Boost.Range library
+//
+//  Copyright Arno Schoedl & Neil Groves 2009.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/mpl/has_xxx.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_XXX)
+
+// Defines extract_some_typedef<T> which exposes T::some_typedef as
+// extract_some_typedef<T>::type if T::some_typedef exists. Otherwise
+// extract_some_typedef<T> is empty.
+#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                          \
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(a_typedef)                                      \
+    template< typename  C, bool B = BOOST_PP_CAT(has_, a_typedef)<C>::value >   \
+    struct BOOST_PP_CAT(extract_, a_typedef)                                    \
+    {};                                                                         \
+    template< typename C >                                                      \
+    struct BOOST_PP_CAT(extract_, a_typedef)< C, true >                         \
+    {                                                                           \
+        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                       \
+    };
+
+#else
+
+#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                          \
+    template< typename C >                                                      \
+    struct BOOST_PP_CAT(extract_, a_typedef)                                    \
+    {                                                                           \
+        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                       \
+    };
+
+#endif
+
+#endif // include guard
diff --git a/include/boost/range/detail/has_member_size.hpp b/include/boost/range/detail/has_member_size.hpp
new file mode 100644
index 0000000..0c639aa
--- /dev/null
+++ b/include/boost/range/detail/has_member_size.hpp
@@ -0,0 +1,66 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014.
+//
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP
+#define BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP
+
+#include <boost/type_traits/is_class.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/cstdint.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<class T>
+class has_member_size_impl
+{
+private:
+    template<class U, U>
+    class check
+    {
+    };
+
+    template<class C>
+    static boost::uint8_t f(check<std::size_t(C::*)(void) const, &C::size>*);
+
+    template<class C>
+    static boost::uint16_t f(...);
+
+public:
+    static const bool value =
+        (sizeof(f<T>(0)) == sizeof(boost::uint8_t));
+
+    typedef typename mpl::if_c<
+        (sizeof(f<T>(0)) == sizeof(boost::uint8_t)),
+        mpl::true_,
+        mpl::false_
+    >::type type;
+};
+
+template<class T>
+struct has_member_size
+{
+    typedef typename mpl::and_<
+        typename is_class<T>::type,
+        typename has_member_size_impl<const T>::type
+    >::type type;
+
+    static const bool value =
+        is_class<T>::value && has_member_size_impl<const T>::value;
+};
+
+    } // namespace range_detail
+}// namespace boost
+ 
+#endif // include guard
diff --git a/include/boost/range/detail/implementation_help.hpp b/include/boost/range/detail/implementation_help.hpp
new file mode 100644
index 0000000..59a3ade
--- /dev/null
+++ b/include/boost/range/detail/implementation_help.hpp
@@ -0,0 +1,114 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
+#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
+
+#include <boost/range/config.hpp>
+#include <boost/range/detail/common.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <cstddef>
+#include <string.h>
+
+#ifndef BOOST_NO_CWCHAR
+#include <wchar.h>
+#endif
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template <typename T>
+        inline void boost_range_silence_warning( const T& ) { }
+
+        /////////////////////////////////////////////////////////////////////
+        // end() help
+        /////////////////////////////////////////////////////////////////////
+
+        inline const char* str_end( const char* s, const char* )
+        {
+            return s + strlen( s );
+        }
+
+#ifndef BOOST_NO_CWCHAR
+        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
+        {
+            return s + wcslen( s );
+        }
+#else
+        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
+        {
+            if( s == 0 || s[0] == 0 )
+                return s;
+            while( *++s != 0 )
+                ;
+            return s;
+        }
+#endif
+
+        template< class Char >
+        inline Char* str_end( Char* s )
+        {
+            return const_cast<Char*>( str_end( s, s ) );
+        }
+
+        template< class T, std::size_t sz >
+        BOOST_CONSTEXPR inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
+        {
+            return boost_range_array + sz;
+        }
+
+        template< class T, std::size_t sz >
+        BOOST_CONSTEXPR inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
+        {
+            return boost_range_array + sz;
+        }
+
+        /////////////////////////////////////////////////////////////////////
+        // size() help
+        /////////////////////////////////////////////////////////////////////
+
+        template< class Char >
+        inline std::size_t str_size( const Char* const& s )
+        {
+            return str_end( s ) - s;
+        }
+
+        template< class T, std::size_t sz >
+        inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
+        {
+            boost_range_silence_warning( boost_range_array );
+            return sz;
+        }
+
+        template< class T, std::size_t sz >
+        inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
+        {
+            boost_range_silence_warning( boost_range_array );
+            return sz;
+        }
+
+        inline bool is_same_address(const void* l, const void* r)
+        {
+            return l == r;
+        }
+
+        template<class T1, class T2>
+        inline bool is_same_object(const T1& l, const T2& r)
+        {
+            return range_detail::is_same_address(&l, &r);
+        }
+
+    } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/detail/join_iterator.hpp b/include/boost/range/detail/join_iterator.hpp
new file mode 100644
index 0000000..0f47f58
--- /dev/null
+++ b/include/boost/range/detail/join_iterator.hpp
@@ -0,0 +1,358 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// aschoedl contributed an improvement to the determination
+// of the Reference type parameter.
+//
+// Leonid Gershanovich reported Trac ticket 7376 about the dereference operator
+// requiring identical reference types due to using the ternary if.
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
+
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/detail/demote_iterator_traversal_tag.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/next_prior.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<typename Iterator1, typename Iterator2>
+struct join_iterator_link
+{
+public:
+    join_iterator_link(Iterator1 last1, Iterator2 first2)
+        :    last1(last1)
+        ,    first2(first2)
+    {
+    }
+
+    Iterator1 last1;
+    Iterator2 first2;
+
+private:
+    join_iterator_link() /* = delete */ ;
+};
+
+class join_iterator_begin_tag {};
+class join_iterator_end_tag {};
+
+template<typename Iterator1
+       , typename Iterator2
+       , typename Reference
+>
+class join_iterator_union
+{
+public:
+    typedef Iterator1 iterator1_t;
+    typedef Iterator2 iterator2_t;
+
+    join_iterator_union() {}
+    join_iterator_union(unsigned int /*selected*/, const iterator1_t& it1, const iterator2_t& it2) : m_it1(it1), m_it2(it2) {}
+
+    iterator1_t& it1() { return m_it1; }
+    const iterator1_t& it1() const { return m_it1; }
+
+    iterator2_t& it2() { return m_it2; }
+    const iterator2_t& it2() const { return m_it2; }
+
+    Reference dereference(unsigned int selected) const
+    {
+        if (selected)
+            return *m_it2;
+        return *m_it1;
+    }
+
+    bool equal(const join_iterator_union& other, unsigned int selected) const
+    {
+        return selected
+            ? m_it2 == other.m_it2
+            : m_it1 == other.m_it1;
+    }
+
+private:
+    iterator1_t m_it1;
+    iterator2_t m_it2;
+};
+
+template<class Iterator, class Reference>
+class join_iterator_union<Iterator, Iterator, Reference>
+{
+public:
+    typedef Iterator iterator1_t;
+    typedef Iterator iterator2_t;
+
+    join_iterator_union() {}
+
+    join_iterator_union(unsigned int selected, const iterator1_t& it1, const iterator2_t& it2)
+        : m_it(selected ? it2 : it1)
+    {
+    }
+
+    iterator1_t& it1() { return m_it; }
+    const iterator1_t& it1() const { return m_it; }
+
+    iterator2_t& it2() { return m_it; }
+    const iterator2_t& it2() const { return m_it; }
+
+    Reference dereference(unsigned int) const
+    {
+        return *m_it;
+    }
+
+    bool equal(const join_iterator_union& other,
+               unsigned int /*selected*/) const
+    {
+        return m_it == other.m_it;
+    }
+
+private:
+    iterator1_t m_it;
+};
+
+template<typename Iterator1
+       , typename Iterator2
+       , typename ValueType = typename iterator_value<Iterator1>::type
+       // find least demanding, commonly supported reference type, in the order &, const&, and by-value:
+       , typename Reference = typename mpl::if_c<
+                !is_reference<typename iterator_reference<Iterator1>::type>::value
+             || !is_reference<typename iterator_reference<Iterator2>::type>::value,
+                        typename remove_const<
+                            typename remove_reference<
+                                typename iterator_reference<Iterator1>::type
+                            >::type
+                        >::type,
+                        typename mpl::if_c<
+                            is_const<
+                                typename remove_reference<
+                                    typename iterator_reference<Iterator1>::type
+                                >::type
+                            >::value
+                            || is_const<
+                                typename remove_reference<
+                                    typename iterator_reference<Iterator2>::type
+                                >::type
+                            >::value,
+                            typename add_reference<
+                                typename add_const<
+                                    typename remove_reference<
+                                        typename iterator_reference<Iterator1>::type
+                                    >::type
+                                >::type
+                            >::type,
+                            typename iterator_reference<Iterator1>::type
+                        >::type
+                    >::type
+       , typename Traversal = typename demote_iterator_traversal_tag<
+                                  typename iterator_traversal<Iterator1>::type
+                                , typename iterator_traversal<Iterator2>::type>::type
+>
+class join_iterator
+    : public iterator_facade<join_iterator<Iterator1,Iterator2,ValueType,Reference,Traversal>, ValueType, Traversal, Reference>
+{
+    typedef join_iterator_link<Iterator1, Iterator2> link_t;
+    typedef join_iterator_union<Iterator1, Iterator2, Reference> iterator_union;
+public:
+    typedef Iterator1 iterator1_t;
+    typedef Iterator2 iterator2_t;
+
+    join_iterator()
+        : m_section(0u)
+        , m_it(0u, iterator1_t(), iterator2_t())
+        , m_link(link_t(iterator1_t(), iterator2_t()))
+    {}
+
+    join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2)
+        : m_section(section)
+        , m_it(section, current1, current2)
+        , m_link(link_t(last1, first2))
+        {
+        }
+
+    template<typename Range1, typename Range2>
+    join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag)
+        : m_section(boost::empty(r1) ? 1u : 0u)
+        , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2))
+        , m_link(link_t(boost::end(r1), boost::begin(r2)))
+    {
+    }
+
+    template<typename Range1, typename Range2>
+    join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag)
+        : m_section(boost::empty(r1) ? 1u : 0u)
+        , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2))
+        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
+    {
+    }
+
+    template<typename Range1, typename Range2>
+    join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag)
+        : m_section(1u)
+        , m_it(1u, boost::end(r1), boost::end(r2))
+        , m_link(link_t(boost::end(r1), boost::begin(r2)))
+    {
+    }
+
+    template<typename Range1, typename Range2>
+    join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag)
+        : m_section(1u)
+        , m_it(1u, boost::const_end(r1), boost::const_end(r2))
+        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
+    {
+    }
+
+private:
+    void increment()
+    {
+        if (m_section)
+            ++m_it.it2();
+        else
+        {
+            ++m_it.it1();
+            if (m_it.it1() == m_link.last1)
+            {
+                m_it.it2() = m_link.first2;
+                m_section = 1u;
+            }
+        }
+    }
+
+    void decrement()
+    {
+        if (m_section)
+        {
+            if (m_it.it2() == m_link.first2)
+            {
+                m_it.it1() = boost::prior(m_link.last1);
+                m_section = 0u;
+            }
+            else
+                --m_it.it2();
+        }
+        else
+            --m_it.it1();
+    }
+
+    typename join_iterator::reference dereference() const
+    {
+        return m_it.dereference(m_section);
+    }
+
+    bool equal(const join_iterator& other) const
+    {
+        return m_section == other.m_section
+            && m_it.equal(other.m_it, m_section);
+    }
+
+    void advance(typename join_iterator::difference_type offset)
+    {
+        if (m_section)
+            advance_from_range2(offset);
+        else
+            advance_from_range1(offset);
+    }
+
+    typename join_iterator::difference_type distance_to(const join_iterator& other) const
+    {
+        typename join_iterator::difference_type result;
+        if (m_section)
+        {
+            if (other.m_section)
+                result = other.m_it.it2() - m_it.it2();
+            else
+            {
+                result = (m_link.first2 - m_it.it2())
+                       + (other.m_it.it1() - m_link.last1);
+
+                BOOST_ASSERT( result <= 0 );
+            }
+        }
+        else
+        {
+            if (other.m_section)
+            {
+                result = (m_link.last1 - m_it.it1())
+                       + (other.m_it.it2() - m_link.first2);
+            }
+            else
+                result = other.m_it.it1() - m_it.it1();
+        }
+        return result;
+    }
+
+    void advance_from_range2(typename join_iterator::difference_type offset)
+    {
+        typedef typename join_iterator::difference_type difference_t;
+        BOOST_ASSERT( m_section == 1u );
+        if (offset < 0)
+        {
+            difference_t r2_dist = m_link.first2 - m_it.it2();
+            BOOST_ASSERT( r2_dist <= 0 );
+            if (offset >= r2_dist)
+                std::advance(m_it.it2(), offset);
+            else
+            {
+                difference_t r1_dist = offset - r2_dist;
+                BOOST_ASSERT( r1_dist <= 0 );
+                m_it.it1() = m_link.last1 + r1_dist;
+                m_section = 0u;
+            }
+        }
+        else
+            std::advance(m_it.it2(), offset);
+    }
+
+    void advance_from_range1(typename join_iterator::difference_type offset)
+    {
+        typedef typename join_iterator::difference_type difference_t;
+        BOOST_ASSERT( m_section == 0u );
+        if (offset > 0)
+        {
+            difference_t r1_dist = m_link.last1 - m_it.it1();
+            BOOST_ASSERT( r1_dist >= 0 );
+            if (offset < r1_dist)
+                std::advance(m_it.it1(), offset);
+            else
+            {
+                difference_t r2_dist = offset - r1_dist;
+                BOOST_ASSERT( r2_dist >= 0 );
+                m_it.it2() = m_link.first2 + r2_dist;
+                m_section = 1u;
+            }
+        }
+        else
+            std::advance(m_it.it1(), offset);
+    }
+
+    unsigned int m_section;
+    iterator_union m_it;
+    link_t m_link;
+
+    friend class ::boost::iterator_core_access;
+};
+
+    } // namespace range_detail
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/microsoft.hpp b/include/boost/range/detail/microsoft.hpp
new file mode 100644
index 0000000..d04575c
--- /dev/null
+++ b/include/boost/range/detail/microsoft.hpp
@@ -0,0 +1,932 @@
+#ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP
+#define BOOST_RANGE_DETAIL_MICROSOFT_HPP
+
+// Boost.Range MFC/ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <boost/range/iterator.hpp>
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1
+
+
+#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
+#else
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
+    #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
+#endif
+
+
+
+
+// yet another customization way
+//
+
+
+#include <boost/iterator/iterator_traits.hpp> // iterator_difference
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comma_if.hpp>
+#include <boost/preprocessor/detail/is_unary.hpp>
+#include <boost/preprocessor/list/for_each.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/utility/enable_if.hpp> // disable_if
+#include <boost/next_prior.hpp>
+
+#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+    #include <boost/range/mutable_iterator.hpp>
+#else
+    #include <iterator> // distance
+    #include <boost/range/begin.hpp>
+    #include <boost/range/end.hpp>
+    #include <boost/range/iterator.hpp>
+#endif
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+    // customization point
+    //
+
+    template< class Tag >
+    struct customization;
+
+
+    template< class T >
+    struct customization_tag;
+
+
+    struct using_type_as_tag
+    { };
+
+
+    // Topic:
+    // In fact, it is unnecessary for VC++.
+    // VC++'s behavior seems conforming, while GCC fails without this.
+    template< class Iterator, class T >
+    struct mutable_ :
+        disable_if< is_const<T>, Iterator >
+    { };
+
+
+    // helpers
+    //
+
+    template< class Tag, class T >
+    struct customization_tag_of
+    {
+        typedef typename mpl::if_< is_same<using_type_as_tag, Tag>,
+            T,
+            Tag
+        >::type type;
+    };
+
+
+    template< class T >
+    struct customization_of
+    {
+        typedef typename remove_cv<T>::type bare_t;
+        typedef typename customization_tag<bare_t>::type tag_t;
+        typedef customization<tag_t> type;
+    };
+
+
+    template< class T >
+    struct mutable_iterator_of
+    {
+        typedef typename remove_cv<T>::type bare_t;
+        typedef typename customization_of<bare_t>::type cust_t;
+        typedef typename cust_t::template meta<bare_t>::mutable_iterator type;
+    };
+
+
+    template< class T >
+    struct const_iterator_of
+    {
+        typedef typename remove_cv<T>::type bare_t;
+        typedef typename customization_of<bare_t>::type cust_t;
+        typedef typename cust_t::template meta<bare_t>::const_iterator type;
+    };
+
+
+    template< class T >
+    struct size_type_of
+    {
+        typedef typename range_detail_microsoft::mutable_iterator_of<T>::type miter_t;
+        typedef typename iterator_difference<miter_t>::type type;
+    };
+
+
+    template< class T > inline
+    typename mutable_iterator_of<T>::type
+    begin_of(T& x)
+    {
+        typedef typename customization_of<T>::type cust_t;
+        return cust_t().template begin<typename mutable_iterator_of<T>::type>(x);
+    }
+
+
+    template< class T > inline
+    typename const_iterator_of<T>::type
+    begin_of(T const& x)
+    {
+        typedef typename customization_of<T>::type cust_t;
+        return cust_t().template begin<typename const_iterator_of<T>::type>(x);
+    }
+
+
+    template< class T > inline
+    typename mutable_iterator_of<T>::type
+    end_of(T& x)
+    {
+        typedef typename customization_of<T>::type cust_t;
+        return cust_t().template end<typename mutable_iterator_of<T>::type>(x);
+    }
+
+
+    template< class T > inline
+    typename const_iterator_of<T>::type
+    end_of(T const& x)
+    {
+        typedef typename customization_of<T>::type cust_t;
+        return cust_t().template end<typename const_iterator_of<T>::type>(x);
+    }
+
+
+#if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+    template< class T > inline
+    typename size_type_of<T>::type
+    size_of(T const& x)
+    {
+        return std::distance(boost::begin(x), boost::end(x));
+    }
+
+#endif
+
+
+    template< class Range >
+    struct compatible_mutable_iterator : 
+        BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>
+    { };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+    BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \
+/**/
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \
+        namespace elem { \
+    /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+    BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \
+/**/
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \
+        } \
+    /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \
+    :: elem \
+/**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \
+    namespace boost { namespace range_detail_microsoft { \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+    } } \
+    \
+    namespace boost { \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+    } \
+    \
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+/**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \
+        BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \
+        template< > \
+        struct customization_tag< Fullname > : \
+            customization_tag_of< Tag, Fullname > \
+        { }; \
+    /**/
+
+
+    // metafunctions
+    //
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \
+        template< > \
+        struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
+            range_detail_microsoft::mutable_iterator_of< Fullname > \
+        { }; \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \
+        template< > \
+        struct range_const_iterator< Fullname > : \
+            range_detail_microsoft::const_iterator_of< Fullname > \
+        { }; \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \
+        template< > \
+        struct range_size< Fullname > : \
+            range_detail_microsoft::size_type_of< Fullname > \
+        { }; \
+    /**/
+
+
+    // functions
+    //
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \
+        inline \
+        boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
+        { \
+            return boost::range_detail_microsoft::begin_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \
+        inline \
+        boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
+        { \
+            return boost::range_detail_microsoft::begin_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \
+        inline \
+        boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
+        { \
+            return boost::range_detail_microsoft::end_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \
+        inline \
+        boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
+        { \
+            return boost::range_detail_microsoft::end_of(x); \
+        } \
+    /**/
+
+
+    #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
+        /**/
+
+    #else
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
+            inline \
+            boost::range_detail_microsoft::size_type_of< Fullname >::type \
+            boost_range_size(Fullname const& x) \
+            { \
+                return boost::range_detail_microsoft::size_of(x); \
+            } \
+        /**/
+
+    #endif
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \
+        Tag, NamespaceList, Name, \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
+    ) \
+/**/
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
+        BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \
+            ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \
+            BOOST_PP_REPEAT \
+        )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \
+    /**/
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \
+            (class) \
+        /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \
+    namespace boost { namespace range_detail_microsoft { \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \
+            Tag, \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+    } } \
+    \
+    namespace boost { \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+    } \
+    \
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        ) \
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+/**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \
+        BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \
+    /**/
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \
+            BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \
+        /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+        BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \
+        :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \
+        template< Params > \
+        struct customization_tag< Fullname > : \
+            customization_tag_of< Tag, Fullname > \
+        { }; \
+    /**/
+
+
+    // metafunctions
+    //
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \
+        template< Params > \
+        struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
+            range_detail_microsoft::mutable_iterator_of< Fullname > \
+        { }; \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \
+        template< Params > \
+        struct range_const_iterator< Fullname > : \
+            range_detail_microsoft::const_iterator_of< Fullname > \
+        { }; \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \
+        template< Params > \
+        struct range_size< Fullname > : \
+            range_detail_microsoft::size_type_of< Fullname > \
+        { }; \
+    /**/
+
+
+    // functions
+    //
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \
+        template< Params > inline \
+        typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
+        { \
+            return boost::range_detail_microsoft::begin_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \
+        template< Params > inline \
+        typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
+        { \
+            return boost::range_detail_microsoft::begin_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \
+        template< Params > inline \
+        typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
+        { \
+            return boost::range_detail_microsoft::end_of(x); \
+        } \
+    /**/
+
+
+    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \
+        template< Params > inline \
+        typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
+        { \
+            return boost::range_detail_microsoft::end_of(x); \
+        } \
+    /**/
+
+
+    #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
+        /**/
+
+    #else
+
+        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
+            template< Params > inline \
+            typename boost::range_detail_microsoft::size_type_of< Fullname >::type \
+            boost_range_size(Fullname const& x) \
+            { \
+                return boost::range_detail_microsoft::size_of(x); \
+            } \
+        /**/
+
+    #endif
+
+
+
+
+// list_iterator and helpers
+//
+
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+// POSITION's header is undocumented, so is NULL.
+//
+struct __POSITION; // incomplete, but used as just a pointer.
+typedef __POSITION *POSITION;
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+    template<
+        class ListT,
+        class Value,
+        class Reference,
+        class Traversal
+    >
+    struct list_iterator;
+
+
+    template<
+        class ListT,
+        class Value,
+        class Reference,
+        class Traversal
+    >
+    struct list_iterator_super
+    {
+        typedef typename mpl::if_< is_same<use_default, Reference>,
+            Value&,
+            Reference
+        >::type ref_t;
+
+        typedef typename mpl::if_< is_same<use_default, Traversal>,
+            bidirectional_traversal_tag,
+            Traversal
+        >::type trv_t;
+
+        typedef iterator_facade<
+            list_iterator<ListT, Value, Reference, Traversal>,
+            Value,
+            trv_t,
+            ref_t
+        > type;
+    };
+
+
+    template<
+        class ListT,
+        class Value,
+        class Reference = use_default,
+        class Traversal = use_default
+    >
+    struct list_iterator :
+        list_iterator_super<ListT, Value, Reference, Traversal>::type
+    {
+    private:
+        typedef list_iterator self_t;
+        typedef typename list_iterator_super<ListT, Value, Reference, Traversal>::type super_t;
+        typedef typename super_t::reference ref_t;
+
+    public:
+        explicit list_iterator()
+        { }
+
+        explicit list_iterator(ListT& lst, POSITION pos) :
+            m_plst(boost::addressof(lst)), m_pos(pos)
+        { }
+
+    template< class, class, class, class > friend struct list_iterator;
+        template< class ListT_, class Value_, class Reference_, class Traversal_>
+        list_iterator(list_iterator<ListT_, Value_, Reference_, Traversal_> const& other) :
+            m_plst(other.m_plst), m_pos(other.m_pos)
+        { }
+
+    private:
+        ListT *m_plst;
+        POSITION m_pos;
+
+    friend class iterator_core_access;
+        ref_t dereference() const
+        {
+            BOOST_ASSERT(m_pos != 0 && "out of range");
+            return m_plst->GetAt(m_pos);
+        }
+
+        // A    B    C    D    x
+        // Head           Tail NULL(0)
+        //
+        void increment()
+        {
+            BOOST_ASSERT(m_pos != 0 && "out of range");
+            m_plst->GetNext(m_pos);
+        }
+
+        void decrement()
+        {
+            if (m_pos == 0) {
+                m_pos = m_plst->GetTailPosition();
+                return;
+            }
+
+            m_plst->GetPrev(m_pos);
+        }
+
+        bool equal(self_t const& other) const
+        {
+            BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible");
+            return m_pos == other.m_pos;
+        }
+    };
+
+
+    // customization helpers
+    //
+
+    struct array_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return x.GetData();
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return begin<Iterator>(x) + x.GetSize();
+        }
+    };
+
+
+    struct list_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return Iterator(x, x.GetHeadPosition());
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(x, POSITION(0));
+        }
+    };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// test
+//
+
+
+#if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
+
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <boost/concept_check.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/range/rbegin.hpp>
+#include <boost/range/rend.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+    template< class Range1, class Range2 >
+    bool test_equals(Range1 const& rng1, Range2 const& rng2)
+    {
+        return
+            boost::distance(rng1) == boost::distance(rng2) &&
+            std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2))
+        ;
+    }
+
+
+    template< class AssocContainer, class PairT >
+    bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa)
+    {
+        typedef typename boost::range_const_iterator<AssocContainer>::type iter_t;
+        for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) {
+            if (it->first == pa.first && it->second == pa.second)
+                return true;
+        }
+
+        return false;
+    }
+
+
+    // test functions
+    //
+
+    template< class Range >
+    bool test_emptiness(Range& )
+    {
+        bool result = true;
+
+        Range emptyRng;
+        result = result && boost::empty(emptyRng);
+
+        return result;
+    }
+
+
+    template< class Range >
+    bool test_trivial(Range& rng)
+    {
+        bool result = true;
+
+        // convertibility check
+        typedef typename range_const_iterator<Range>::type citer_t;
+        citer_t cit = boost::begin(rng);
+        (void)cit; // unused
+
+        // mutability check
+        typedef typename range_value<Range>::type val_t;
+        val_t v = *boost::begin(rng);
+        *boost::begin(rng) = v;
+        result = result && *boost::begin(rng) == v;
+
+        return result;
+    }
+
+
+    template< class Range >
+    bool test_forward(Range& rng)
+    {
+        boost::function_requires< ForwardRangeConcept<Range> >();
+
+        bool result = (test_trivial)(rng);
+
+        typedef typename range_value<Range>::type val_t;
+
+        std::vector<val_t> saved;
+        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+        std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved));
+
+        std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng));
+
+        return result && (test_equals)(saved, rng);
+    };
+
+
+    template< class Range >
+    bool test_bidirectional(Range& rng)
+    {
+        boost::function_requires< BidirectionalRangeConcept<Range> >();
+
+        bool result = (test_forward)(rng);
+
+        typedef typename range_value<Range>::type val_t;
+
+        std::vector<val_t> saved;
+        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+
+        result = result && (test_equals)(
+            boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)),
+            boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng))
+        );
+
+        return result;
+    }
+
+
+    template< class Range >
+    bool test_random_access(Range& rng)
+    {
+        boost::function_requires< RandomAccessRangeConcept<Range> >();
+
+        bool result = (test_bidirectional)(rng);
+
+        typedef typename range_value<Range>::type val_t;
+
+        std::vector<val_t> saved;
+        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+        std::sort(boost::begin(saved), boost::end(saved));
+
+        std::random_shuffle(boost::begin(rng), boost::end(rng));
+        std::sort(boost::begin(rng), boost::end(rng));
+        result = result && (test_equals)(rng, saved);
+
+        std::random_shuffle(boost::begin(rng), boost::end(rng));
+        std::stable_sort(boost::begin(rng), boost::end(rng));
+        result = result && (test_equals)(rng, saved);
+
+        std::random_shuffle(boost::begin(rng), boost::end(rng));
+        std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng));
+        result = result && (test_equals)(rng, saved);
+
+        return result;
+    }
+
+
+    // initializer
+    //
+
+    template< class ArrayT, class SampleRange >
+    bool test_init_array(ArrayT& arr, SampleRange const& sample)
+    {
+        typedef typename range_const_iterator<SampleRange>::type iter_t;
+        typedef typename range_value<SampleRange>::type val_t;
+
+        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+            val_t v = *it; // works around ATL3 CSimpleArray
+            arr.Add(v);
+        }
+
+        return (test_equals)(arr, sample);
+    }
+
+
+    template< class ListT, class SampleRange >
+    bool test_init_list(ListT& lst, SampleRange const& sample)
+    {
+        typedef typename range_const_iterator<SampleRange>::type iter_t;
+
+        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+            lst.AddTail(*it);
+        }
+
+        return (test_equals)(lst, sample);
+    }
+
+
+    template< class StringT, class SampleRange >
+    bool test_init_string(StringT& str, SampleRange const& sample)
+    {
+        typedef typename range_const_iterator<SampleRange>::type iter_t;
+        typedef typename range_value<SampleRange>::type val_t;
+
+        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+            str += *it;
+        }
+
+        return (test_equals)(str, sample);
+    }
+
+
+    template< class MapT, class SampleMap >
+    bool test_init_map(MapT& map, SampleMap const& sample)
+    {
+        typedef typename range_const_iterator<SampleMap>::type iter_t;
+
+        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+            map.SetAt(it->first, it->second);
+        }
+
+        return boost::distance(map) == boost::distance(sample);
+    }
+
+
+    // metafunction test
+    //
+
+    template< class Range, class Iter >
+    struct test_mutable_iter :
+        boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>::type, Iter >
+    { };
+
+
+    template< class Range, class Iter >
+    struct test_const_iter :
+        boost::is_same< typename boost::range_const_iterator<Range>::type, Iter >
+    { };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+#endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
+
+
+
+#endif
diff --git a/include/boost/range/detail/misc_concept.hpp b/include/boost/range/detail/misc_concept.hpp
new file mode 100644
index 0000000..74cb919
--- /dev/null
+++ b/include/boost/range/detail/misc_concept.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library concept checks
+//
+//  Copyright Neil Groves 2009. Use, modification and distribution
+//  are subject to the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template<typename T1, typename T2>
+        class SameTypeConcept
+        {
+        public:
+            BOOST_CONCEPT_USAGE(SameTypeConcept)
+            {
+                same_type(a,b);
+            }
+        private:
+            template<typename T> void same_type(T,T) {}
+            T1 a;
+            T2 b;
+        };
+    }
+}
+
+#endif // include guard
diff --git a/include/boost/range/detail/msvc_has_iterator_workaround.hpp b/include/boost/range/detail/msvc_has_iterator_workaround.hpp
new file mode 100644
index 0000000..62b67fd
--- /dev/null
+++ b/include/boost/range/detail/msvc_has_iterator_workaround.hpp
@@ -0,0 +1,132 @@
+// Boost.Range library
+//
+//  Copyright Eric Niebler 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_MSVC_HAS_ITERATOR_WORKAROUND_HPP
+#define BOOST_RANGE_DETAIL_MSVC_HAS_ITERATOR_WORKAROUND_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP
+# error This file should only be included from <boost/range/mutable_iterator.hpp>
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600)
+namespace boost
+{
+namespace cb_details
+{
+    template <class Buff, class Traits>
+    struct iterator;
+}
+
+namespace python
+{
+    template <class Container
+              , class NextPolicies /*= objects::default_iterator_call_policies*/>
+    struct iterator;
+}
+
+namespace type_erasure
+{
+    template<
+        class Traversal,
+        class T                 /*= _self*/,
+        class Reference         /*= ::boost::use_default*/,
+        class DifferenceType    /*= ::std::ptrdiff_t*/,
+        class ValueType         /*= typename deduced<iterator_value_type<T> >::type*/
+    >
+    struct iterator;
+}
+
+namespace unordered { namespace iterator_detail
+{
+    template <typename Node>
+    struct iterator;
+}}
+
+namespace container { namespace container_detail
+{
+    template<class IIterator, bool IsConst>
+    class iterator;
+}}
+
+namespace spirit { namespace lex { namespace lexertl
+{
+    template <typename Functor>
+    class iterator;
+}}}
+
+namespace range_detail
+{
+    template <class Buff, class Traits>
+    struct has_iterator< ::boost::cb_details::iterator<Buff, Traits> >
+      : mpl::false_
+    {};
+
+    template <class Buff, class Traits>
+    struct has_iterator< ::boost::cb_details::iterator<Buff, Traits> const>
+      : mpl::false_
+    {};
+
+    template <class Container, class NextPolicies>
+    struct has_iterator< ::boost::python::iterator<Container, NextPolicies> >
+      : mpl::false_
+    {};
+
+    template <class Container, class NextPolicies>
+    struct has_iterator< ::boost::python::iterator<Container, NextPolicies> const>
+      : mpl::false_
+    {};
+
+    template<class Traversal, class T, class Reference, class DifferenceType, class ValueType>
+    struct has_iterator< ::boost::type_erasure::iterator<Traversal, T, Reference, DifferenceType, ValueType> >
+      : mpl::false_
+    {};
+
+    template<class Traversal, class T, class Reference, class DifferenceType, class ValueType>
+    struct has_iterator< ::boost::type_erasure::iterator<Traversal, T, Reference, DifferenceType, ValueType> const>
+      : mpl::false_
+    {};
+
+    template <typename Node>
+    struct has_iterator< ::boost::unordered::iterator_detail::iterator<Node> >
+      : mpl::false_
+    {};
+
+    template <typename Node>
+    struct has_iterator< ::boost::unordered::iterator_detail::iterator<Node> const>
+      : mpl::false_
+    {};
+
+    template<class IIterator, bool IsConst>
+    struct has_iterator< ::boost::container::container_detail::iterator<IIterator, IsConst> >
+      : mpl::false_
+    {};
+
+    template<class IIterator, bool IsConst>
+    struct has_iterator< ::boost::container::container_detail::iterator<IIterator, IsConst> const>
+      : mpl::false_
+    {};
+
+    template <typename Functor>
+    struct has_iterator< ::boost::spirit::lex::lexertl::iterator<Functor> >
+      : mpl::false_
+    {};
+
+    template <typename Functor>
+    struct has_iterator< ::boost::spirit::lex::lexertl::iterator<Functor> const>
+      : mpl::false_
+    {};
+}
+}
+#endif
+#endif
diff --git a/include/boost/range/detail/range_return.hpp b/include/boost/range/detail/range_return.hpp
new file mode 100644
index 0000000..9b98e09
--- /dev/null
+++ b/include/boost/range/detail/range_return.hpp
@@ -0,0 +1,181 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/next_prior.hpp>
+
+namespace boost
+{
+    enum range_return_value
+    {
+        // (*) indicates the most common values
+        return_found,       // only the found resulting iterator (*)
+        return_next,        // next(found) iterator
+        return_prior,       // prior(found) iterator
+        return_begin_found, // [begin, found) range (*)
+        return_begin_next,  // [begin, next(found)) range
+        return_begin_prior, // [begin, prior(found)) range
+        return_found_end,   // [found, end) range (*)
+        return_next_end,    // [next(found), end) range
+        return_prior_end,   // [prior(found), end) range
+        return_begin_end    // [begin, end) range
+    };
+
+    template< class SinglePassRange, range_return_value >
+    struct range_return
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+                         SinglePassRange& rng)
+        {
+            return type(found, boost::end(rng));
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_found >
+    {
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
+
+        static type pack(type found, SinglePassRange&)
+        {
+            return found;
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_next >
+    {
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
+
+        static type pack(type found, SinglePassRange& rng)
+        {
+            return found == boost::end(rng)
+                ? found
+                : boost::next(found);
+        }
+    };
+
+    template< class BidirectionalRange >
+    struct range_return< BidirectionalRange, return_prior >
+    {
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type type;
+
+        static type pack(type found, BidirectionalRange& rng)
+        {
+            return found == boost::begin(rng)
+                ? found
+                : boost::prior(found);
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_begin_found >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+                         SinglePassRange& rng)
+        {
+            return type(boost::begin(rng), found);
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_begin_next >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+                         SinglePassRange& rng)
+        {
+            return type( boost::begin(rng), 
+                         found == boost::end(rng) ? found : boost::next(found) );
+        }
+    };
+
+    template< class BidirectionalRange >
+    struct range_return< BidirectionalRange, return_begin_prior >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
+                         BidirectionalRange& rng)
+        {
+            return type( boost::begin(rng),
+                         found == boost::begin(rng) ? found : boost::prior(found) );
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_found_end >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+                         SinglePassRange& rng)
+        {
+            return type(found, boost::end(rng));
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_next_end >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+                         SinglePassRange& rng)
+        {
+            return type( found == boost::end(rng) ? found : boost::next(found),
+                         boost::end(rng) );
+        }
+    };
+
+    template< class BidirectionalRange >
+    struct range_return< BidirectionalRange, return_prior_end >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
+                         BidirectionalRange& rng)
+        {
+            return type( found == boost::begin(rng) ? found : boost::prior(found),
+                         boost::end(rng) );
+        }
+    };
+
+    template< class SinglePassRange >
+    struct range_return< SinglePassRange, return_begin_end >
+    {
+        typedef boost::iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
+                         SinglePassRange& rng)
+        {
+            return type(boost::begin(rng), boost::end(rng));
+        }
+    };
+
+}
+
+#endif // include guard
diff --git a/include/boost/range/detail/remove_extent.hpp b/include/boost/range/detail/remove_extent.hpp
new file mode 100644
index 0000000..68e4597
--- /dev/null
+++ b/include/boost/range/detail/remove_extent.hpp
@@ -0,0 +1,157 @@
+// Boost.Range library
+//
+//  Copyright Jonathan Turkanis 2005. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#ifndef BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
+#define BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
+
+#include <boost/config.hpp>  // MSVC, NO_INTRINSIC_WCHAR_T, put size_t in std.
+#include <cstddef>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost 
+{
+    namespace range_detail
+    {
+        
+        template< typename Case1 = mpl::true_,
+                  typename Type1 = mpl::void_,
+                  typename Case2 = mpl::true_,
+                  typename Type2 = mpl::void_,
+                  typename Case3 = mpl::true_,
+                  typename Type3 = mpl::void_,
+                  typename Case4 = mpl::true_,
+                  typename Type4 = mpl::void_,
+                  typename Case5 = mpl::true_,
+                  typename Type5 = mpl::void_,
+                  typename Case6 = mpl::true_,
+                  typename Type6 = mpl::void_,
+                  typename Case7 = mpl::true_,
+                  typename Type7 = mpl::void_,
+                  typename Case8 = mpl::true_,
+                  typename Type8 = mpl::void_,
+                  typename Case9 = mpl::true_,
+                  typename Type9 = mpl::void_,
+                  typename Case10 = mpl::true_,
+                  typename Type10 = mpl::void_,
+                  typename Case11 = mpl::true_,
+                  typename Type11 = mpl::void_,
+                  typename Case12 = mpl::true_,
+                  typename Type12 = mpl::void_,
+                  typename Case13 = mpl::true_,
+                  typename Type13 = mpl::void_,
+                  typename Case14 = mpl::true_,
+                  typename Type14 = mpl::void_,
+                  typename Case15 = mpl::true_,
+                  typename Type15 = mpl::void_,
+                  typename Case16 = mpl::true_,
+                  typename Type16 = mpl::void_,
+                  typename Case17 = mpl::true_,
+                  typename Type17 = mpl::void_,
+                  typename Case18 = mpl::true_,
+                  typename Type18 = mpl::void_,
+                  typename Case19 = mpl::true_,
+                  typename Type19 = mpl::void_,
+                  typename Case20 = mpl::true_,
+                  typename Type20 = mpl::void_>
+        struct select {
+            typedef typename
+                    mpl::eval_if<
+                        Case1, mpl::identity<Type1>, mpl::eval_if<
+                        Case2, mpl::identity<Type2>, mpl::eval_if<
+                        Case3, mpl::identity<Type3>, mpl::eval_if<
+                        Case4, mpl::identity<Type4>, mpl::eval_if<
+                        Case5, mpl::identity<Type5>, mpl::eval_if<
+                        Case6, mpl::identity<Type6>, mpl::eval_if<
+                        Case7, mpl::identity<Type7>, mpl::eval_if<
+                        Case8, mpl::identity<Type8>, mpl::eval_if<
+                        Case9, mpl::identity<Type9>, mpl::if_<
+                        Case10, Type10, mpl::void_ > > > > > > > > >
+                    >::type result1;
+            typedef typename
+                    mpl::eval_if<
+                        Case11, mpl::identity<Type11>, mpl::eval_if<
+                        Case12, mpl::identity<Type12>, mpl::eval_if<
+                        Case13, mpl::identity<Type13>, mpl::eval_if<
+                        Case14, mpl::identity<Type14>, mpl::eval_if<
+                        Case15, mpl::identity<Type15>, mpl::eval_if<
+                        Case16, mpl::identity<Type16>, mpl::eval_if<
+                        Case17, mpl::identity<Type17>, mpl::eval_if<
+                        Case18, mpl::identity<Type18>, mpl::eval_if<
+                        Case19, mpl::identity<Type19>, mpl::if_<
+                        Case20, Type20, mpl::void_ > > > > > > > > >
+                    > result2;
+            typedef typename    
+                    mpl::eval_if<
+                        is_same<result1, mpl::void_>,
+                        result2,
+                        mpl::identity<result1>
+                    >::type type;
+        };
+
+        template<typename T>
+        struct remove_extent {
+            static T* ar;
+            BOOST_STATIC_CONSTANT(std::size_t, size = sizeof(*ar) / sizeof((*ar)[0]));
+
+            typedef typename
+                    select<
+                        is_same<T, bool[size]>,                  bool,
+                        is_same<T, char[size]>,                  char,
+                        is_same<T, signed char[size]>,           signed char,
+                        is_same<T, unsigned char[size]>,         unsigned char,
+                    #ifndef BOOST_NO_INTRINSIC_WCHAR_T
+                        is_same<T, wchar_t[size]>,               wchar_t,
+                    #endif
+                        is_same<T, short[size]>,                 short,
+                        is_same<T, unsigned short[size]>,        unsigned short,
+                        is_same<T, int[size]>,                   int,
+                        is_same<T, unsigned int[size]>,          unsigned int,
+                        is_same<T, long[size]>,                  long,
+                        is_same<T, unsigned long[size]>,         unsigned long,
+                        is_same<T, float[size]>,                 float,
+                        is_same<T, double[size]>,                double,
+                        is_same<T, long double[size]>,           long double
+                    >::type result1;
+            typedef typename
+                    select<
+                        is_same<T, const bool[size]>,            const bool,
+                        is_same<T, const char[size]>,            const char,
+                        is_same<T, const signed char[size]>,     const signed char,
+                        is_same<T, const unsigned char[size]>,   const unsigned char,
+                    #ifndef BOOST_NO_INTRINSIC_WCHAR_T
+                        is_same<T, const wchar_t[size]>,         const wchar_t,
+                    #endif
+                        is_same<T, const short[size]>,           const short,
+                        is_same<T, const unsigned short[size]>,  const unsigned short,
+                        is_same<T, const int[size]>,             const int,
+                        is_same<T, const unsigned int[size]>,    const unsigned int,
+                        is_same<T, const long[size]>,            const long,
+                        is_same<T, const unsigned long[size]>,   const unsigned long,
+                        is_same<T, const float[size]>,           const float,
+                        is_same<T, const double[size]>,          const double,
+                        is_same<T, const long double[size]>,     const long double
+                    > result2;
+            typedef typename
+                    mpl::eval_if<
+                        is_same<result1, mpl::void_>,
+                        result2,
+                        mpl::identity<result1>
+                    >::type type;
+        };
+
+    } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/detail/safe_bool.hpp b/include/boost/range/detail/safe_bool.hpp
new file mode 100644
index 0000000..182e510
--- /dev/null
+++ b/include/boost/range/detail/safe_bool.hpp
@@ -0,0 +1,72 @@
+//  This header intentionally has no include guards.
+//
+//  Copyright (c) 2010 Neil Groves
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+// This code utilises the experience gained during the evolution of
+// <boost/smart_ptr/operator_bool.hpp>
+#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
+#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
+
+#include <boost/config.hpp>
+#include <boost/range/config.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<class DataMemberPtr>
+class safe_bool
+{
+public:
+    typedef safe_bool this_type;
+
+#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_)
+    typedef bool unspecified_bool_type;
+    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+    {
+        return x;
+    }
+#elif defined(_MANAGED)
+    static void unspecified_bool(this_type***)
+    {
+    }
+    typedef void(*unspecified_bool_type)(this_type***);
+    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+    {
+        return x ? unspecified_bool : 0;
+    }
+#elif \
+    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
+    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
+    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
+
+    typedef bool (this_type::*unspecified_bool_type)() const;
+
+    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+    {
+        return x ? &this_type::detail_safe_bool_member_fn : 0;
+    }
+private:
+    bool detail_safe_bool_member_fn() const { return false; }
+#else
+    typedef DataMemberPtr unspecified_bool_type;
+    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p)
+    {
+        return x ? p : 0;
+    }
+#endif
+private:
+    safe_bool();
+    safe_bool(const safe_bool&);
+    void operator=(const safe_bool&);
+    ~safe_bool();
+};
+
+    } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/detail/sfinae.hpp b/include/boost/range/detail/sfinae.hpp
new file mode 100644
index 0000000..5b2c61e
--- /dev/null
+++ b/include/boost/range/detail/sfinae.hpp
@@ -0,0 +1,77 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SFINAE_HPP
+#define BOOST_RANGE_DETAIL_SFINAE_HPP
+
+#include <boost/range/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <utility>
+
+
+namespace boost 
+{
+    namespace range_detail
+    {          
+        using type_traits::yes_type;
+        using type_traits::no_type;
+
+        //////////////////////////////////////////////////////////////////////
+        // string
+        //////////////////////////////////////////////////////////////////////
+        
+        yes_type is_string_impl( const char* const );
+        yes_type is_string_impl( const wchar_t* const );
+        no_type  is_string_impl( ... );
+        
+        template< std::size_t sz >
+        yes_type is_char_array_impl( char BOOST_RANGE_ARRAY_REF()[sz] );
+        template< std::size_t sz >
+        yes_type is_char_array_impl( const char BOOST_RANGE_ARRAY_REF()[sz] );
+        no_type  is_char_array_impl( ... );
+        
+        template< std::size_t sz >
+        yes_type is_wchar_t_array_impl( wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
+        template< std::size_t sz >
+        yes_type is_wchar_t_array_impl( const wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
+        no_type  is_wchar_t_array_impl( ... );
+                                     
+        yes_type is_char_ptr_impl( char* const );
+        no_type  is_char_ptr_impl( ... );
+        
+        yes_type is_const_char_ptr_impl( const char* const );
+        no_type  is_const_char_ptr_impl( ... );
+
+        yes_type is_wchar_t_ptr_impl( wchar_t* const );
+        no_type  is_wchar_t_ptr_impl( ... );
+        
+        yes_type is_const_wchar_t_ptr_impl( const wchar_t* const );
+        no_type  is_const_wchar_t_ptr_impl( ... );
+        
+        //////////////////////////////////////////////////////////////////////
+        // pair
+        //////////////////////////////////////////////////////////////////////
+
+        template< typename Iterator >
+        yes_type is_pair_impl( const std::pair<Iterator,Iterator>* );
+        no_type  is_pair_impl( ... );
+
+        //////////////////////////////////////////////////////////////////////
+        // tags
+        //////////////////////////////////////////////////////////////////////
+
+        struct char_or_wchar_t_array_tag {};
+        
+    } // namespace 'range_detail'
+    
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/detail/size_type.hpp b/include/boost/range/detail/size_type.hpp
new file mode 100644
index 0000000..78a60a4
--- /dev/null
+++ b/include/boost/range/detail/size_type.hpp
@@ -0,0 +1,55 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization  workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< typename T >
+        struct range_size_type_
+        {
+            template< typename C >
+            struct pts
+            {
+                typedef std::size_t type;
+            };
+        };
+
+        template<>
+        struct range_size_type_<std_container_>
+        {
+            template< typename C >
+            struct pts
+            {
+                typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type;
+            };
+        };
+    }
+
+    template< typename C >
+    class range_size
+    {
+        typedef typename range_detail::range<C>::type c_type;
+    public:
+        typedef typename range_detail::range_size_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+    };
+}
+
+#endif
+
diff --git a/include/boost/range/detail/sizer.hpp b/include/boost/range/detail/sizer.hpp
new file mode 100644
index 0000000..cd6679c
--- /dev/null
+++ b/include/boost/range/detail/sizer.hpp
@@ -0,0 +1,35 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SIZER_HPP
+#define BOOST_RANGE_DETAIL_SIZER_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <cstddef>
+
+namespace boost 
+{
+    //////////////////////////////////////////////////////////////////////
+    // constant array size
+    //////////////////////////////////////////////////////////////////////
+    
+    template< typename T, std::size_t sz >
+    char (& sizer( const T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
+    
+    template< typename T, std::size_t sz >
+    char (& sizer( T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
+
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/detail/str_types.hpp b/include/boost/range/detail/str_types.hpp
new file mode 100644
index 0000000..f8cab19
--- /dev/null
+++ b/include/boost/range/detail/str_types.hpp
@@ -0,0 +1,38 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_STR_TYPES_HPP
+#define BOOST_RANGE_DETAIL_STR_TYPES_HPP
+
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+    template< class T >
+    struct range_mutable_iterator<T*>
+    {
+        typedef T* type;
+    };
+
+    template< class T >
+    struct range_const_iterator<T*>
+    {
+        typedef const T* type;
+    };
+
+    template< class T >
+    struct range_size<T*>
+    {
+       typedef std::size_t type;
+    };    
+}
+
+#endif
diff --git a/include/boost/range/detail/value_type.hpp b/include/boost/range/detail/value_type.hpp
new file mode 100644
index 0000000..2784514
--- /dev/null
+++ b/include/boost/range/detail/value_type.hpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization  workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost 
+{
+    namespace range_detail 
+    {        
+        template< typename T >
+        struct range_value_type_;
+
+        template<>
+        struct range_value_type_<std_container_>
+        {
+            template< typename C >
+            struct pts
+            {
+                typedef BOOST_RANGE_DEDUCED_TYPENAME C::value_type type;
+            };
+        };
+
+        template<>
+        struct range_value_type_<std_pair_>
+        {
+            template< typename P >
+            struct pts
+            {
+                typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_value< BOOST_RANGE_DEDUCED_TYPENAME P::first_type >::type type;
+            };
+        };
+
+        template<>
+        struct range_value_type_<array_>
+        { 
+            template< typename T >
+            struct pts
+            {
+                typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type type;
+            };
+        };
+        
+    } 
+    
+    template< typename C >
+    class range_value
+    {
+        typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+    public:
+        typedef BOOST_DEDUCED_TYPENAME range_detail::range_value_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
+    };
+
+}
+
+#endif
+
diff --git a/include/boost/range/difference_type.hpp b/include/boost/range/difference_type.hpp
new file mode 100644
index 0000000..6bb3c5f
--- /dev/null
+++ b/include/boost/range/difference_type.hpp
@@ -0,0 +1,47 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DIFFERENCE_TYPE_HPP
+#define BOOST_RANGE_DIFFERENCE_TYPE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/mpl/and.hpp>
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/has_range_iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        template< class T, bool B = has_type<range_iterator<T> >::value >
+        struct range_difference
+        { };
+
+        template< class T >
+        struct range_difference<T, true>
+          : iterator_difference<
+                BOOST_DEDUCED_TYPENAME range_iterator<T>::type
+            >
+        { };
+    }
+
+    template< class T >
+    struct range_difference
+      : range_detail::range_difference<BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
+    { };
+}
+
+#endif
diff --git a/include/boost/range/distance.hpp b/include/boost/range/distance.hpp
new file mode 100644
index 0000000..8dcf05b
--- /dev/null
+++ b/include/boost/range/distance.hpp
@@ -0,0 +1,35 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DISTANCE_HPP
+#define BOOST_RANGE_DISTANCE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/iterator/distance.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/difference_type.hpp>
+
+namespace boost
+{
+
+    template< class T >
+    inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME range_difference<T>::type
+    distance( const T& r )
+    {
+        return boost::distance( boost::begin( r ), boost::end( r ) );
+    }
+
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/empty.hpp b/include/boost/range/empty.hpp
new file mode 100644
index 0000000..d57a30e
--- /dev/null
+++ b/include/boost/range/empty.hpp
@@ -0,0 +1,34 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_EMPTY_HPP
+#define BOOST_RANGE_EMPTY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+namespace boost 
+{ 
+
+    template< class T >
+    inline bool empty( const T& r )
+    {
+        return boost::begin( r ) == boost::end( r );
+    }
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/include/boost/range/end.hpp b/include/boost/range/end.hpp
new file mode 100644
index 0000000..588495c
--- /dev/null
+++ b/include/boost/range/end.hpp
@@ -0,0 +1,128 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_END_HPP
+#define BOOST_RANGE_END_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/end.hpp>
+#else
+
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/const_iterator.hpp>
+
+namespace boost
+{
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+namespace range_detail
+{
+#endif
+
+        //////////////////////////////////////////////////////////////////////
+        // primary template
+        //////////////////////////////////////////////////////////////////////
+        template< typename C >
+        BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
+        range_end( C& c )
+        {
+            //
+            // If you get a compile-error here, it is most likely because
+            // you have not implemented range_begin() properly in
+            // the namespace of C
+            //
+            return c.end();
+        }
+
+        //////////////////////////////////////////////////////////////////////
+        // pair
+        //////////////////////////////////////////////////////////////////////
+
+        template< typename Iterator >
+        BOOST_CONSTEXPR inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
+        {
+            return p.second;
+        }
+
+        template< typename Iterator >
+        BOOST_CONSTEXPR inline Iterator range_end( std::pair<Iterator,Iterator>& p )
+        {
+            return p.second;
+        }
+
+        //////////////////////////////////////////////////////////////////////
+        // array
+        //////////////////////////////////////////////////////////////////////
+
+        template< typename T, std::size_t sz >
+        BOOST_CONSTEXPR inline const T* range_end( const T (&a)[sz] ) BOOST_NOEXCEPT
+        {
+            return range_detail::array_end<T,sz>( a );
+        }
+
+        template< typename T, std::size_t sz >
+        BOOST_CONSTEXPR inline T* range_end( T (&a)[sz] ) BOOST_NOEXCEPT
+        {
+            return range_detail::array_end<T,sz>( a );
+        }
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+} // namespace 'range_detail'
+#endif
+
+namespace range_adl_barrier
+{
+
+template< class T >
+BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    using namespace range_detail;
+#endif
+    return range_end( r );
+}
+
+template< class T >
+BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    using namespace range_detail;
+#endif
+    return range_end( r );
+}
+
+    } // namespace range_adl_barrier
+} // namespace 'boost'
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+namespace boost
+{
+    namespace range_adl_barrier
+    {
+        template< class T >
+        BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
+        const_end( const T& r )
+        {
+            return boost::range_adl_barrier::end( r );
+        }
+    } // namespace range_adl_barrier
+    using namespace range_adl_barrier;
+} // namespace boost
+
+#endif
+
diff --git a/include/boost/range/functions.hpp b/include/boost/range/functions.hpp
new file mode 100644
index 0000000..43c54b1
--- /dev/null
+++ b/include/boost/range/functions.hpp
@@ -0,0 +1,27 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_FUNCTIONS_HPP
+#define BOOST_RANGE_FUNCTIONS_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/rbegin.hpp>
+#include <boost/range/rend.hpp>
+
+#endif
+
diff --git a/include/boost/range/has_range_iterator.hpp b/include/boost/range/has_range_iterator.hpp
new file mode 100644
index 0000000..88d8664
--- /dev/null
+++ b/include/boost/range/has_range_iterator.hpp
@@ -0,0 +1,83 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Acknowledgments:
+// Ticket #8341: Arno Schoedl - improved handling of has_range_iterator upon
+// use-cases where T was const.
+#ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
+
+        template<class T, class Enabler = void>
+        struct has_range_iterator_impl
+            : boost::mpl::false_
+        {
+        };
+
+        template<class T>
+        struct has_range_iterator_impl<
+            T,
+            BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                BOOST_DEDUCED_TYPENAME mpl::eval_if<is_const<T>,
+                    has_type<boost::range_const_iterator<
+                                BOOST_DEDUCED_TYPENAME remove_const<T>::type> >,
+                    has_type<boost::range_mutable_iterator<T> >
+                >::type
+            >::type
+        >
+            : boost::mpl::true_
+        {
+        };
+
+        template<class T, class Enabler = void>
+        struct has_range_const_iterator_impl
+            : boost::mpl::false_
+        {
+        };
+
+        template<class T>
+        struct has_range_const_iterator_impl<
+            T,
+            BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                has_type<boost::range_const_iterator<T> >
+            >::type
+        >
+            : boost::mpl::true_
+        {
+        };
+
+    } // namespace range_detail
+
+    template<class T>
+    struct has_range_iterator
+        : range_detail::has_range_iterator_impl<
+            BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
+    {};
+
+    template<class T>
+    struct has_range_const_iterator
+        : range_detail::has_range_const_iterator_impl<
+            BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
+    {};
+} // namespace boost
+
+#endif // include guard
+
diff --git a/include/boost/range/irange.hpp b/include/boost/range/irange.hpp
new file mode 100644
index 0000000..7d5fee5
--- /dev/null
+++ b/include/boost/range/irange.hpp
@@ -0,0 +1,243 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_IRANGE_HPP_INCLUDED
+#define BOOST_RANGE_IRANGE_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // integer_iterator is an iterator over an integer sequence that
+        // is bounded only by the limits of the underlying integer
+        // representation.
+        //
+        // This is useful for implementing the irange(first, last)
+        // function.
+        //
+        // Note:
+        // This use of this iterator and irange is appreciably less
+        // performant than the corresponding hand-written integer
+        // loop on many compilers.
+        template<typename Integer>
+        class integer_iterator
+            : public boost::iterator_facade<
+                        integer_iterator<Integer>,
+                        Integer,
+                        boost::random_access_traversal_tag,
+                        Integer,
+                        std::ptrdiff_t
+                    >
+        {
+            typedef boost::iterator_facade<
+                        integer_iterator<Integer>,
+                        Integer,
+                        boost::random_access_traversal_tag,
+                        Integer,
+                        std::ptrdiff_t
+                    > base_t;
+        public:
+            typedef typename base_t::value_type value_type;
+            typedef typename base_t::difference_type difference_type;
+            typedef typename base_t::reference reference;
+            typedef std::random_access_iterator_tag iterator_category;
+
+            integer_iterator() : m_value() {}
+            explicit integer_iterator(value_type x) : m_value(x) {}
+
+        private:
+            void increment()
+            {
+                ++m_value;
+            }
+
+            void decrement()
+            {
+                --m_value;
+            }
+
+            void advance(difference_type offset)
+            {
+                m_value += offset;
+            }
+
+            difference_type distance_to(const integer_iterator& other) const
+            {
+                return is_signed<value_type>::value
+                    ? (other.m_value - m_value)
+                    : (other.m_value >= m_value)
+                        ? static_cast<difference_type>(other.m_value - m_value)
+                        : -static_cast<difference_type>(m_value - other.m_value);
+            }
+
+            bool equal(const integer_iterator& other) const
+            {
+                return m_value == other.m_value;
+            }
+
+            reference dereference() const
+            {
+                return m_value;
+            }
+
+            friend class ::boost::iterator_core_access;
+            value_type m_value;
+        };
+
+        // integer_iterator_with_step is similar in nature to the
+        // integer_iterator but provides the ability to 'move' in
+        // a number of steps specified at construction time.
+        //
+        // The three variable implementation provides the best guarantees
+        // of loop termination upon various combinations of input.
+        //
+        // While this design is less performant than some less
+        // safe alternatives, the use of ranges and iterators to
+        // perform counting will never be optimal anyhow, hence
+        // if optimal performance is desired a hand-coded loop
+        // is the solution.
+        template<typename Integer>
+        class integer_iterator_with_step
+            : public boost::iterator_facade<
+                        integer_iterator_with_step<Integer>,
+                        Integer,
+                        boost::random_access_traversal_tag,
+                        Integer,
+                        std::ptrdiff_t
+                    >
+        {
+            typedef boost::iterator_facade<
+                        integer_iterator_with_step<Integer>,
+                        Integer,
+                        boost::random_access_traversal_tag,
+                        Integer,
+                        std::ptrdiff_t
+                    > base_t;
+        public:
+            typedef typename base_t::value_type value_type;
+            typedef typename base_t::difference_type difference_type;
+            typedef typename base_t::reference reference;
+            typedef std::random_access_iterator_tag iterator_category;
+
+            integer_iterator_with_step(value_type first, difference_type step, value_type step_size)
+                : m_first(first)
+                , m_step(step)
+                , m_step_size(step_size)
+            {
+            }
+
+        private:
+            void increment()
+            {
+                ++m_step;
+            }
+
+            void decrement()
+            {
+                --m_step;
+            }
+
+            void advance(difference_type offset)
+            {
+                m_step += offset;
+            }
+
+            difference_type distance_to(const integer_iterator_with_step& other) const
+            {
+                return other.m_step - m_step;
+            }
+
+            bool equal(const integer_iterator_with_step& other) const
+            {
+                return m_step == other.m_step;
+            }
+
+            reference dereference() const
+            {
+                return m_first + (m_step * m_step_size);
+            }
+
+            friend class ::boost::iterator_core_access;
+            value_type m_first;
+            difference_type m_step;
+            difference_type m_step_size;
+        };
+
+    } // namespace range_detail
+
+    template<typename Integer>
+    class integer_range
+        : public iterator_range< range_detail::integer_iterator<Integer> >
+    {
+        typedef range_detail::integer_iterator<Integer> iterator_t;
+        typedef iterator_range<iterator_t> base_t;
+    public:
+        integer_range(Integer first, Integer last)
+            : base_t(iterator_t(first), iterator_t(last))
+        {
+        }
+    };
+
+    template<typename Integer>
+    class strided_integer_range
+    : public iterator_range< range_detail::integer_iterator_with_step<Integer> >
+    {
+        typedef range_detail::integer_iterator_with_step<Integer> iterator_t;
+        typedef iterator_range<iterator_t> base_t;
+    public:
+        template<typename Iterator>
+        strided_integer_range(Iterator first, Iterator last)
+            : base_t(first, last)
+        {
+        }
+    };
+
+    template<typename Integer>
+    integer_range<Integer>
+    irange(Integer first, Integer last)
+    {
+        BOOST_ASSERT( first <= last );
+        return integer_range<Integer>(first, last);
+    }
+
+    template<typename Integer, typename StepSize>
+    strided_integer_range<Integer>
+        irange(Integer first, Integer last, StepSize step_size)
+    {
+        BOOST_ASSERT( step_size != 0 );
+        BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
+
+        typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
+
+        const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
+        const Integer l = step_size >= 0 ? last : first;
+        const Integer f = step_size >= 0 ? first : last;
+        const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0);
+        BOOST_ASSERT(num_steps >= 0);
+
+        return strided_integer_range<Integer>(
+            iterator_t(first, 0, step_size),
+            iterator_t(first, num_steps, step_size));
+    }
+
+    template<typename Integer>
+    integer_range<Integer>
+    irange(Integer last)
+    {
+        return integer_range<Integer>(static_cast<Integer>(0), last);
+    }
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/istream_range.hpp b/include/boost/range/istream_range.hpp
new file mode 100644
index 0000000..a486317
--- /dev/null
+++ b/include/boost/range/istream_range.hpp
@@ -0,0 +1,37 @@
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
+
+/*!
+ * \file istream_range.hpp
+ */
+
+#include <iterator>
+#include <iosfwd>
+#include <boost/config.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+        template<class Type, class Elem, class Traits> inline
+            iterator_range<std::istream_iterator<Type, Elem, Traits> >
+        istream_range(std::basic_istream<Elem, Traits>& in)
+        {
+            return iterator_range<std::istream_iterator<Type, Elem, Traits> >(
+                std::istream_iterator<Type, Elem, Traits>(in),
+                std::istream_iterator<Type, Elem, Traits>());
+        }
+    } // namespace range
+    using range::istream_range;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/iterator.hpp b/include/boost/range/iterator.hpp
new file mode 100644
index 0000000..2956353
--- /dev/null
+++ b/include/boost/range/iterator.hpp
@@ -0,0 +1,74 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ITERATOR_HPP
+#define BOOST_RANGE_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/range_fwd.hpp>
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/mpl/eval_if.hpp>
+
+namespace boost
+{
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)  
+
+    namespace range_detail_vc7_1  
+    {  
+       template< typename C, typename Sig = void(C) >  
+       struct range_iterator  
+       {  
+           typedef BOOST_RANGE_DEDUCED_TYPENAME   
+               mpl::eval_if_c< is_const<C>::value,   
+                               range_const_iterator< typename remove_const<C>::type >,  
+                               range_mutable_iterator<C> >::type type;  
+       };  
+    
+       template< typename C, typename T >  
+       struct range_iterator< C, void(T[]) >  
+       {  
+           typedef T* type;  
+       };       
+    }  
+    
+    template< typename C, typename Enabler=void >
+    struct range_iterator
+    {
+
+        typedef BOOST_RANGE_DEDUCED_TYPENAME  
+               range_detail_vc7_1::range_iterator<C>::type type;  
+
+    };
+
+#else
+
+    template< typename C, typename Enabler=void >
+    struct range_iterator
+      : mpl::if_c<
+            is_const<typename remove_reference<C>::type>::value,
+            range_const_iterator<typename remove_const<typename remove_reference<C>::type>::type>,
+            range_mutable_iterator<typename remove_reference<C>::type>
+        >::type
+    {
+    };
+
+#endif
+
+} // namespace boost
+
+#endif
diff --git a/include/boost/range/iterator_range.hpp b/include/boost/range/iterator_range.hpp
new file mode 100644
index 0000000..dfcd4d2
--- /dev/null
+++ b/include/boost/range/iterator_range.hpp
@@ -0,0 +1,16 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
+
+#include "boost/range/iterator_range_core.hpp"
+#include "boost/range/iterator_range_io.hpp"
+
+#endif // include guard
diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp
new file mode 100644
index 0000000..7f2dc3f
--- /dev/null
+++ b/include/boost/range/iterator_range_core.hpp
@@ -0,0 +1,884 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Credits:
+// 'michel' reported Trac 9072 which included a patch for allowing references
+// to function types.
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
+
+#include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+    #pragma warning( push )
+    #pragma warning( disable : 4996 )
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_abstract.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/has_range_iterator.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/detail/safe_bool.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/next_prior.hpp>
+#include <iterator>
+#include <algorithm>
+#include <cstddef>
+
+/*! \file
+    Defines the \c iterator_class and related functions.
+    \c iterator_range is a simple wrapper of iterator pair idiom. It provides
+    a rich subset of Container interface.
+*/
+
+
+namespace boost
+{
+    namespace iterator_range_detail
+    {
+        //
+        // The functions adl_begin and adl_end are implemented in a separate
+        // class for gcc-2.9x
+        //
+        template<class IteratorT>
+        struct iterator_range_impl {
+            template< class ForwardRange >
+            static IteratorT adl_begin( ForwardRange& r )
+            {
+                return IteratorT( boost::begin( r ) );
+            }
+
+            template< class ForwardRange >
+            static IteratorT adl_end( ForwardRange& r )
+            {
+                return IteratorT( boost::end( r ) );
+            }
+        };
+
+        template< class Left, class Right >
+        inline bool less_than( const Left& l, const Right& r )
+        {
+            return std::lexicographical_compare( boost::begin(l),
+                                                 boost::end(l),
+                                                 boost::begin(r),
+                                                 boost::end(r) );
+        }
+        
+        template< class Left, class Right >
+        inline bool greater_than( const Left& l, const Right& r )
+        {
+            return iterator_range_detail::less_than(r,l);
+        }
+        
+        template< class Left, class Right >
+        inline bool less_or_equal_than( const Left& l, const Right& r )
+        {
+            return !iterator_range_detail::less_than(r,l);
+        }
+        
+        template< class Left, class Right >
+        inline bool greater_or_equal_than( const Left& l, const Right& r )
+        {
+            return !iterator_range_detail::less_than(l,r);
+        }
+
+        // This version is maintained since it is used in other boost libraries
+        // such as Boost.Assign
+        template< class Left, class Right >
+        inline bool equal(const Left& l, const Right& r)
+        {
+            return boost::equal(l, r);
+        }
+
+struct range_tag
+{
+};
+
+struct const_range_tag
+{
+};
+
+struct iterator_range_tag
+{
+};
+
+typedef char (&incrementable_t)[1];
+typedef char (&bidirectional_t)[2];
+typedef char (&random_access_t)[3];
+
+incrementable_t test_traversal_tag(boost::incrementable_traversal_tag);
+bidirectional_t test_traversal_tag(boost::bidirectional_traversal_tag);
+random_access_t test_traversal_tag(boost::random_access_traversal_tag);
+
+template<std::size_t S>
+struct pure_iterator_traversal_impl
+{
+    typedef boost::incrementable_traversal_tag type;
+};
+
+template<>
+struct pure_iterator_traversal_impl<sizeof(bidirectional_t)>
+{
+    typedef boost::bidirectional_traversal_tag type;
+};
+
+template<>
+struct pure_iterator_traversal_impl<sizeof(random_access_t)>
+{
+    typedef boost::random_access_traversal_tag type;
+};
+
+template<typename IteratorT>
+struct pure_iterator_traversal
+{
+    typedef
+        BOOST_DEDUCED_TYPENAME iterator_traversal<IteratorT>::type
+    traversal_t;
+    BOOST_STATIC_CONSTANT(
+        std::size_t,
+        traversal_i = sizeof(iterator_range_detail::test_traversal_tag((traversal_t())))
+    );
+    typedef
+        BOOST_DEDUCED_TYPENAME pure_iterator_traversal_impl<traversal_i>::type
+    type;
+};
+
+template<class IteratorT, class TraversalTag>
+class iterator_range_base
+    : public iterator_range_tag
+{
+    typedef range_detail::safe_bool<
+                IteratorT iterator_range_base<IteratorT, TraversalTag>::*
+    > safe_bool_t;
+
+    typedef iterator_range_base<IteratorT, TraversalTag> type;
+
+protected:
+    typedef iterator_range_impl<IteratorT> impl;
+
+public:
+    typedef BOOST_DEDUCED_TYPENAME
+        safe_bool_t::unspecified_bool_type unspecified_bool_type;
+
+    typedef BOOST_DEDUCED_TYPENAME
+        iterator_value<IteratorT>::type value_type;
+
+    typedef BOOST_DEDUCED_TYPENAME
+        iterator_difference<IteratorT>::type difference_type;
+
+    typedef std::size_t size_type; // note: must be unsigned
+
+    // Needed because value-type is the same for
+    // const and non-const iterators
+    typedef BOOST_DEDUCED_TYPENAME
+                iterator_reference<IteratorT>::type reference;
+
+    //! const_iterator type
+    /*!
+        There is no distinction between const_iterator and iterator.
+        These typedefs are provides to fulfill container interface
+    */
+    typedef IteratorT const_iterator;
+    //! iterator type
+    typedef IteratorT iterator;
+
+protected:
+    iterator_range_base()
+        : m_Begin()
+        , m_End()
+    {
+    }
+
+    template<class Iterator>
+    iterator_range_base(Iterator Begin, Iterator End)
+        : m_Begin(Begin)
+        , m_End(End)
+    {
+    }
+
+public:
+    IteratorT begin() const
+    {
+        return m_Begin;
+    }
+
+    IteratorT end() const
+    {
+        return m_End;
+    }
+
+    bool empty() const
+    {
+        return m_Begin == m_End;
+    }
+
+    operator unspecified_bool_type() const
+    {
+        return safe_bool_t::to_unspecified_bool(
+                    m_Begin != m_End, &iterator_range_base::m_Begin);
+    }
+
+    bool operator!() const
+    {
+        return empty();
+    }
+
+    bool equal(const iterator_range_base& r) const
+    {
+        return m_Begin == r.m_Begin && m_End == r.m_End;
+    }
+
+   reference front() const
+   {
+       BOOST_ASSERT(!empty());
+       return *m_Begin;
+   }
+
+   void drop_front()
+   {
+       BOOST_ASSERT(!empty());
+       ++m_Begin;
+   }
+
+   void drop_front(difference_type n)
+   {
+       BOOST_ASSERT(n >= difference_type());
+       std::advance(this->m_Begin, n);
+   }
+   
+   // Deprecated
+   void pop_front() { drop_front(); }
+
+protected:
+    template<class Iterator>
+    void assign(Iterator first, Iterator last)
+    {
+        m_Begin = first;
+        m_End = last;
+    }
+
+    template<class SinglePassRange>
+    void assign(const SinglePassRange& r)
+    {
+        m_Begin = impl::adl_begin(r);
+        m_End = impl::adl_end(r);
+    }
+
+    template<class SinglePassRange>
+    void assign(SinglePassRange& r)
+    {
+        m_Begin = impl::adl_begin(r);
+        m_End = impl::adl_end(r);
+    }
+
+    IteratorT m_Begin;
+    IteratorT m_End;
+};
+
+template<class IteratorT>
+class iterator_range_base<IteratorT, bidirectional_traversal_tag>
+        : public iterator_range_base<IteratorT, incrementable_traversal_tag>
+{
+    typedef iterator_range_base<IteratorT, incrementable_traversal_tag> base_type;
+
+protected:
+    iterator_range_base()
+    {
+    }
+
+    template<class Iterator>
+    iterator_range_base(Iterator first, Iterator last)
+        : base_type(first, last)
+    {
+    }
+
+public:
+    typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
+    typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
+
+    reference back() const
+    {
+        BOOST_ASSERT(!this->empty());
+        return *boost::prior(this->m_End);
+    }
+
+    void drop_back()
+    {
+        BOOST_ASSERT(!this->empty());
+        --this->m_End;
+    }
+
+    void drop_back(difference_type n)
+    {
+        BOOST_ASSERT(n >= difference_type());
+        std::advance(this->m_End, -n);
+    }
+    
+    // Deprecated
+    void pop_back() { drop_back(); }
+};
+
+template<class IteratorT>
+class iterator_range_base<IteratorT, random_access_traversal_tag>
+        : public iterator_range_base<IteratorT, bidirectional_traversal_tag>
+{
+    typedef iterator_range_base<
+                IteratorT, bidirectional_traversal_tag> base_type;
+
+public:
+    typedef BOOST_DEDUCED_TYPENAME
+        boost::mpl::if_<
+            boost::mpl::or_<
+                boost::is_abstract<
+                    BOOST_DEDUCED_TYPENAME base_type::value_type
+                >,
+                boost::is_array<
+                    BOOST_DEDUCED_TYPENAME base_type::value_type
+                >,
+                boost::is_function<
+                    BOOST_DEDUCED_TYPENAME base_type::value_type
+                >
+            >,
+            BOOST_DEDUCED_TYPENAME base_type::reference,
+            BOOST_DEDUCED_TYPENAME base_type::value_type
+        >::type abstract_value_type;
+
+    // Rationale:
+    // typedef these here to reduce verbiage in the implementation of this
+    // type.
+    typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
+    typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type;
+    typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
+
+protected:
+    iterator_range_base()
+    {
+    }
+
+    template<class Iterator>
+    iterator_range_base(Iterator first, Iterator last)
+        : base_type(first, last)
+    {
+    }
+
+public:
+    reference operator[](difference_type at) const
+    {
+        BOOST_ASSERT(at >= 0);
+        BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
+        return this->m_Begin[at];
+    }
+
+    //
+    // When storing transform iterators, operator[]()
+    // fails because it returns by reference. Therefore
+    // operator()() is provided for these cases.
+    //
+    abstract_value_type operator()(difference_type at) const
+    {
+        BOOST_ASSERT(at >= 0);
+        BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
+        return this->m_Begin[at];
+    }
+
+    BOOST_DEDUCED_TYPENAME base_type::size_type size() const
+    {
+        return this->m_End - this->m_Begin;
+    }
+};
+
+    }
+
+//  iterator range template class -----------------------------------------//
+
+        //! iterator_range class
+        /*!
+            An \c iterator_range delimits a range in a sequence by beginning and ending iterators.
+            An iterator_range can be passed to an algorithm which requires a sequence as an input.
+            For example, the \c toupper() function may be used most frequently on strings,
+            but can also be used on iterator_ranges:
+
+            \code
+                boost::tolower( find( s, "UPPERCASE STRING" ) );
+            \endcode
+
+            Many algorithms working with sequences take a pair of iterators,
+            delimiting a working range, as an arguments. The \c iterator_range class is an
+            encapsulation of a range identified by a pair of iterators.
+            It provides a collection interface,
+            so it is possible to pass an instance to an algorithm requiring a collection as an input.
+        */
+        template<class IteratorT>
+        class iterator_range
+            : public iterator_range_detail::iterator_range_base<
+                    IteratorT,
+                    BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
+                >
+        {
+            typedef iterator_range_detail::iterator_range_base<
+                    IteratorT,
+                    BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
+            > base_type;
+
+            template<class Source>
+            struct is_compatible_range_
+              : is_convertible<
+                    BOOST_DEDUCED_TYPENAME mpl::eval_if<
+                        has_range_iterator<Source>,
+                        range_iterator<Source>,
+                        mpl::identity<void>
+                    >::type,
+                    BOOST_DEDUCED_TYPENAME base_type::iterator
+                >
+            {
+            };
+
+            template<class Source>
+            struct is_compatible_range
+                : mpl::and_<
+                    mpl::not_<
+                        is_convertible<
+                            Source,
+                            BOOST_DEDUCED_TYPENAME base_type::iterator
+                        >
+                    >,
+                    is_compatible_range_<Source>
+                >
+            {
+            };
+
+        protected:
+            typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
+
+        public:
+            typedef iterator_range<IteratorT> type;
+
+            iterator_range()
+            {
+            }
+
+            template<class Iterator>
+            iterator_range(Iterator first, Iterator last)
+                : base_type(first, last)
+            {
+            }
+
+            template<class SinglePassRange>
+            iterator_range(
+                const SinglePassRange& r,
+                BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                    is_compatible_range<const SinglePassRange>
+                >::type* = 0
+            )
+                : base_type(impl::adl_begin(r), impl::adl_end(r))
+            {
+            }
+
+            template<class SinglePassRange>
+            iterator_range(
+                SinglePassRange& r,
+                BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                    is_compatible_range<SinglePassRange>
+                >::type* = 0
+            )
+                : base_type(impl::adl_begin(r), impl::adl_end(r))
+            {
+            }
+
+            template<class SinglePassRange>
+            iterator_range(const SinglePassRange& r,
+                           iterator_range_detail::const_range_tag)
+                : base_type(impl::adl_begin(r), impl::adl_end(r))
+            {
+            }
+
+            template<class SinglePassRange>
+            iterator_range(SinglePassRange& r,
+                           iterator_range_detail::range_tag)
+                : base_type(impl::adl_begin(r), impl::adl_end(r))
+            {
+            }
+
+            template<class Iterator>
+            iterator_range& operator=(const iterator_range<Iterator>& other)
+            {
+                this->assign(other.begin(), other.end());
+                return *this;
+            }
+
+            template<class Iterator>
+            iterator_range& operator=(iterator_range<Iterator>& other)
+            {
+                this->assign(other.begin(), other.end());
+                return *this;
+            }
+
+            template<class SinglePassRange>
+            iterator_range& operator=(SinglePassRange& r)
+            {
+                this->assign(r);
+                return *this;
+            }
+
+            template<class SinglePassRange>
+            iterator_range& operator=(const SinglePassRange& r)
+            {
+                this->assign(r);
+                return *this;
+            }
+
+            iterator_range& advance_begin(
+                BOOST_DEDUCED_TYPENAME base_type::difference_type n)
+            {
+                std::advance(this->m_Begin, n);
+                return *this;
+            }
+
+            iterator_range& advance_end(
+                BOOST_DEDUCED_TYPENAME base_type::difference_type n)
+            {
+                std::advance(this->m_End, n);
+                return *this;
+            }
+
+        protected:
+            //
+            // Allow subclasses an easy way to access the
+            // base type
+            //
+            typedef iterator_range iterator_range_;
+        };
+
+//  iterator range free-standing operators ---------------------------//
+
+        /////////////////////////////////////////////////////////////////////
+        // comparison operators
+        /////////////////////////////////////////////////////////////////////
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator==( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return boost::equal( l, r );
+        }
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator!=( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return !boost::equal( l, r );
+        }
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator<( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return iterator_range_detail::less_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator<=( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return iterator_range_detail::less_or_equal_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator>( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return iterator_range_detail::greater_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator>=( const ForwardRange& l, const iterator_range<IteratorT>& r )
+        {
+            return iterator_range_detail::greater_or_equal_than( l, r );
+        }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#else
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator==( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return boost::equal( l, r );
+        }
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator==( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return boost::equal( l, r );
+        }
+
+
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator!=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return !boost::equal( l, r );
+        }
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator!=( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return !boost::equal( l, r );
+        }
+
+
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator<( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return iterator_range_detail::less_than( l, r );
+        }
+
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator<( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return iterator_range_detail::less_than( l, r );
+        }
+        
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator<=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return iterator_range_detail::less_or_equal_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator<=( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return iterator_range_detail::less_or_equal_than( l, r );
+        }
+        
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator>( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return iterator_range_detail::greater_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator>( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return iterator_range_detail::greater_than( l, r );
+        }
+        
+        template< class Iterator1T, class Iterator2T >
+        inline bool
+        operator>=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
+        {
+            return iterator_range_detail::greater_or_equal_than( l, r );
+        }
+        
+        template< class IteratorT, class ForwardRange >
+        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
+            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
+            bool
+        >::type
+        operator>=( const iterator_range<IteratorT>& l, const ForwardRange& r )
+        {
+            return iterator_range_detail::greater_or_equal_than( l, r );
+        }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+//  iterator range utilities -----------------------------------------//
+
+        //! iterator_range construct helper
+        /*!
+            Construct an \c iterator_range from a pair of iterators
+
+            \param Begin A begin iterator
+            \param End An end iterator
+            \return iterator_range object
+        */
+        template< typename IteratorT >
+        inline iterator_range< IteratorT >
+        make_iterator_range( IteratorT Begin, IteratorT End )
+        {
+            return iterator_range<IteratorT>( Begin, End );
+        }
+
+        template<typename IteratorT, typename IntegerT>
+        inline iterator_range<IteratorT>
+        make_iterator_range_n(IteratorT first, IntegerT n)
+        {
+            return iterator_range<IteratorT>(first, boost::next(first, n));
+        }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        template< typename Range >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+        make_iterator_range( Range& r )
+        {
+            return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+                ( boost::begin( r ), boost::end( r ) );
+        }
+
+#else
+        //! iterator_range construct helper
+        /*!
+            Construct an \c iterator_range from a \c Range containing the begin
+            and end iterators.
+        */
+        template< class ForwardRange >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+        make_iterator_range( ForwardRange& r )
+        {
+           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+                ( r, iterator_range_detail::range_tag() );
+        }
+
+        template< class ForwardRange >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
+        make_iterator_range( const ForwardRange& r )
+        {
+           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
+                ( r, iterator_range_detail::const_range_tag() );
+        }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        namespace iterator_range_detail
+        {
+            template< class Range >
+            inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+            make_range_impl( Range& r,
+                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+            {
+                //
+                // Not worth the effort
+                //
+                //if( advance_begin == 0 && advance_end == 0 )
+                //    return make_iterator_range( r );
+                //
+
+                BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
+                    new_begin = boost::begin( r ),
+                    new_end   = boost::end( r );
+                std::advance( new_begin, advance_begin );
+                std::advance( new_end, advance_end );
+                return make_iterator_range( new_begin, new_end );
+            }
+        }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        template< class Range >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+        make_iterator_range( Range& r,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+        {
+            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+        }
+
+#else
+
+        template< class Range >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+        make_iterator_range( Range& r,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+        {
+            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+        }
+
+        template< class Range >
+        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
+        make_iterator_range( const Range& r,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+        {
+            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+        }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+        //! copy a range into a sequence
+        /*!
+            Construct a new sequence of the specified type from the elements
+            in the given range
+
+            \param Range An input range
+            \return New sequence
+        */
+        template< typename SeqT, typename Range >
+        inline SeqT copy_range( const Range& r )
+        {
+            return SeqT( boost::begin( r ), boost::end( r ) );
+        }
+
+} // namespace 'boost'
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+    #pragma warning( pop )
+#endif
+
+#endif
+
diff --git a/include/boost/range/iterator_range_hash.hpp b/include/boost/range/iterator_range_hash.hpp
new file mode 100644
index 0000000..615d22f
--- /dev/null
+++ b/include/boost/range/iterator_range_hash.hpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/functional/hash.hpp>
+
+namespace boost
+{
+
+template<class T>
+std::size_t hash_value(const iterator_range<T>& rng)
+{
+    return boost::hash_range(rng.begin(), rng.end());
+}
+
+} // namespace boost
diff --git a/include/boost/range/iterator_range_io.hpp b/include/boost/range/iterator_range_io.hpp
new file mode 100644
index 0000000..8c29400
--- /dev/null
+++ b/include/boost/range/iterator_range_io.hpp
@@ -0,0 +1,93 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+    #pragma warning( push )
+    #pragma warning( disable : 4996 )
+#endif
+
+// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for Cray X1 patch.
+#ifndef BOOST_OLD_IOSTREAMS 
+# if defined(__STL_CONFIG_H) && \
+    !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \
+    /**/
+#  define BOOST_OLD_IOSTREAMS
+# endif
+#endif // #ifndef BOOST_OLD_IOSTREAMS
+
+#ifndef _STLP_NO_IOSTREAMS
+# ifndef BOOST_OLD_IOSTREAMS
+#  include <ostream>
+# else
+#  include <ostream.h>
+# endif
+#endif // _STLP_NO_IOSTREAMS
+
+#include <boost/range/iterator_range_core.hpp>
+#include <iterator>
+#include <algorithm>
+#include <cstddef>
+
+namespace boost
+{
+
+#ifndef _STLP_NO_IOSTREAMS
+# ifndef BOOST_OLD_IOSTREAMS   
+
+        //! iterator_range output operator
+        /*!
+            Output the range to an ostream. Elements are outputted
+            in a sequence without separators.
+        */
+        template< typename IteratorT, typename Elem, typename Traits >
+        inline std::basic_ostream<Elem,Traits>& operator<<( 
+                    std::basic_ostream<Elem, Traits>& Os,
+                    const iterator_range<IteratorT>& r )
+        {
+            std::copy( r.begin(), r.end(), 
+                       std::ostream_iterator< BOOST_DEDUCED_TYPENAME 
+                                              iterator_value<IteratorT>::type, 
+                                              Elem, Traits>(Os) );
+            return Os;
+        }
+
+# else
+
+        //! iterator_range output operator
+        /*!
+            Output the range to an ostream. Elements are outputted
+            in a sequence without separators.
+        */
+        template< typename IteratorT >
+        inline std::ostream& operator<<( 
+                    std::ostream& Os,
+                    const iterator_range<IteratorT>& r )
+        {
+            std::copy( r.begin(), r.end(), std::ostream_iterator<char>(Os));
+            return Os;
+        }
+
+# endif
+#endif // _STLP_NO_IOSTREAMS
+
+} // namespace boost
+
+#undef BOOST_OLD_IOSTREAMS
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+    #pragma warning(pop)
+#endif
+
+#endif // include guard
diff --git a/include/boost/range/join.hpp b/include/boost/range/join.hpp
new file mode 100644
index 0000000..aacc0a3
--- /dev/null
+++ b/include/boost/range/join.hpp
@@ -0,0 +1,91 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_JOIN_HPP_INCLUDED
+#define BOOST_RANGE_JOIN_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/detail/join_iterator.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<class SinglePassRange1, class SinglePassRange2>
+class joined_type
+{
+public:
+    typedef iterator_range<
+        range_detail::join_iterator<
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
+            BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
+        >
+    > type;
+};
+
+    } // namespace range_detail
+
+namespace range
+{
+
+template<class SinglePassRange1, class SinglePassRange2>
+class joined_range
+    : public range_detail::joined_type<SinglePassRange1, SinglePassRange2>::type
+{
+    typedef range_detail::join_iterator<
+        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
+        BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
+        > iterator_t;
+
+    typedef BOOST_DEDUCED_TYPENAME range_detail::joined_type<
+                    SinglePassRange1, SinglePassRange2>::type base_t;
+public:
+    joined_range(SinglePassRange1& rng1, SinglePassRange2& rng2)
+        : base_t(
+            iterator_t(rng1, rng2, range_detail::join_iterator_begin_tag()),
+            iterator_t(rng1, rng2, range_detail::join_iterator_end_tag())
+        )
+    {
+    }
+};
+
+template<class SinglePassRange1, class SinglePassRange2>
+joined_range<const SinglePassRange1, const SinglePassRange2>
+join(const SinglePassRange1& r1, const SinglePassRange2& r2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return joined_range<const SinglePassRange1, const SinglePassRange2>(r1, r2);
+}
+
+template<class SinglePassRange1, class SinglePassRange2>
+joined_range<SinglePassRange1, SinglePassRange2>
+join(SinglePassRange1& r1, SinglePassRange2& r2)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+    return joined_range<SinglePassRange1, SinglePassRange2>(r1, r2);
+}
+
+} // namespace range
+
+using ::boost::range::joined_range;
+using ::boost::range::join;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/metafunctions.hpp b/include/boost/range/metafunctions.hpp
new file mode 100644
index 0000000..9dc59d0
--- /dev/null
+++ b/include/boost/range/metafunctions.hpp
@@ -0,0 +1,31 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_METAFUNCTIONS_HPP
+#define BOOST_RANGE_METAFUNCTIONS_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/has_range_iterator.hpp>
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/reverse_iterator.hpp>
+#include <boost/range/const_reverse_iterator.hpp>
+#include <boost/range/reverse_result_iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/category.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/pointer.hpp>
+
+#endif
diff --git a/include/boost/range/mfc.hpp b/include/boost/range/mfc.hpp
new file mode 100644
index 0000000..058e54e
--- /dev/null
+++ b/include/boost/range/mfc.hpp
@@ -0,0 +1,984 @@
+#ifndef BOOST_RANGE_MFC_HPP
+#define BOOST_RANGE_MFC_HPP
+
+
+
+
+// Boost.Range MFC Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <afx.h> // _MFC_VER
+
+
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+    #if (_MFC_VER < 0x0700) // dubious
+        #define BOOST_RANGE_MFC_NO_CPAIR
+    #endif
+#endif
+
+
+#if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+    #if (_MFC_VER < 0x0700) // dubious
+        #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
+    #endif
+#endif
+
+
+// A const collection of old MFC doesn't return const reference.
+//
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+    #if (_MFC_VER < 0x0700) // dubious
+        #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
+    #endif
+#endif
+
+
+
+
+// forward declarations
+//
+
+
+template< class Type, class ArgType >
+class CArray;
+
+template< class Type, class ArgType >
+class CList;
+
+template< class Key, class ArgKey, class Mapped, class ArgMapped >
+class CMap;
+
+template< class BaseClass, class PtrType >
+class CTypedPtrArray;
+
+template< class BaseClass, class PtrType >
+class CTypedPtrList;
+
+template< class BaseClass, class KeyPtrType, class MappedPtrType >
+class CTypedPtrMap;
+
+
+
+
+// extended customizations
+//
+
+
+#include <cstddef> // ptrdiff_t
+#include <utility> // pair
+#include <boost/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/atl.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/detail/microsoft.hpp>
+#include <boost/range/end.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/addressof.hpp>
+#include <afx.h> // legacy CString
+#include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
+#include <tchar.h>
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+    // mfc_ptr_array_iterator
+    //
+    // 'void **' is not convertible to 'void const **',
+    // so we define...
+    //
+
+    template< class ArrayT, class PtrType >
+    struct mfc_ptr_array_iterator;
+
+    template< class ArrayT, class PtrType >
+    struct mfc_ptr_array_iterator_super
+    {
+        typedef iterator_adaptor<
+            mfc_ptr_array_iterator<ArrayT, PtrType>,
+            std::ptrdiff_t, // Base!
+            PtrType,        // Value
+            random_access_traversal_tag,
+            use_default,
+            std::ptrdiff_t  // Difference
+        > type;
+    };
+
+    template< class ArrayT, class PtrType >
+    struct mfc_ptr_array_iterator :
+        mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
+    {
+    private:
+        typedef mfc_ptr_array_iterator self_t;
+        typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
+        typedef typename super_t::reference ref_t;
+
+    public:
+        explicit mfc_ptr_array_iterator()
+        { }
+
+        explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
+            super_t(index), m_parr(boost::addressof(arr))
+        { }
+
+    template< class, class > friend struct mfc_ptr_array_iterator;
+        template< class ArrayT_, class PtrType_ >
+        mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
+            super_t(other.base()), m_parr(other.m_parr)
+        { }
+
+    private:
+        ArrayT *m_parr;
+
+    friend class iterator_core_access;
+        ref_t dereference() const
+        {
+            BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
+            return *( m_parr->GetData() + this->base() );
+        }
+
+        bool equal(self_t const& other) const
+        {
+            BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
+            return this->base() == other.base();
+        }
+    };
+
+    struct mfc_ptr_array_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return Iterator(x, 0);
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(x, x.GetSize());
+        }
+    };
+
+
+    // arrays
+    //
+
+    template< >
+    struct customization< ::CByteArray > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef BYTE val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CDWordArray > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef DWORD val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CObArray > :
+        mfc_ptr_array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
+            typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CPtrArray > :
+        mfc_ptr_array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
+            typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CStringArray > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ::CString val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CUIntArray > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef UINT val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CWordArray > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef WORD val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    // lists
+    //
+
+    template< >
+    struct customization< ::CObList > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef list_iterator<X, ::CObject *> mutable_iterator;
+    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+            typedef list_iterator<X const, ::CObject const *> const_iterator;
+    #else
+            typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
+    #endif
+        };
+    };
+
+
+    template< >
+    struct customization< ::CPtrList > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef list_iterator<X, void *> mutable_iterator;
+    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+            typedef list_iterator<X const, void const *> const_iterator;
+    #else
+            typedef list_iterator<X const, void const * const, void const * const> const_iterator;
+    #endif
+        };
+    };
+
+
+    template< >
+    struct customization< ::CStringList > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ::CString val_t;
+
+            typedef list_iterator<X, val_t> mutable_iterator;
+    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+            typedef list_iterator<X const, val_t const> const_iterator;
+    #else
+            typedef list_iterator<X const, val_t const, val_t const> const_iterator;
+    #endif
+        };
+    };
+
+
+    // mfc_map_iterator
+    //
+
+    template< class MapT, class KeyT, class MappedT >
+    struct mfc_map_iterator;
+
+    template< class MapT, class KeyT, class MappedT >
+    struct mfc_map_iterator_super
+    {
+        typedef iterator_facade<
+            mfc_map_iterator<MapT, KeyT, MappedT>,
+            std::pair<KeyT, MappedT>,
+            forward_traversal_tag,
+            std::pair<KeyT, MappedT> const
+        > type;
+    };
+
+    template< class MapT, class KeyT, class MappedT >
+    struct mfc_map_iterator :
+        mfc_map_iterator_super<MapT, KeyT, MappedT>::type
+    {
+    private:
+        typedef mfc_map_iterator self_t;
+        typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
+        typedef typename super_t::reference ref_t;
+
+    public:
+        explicit mfc_map_iterator()
+        { }
+
+        explicit mfc_map_iterator(MapT const& map, POSITION pos) :
+            m_pmap(boost::addressof(map)), m_posNext(pos)
+        {
+            increment();
+        }
+
+        explicit mfc_map_iterator(MapT const& map) :
+            m_pmap(&map), m_pos(0) // end iterator
+        { }
+
+    template< class, class, class > friend struct mfc_map_iterator;
+        template< class MapT_, class KeyT_, class MappedT_>
+        mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
+            m_pmap(other.m_pmap),
+            m_pos(other.m_pos), m_posNext(other.m_posNext),
+            m_key(other.m_key), m_mapped(other.m_mapped)
+        { }
+
+    private:
+        MapT const *m_pmap;
+        POSITION m_pos, m_posNext;
+        KeyT m_key; MappedT m_mapped;
+
+    friend class iterator_core_access;
+        ref_t dereference() const
+        {
+            BOOST_ASSERT(m_pos != 0 && "out of range");
+            return std::make_pair(m_key, m_mapped);
+        }
+
+        void increment()
+        {
+            BOOST_ASSERT(m_pos != 0 && "out of range");
+
+            if (m_posNext == 0) {
+                m_pos = 0;
+                return;
+            }
+
+            m_pos = m_posNext;
+            m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
+        }
+
+        bool equal(self_t const& other) const
+        {
+            BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
+            return m_pos == other.m_pos;
+        }
+    };
+
+    struct mfc_map_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return Iterator(x, x.GetStartPosition());
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(x);
+        }
+    };
+
+
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+
+    // mfc_cpair_map_iterator
+    //
+    // used by ::CMap and ::CMapStringToString
+    //
+
+    template< class MapT, class PairT >
+    struct mfc_cpair_map_iterator;
+
+    template< class MapT, class PairT >
+    struct mfc_pget_map_iterator_super
+    {
+        typedef iterator_facade<
+            mfc_cpair_map_iterator<MapT, PairT>,
+            PairT,
+            forward_traversal_tag
+        > type;
+    };
+
+    template< class MapT, class PairT >
+    struct mfc_cpair_map_iterator :
+        mfc_pget_map_iterator_super<MapT, PairT>::type
+    {
+    private:
+        typedef mfc_cpair_map_iterator self_t;
+        typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
+        typedef typename super_t::reference ref_t;
+
+    public:
+        explicit mfc_cpair_map_iterator()
+        { }
+
+        explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
+            m_pmap(boost::addressof(map)), m_pp(pp)
+        { }
+
+    template< class, class > friend struct mfc_cpair_map_iterator;
+        template< class MapT_, class PairT_>
+        mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
+            m_pmap(other.m_pmap), m_pp(other.m_pp)
+        { }
+
+    private:
+        MapT  *m_pmap;
+        PairT *m_pp;
+
+    friend class iterator_core_access;
+        ref_t dereference() const
+        {
+            BOOST_ASSERT(m_pp != 0 && "out of range");
+            return *m_pp;
+        }
+
+        void increment()
+        {
+            BOOST_ASSERT(m_pp != 0 && "out of range");
+            m_pp = m_pmap->PGetNextAssoc(m_pp);
+        }
+
+        bool equal(self_t const& other) const
+        {
+            BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
+            return m_pp == other.m_pp;
+        }
+    };
+
+    struct mfc_cpair_map_functions
+    {
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            // Workaround:
+            // Assertion fails if empty.
+            // MFC document is wrong.
+    #if !defined(NDEBUG)
+            if (x.GetCount() == 0) 
+                return Iterator(x, 0);
+    #endif
+
+            return Iterator(x, x.PGetFirstAssoc());
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(x, 0);
+        }
+    };
+
+
+#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+
+    // maps
+    //
+
+    template< >
+    struct customization< ::CMapPtrToWord > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef void *key_t;
+            typedef WORD mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapPtrToPtr > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef void *key_t;
+            typedef void *mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapStringToOb > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ::CString key_t;
+            typedef ::CObject *mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapStringToPtr > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef ::CString key_t;
+            typedef void *mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapStringToString > :
+    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+        mfc_cpair_map_functions
+    #else
+        mfc_map_functions
+    #endif
+    {
+        template< class X >
+        struct meta
+        {
+    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+            typedef typename X::CPair pair_t;
+
+            typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
+            typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
+    #else
+            typedef ::CString key_t;
+            typedef ::CString mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+    #endif
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapWordToOb > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef WORD key_t;
+            typedef ::CObject *mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    template< >
+    struct customization< ::CMapWordToPtr > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef WORD key_t;
+            typedef void *mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    // templates
+    //
+
+    template< class Type, class ArgType >
+    struct customization< ::CArray<Type, ArgType> > :
+        array_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef Type val_t;
+
+            typedef val_t *mutable_iterator;
+            typedef val_t const *const_iterator;
+        };
+    };
+
+
+    template< class Type, class ArgType >
+    struct customization< ::CList<Type, ArgType> > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef Type val_t;
+
+            typedef list_iterator<X, val_t> mutable_iterator;
+    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+            typedef list_iterator<X const, val_t const> const_iterator;
+    #else
+            typedef list_iterator<X const, val_t const, val_t const> const_iterator;
+    #endif
+        };
+    };
+
+
+    template< class Key, class ArgKey, class Mapped, class ArgMapped >
+    struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
+    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+        mfc_cpair_map_functions
+    #else
+        mfc_map_functions
+    #endif
+    {
+        template< class X >
+        struct meta
+        {
+    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+            typedef typename X::CPair pair_t;
+
+            typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
+            typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
+    #else
+            typedef Key key_t;
+            typedef Mapped mapped_t;
+
+            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+    #endif            
+        };
+    };
+
+
+    template< class BaseClass, class PtrType >
+    struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
+    {
+        template< class X >
+        struct fun
+        {
+            typedef typename remove_pointer<PtrType>::type val_t;
+
+            typedef typename mpl::if_< is_const<X>,
+                val_t const,
+                val_t
+            >::type val_t_;
+
+            typedef val_t_ * const result_type;
+
+            template< class PtrType_ >
+            result_type operator()(PtrType_ p) const
+            {
+                return static_cast<result_type>(p);
+            }
+        };
+
+        template< class X >
+        struct meta
+        {
+            typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
+            typedef typename range_const_iterator<BaseClass>::type citer_t;
+
+            typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
+            typedef transform_iterator<fun<X const>, citer_t> const_iterator;
+        };
+
+        template< class Iterator, class X >
+        Iterator begin(X& x)
+        {
+            return Iterator(boost::begin<BaseClass>(x), fun<X>());
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return Iterator(boost::end<BaseClass>(x), fun<X>());
+        }
+    };
+
+
+    template< class BaseClass, class PtrType >
+    struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
+        list_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef typename remove_pointer<PtrType>::type val_t;
+
+            // not l-value
+            typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
+            typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
+        };
+    };
+
+
+    template< class BaseClass, class KeyPtrType, class MappedPtrType >
+    struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
+        mfc_map_functions
+    {
+        template< class X >
+        struct meta
+        {
+            typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
+            typedef mutable_iterator const_iterator;
+        };
+    };
+
+
+    // strings
+    //
+
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+    template< >
+    struct customization< ::CString >
+    {
+        template< class X >
+        struct meta
+        {
+            // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
+            typedef TCHAR *mutable_iterator;
+            typedef TCHAR const *const_iterator;
+        };
+
+        template< class Iterator, class X >
+        typename mutable_<Iterator, X>::type begin(X& x)
+        {
+            return x.GetBuffer(0);
+        }
+
+        template< class Iterator, class X >
+        Iterator begin(X const& x)
+        {
+            return x;
+        }
+
+        template< class Iterator, class X >
+        Iterator end(X& x)
+        {
+            return begin<Iterator>(x) + x.GetLength();
+        }
+    };
+
+#endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// range customizations
+//
+
+
+// arrays
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CByteArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CDWordArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CStringArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CUIntArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CWordArray
+)
+
+
+// lists
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CObList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CPtrList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CStringList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CObArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CPtrArray
+)
+
+
+// maps
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapPtrToWord
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapPtrToPtr
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapStringToOb
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapStringToPtr
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapStringToString
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapWordToOb
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMapWordToPtr
+)
+
+
+// templates
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CArray, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CList, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CMap, 4
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CTypedPtrArray, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CTypedPtrList, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+    boost::range_detail_microsoft::using_type_as_tag,
+    BOOST_PP_NIL, CTypedPtrMap, 3
+)
+
+
+// strings
+//
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+        boost::range_detail_microsoft::using_type_as_tag,
+        BOOST_PP_NIL, CString
+    )
+
+#endif
+
+
+
+
+#endif
diff --git a/include/boost/range/mfc_map.hpp b/include/boost/range/mfc_map.hpp
new file mode 100644
index 0000000..2cd42b4
--- /dev/null
+++ b/include/boost/range/mfc_map.hpp
@@ -0,0 +1,114 @@
+// Boost.Range library
+//
+//  Copyright Adam D. Walling 2012. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_MFC_MAP_HPP
+#define BOOST_RANGE_ADAPTOR_MFC_MAP_HPP
+
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+#include <boost/range/mfc.hpp>
+#include <boost/range/adaptor/map.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+        // CMap and CMapStringToString range iterators return CPair,
+        // which has a key and value member. Other MFC range iterators
+        // already return adapted std::pair objects. This allows usage
+        // of the map_keys and map_values range adaptors with CMap 
+        // and CMapStringToString
+        
+        // CPair has a VALUE value member, and a KEY key member; we will
+        // use VALUE& as the result_type consistent with CMap::operator[]
+        
+        // specialization for CMap 
+        template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
+        struct select_first< CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> >
+        {
+            typedef BOOST_DEDUCED_TYPENAME CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> map_type;
+            typedef BOOST_DEDUCED_TYPENAME range_reference<const map_type>::type argument_type;
+            typedef BOOST_DEDUCED_TYPENAME const KEY& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.key;
+            }
+        };
+
+        template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
+        struct select_second_mutable< CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> >
+        {
+            typedef BOOST_DEDUCED_TYPENAME CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> map_type;
+            typedef BOOST_DEDUCED_TYPENAME range_reference<map_type>::type argument_type;
+            typedef BOOST_DEDUCED_TYPENAME VALUE& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.value;
+            }
+        };
+
+        template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
+        struct select_second_const< CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> >
+        {
+            typedef BOOST_DEDUCED_TYPENAME CMap<KEY, ARG_KEY, VALUE, ARG_VALUE> map_type;
+            typedef BOOST_DEDUCED_TYPENAME range_reference<const map_type>::type argument_type;
+            typedef BOOST_DEDUCED_TYPENAME const VALUE& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.value;
+            }
+        };
+
+
+        // specialization for CMapStringToString
+        template<>
+        struct select_first< CMapStringToString >
+        {
+            typedef range_reference<const CMapStringToString>::type argument_type;
+            typedef const CString& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.key;
+            }
+        };
+
+        template<>
+        struct select_second_mutable< CMapStringToString >
+        {
+            typedef range_reference<CMapStringToString>::type argument_type;
+            typedef CString& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.value;
+            }
+        };
+
+        template<>
+        struct select_second_const< CMapStringToString >
+        {
+            typedef range_reference<const CMapStringToString>::type argument_type;
+            typedef const CString& result_type;
+
+            result_type operator()( argument_type r ) const
+            {
+                return r.value;
+            }
+        };
+    } // 'range_detail'
+} // 'boost'
+
+#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+#endif
diff --git a/include/boost/range/mutable_iterator.hpp b/include/boost/range/mutable_iterator.hpp
new file mode 100644
index 0000000..b924666
--- /dev/null
+++ b/include/boost/range/mutable_iterator.hpp
@@ -0,0 +1,79 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP
+#define BOOST_RANGE_MUTABLE_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#include <boost/range/range_fwd.hpp>
+#include <boost/range/detail/extract_optional_type.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+
+    //////////////////////////////////////////////////////////////////////////
+    // default
+    //////////////////////////////////////////////////////////////////////////
+    
+    namespace range_detail
+    {
+
+BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator )
+
+template< typename C >
+struct range_mutable_iterator
+        : range_detail::extract_iterator<
+            BOOST_DEDUCED_TYPENAME remove_reference<C>::type>
+{};
+
+//////////////////////////////////////////////////////////////////////////
+// pair
+//////////////////////////////////////////////////////////////////////////
+
+template< typename Iterator >
+struct range_mutable_iterator< std::pair<Iterator,Iterator> >
+{
+    typedef Iterator type;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// array
+//////////////////////////////////////////////////////////////////////////
+
+template< typename T, std::size_t sz >
+struct range_mutable_iterator< T[sz] >
+{
+    typedef T* type;
+};
+
+    } // namespace range_detail
+
+template<typename C, typename Enabler=void>
+struct range_mutable_iterator
+        : range_detail::range_mutable_iterator<
+            BOOST_DEDUCED_TYPENAME remove_reference<C>::type
+        >
+{
+};
+
+} // namespace boost
+
+#include <boost/range/detail/msvc_has_iterator_workaround.hpp>
+
+#endif
diff --git a/include/boost/range/numeric.hpp b/include/boost/range/numeric.hpp
new file mode 100644
index 0000000..d1510cd
--- /dev/null
+++ b/include/boost/range/numeric.hpp
@@ -0,0 +1,188 @@
+// Copyright 2009-2014 Neil Groves.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Copyright 2006 Thorsten Ottosen.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Copyright 2004 Eric Niebler.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//   Contains range-based versions of the numeric std algorithms
+//
+#if defined(_MSC_VER)
+    #pragma once
+#endif
+
+#ifndef BOOST_RANGE_NUMERIC_HPP
+#define BOOST_RANGE_NUMERIC_HPP
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/category.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/size.hpp>
+#include <numeric>
+
+
+namespace boost
+{
+    template<class SinglePassRange, class Value>
+    inline Value accumulate(const SinglePassRange& rng, Value init)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+            SinglePassRangeConcept<const SinglePassRange>));
+
+        return std::accumulate(boost::begin(rng), boost::end(rng), init);
+    }
+
+    template<class SinglePassRange, class Value, class BinaryOperation>
+    inline Value accumulate(const SinglePassRange& rng, Value init,
+                            BinaryOperation op)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange> ));
+
+        return std::accumulate(boost::begin(rng), boost::end(rng), init, op);
+    }
+
+    namespace range_detail
+    {
+        template<class SinglePassRange1, class SinglePassRange2>
+        inline bool inner_product_precondition(
+            const SinglePassRange1&,
+            const SinglePassRange2&,
+            std::input_iterator_tag,
+            std::input_iterator_tag)
+        {
+            return true;
+        }
+
+        template<class SinglePassRange1, class SinglePassRange2>
+        inline bool inner_product_precondition(
+            const SinglePassRange1& rng1,
+            const SinglePassRange2& rng2,
+            std::forward_iterator_tag,
+            std::forward_iterator_tag)
+        {
+            return boost::size(rng2) >= boost::size(rng1);
+        }
+
+    } // namespace range_detail
+
+    template<
+        class SinglePassRange1,
+        class SinglePassRange2,
+        class Value
+    >
+    inline Value inner_product(
+        const SinglePassRange1& rng1,
+        const SinglePassRange2& rng2,
+        Value                   init)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+            SinglePassRangeConcept<const SinglePassRange1>));
+
+        BOOST_RANGE_CONCEPT_ASSERT((
+            SinglePassRangeConcept<const SinglePassRange2>));
+
+        BOOST_ASSERT(
+            range_detail::inner_product_precondition(
+                    rng1, rng2,
+                    typename range_category<const SinglePassRange1>::type(),
+                    typename range_category<const SinglePassRange2>::type()));
+
+        return std::inner_product(
+            boost::begin(rng1), boost::end(rng1),
+            boost::begin(rng2), init);
+    }
+
+    template<
+        class SinglePassRange1,
+        class SinglePassRange2,
+        class Value,
+        class BinaryOperation1,
+        class BinaryOperation2
+    >
+    inline Value inner_product(
+        const SinglePassRange1& rng1,
+        const SinglePassRange2& rng2,
+        Value                   init,
+        BinaryOperation1        op1,
+        BinaryOperation2        op2)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange1>));
+
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange2>));
+
+        BOOST_ASSERT(
+            range_detail::inner_product_precondition(
+                rng1, rng2,
+                typename range_category<const SinglePassRange1>::type(),
+                typename range_category<const SinglePassRange2>::type()));
+
+        return std::inner_product(
+            boost::begin(rng1), boost::end(rng1),
+            boost::begin(rng2), init, op1, op2);
+    }
+
+    template<class SinglePassRange, class OutputIterator>
+    inline OutputIterator partial_sum(const SinglePassRange& rng,
+                                      OutputIterator result)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+        return std::partial_sum(boost::begin(rng), boost::end(rng), result);
+    }
+
+    template<class SinglePassRange, class OutputIterator, class BinaryOperation>
+    inline OutputIterator partial_sum(
+        const SinglePassRange&  rng,
+        OutputIterator          result,
+        BinaryOperation         op)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+        return std::partial_sum(boost::begin(rng), boost::end(rng), result, op);
+    }
+
+    template<class SinglePassRange, class OutputIterator>
+    inline OutputIterator adjacent_difference(
+        const SinglePassRange&  rng,
+        OutputIterator          result)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+        return std::adjacent_difference(boost::begin(rng), boost::end(rng),
+                                        result);
+    }
+
+    template<class SinglePassRange, class OutputIterator, class BinaryOperation>
+    inline OutputIterator adjacent_difference(
+        const SinglePassRange&  rng,
+        OutputIterator          result,
+        BinaryOperation         op)
+    {
+        BOOST_RANGE_CONCEPT_ASSERT((
+                SinglePassRangeConcept<const SinglePassRange>));
+
+        return std::adjacent_difference(boost::begin(rng), boost::end(rng),
+                                        result, op);
+    }
+
+} // namespace boost
+
+#endif
diff --git a/include/boost/range/pointer.hpp b/include/boost/range/pointer.hpp
new file mode 100644
index 0000000..b1e8dc5
--- /dev/null
+++ b/include/boost/range/pointer.hpp
@@ -0,0 +1,30 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_POINTER_TYPE_HPP
+#define BOOST_RANGE_POINTER_TYPE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+    template< class T >
+    struct range_pointer
+            : iterator_pointer< BOOST_DEDUCED_TYPENAME range_iterator<T>::type >
+    { };
+}
+
+#endif
diff --git a/include/boost/range/range_fwd.hpp b/include/boost/range/range_fwd.hpp
new file mode 100644
index 0000000..0e6e00f
--- /dev/null
+++ b/include/boost/range/range_fwd.hpp
@@ -0,0 +1,63 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2003-2004.
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_RANGE_FWD_HPP_INCLUDED
+#define BOOST_RANGE_RANGE_FWD_HPP_INCLUDED
+
+namespace boost
+{
+
+// Extension points
+    template<typename C, typename Enabler>
+    struct range_iterator;
+
+    template<typename C, typename Enabler>
+    struct range_mutable_iterator;
+
+    template<typename C, typename Enabler>
+    struct range_const_iterator;
+
+// Core classes
+    template<typename IteratorT>
+    class iterator_range;
+
+    template<typename ForwardRange>
+    class sub_range;
+
+// Meta-functions
+    template<typename T>
+    struct range_category;
+
+    template<typename T>
+    struct range_difference;
+
+    template<typename T>
+    struct range_pointer;
+
+    template<typename T>
+    struct range_reference;
+
+    template<typename T>
+    struct range_reverse_iterator;
+
+    template<typename T>
+    struct range_size;
+
+    template<typename T>
+    struct range_value;
+
+    template<typename T>
+    struct has_range_iterator;
+
+    template<typename T>
+    struct has_range_const_iterator;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/rbegin.hpp b/include/boost/range/rbegin.hpp
new file mode 100644
index 0000000..6d66de9
--- /dev/null
+++ b/include/boost/range/rbegin.hpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_RBEGIN_HPP
+#define BOOST_RANGE_RBEGIN_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/end.hpp>
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rbegin( C& c )
+{
+    return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::end( c ) );
+}
+
+#else
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rbegin( C& c )
+{
+    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+        iter_type;
+    return iter_type( boost::end( c ) );
+}
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+rbegin( const C& c )
+{
+    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+        iter_type;
+    return iter_type( boost::end( c ) );
+}
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
+const_rbegin( const T& r )
+{
+    return boost::rbegin( r );
+}
+
+} // namespace 'boost'
+
+#endif
+
diff --git a/include/boost/range/reference.hpp b/include/boost/range/reference.hpp
new file mode 100644
index 0000000..c664c38
--- /dev/null
+++ b/include/boost/range/reference.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REFERENCE_TYPE_HPP
+#define BOOST_RANGE_REFERENCE_TYPE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+    template< class T >
+    struct range_reference : iterator_reference< typename range_iterator<T>::type >
+    { };
+}
+
+#endif
diff --git a/include/boost/range/rend.hpp b/include/boost/range/rend.hpp
new file mode 100644
index 0000000..ef70407
--- /dev/null
+++ b/include/boost/range/rend.hpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REND_HPP
+#define BOOST_RANGE_REND_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rend( C& c )
+{
+    return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::begin( c ) );
+}
+
+#else
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rend( C& c )
+{
+    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+               iter_type;
+    return iter_type( boost::begin( c ) );
+}
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+rend( const C& c )
+{
+    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+        iter_type;
+    return iter_type( boost::begin( c ) );
+}
+
+#endif
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
+const_rend( const T& r )
+{
+    return boost::rend( r );
+}
+
+} // namespace 'boost'
+
+#endif
+
diff --git a/include/boost/range/result_iterator.hpp b/include/boost/range/result_iterator.hpp
new file mode 100644
index 0000000..54e343d
--- /dev/null
+++ b/include/boost/range/result_iterator.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_RESULT_ITERATOR_HPP
+#define BOOST_RANGE_RESULT_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+    //
+    // This interface is deprecated, use range_iterator<T>
+    //
+    
+    template< typename C >
+    struct range_result_iterator : range_iterator<C>
+    { };
+    
+} // namespace boost
+
+
+#endif
diff --git a/include/boost/range/reverse_iterator.hpp b/include/boost/range/reverse_iterator.hpp
new file mode 100644
index 0000000..0aa0130
--- /dev/null
+++ b/include/boost/range/reverse_iterator.hpp
@@ -0,0 +1,42 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REVERSE_ITERATOR_HPP
+#define BOOST_RANGE_REVERSE_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+
+
+namespace boost
+{
+    //////////////////////////////////////////////////////////////////////////
+    // default
+    //////////////////////////////////////////////////////////////////////////
+    
+    template< typename T >
+    struct range_reverse_iterator
+    {
+        typedef reverse_iterator< 
+            BOOST_DEDUCED_TYPENAME range_iterator<
+                BOOST_DEDUCED_TYPENAME remove_reference<T>::type>::type > type;
+    };
+    
+
+} // namespace boost
+
+
+#endif
diff --git a/include/boost/range/reverse_result_iterator.hpp b/include/boost/range/reverse_result_iterator.hpp
new file mode 100644
index 0000000..d375cfd
--- /dev/null
+++ b/include/boost/range/reverse_result_iterator.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
+#define BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+    //
+    // This interface is deprecated, use range_reverse_iterator<T>
+    //
+   
+    template< typename C >
+    struct range_reverse_result_iterator : range_reverse_iterator<C>
+    { };
+    
+} // namespace boost
+
+#endif
diff --git a/include/boost/range/size.hpp b/include/boost/range/size.hpp
new file mode 100644
index 0000000..7f38db8
--- /dev/null
+++ b/include/boost/range/size.hpp
@@ -0,0 +1,76 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SIZE_HPP
+#define BOOST_RANGE_SIZE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/detail/has_member_size.hpp>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/utility.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+        template<class SinglePassRange>
+        inline typename ::boost::enable_if<
+            has_member_size<SinglePassRange>,
+            typename range_size<const SinglePassRange>::type
+        >::type
+        range_calculate_size(const SinglePassRange& rng)
+        {
+            return rng.size();
+        }
+
+        template<class SinglePassRange>
+        inline typename disable_if<
+            has_member_size<SinglePassRange>,
+            typename range_size<const SinglePassRange>::type
+        >::type
+        range_calculate_size(const SinglePassRange& rng)
+        {
+            return std::distance(boost::begin(rng), boost::end(rng));
+        }
+    }
+
+    template<class SinglePassRange>
+    inline typename range_size<const SinglePassRange>::type
+    size(const SinglePassRange& rng)
+    {
+// Very strange things happen on some compilers that have the range concept
+// asserts disabled. This preprocessor condition is clearly redundant on a
+// working compiler but is vital for at least some compilers such as clang 4.2
+// but only on the Mac!
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
+        BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<SinglePassRange>));
+#endif
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+    !BOOST_WORKAROUND(__GNUC__, < 3) \
+    /**/
+        using namespace range_detail;
+#endif
+
+        return range_calculate_size(rng);
+    }
+
+} // namespace 'boost'
+
+#endif
diff --git a/include/boost/range/size_type.hpp b/include/boost/range/size_type.hpp
new file mode 100644
index 0000000..0a2ea81
--- /dev/null
+++ b/include/boost/range/size_type.hpp
@@ -0,0 +1,90 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SIZE_TYPE_HPP
+#define BOOST_RANGE_SIZE_TYPE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/has_range_iterator.hpp>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+    namespace detail
+    {
+
+        //////////////////////////////////////////////////////////////////////////
+        // default
+        //////////////////////////////////////////////////////////////////////////
+
+        template<typename T>
+        class has_size_type
+        {
+            typedef char no_type;
+            struct yes_type { char dummy[2]; };
+
+            template<typename C>
+            static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x);
+
+            template<typename C>
+            static no_type test(...);
+
+        public:
+            static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+        };
+
+        template<typename C, typename Enabler=void>
+        struct range_size_
+        {
+            typedef BOOST_DEDUCED_TYPENAME make_unsigned<
+                BOOST_DEDUCED_TYPENAME range_difference<C>::type
+            >::type type;
+        };
+
+        template<typename C>
+        struct range_size_<
+            C,
+            BOOST_DEDUCED_TYPENAME ::boost::enable_if<has_size_type<C>, void>::type
+        >
+        {
+            typedef BOOST_DEDUCED_TYPENAME C::size_type type;
+        };
+
+        template<typename C, bool B = range_detail::has_type< range_iterator<C> >::value>
+        struct range_size
+        { };
+
+        template<typename C>
+        struct range_size<C, true>
+          : range_size_<C>
+        { };
+    }
+
+    template< class T >
+    struct range_size :
+        detail::range_size<T>
+    { };
+
+} // namespace boost
+
+
+
+#endif
diff --git a/include/boost/range/sub_range.hpp b/include/boost/range/sub_range.hpp
new file mode 100644
index 0000000..d1c3b99
--- /dev/null
+++ b/include/boost/range/sub_range.hpp
@@ -0,0 +1,287 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009.
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SUB_RANGE_HPP
+#define BOOST_RANGE_SUB_RANGE_HPP
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) 
+    #pragma warning( push )
+    #pragma warning( disable : 4996 )
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/assert.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost
+{
+    namespace range_detail
+    {
+
+template<class ForwardRange, class TraversalTag>
+class sub_range_base
+        : public iterator_range<
+            BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+        >
+{
+    typedef iterator_range<
+        BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+    > base;
+
+protected:
+    typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
+
+public:
+    typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
+    typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
+    typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
+    typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
+    typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
+
+    sub_range_base()
+    {
+    }
+
+    template<class Iterator>
+    sub_range_base(Iterator first, Iterator last)
+        : base(first, last)
+    {
+    }
+
+    reference front()
+    {
+        return base::front();
+    }
+
+    const_reference front() const
+    {
+        return base::front();
+    }
+};
+
+template<class ForwardRange>
+class sub_range_base<ForwardRange, bidirectional_traversal_tag>
+        : public sub_range_base<ForwardRange, forward_traversal_tag>
+{
+    typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
+public:
+    sub_range_base()
+    {
+    }
+
+    template<class Iterator>
+    sub_range_base(Iterator first, Iterator last)
+        : base(first, last)
+    {
+    }
+
+    BOOST_DEDUCED_TYPENAME base::reference back()
+    {
+        return base::back();
+    }
+
+    BOOST_DEDUCED_TYPENAME base::const_reference back() const
+    {
+        return base::back();
+    }
+};
+
+template<class ForwardRange>
+class sub_range_base<ForwardRange, random_access_traversal_tag>
+        : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
+{
+    typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
+
+public:
+    sub_range_base()
+    {
+    }
+
+    template<class Iterator>
+    sub_range_base(Iterator first, Iterator last)
+        : base(first, last)
+    {
+    }
+
+    BOOST_DEDUCED_TYPENAME base::reference
+    operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
+    {
+        return this->begin()[n];
+    }
+
+    BOOST_DEDUCED_TYPENAME base::const_reference
+    operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
+    {
+        return this->begin()[n];
+    }
+};
+
+    } // namespace range_detail
+
+    template<class ForwardRange>
+    class sub_range
+        : public range_detail::sub_range_base<
+                ForwardRange,
+                BOOST_DEDUCED_TYPENAME iterator_traversal<
+                    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+                >::type
+            >
+    {
+        typedef BOOST_DEDUCED_TYPENAME range_iterator<
+            ForwardRange
+        >::type iterator_t;
+
+        typedef range_detail::sub_range_base<
+            ForwardRange,
+            BOOST_DEDUCED_TYPENAME iterator_traversal<
+                BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+            >::type
+        > base;
+
+        typedef BOOST_DEDUCED_TYPENAME base::impl impl;
+
+    protected:
+        typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
+
+    private:
+        template<class Source>
+        struct is_compatible_range
+            : is_convertible<
+                BOOST_DEDUCED_TYPENAME mpl::eval_if<
+                    has_range_iterator<Source>,
+                    range_iterator<Source>,
+                    mpl::identity<void>
+                >::type,
+                BOOST_DEDUCED_TYPENAME base::iterator
+            >
+        {
+        };
+
+    public:
+        sub_range()
+        { }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) 
+        sub_range(const sub_range& r)
+            : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
+                   impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
+        { }  
+#endif
+
+        template< class ForwardRange2 >
+        sub_range(
+            ForwardRange2& r,
+            BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                is_compatible_range<ForwardRange2>
+            >::type* = 0
+        )
+        : base(impl::adl_begin(r), impl::adl_end(r))
+        {
+        }
+
+        template< class ForwardRange2 >
+        sub_range(
+            const ForwardRange2& r,
+            BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+                is_compatible_range<const ForwardRange2>
+            >::type* = 0
+        )
+        : base(impl::adl_begin(r), impl::adl_end(r))
+        {
+        }
+
+        BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
+        {
+            return base::begin();
+        }
+
+        BOOST_DEDUCED_TYPENAME base::iterator begin()
+        {
+            return base::begin();
+        }
+
+        BOOST_DEDUCED_TYPENAME base::const_iterator end() const
+        {
+            return base::end();
+        }
+
+        BOOST_DEDUCED_TYPENAME base::iterator end()
+        {
+            return base::end();
+        }
+
+        template< class Iter >
+        sub_range( Iter first, Iter last ) :
+            base( first, last )
+        { }
+
+        template<class ForwardRange2>
+        BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+            is_compatible_range<ForwardRange2>,
+            sub_range&
+        >::type
+        operator=(ForwardRange2& r)
+        {
+            iterator_range_::operator=( r );
+            return *this;
+        }
+
+        template<class ForwardRange2>
+        BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+            is_compatible_range<const ForwardRange2>,
+            sub_range&
+        >::type
+        operator=( const ForwardRange2& r )
+        {
+            iterator_range_::operator=( r );
+            return *this;
+        }   
+
+        sub_range& operator=( const sub_range& r )
+        {
+            iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
+            return *this;            
+        }
+        
+        sub_range& advance_begin(
+            BOOST_DEDUCED_TYPENAME base::difference_type n)
+        {
+            std::advance(this->m_Begin, n);
+            return *this;
+        }
+        
+        sub_range& advance_end(
+            BOOST_DEDUCED_TYPENAME base::difference_type n)
+        {
+            std::advance(this->m_End, n);
+            return *this;
+        }
+    };
+
+} // namespace 'boost'
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) 
+    #pragma warning( pop )
+#endif
+
+#endif
+
diff --git a/include/boost/range/traversal.hpp b/include/boost/range/traversal.hpp
new file mode 100644
index 0000000..237b3e8
--- /dev/null
+++ b/include/boost/range/traversal.hpp
@@ -0,0 +1,31 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_TRAVERSAL_HPP
+#define BOOST_RANGE_TRAVERSAL_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+    template<typename SinglePassRange>
+    struct range_traversal
+        : iterator_traversal<typename range_iterator<SinglePassRange>::type>
+    {
+    };
+}
+
+#endif
diff --git a/include/boost/range/value_type.hpp b/include/boost/range/value_type.hpp
new file mode 100644
index 0000000..5a3187e
--- /dev/null
+++ b/include/boost/range/value_type.hpp
@@ -0,0 +1,30 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_VALUE_TYPE_HPP
+#define BOOST_RANGE_VALUE_TYPE_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+    template< class T >
+    struct range_value : iterator_value< typename range_iterator<T>::type >
+    { };
+}
+
+#endif
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..29b7f42
--- /dev/null
+++ b/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <title>Boost.Range Documentation</title>
+    <meta http-equiv="Content-Type" content="test/html; charset=us-ascii" />
+    <meta http-equiv="refresh" content="0; URL=doc/html/index.html" />
+</head>
+
+<body>
+    Automatic redirection failed, please go to <a href="doc/html/index.html">doc/html/index.html</a>
+</body>
+</html>
+<!-- Copyright Neil Groves 2010. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..9e2be20
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,16 @@
+{
+    "key": "range",
+    "name": "Range",
+    "authors": [
+        "Niel Groves",
+        "Thorsten Ottosen"
+    ],
+    "description": "A new infrastructure for generic algorithms that builds on top of the new iterator concepts.",
+    "category": [
+        "Algorithms"
+    ],
+    "maintainers": [
+        "Neil Groves <neilgroves -at- googlemail.com>",
+        "Nathan Ridge <zeratul976 -at- hotmail.com>"
+    ]
+}
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
new file mode 100644
index 0000000..b195926
--- /dev/null
+++ b/test/Jamfile.v2
@@ -0,0 +1,225 @@
+# Boost.Range library
+#
+#  Copyright Neil Groves 2009
+#  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+#  distribution is subject to the Boost Software License, Version
+#  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+#  http://www.boost.org/LICENSE_1_0.txt)
+#
+# For more information, see http://www.boost.org/libs/range/
+#
+
+# bring in rules for testing
+import testing ;
+
+project
+    : requirements
+        <library>/boost/test//boost_unit_test_framework/
+        <library>/boost/regex//boost_regex/
+        <link>static
+        <threading>multi
+    ;
+
+rule range-test ( name : includes * )
+{
+    return [
+        run $(name).cpp /boost/test//boost_unit_test_framework /boost/regex//boost_regex/<link>static
+        :
+        :
+        : <toolset>gcc:<cxxflags>"-Wall -Wunused "
+        ] ;
+}
+
+test-suite range :
+    [ compile-fail compile_fail/iterator_range1.cpp ]
+    [ compile-fail compile_fail/adaptor/adjacent_filtered_concept.cpp ]
+    [ compile-fail compile_fail/adaptor/adjacent_filtered_concept2.cpp ]
+    [ compile-fail compile_fail/adaptor/adjacent_filtered_concept3.cpp ]
+    [ compile-fail compile_fail/adaptor/adjacent_filtered_concept4.cpp ]
+    [ compile-fail compile_fail/adaptor/copied_concept.cpp ]
+    [ compile-fail compile_fail/adaptor/copied_concept2.cpp ]
+    [ compile-fail compile_fail/adaptor/copied_concept3.cpp ]
+    [ compile-fail compile_fail/adaptor/copied_concept4.cpp ]
+    [ compile-fail compile_fail/adaptor/reversed_concept.cpp ]
+    [ compile-fail compile_fail/adaptor/reversed_concept2.cpp ]
+    [ compile-fail compile_fail/adaptor/reversed_concept3.cpp ]
+    [ compile-fail compile_fail/adaptor/reversed_concept4.cpp ]
+    [ compile-fail compile_fail/adaptor/sliced_concept.cpp ]
+    [ compile-fail compile_fail/adaptor/sliced_concept2.cpp ]
+    [ compile-fail compile_fail/adaptor/sliced_concept3.cpp ]
+    [ compile-fail compile_fail/adaptor/sliced_concept4.cpp ]
+    [ compile-fail compile_fail/adaptor/uniqued_concept.cpp ]
+    [ compile-fail compile_fail/adaptor/uniqued_concept2.cpp ]
+    [ compile-fail compile_fail/adaptor/uniqued_concept3.cpp ]
+    [ compile-fail compile_fail/adaptor/uniqued_concept4.cpp ]
+    [ range-test adaptor_test/adjacent_filtered ]
+    [ range-test adaptor_test/chained ]
+    [ range-test adaptor_test/copied ]
+    [ range-test adaptor_test/filtered ]
+    [ range-test adaptor_test/indexed ]
+    [ range-test adaptor_test/indirected ]
+    [ range-test adaptor_test/map ]
+    [ range-test adaptor_test/ref_unwrapped ]
+    [ range-test adaptor_test/ref_unwrapped_example ]
+    [ range-test adaptor_test/replaced ]
+    [ range-test adaptor_test/replaced_if ]
+    [ range-test adaptor_test/reversed ]
+    [ range-test adaptor_test/sliced ]
+    [ range-test adaptor_test/strided ]
+    [ range-test adaptor_test/strided2 ]
+    [ range-test adaptor_test/ticket_6742_transformed_c4789_warning ]
+    [ range-test adaptor_test/ticket_8676_sliced_transformed ]
+    [ range-test adaptor_test/ticket_9519_strided_reversed ]
+    [ range-test adaptor_test/tokenized ]
+    [ range-test adaptor_test/transformed ]
+    [ range-test adaptor_test/type_erased ]
+    [ range-test adaptor_test/type_erased_abstract ]
+    [ range-test adaptor_test/type_erased_brackets ]
+    [ range-test adaptor_test/type_erased_mix_values ]
+    [ range-test adaptor_test/type_erased_tparam_conv ]
+    [ range-test adaptor_test/type_erased_single_pass ]
+    [ range-test adaptor_test/type_erased_forward ]
+    [ range-test adaptor_test/type_erased_bidirectional ]
+    [ range-test adaptor_test/type_erased_random_access ]
+    [ range-test adaptor_test/uniqued ]
+    [ range-test adaptor_test/adjacent_filtered_example ]
+    [ range-test adaptor_test/copied_example ]
+    [ range-test adaptor_test/filtered_example ]
+    [ range-test adaptor_test/formatted ]
+    [ range-test adaptor_test/formatted_example ]
+    [ range-test adaptor_test/indexed_example ]
+    [ range-test adaptor_test/indirected_example ]
+    [ range-test adaptor_test/map_keys_example ]
+    [ range-test adaptor_test/map_values_example ]
+    [ range-test adaptor_test/replaced_example ]
+    [ range-test adaptor_test/replaced_if_example ]
+    [ range-test adaptor_test/reversed_example ]
+    [ range-test adaptor_test/sliced_example ]
+    [ range-test adaptor_test/strided_example ]
+    [ range-test adaptor_test/transformed_example ]
+    [ range-test adaptor_test/tokenized_example ]
+    [ range-test adaptor_test/type_erased_example ]
+    [ range-test adaptor_test/uniqued_example ]
+    [ range-test algorithm_test/adjacent_find ]
+    [ range-test algorithm_test/binary_search ]
+    [ range-test algorithm_test/copy ]
+    [ range-test algorithm_test/copy_backward ]
+    [ range-test algorithm_test/count ]
+    [ range-test algorithm_test/count_if ]
+    [ range-test algorithm_test/equal ]
+    [ range-test algorithm_test/equal_range ]
+    [ range-test algorithm_test/fill ]
+    [ range-test algorithm_test/find ]
+    [ range-test algorithm_test/find_if ]
+    [ range-test algorithm_test/find_end ]
+    [ range-test algorithm_test/find_first_of ]
+    [ range-test algorithm_test/for_each ]
+    [ range-test algorithm_test/generate ]
+    [ range-test algorithm_test/heap ]
+    [ range-test algorithm_test/includes ]
+    [ range-test algorithm_test/inplace_merge ]
+    [ range-test algorithm_test/lexicographical_compare ]
+    [ range-test algorithm_test/lower_bound ]
+    [ range-test algorithm_test/max_element ]
+    [ range-test algorithm_test/merge ]
+    [ range-test algorithm_test/min_element ]
+    [ range-test algorithm_test/mismatch ]
+    [ range-test algorithm_test/next_permutation ]
+    [ range-test algorithm_test/nth_element ]
+    [ range-test algorithm_test/partial_sort ]
+    [ range-test algorithm_test/partition ]
+    [ range-test algorithm_test/prev_permutation ]
+    [ range-test algorithm_test/random_shuffle ]
+    [ range-test algorithm_test/remove ]
+    [ range-test algorithm_test/remove_copy ]
+    [ range-test algorithm_test/remove_copy_if ]
+    [ range-test algorithm_test/remove_if ]
+    [ range-test algorithm_test/replace ]
+    [ range-test algorithm_test/replace_copy ]
+    [ range-test algorithm_test/replace_copy_if ]
+    [ range-test algorithm_test/replace_if ]
+    [ range-test algorithm_test/reverse ]
+    [ range-test algorithm_test/reverse_copy ]
+    [ range-test algorithm_test/rotate ]
+    [ range-test algorithm_test/rotate_copy ]
+    [ range-test algorithm_test/search ]
+    [ range-test algorithm_test/search_n ]
+    [ range-test algorithm_test/set_difference ]
+    [ range-test algorithm_test/set_intersection ]
+    [ range-test algorithm_test/set_symmetric_difference ]
+    [ range-test algorithm_test/set_union ]
+    [ range-test algorithm_test/sort ]
+    [ range-test algorithm_test/stable_partition ]
+    [ range-test algorithm_test/stable_sort ]
+    [ range-test algorithm_test/swap_ranges ]
+    [ range-test algorithm_test/transform ]
+    [ range-test algorithm_test/unique ]
+    [ range-test algorithm_test/unique_copy ]
+    [ range-test algorithm_test/upper_bound ]
+    [ range-test algorithm_ext_test/copy_n ]
+    [ range-test algorithm_ext_test/erase ]
+    [ range-test algorithm_ext_test/for_each_ext ]
+    [ range-test algorithm_ext_test/insert ]
+    [ range-test algorithm_ext_test/iota ]
+    [ range-test algorithm_ext_test/is_sorted ]
+    [ range-test algorithm_ext_test/overwrite ]
+    [ range-test algorithm_ext_test/push_back ]
+    [ range-test algorithm_ext_test/push_front ]
+    [ range-test adl_conformance ]
+    [ range-test adl_conformance_no_using ]
+    [ range-test algorithm ]
+    [ range-test algorithm_example ]
+    [ range-test array ]
+#    [ range-test atl : <include>$(VC71_ROOT)/atlmfc/include ]
+    [ range-test begin ]
+    [ range-test category ]
+    [ range-test combine ]
+    [ range-test compat2 ]
+    [ range-test compat3 ]
+    [ range-test const_iterator ]
+    [ range-test const_ranges ]
+    [ range-test const_reverse_iterator ]
+    [ range-test counting_range ]
+    [ range-test difference_type ]
+    [ range-test end ]
+    [ range-test extension_mechanism ]
+    [ range-test extension_size ]
+    [ range-test has_range_iterator ]
+    [ range-test irange ]
+    [ range-test istream_range ]
+    [ range-test iterator ]
+    [ range-test iterator_ext ]
+    [ range-test iterator_pair ]
+    [ range-test iterator_range ]
+    [ range-test iterator_range_drop ]
+    [ range-test iterator_range_equality_bug ]
+    [ range-test iterator_range_hash ]
+    [ range-test iterator_range_variant ]
+#       [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
+    [ range-test join ]
+    [ range-test mutable_iterator ]
+    [ range-test partial_workaround ]
+    [ range-test pointer ]
+    [ range-test pointer_as_iterator ]
+    [ range-test reference ]
+    [ range-test result_iterator ]
+    [ range-test reverse_iterator ]
+    [ range-test reverse_result_iterator ]
+    [ range-test reversible_range ]
+    [ range-test size_type ]
+    [ range-test std_container ]
+    [ range-test string ]
+    [ range-test sub_range ]
+    [ range-test ticket_5486 ]
+    [ range-test ticket_5544_terminate_irange ]
+    [ range-test ticket_5547 ]
+    [ range-test ticket_5556_is_sorted_namespace ]
+    [ range-test ticket_5811_indirected_optional ]
+    [ range-test ticket_6715_iterator_range_equality ]
+    [ range-test ticket_6944 ]
+    [ range-test ticket_10336 ]
+    [ range-test value_type ]
+    ;
+
+# `quick` target (for CI)
+alias quick : std_container ;
diff --git a/test/adaptor_test/adjacent_filtered.cpp b/test/adaptor_test/adjacent_filtered.cpp
new file mode 100644
index 0000000..48025ab
--- /dev/null
+++ b/test/adaptor_test/adjacent_filtered.cpp
@@ -0,0 +1,110 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void adjacent_filtered_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            // This is my preferred syntax using the | operator.
+            std::vector< value_t > test_result1
+                = boost::copy_range< std::vector< value_t > >(
+                c | adjacent_filtered(std::not_equal_to< value_t >()));
+
+            // This is an alternative syntax preferred by some.
+            std::vector< value_t > test_result2
+                = boost::copy_range< std::vector< value_t > >(
+                    adaptors::adjacent_filter(c, std::not_equal_to< value_t >()));
+
+            // Calculate the reference result.
+            std::vector< value_t > reference_result;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
+            value_t prev_v = value_t();
+            for (iter_t it = c.begin(); it != c.end(); ++it)
+            {
+                if (it == c.begin())
+                {
+                    reference_result.push_back(*it);
+                }
+                else if (*it != prev_v)
+                {
+                    reference_result.push_back(*it);
+                }
+                prev_v = *it;
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result1.begin(),
+                                           test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result2.begin(),
+                                           test_result2.end() );
+        }
+
+        template< class Collection >
+        void adjacent_filtered_test_impl()
+        {
+            using namespace boost::assign;
+
+            Collection c;
+
+            // test empty collection
+            adjacent_filtered_test_impl(c);
+
+            // test one element;
+            c += 1;
+            adjacent_filtered_test_impl(c);
+
+            // test many elements;
+            c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
+            adjacent_filtered_test_impl(c);
+        }
+
+        void adjacent_filtered_test()
+        {
+            adjacent_filtered_test_impl< std::vector< int > >();
+            adjacent_filtered_test_impl< std::list< int > >();
+            adjacent_filtered_test_impl< std::set< int > >();
+            adjacent_filtered_test_impl< std::multiset< int > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.adjacent_filtered" );
+
+    test->add( BOOST_TEST_CASE( &boost::adjacent_filtered_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/adjacent_filtered_example.cpp b/test/adaptor_test/adjacent_filtered_example.cpp
new file mode 100644
index 0000000..83f7a8a
--- /dev/null
+++ b/test/adaptor_test/adjacent_filtered_example.cpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[adjacent_filtered_example
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <functional>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace
+{
+void adjacent_filtered_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::vector<int> input;
+    input += 1,1,2,2,2,3,4,5,6;
+
+    boost::copy(
+        input | adjacent_filtered(std::not_equal_to<int>()),
+        std::ostream_iterator<int>(std::cout, ","));
+    
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 1,2,3,4,5,6;
+
+    std::vector<int> test;
+    boost::push_back(test, input | adjacent_filtered(std::not_equal_to<int>()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.adjacent_filtered_example" );
+
+    test->add( BOOST_TEST_CASE( &adjacent_filtered_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/chained.cpp b/test/adaptor_test/chained.cpp
new file mode 100644
index 0000000..1b756c9
--- /dev/null
+++ b/test/adaptor_test/chained.cpp
@@ -0,0 +1,117 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Credits:
+//  Jurgen Hunold provided a test case that demonstrated that the range adaptors
+//  were producing iterators that were not default constructible. This became
+//  symptomatic after enabling concept checking assertions. This test is a
+//  lightly modified version of his supplied code to ensure that his use case
+//  never breaks again. (hopefully!)
+//
+
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/bind.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+#include <set>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+class foo
+{
+public:
+    static foo from_string(const std::string& source)
+    {
+        foo f;
+        f.m_valid = true;
+        f.m_value = 0u;
+        for (std::string::const_iterator it = source.begin();
+             it != source.end(); ++it)
+        {
+            f.m_value += *it;
+            if ((*it < 'a') || (*it > 'z'))
+                f.m_valid = false;
+        }
+        return f;
+    }
+    bool is_valid() const
+    {
+        return m_valid;
+    }
+    bool operator<(const foo& other) const
+    {
+        return m_value < other.m_value;
+    }
+    bool operator==(const foo& other) const
+    {
+        return m_value == other.m_value && m_valid == other.m_valid;
+    }
+    bool operator!=(const foo& other) const
+    {
+        return !operator==(other);
+    }
+
+    friend inline std::ostream& operator<<(std::ostream& out, const foo& obj)
+    {
+        out << "{value=" << obj.m_value
+            << ", valid=" << std::boolalpha << obj.m_valid << "}\n";
+        return out;
+    }
+
+private:
+    boost::uint64_t m_value;
+    bool m_valid;
+};
+
+void chained_adaptors_test()
+{
+    std::vector<std::string> sep;
+
+    sep.push_back("AB");
+    sep.push_back("ab");
+    sep.push_back("aghj");
+
+    std::set<foo> foos;
+
+    boost::copy(sep
+        | boost::adaptors::transformed(boost::bind(&foo::from_string, _1))
+        | boost::adaptors::filtered(boost::bind(&foo::is_valid, _1)),
+        std::inserter(foos, foos.end()));
+
+    std::vector<foo> reference;
+    reference.push_back(foo::from_string("ab"));
+    reference.push_back(foo::from_string("aghj"));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                foos.begin(), foos.end());
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.chained adaptors" );
+
+    test->add(BOOST_TEST_CASE( boost_range_test::chained_adaptors_test));
+
+    return test;
+}
diff --git a/test/adaptor_test/copied.cpp b/test/adaptor_test/copied.cpp
new file mode 100644
index 0000000..93f1cb7
--- /dev/null
+++ b/test/adaptor_test/copied.cpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/copied.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+
+#include <algorithm>
+#include <deque>
+#include <string>
+#include <vector>
+#include <boost/range/algorithm_ext.hpp>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void copied_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            // This is my preferred syntax using the | operator.
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | copied(0u, c.size()));
+
+            // This is the alternative syntax preferred by some.
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, adaptors::copy(c, 0u, c.size()));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test_result1.begin(), test_result1.end(),
+                                           c.begin(), c.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test_result2.begin(), test_result2.end(),
+                                           c.begin(), c.end() );
+        }
+
+        template< class Container >
+        void copied_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // test empty collection
+            copied_test_impl(c);
+
+            // test one element
+            c += 1;
+            copied_test_impl(c);
+
+            // test many elements
+            c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
+            copied_test_impl(c);
+        }
+
+        void copied_test()
+        {
+            copied_test_impl< std::vector< int > >();
+            copied_test_impl< std::deque< int > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.copied" );
+
+    test->add( BOOST_TEST_CASE( &boost::copied_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/copied_example.cpp b/test/adaptor_test/copied_example.cpp
new file mode 100644
index 0000000..c1d0e31
--- /dev/null
+++ b/test/adaptor_test/copied_example.cpp
@@ -0,0 +1,64 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[copied_example
+#include <boost/range/adaptor/copied.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace
+{
+void copied_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9,10;
+
+    boost::copy(
+        input | copied(1, 5),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 2,3,4,5;
+
+    std::vector<int> test;
+    boost::push_back(test, input | copied(1, 5));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.copied_example" );
+
+    test->add( BOOST_TEST_CASE( &copied_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/filtered.cpp b/test/adaptor_test/filtered.cpp
new file mode 100644
index 0000000..be34872
--- /dev/null
+++ b/test/adaptor_test/filtered.cpp
@@ -0,0 +1,197 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/filtered.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+#include <sstream>
+
+namespace boost
+{
+    namespace
+    {
+        struct always_false_pred
+        {
+            template< class T1 >
+            bool operator()(T1) const { return false; }
+        };
+
+        struct always_true_pred
+        {
+            template< class T1 >
+            bool operator()(T1) const { return true; }
+        };
+
+        struct is_even
+        {
+            template< class IntegerT >
+            bool operator()( IntegerT x ) const { return x % 2 == 0; }
+        };
+
+        struct is_odd
+        {
+            template< class IntegerT >
+            bool operator()( IntegerT x ) const { return x % 2 != 0; }
+        };
+
+        struct lambda_init
+        {
+        };
+
+        struct lambda
+        {
+            lambda(const lambda_init& init) {}
+            lambda(const lambda& rhs) {}
+
+            template< class T1 >
+            bool operator()(T1) const { return false; }
+
+        private:
+            lambda() {}
+            lambda& operator=(const lambda& rhs) { return *this; }
+        };
+
+        template< class Container, class Pred >
+        void filtered_test_impl( Container& c, Pred pred )
+        {
+            using namespace boost::adaptors;
+
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            // This is my preferred syntax using the | operator.
+            std::vector< value_t > test_result1;
+            boost::push_back(test_result1, c | filtered(pred));
+
+            // This is an alternative syntax preferred by some.
+            std::vector< value_t > test_result2;
+            boost::push_back(test_result2, adaptors::filter(c, pred));
+
+            // Calculate the reference result.
+            std::vector< value_t > reference_result;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
+            for (iter_t it = c.begin(); it != c.end(); ++it)
+            {
+                if (pred(*it))
+                    reference_result.push_back(*it);
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result1.begin(),
+                                           test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result2.begin(),
+                                           test_result2.end() );
+        }
+
+        template< class Rng >
+        void check_copy_assign(Rng r)
+        {
+            Rng r2 = r;
+            r2 = r;
+        }
+
+        template< class Container, class Pred >
+        void filtered_range_copy_assign(Container& c, Pred pred)
+        {
+            using namespace boost::adaptors;
+            check_copy_assign(c | filtered(pred));
+            check_copy_assign(adaptors::filter(c, pred));
+        }
+
+        template< class Container, class Pred, class PredInit >
+        void filtered_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+            PredInit init;
+            Pred pred(init);
+
+            // test empty container
+            filtered_test_impl(c, pred);
+
+            // test one element
+            c += 1;
+            filtered_test_impl(c, pred);
+
+            // test many elements
+            c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
+            filtered_test_impl(c, pred);
+
+            // test the range and iterator are copy assignable
+            filtered_range_copy_assign(c, pred);
+        }
+
+        template< class Container >
+        void filtered_test_all_predicates()
+        {
+            filtered_test_impl< Container, always_false_pred, always_false_pred >();
+            filtered_test_impl< Container, always_true_pred, always_true_pred >();
+            filtered_test_impl< Container, is_odd, is_odd >();
+            filtered_test_impl< Container, is_even, is_even >();
+            filtered_test_impl< Container, lambda, lambda_init >();
+        }
+
+        void ticket_10988_single_pass()
+        {
+            std::vector<int> v;
+            std::string str("0 1 2 3 4 5");
+            std::istringstream in(str);
+
+            boost::push_back(v,
+                boost::make_iterator_range(
+                    std::istream_iterator<int>(in),
+                    std::istream_iterator<int>())
+                | boost::adaptors::filtered(is_even()));
+
+            std::vector<int> reference;
+            for (int i = 0; i < 6; i += 2)
+            {
+                reference.push_back(i);
+            }
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                v.begin(), v.end());
+        }
+
+        void filtered_test()
+        {
+            filtered_test_all_predicates< std::vector< int > >();
+            filtered_test_all_predicates< std::list< int > >();
+            filtered_test_all_predicates< std::set< int > >();
+            filtered_test_all_predicates< std::multiset< int > >();
+            ticket_10988_single_pass();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.filtered" );
+
+    test->add( BOOST_TEST_CASE( &boost::filtered_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/filtered_example.cpp b/test/adaptor_test/filtered_example.cpp
new file mode 100644
index 0000000..e16d0af
--- /dev/null
+++ b/test/adaptor_test/filtered_example.cpp
@@ -0,0 +1,71 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[filtered_example
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+//->    
+struct is_even
+{
+    bool operator()( int x ) const { return x % 2 == 0; }
+};
+
+//<-
+void filtered_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9;
+
+    boost::copy(
+        input | filtered(is_even()),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 2,4,6,8;
+
+    std::vector<int> test;
+    boost::push_back(test, input | filtered(is_even()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.filtered_example" );
+
+    test->add( BOOST_TEST_CASE( &filtered_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/formatted.cpp b/test/adaptor_test/formatted.cpp
new file mode 100644
index 0000000..b6c1783
--- /dev/null
+++ b/test/adaptor_test/formatted.cpp
@@ -0,0 +1,311 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/formatted.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+    template<typename T>
+    std::string make_string(T x)
+    {
+        std::ostringstream result;
+        result << x;
+        return result.str();
+    }
+
+    template<typename T1, typename T2>
+    std::string make_string(T1 x, T2 y)
+    {
+        std::ostringstream result;
+        result << x << y;
+        return result.str();
+    }
+
+std::string reference_result(const std::vector<boost::int32_t>& v,
+                             const std::string& separator,
+                             const std::string& prefix,
+                             const std::string& postfix)
+{
+    std::ostringstream out;
+    out << prefix;
+    if (!v.empty())
+    {
+        out << v.at(0);
+        std::vector<boost::int32_t>::const_iterator it = v.begin();
+        for (++it; it != v.end(); ++it)
+        {
+            out << separator << *it;
+        }
+    }
+    out << postfix;
+
+    return out.str();
+}
+
+void test_formatted_0args_impl(const std::vector<boost::int32_t>& v)
+{
+    std::ostringstream out1;
+    out1 << '[' << (v | boost::adaptors::formatted()) << ']';
+    BOOST_CHECK_EQUAL(out1.str(), reference_result(v, ",", "[{", "}]"));
+
+    std::ostringstream out2;
+    out2 << '[' << boost::adaptors::format(v) << ']';
+    BOOST_CHECK_EQUAL(out2.str(), reference_result(v, ",", "[{", "}]"));
+
+    std::ostringstream out3;
+    out3 << (v | boost::adaptors::formatted());
+    BOOST_CHECK_EQUAL(out3.str(), reference_result(v, ",", "{", "}"));
+
+    std::ostringstream out4;
+    out4 << boost::adaptors::format(v);
+    BOOST_CHECK_EQUAL(out4.str(), reference_result(v, ",", "{", "}"));
+}
+
+template<typename Sep>
+void test_formatted_1arg_impl(
+        const std::vector<boost::int32_t>& v,
+        const Sep& sep)
+{
+    const std::string ref_sep = make_string(sep);
+    std::ostringstream out1;
+    out1 << '[' << (v | boost::adaptors::formatted(sep)) << ']';
+
+    BOOST_CHECK_EQUAL(out1.str(), reference_result(v, ref_sep, "[{", "}]"));
+
+    std::ostringstream out2;
+    out2 << '[' << boost::adaptors::format(v, sep) << ']';
+    BOOST_CHECK_EQUAL(out2.str(), reference_result(v, ref_sep, "[{", "}]"));
+
+    std::ostringstream out3;
+    out3 << (v | boost::adaptors::formatted(sep));
+    BOOST_CHECK_EQUAL(out3.str(), reference_result(v, ref_sep, "{", "}"));
+
+    std::ostringstream out4;
+    out4 << boost::adaptors::format(v, sep);
+    BOOST_CHECK_EQUAL(out4.str(), reference_result(v, ref_sep, "{", "}"));
+}
+
+void test_formatted_1arg_impl(const std::vector<boost::int32_t>& v)
+{
+    test_formatted_1arg_impl(v, ',');
+    test_formatted_1arg_impl(v, ' ');
+    test_formatted_1arg_impl<const char[3]>(v, ":?");
+}
+
+template<typename Sep, typename Prefix>
+void test_formatted_2args_impl(
+        const std::vector<boost::int32_t>& v,
+        const Sep& sep,
+        const Prefix& prefix
+)
+{
+    const std::string ref_sep = make_string(sep);
+
+    std::ostringstream out1;
+    out1 << '[' << (v | boost::adaptors::formatted(sep, prefix)) << ']';
+    BOOST_CHECK_EQUAL(
+        out1.str(),
+        reference_result(v, ref_sep, make_string('[', prefix), "}]"));
+
+    std::ostringstream out2;
+    out2 << '[' << boost::adaptors::format(v, sep, prefix) << ']';
+    BOOST_CHECK_EQUAL(
+        out2.str(),
+        reference_result(v, ref_sep, make_string('[', prefix), "}]"));
+
+    std::ostringstream out3;
+    out3 << (v | boost::adaptors::formatted(sep, prefix));
+    BOOST_CHECK_EQUAL(
+        out3.str(),
+        reference_result(v, ref_sep, make_string(prefix), "}"));
+
+    std::ostringstream out4;
+    out4 << boost::adaptors::format(v, sep, prefix);
+    BOOST_CHECK_EQUAL(
+        out4.str(),
+        reference_result(v, ref_sep, make_string(prefix), "}"));
+}
+
+void test_formatted_2args_impl(const std::vector<boost::int32_t>& v)
+{
+    test_formatted_2args_impl(v, ',', '{');
+    test_formatted_2args_impl(v, ':', '(');
+    test_formatted_2args_impl<char, const char[3]>(v, ',', "{!");
+    test_formatted_2args_impl<const char[3], char>(v, "#$", '{');
+    test_formatted_2args_impl<const char[3], const char[3]>(v, "#$", "{!");
+}
+
+template<typename Sep, typename Prefix, typename Postfix>
+void test_formatted_3args_impl(
+        const std::vector<boost::int32_t>& v,
+        const Sep& sep,
+        const Prefix& prefix,
+        const Postfix& postfix
+)
+{
+    const std::string ref_sep = make_string(sep);
+
+    std::ostringstream out1;
+    out1 << '[' << (v | boost::adaptors::formatted(sep, prefix, postfix))
+         << ']';
+    BOOST_CHECK_EQUAL(
+        out1.str(),
+        reference_result(v, ref_sep, make_string('[', prefix),
+                         make_string(postfix, ']')));
+}
+
+void test_formatted_3args_impl(const std::vector<boost::int32_t>& v)
+{
+    test_formatted_3args_impl(v, ',', '{', '}');
+    test_formatted_3args_impl(v, ':', '(', ')');
+    test_formatted_3args_impl<char, char, const char[3]>(v, ',', '{', "!}");
+    test_formatted_3args_impl<char, const char[3], char>(v, ',', "{!", '}');
+    test_formatted_3args_impl<const char[3], char, char>(v, "#$", '{', '}');
+    test_formatted_3args_impl<
+            const char[3], const char[3], const char[3]
+    >(v, "#$", "{!", "!}");
+}
+
+void test_formatted_impl(const std::vector<boost::int32_t>& v)
+{
+    test_formatted_0args_impl(v);
+    test_formatted_1arg_impl(v);
+    test_formatted_2args_impl(v);
+    test_formatted_3args_impl(v);
+}
+
+void test_formatted1()
+{
+    std::vector<boost::int32_t> v;
+    for (boost::int32_t i = 0; i < 10; ++i)
+        v.push_back(i);
+
+    test_formatted_impl(v);
+}
+
+void test_formatted2()
+{
+    std::vector<boost::int32_t> v;
+    v.push_back(3);
+
+    test_formatted_impl(v);
+}
+
+void test_formatted3()
+{
+    std::vector<boost::int32_t> v;
+
+    test_formatted_impl(v);
+}
+
+void test_formatted4()
+{
+    std::vector<boost::int32_t> v;
+    for (boost::int32_t i = 0; i < 5; ++i)
+        v.push_back(i);
+
+    test_formatted_impl(v);
+}
+
+struct udt_separator
+{
+};
+
+template<typename Char, typename Traits>
+inline std::basic_ostream<Char,Traits>&
+operator<<(std::basic_ostream<Char,Traits>& out, udt_separator)
+{
+    return out << "[sep]";
+}
+
+void test_formatted5()
+{
+    std::vector<boost::int32_t> v;
+    for (boost::int32_t i = 0; i < 5; ++i)
+        v.push_back(i);
+
+    std::ostringstream out1;
+    out1 << (v | boost::adaptors::formatted(udt_separator()));
+    BOOST_CHECK_EQUAL(out1.str(), "{0[sep]1[sep]2[sep]3[sep]4}");
+
+    std::ostringstream out2;
+    out2 << boost::adaptors::format(v, udt_separator());
+    BOOST_CHECK_EQUAL(out2.str(), "{0[sep]1[sep]2[sep]3[sep]4}");
+}
+
+// This test is already covered by the more complex code above. This
+// code duplicates coverage to ensure that char literal arrays are handled
+// correctly. I was particularly concerned that my test code above may pass
+// erroneously by decaying a char literal to a pointer. This function makes
+// it very plain that character literal strings work.
+void test_formatted_empty()
+{
+    std::vector<boost::int32_t> v;
+
+    std::ostringstream out1;
+    out1 << (v | boost::adaptors::formatted());
+    BOOST_CHECK_EQUAL(out1.str(), "{}");
+
+    std::ostringstream out2;
+    out2 << boost::adaptors::format(v);
+    BOOST_CHECK_EQUAL(out2.str(), "{}");
+
+    std::ostringstream out3;
+    out3 << (v | boost::adaptors::formatted(','));
+    BOOST_CHECK_EQUAL(out3.str(), "{}");
+
+    std::ostringstream out4;
+    out4 << boost::adaptors::format(v, ',');
+    BOOST_CHECK_EQUAL(out4.str(), "{}");
+
+    std::ostringstream out5;
+    out5 << (v | boost::adaptors::formatted("#$"));
+    BOOST_CHECK_EQUAL(out5.str(), "{}");
+
+    std::ostringstream out6;
+    out6 << boost::adaptors::format(v, "#$");
+    BOOST_CHECK_EQUAL(out6.str(), "{}");
+
+    std::ostringstream out7;
+    out7 << (v | boost::adaptors::formatted("", "12", "34"));
+    BOOST_CHECK_EQUAL(out7.str(), "1234");
+
+    std::ostringstream out8;
+    out8 << boost::adaptors::format(v, "", "12", "34");
+    BOOST_CHECK_EQUAL(out8.str(), "1234");
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char*[] )
+{
+    boost::unit_test::test_suite* test =
+            BOOST_TEST_SUITE( "Boost.Range formatted test suite" );
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted1));
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted2));
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted3));
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted4));
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted5));
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted_empty));
+
+    return test;
+}
diff --git a/test/adaptor_test/formatted_example.cpp b/test/adaptor_test/formatted_example.cpp
new file mode 100644
index 0000000..838a671
--- /dev/null
+++ b/test/adaptor_test/formatted_example.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[formatted_example
+#include <boost/range/adaptor/formatted.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace
+{
+void formatted_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5;
+    
+    std::cout << boost::adaptors::format(input) << std::endl;
+
+    // Alternatively this can be written:
+    // std::cout << (input | boost::adaptors::formatted()) << std::endl;
+
+//=    return 0;
+//=}
+//]
+    std::ostringstream test;
+    test << boost::adaptors::format(input);
+
+    BOOST_CHECK_EQUAL(test.str(), "{1,2,3,4,5}");
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.formatted_example" );
+
+    test->add( BOOST_TEST_CASE( &formatted_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/indexed.cpp b/test/adaptor_test/indexed.cpp
new file mode 100644
index 0000000..f4085be
--- /dev/null
+++ b/test/adaptor_test/indexed.cpp
@@ -0,0 +1,152 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/indexed.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/foreach.hpp>
+#include <boost/range/algorithm_ext.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <algorithm>
+#include <list>
+#include <vector>
+
+#include "../test_utils.hpp"
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+template<typename Container, typename AdaptedRange>
+void check_result(
+    const Container&    reference_range,
+    const AdaptedRange& adapted_range,
+    std::ptrdiff_t      start_index
+    )
+{
+    typedef typename boost::range_iterator<const Container>::type
+                reference_iterator;
+
+    typedef typename boost::range_iterator<const AdaptedRange>::type
+                adapted_iterator;
+
+    BOOST_REQUIRE_EQUAL(boost::size(reference_range),
+                        boost::size(adapted_range));
+
+    reference_iterator reference_it = boost::begin(reference_range);
+    adapted_iterator adapted_it = boost::begin(adapted_range);
+    for (std::ptrdiff_t i = start_index;
+            reference_it != boost::end(reference_range);
+            ++reference_it, ++adapted_it, ++i)
+    {
+        BOOST_CHECK_EQUAL(i, adapted_it->index());
+        BOOST_CHECK_EQUAL(*reference_it, adapted_it->value());
+    }
+}
+
+template<typename Container>
+void indexed_test_impl(Container& c, std::ptrdiff_t start_index)
+{
+    // This is my preferred syntax using the | operator.
+    check_result(c, c | boost::adaptors::indexed(), 0);
+    check_result(c, c | boost::adaptors::indexed(start_index), start_index);
+
+    // This is the function syntax
+    check_result(c, boost::adaptors::index(c), 0);
+    check_result(c, boost::adaptors::index(c, start_index), start_index);
+}
+
+template<typename Container>
+void indexed_test_impl(Container& c)
+{
+    indexed_test_impl(c, 0);
+    indexed_test_impl(c, -1);
+    indexed_test_impl(c, 4);
+}
+
+template<typename Container>
+void indexed_test_impl()
+{
+    using namespace boost::assign;
+
+    Container c;
+
+    // test empty container
+    indexed_test_impl(c);
+
+    // test one element
+    c += 1;
+    indexed_test_impl(c);
+
+    // test many elements
+    c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
+    indexed_test_impl(c);
+}
+
+template<typename Traversal, typename Range>
+void check_traversal(const Range& rng)
+{
+    BOOST_STATIC_ASSERT(
+        boost::is_convertible<
+            typename boost::range_traversal<const Range>::type,
+            Traversal
+        >::value);
+}
+
+template<typename Traversal, typename Range>
+void check_not_traversal(const Range& rng)
+{
+    BOOST_STATIC_ASSERT(
+        !boost::is_convertible<
+            typename boost::range_traversal<const Range>::type,
+            Traversal
+        >::value);
+}
+
+void indexed_test()
+{
+    indexed_test_impl< std::vector< int > >();
+    indexed_test_impl< std::list< int > >();
+
+    std::vector<int> vi;
+
+    check_traversal<boost::random_access_traversal_tag>(
+        vi | boost::adaptors::indexed());
+
+    std::list<int> li;
+
+    check_traversal<boost::forward_traversal_tag>(
+        li | boost::adaptors::indexed());
+
+    check_not_traversal<boost::bidirectional_traversal_tag>(
+        li | boost::adaptors::indexed());
+
+    check_not_traversal<boost::random_access_traversal_tag>(
+        li | boost::adaptors::indexed());
+}
+
+    } // anonymous namesapce
+} // namespace boost_range_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "Boost.Range indexed adaptor test suite" );
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::indexed_test));
+
+    return test;
+}
diff --git a/test/adaptor_test/indexed_example.cpp b/test/adaptor_test/indexed_example.cpp
new file mode 100644
index 0000000..c65e62e
--- /dev/null
+++ b/test/adaptor_test/indexed_example.cpp
@@ -0,0 +1,104 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[indexed_example
+
+//<-
+#include <boost/config.hpp>
+//->
+
+#include <boost/range/adaptor/indexed.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace 
+{
+
+template<class Iterator1, class Iterator2>
+void check_element_and_index(
+        Iterator1 test_first,
+        Iterator1 test_last,
+        Iterator2 reference_first,
+        Iterator2 reference_last)
+{
+    BOOST_CHECK_EQUAL( std::distance(test_first, test_last),
+                       std::distance(reference_first, reference_last) );
+
+    std::ptrdiff_t reference_index = 0;
+
+    Iterator1 test_it = test_first;
+    Iterator2 reference_it = reference_first;
+    for (; test_it != test_last; ++test_it, ++reference_it, ++reference_index)
+    {
+        BOOST_CHECK_EQUAL(test_it->value(), *reference_it);
+        BOOST_CHECK_EQUAL(test_it->index(), reference_index);
+    }
+}
+
+template<class SinglePassRange1, class SinglePassRange2>
+void check_element_and_index(
+    const SinglePassRange1& test_rng,
+    const SinglePassRange2& reference_rng)
+{
+    check_element_and_index(
+        boost::begin(test_rng), boost::end(test_rng),
+        boost::begin(reference_rng), boost::end(reference_rng));
+}
+//->
+
+//<-
+void indexed_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::vector<int> input;
+    input += 10,20,30,40,50,60,70,80,90;
+
+//<-
+#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
+//->
+    for (const auto& element : input | indexed(0))
+    {
+        std::cout << "Element = " << element.value()
+                  << " Index = " << element.index()
+                  << std::endl;
+    }
+//<-
+#endif // C++11 has range for loop
+//->
+    
+//=    return 0;
+//=}
+//]
+    check_element_and_index(
+        input | indexed(0),
+        input);
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indexed_example" );
+
+    test->add( BOOST_TEST_CASE( &indexed_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/indirected.cpp b/test/adaptor_test/indirected.cpp
new file mode 100644
index 0000000..fe3ebdf
--- /dev/null
+++ b/test/adaptor_test/indirected.cpp
@@ -0,0 +1,99 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/indirected.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+
+        template< class Container >
+        void indirected_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            // This is my preferred syntax using the | operator.
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | indirected);
+
+            // This is an alternative syntax preferred by some.
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, adaptors::indirect(c));
+
+            // Calculate the reference result.
+            std::vector< int > reference_result;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
+            for (iter_t it = c.begin(); it != c.end(); ++it)
+            {
+                reference_result.push_back(**it);
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result1.begin(),
+                                           test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
+                                           reference_result.end(),
+                                           test_result2.begin(),
+                                           test_result2.end() );
+        }
+
+        template< class Container >
+        void indirected_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            indirected_test_impl(c);
+
+            c += boost::shared_ptr<int>(new int(1));
+            indirected_test_impl(c);
+
+            std::vector<int> v;
+            v += 1,1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
+            for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)
+            {
+                c += boost::shared_ptr<int>(new int(*it));
+            }
+            indirected_test_impl(c);
+        }
+
+        void indirected_test()
+        {
+            indirected_test_impl< std::vector< boost::shared_ptr< int > > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indirected" );
+
+    test->add( BOOST_TEST_CASE( &boost::indirected_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/indirected_example.cpp b/test/adaptor_test/indirected_example.cpp
new file mode 100644
index 0000000..8b538b5
--- /dev/null
+++ b/test/adaptor_test/indirected_example.cpp
@@ -0,0 +1,66 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[indirected_example
+#include <boost/range/adaptor/indirected.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void indirected_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+
+    std::vector<boost::shared_ptr<int> > input;
+
+    for (int i = 0; i < 10; ++i)
+        input.push_back(boost::shared_ptr<int>(new int(i)));
+    
+    boost::copy(
+        input | indirected,
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    for (int i = 0; i < 10; ++i)
+        reference.push_back(i);
+
+    std::vector<int> test;
+    boost::push_back(test, input | indirected);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indirected_example" );
+
+    test->add( BOOST_TEST_CASE( &indirected_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/map.cpp b/test/adaptor_test/map.cpp
new file mode 100644
index 0000000..615b467
--- /dev/null
+++ b/test/adaptor_test/map.cpp
@@ -0,0 +1,171 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/map.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/array.hpp>
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void map_test_keys( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            std::vector<int> keys;
+            boost::push_back(keys, c | map_keys);
+
+            std::vector<int> keys2;
+            boost::push_back(keys2, adaptors::keys(c));
+
+            std::vector<int> reference_keys;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
+            for (iter_t it = c.begin(); it != c.end(); ++it)
+            {
+                reference_keys.push_back(it->first);
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_keys.begin(),
+                                           reference_keys.end(),
+                                           keys.begin(),
+                                           keys.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_keys.begin(),
+                                           reference_keys.end(),
+                                           keys2.begin(),
+                                           keys2.end() );
+        }
+
+        template< class Container >
+        void map_test_values( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            std::vector<int> values;
+            boost::push_back(values, c | map_values);
+
+            std::vector<int> values2;
+            boost::push_back(values2, adaptors::values(c));
+
+            std::vector<int> reference_values;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
+            for (iter_t it = c.begin(); it != c.end(); ++it)
+            {
+                reference_values.push_back(it->second);
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_values.begin(),
+                                           reference_values.end(),
+                                           values.begin(),
+                                           values.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference_values.begin(),
+                                           reference_values.end(),
+                                           values2.begin(),
+                                           values2.end() );
+        }
+
+        template< class Container >
+        void map_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            map_test_keys(c);
+            map_test_values(c);
+
+            // Test one element
+            c.insert(std::make_pair(1,2));
+            map_test_keys(c);
+            map_test_values(c);
+
+            // Test many elements
+            for (int x = 2; x < 10; ++x)
+            {
+                c.insert(std::make_pair(x, x * 2));
+            }
+            map_test_keys(c);
+            map_test_values(c);
+        }
+
+        void map_test()
+        {
+            map_test_impl< std::map<int,int> >();
+        }
+
+        void test_trac_item_4388()
+        {
+            typedef std::pair<int,char> pair_t;
+            const boost::array<pair_t,3> ar = {{
+                pair_t(3, 'a'),
+                pair_t(1, 'b'),
+                pair_t(4, 'c')
+            }};
+
+            const boost::array<int, 3> expected_keys = {{ 3, 1, 4 }};
+            const boost::array<char, 3> expected_values = {{ 'a', 'b', 'c' }};
+
+            {
+                std::vector<int> test;
+                boost::push_back(test, ar | boost::adaptors::map_keys);
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    expected_keys.begin(), expected_keys.end(),
+                    test.begin(), test.end()
+                );
+            }
+
+            {
+                std::vector<char> test;
+                boost::push_back(test, ar | boost::adaptors::map_values);
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    expected_values.begin(), expected_values.end(),
+                    test.begin(), test.end()
+                );
+            }
+
+            {
+                std::vector<char> test;
+                boost::array<std::pair<int, char>, 3> src(ar);
+                boost::push_back(test, src | boost::adaptors::map_values);
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    expected_values.begin(), expected_values.end(),
+                    test.begin(), test.end()
+                );
+            }
+        }
+
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map" );
+
+    test->add( BOOST_TEST_CASE( &boost::map_test ) );
+    test->add( BOOST_TEST_CASE( &boost::test_trac_item_4388 ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/map_keys_example.cpp b/test/adaptor_test/map_keys_example.cpp
new file mode 100644
index 0000000..99f8505
--- /dev/null
+++ b/test/adaptor_test/map_keys_example.cpp
@@ -0,0 +1,66 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[map_keys_example
+#include <boost/range/adaptor/map.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <map>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void map_keys_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::map<int,int> input;
+    for (int i = 0; i < 10; ++i)
+        input.insert(std::make_pair(i, i * 10));
+
+    boost::copy(
+        input | map_keys,
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 0,1,2,3,4,5,6,7,8,9;
+
+    std::vector<int> test;
+    boost::push_back(test, input | map_keys);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map_keys_example" );
+
+    test->add( BOOST_TEST_CASE( &map_keys_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/map_values_example.cpp b/test/adaptor_test/map_values_example.cpp
new file mode 100644
index 0000000..bfa533f
--- /dev/null
+++ b/test/adaptor_test/map_values_example.cpp
@@ -0,0 +1,66 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[map_values_example
+#include <boost/range/adaptor/map.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <map>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void map_values_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::map<int,int> input;
+    for (int i = 0; i < 10; ++i)
+        input.insert(std::make_pair(i, i * 10));
+
+    boost::copy(
+        input | map_values,
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 0,10,20,30,40,50,60,70,80,90;
+
+    std::vector<int> test;
+    boost::push_back(test, input | map_values);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map_values_example" );
+
+    test->add( BOOST_TEST_CASE( &map_values_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/ref_unwrapped.cpp b/test/adaptor_test/ref_unwrapped.cpp
new file mode 100644
index 0000000..ea190b3
--- /dev/null
+++ b/test/adaptor_test/ref_unwrapped.cpp
@@ -0,0 +1,101 @@
+// Boost.Range library
+//
+//  Copyright Robin Eckert 2015. Use, modification and distribution is
+//  subject to the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/ref_unwrapped.hpp>
+
+#define BOOST_TEST_MAIN
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_CXX11_RANGE_BASED_FOR)
+
+namespace boost
+{
+
+    BOOST_AUTO_TEST_CASE(test_mutable)
+    {
+        int one = 1;
+        int two = 2;
+        int three = 3;
+
+        std::vector<std::reference_wrapper<int>> input_values{one, two, three};
+
+        const std::vector<int*> expected{&one, &two, &three};
+        std::vector<int*> actual;
+
+        for (auto&& value : input_values | adaptors::ref_unwrapped)
+        {
+          actual.push_back(&value);
+        }
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
+                                      expected.end(),
+                                      actual.begin(),
+                                      actual.end());
+    }
+
+    BOOST_AUTO_TEST_CASE(test_const_range)
+    {
+        int one = 1;
+        int two = 2;
+        int three = 3;
+
+        const std::vector<std::reference_wrapper<int>> input_values{one, two, three};
+
+        const std::vector<int*> expected{&one, &two, &three};
+        std::vector<int*> actual;
+
+        for (auto&& value : input_values | adaptors::ref_unwrapped)
+        {
+          actual.push_back(&value);
+        }
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
+                                      expected.end(),
+                                      actual.begin(),
+                                      actual.end());
+    }
+
+    BOOST_AUTO_TEST_CASE(test_const_reference)
+    {
+        const int one = 1;
+        const int two = 2;
+        const int three = 3;
+
+        const std::vector<std::reference_wrapper<const int>> input_values{one, two, three};
+
+        const std::vector<const int*> expected{&one, &two, &three};
+        std::vector<const int*> actual;
+
+        for (auto&& value : input_values | adaptors::ref_unwrapped)
+        {
+          actual.push_back(&value);
+        }
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
+                                      expected.end(),
+                                      actual.begin(),
+                                      actual.end());
+    }
+
+
+}
+
+#else
+
+BOOST_AUTO_TEST_CASE(empty)
+{
+  // C++11 only
+}
+
+#endif
diff --git a/test/adaptor_test/ref_unwrapped_example.cpp b/test/adaptor_test/ref_unwrapped_example.cpp
new file mode 100644
index 0000000..ab3e401
--- /dev/null
+++ b/test/adaptor_test/ref_unwrapped_example.cpp
@@ -0,0 +1,47 @@
+// Boost.Range library
+//
+//  Copyright Robin Eckert 2015. Use, modification and distribution is
+//  subject to the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[ref_unwrapped_example
+#include <boost/range/adaptor/ref_unwrapped.hpp>
+#include <iostream>
+#include <vector>
+
+struct example
+{
+  int value;
+};
+
+int main(int argc, const char* argv[])
+{
+//<-
+#if !defined(BOOST_NO_CXX11_DECLTYPE) \
+ && !defined(BOOST_NO_CXX11_RANGE_BASED_FOR) \
+ && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
+ && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+//->
+    using boost::adaptors::ref_unwrapped;
+
+    example one{1};
+    example two{2};
+    example three{3};
+
+    std::vector<std::reference_wrapper<example> > input{one, two, three};
+
+    for (auto&& entry : input | ref_unwrapped)
+    {
+      std::cout << entry.value;
+    }
+
+    return 0;
+//<-
+#endif
+//->
+}
+//]
diff --git a/test/adaptor_test/replaced.cpp b/test/adaptor_test/replaced.cpp
new file mode 100644
index 0000000..d3eac81
--- /dev/null
+++ b/test/adaptor_test/replaced.cpp
@@ -0,0 +1,87 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/replaced.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void replaced_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            const int value_to_replace = 1;
+            const int replacement_value = 0;
+
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | replaced(value_to_replace, replacement_value));
+
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, adaptors::replace(c, value_to_replace, replacement_value));
+
+            std::vector< int > reference( c.begin(), c.end() );
+            std::replace(reference.begin(), reference.end(), value_to_replace, replacement_value);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result1.begin(), test_result1.end() );
+        }
+
+        template< class Container >
+        void replaced_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            replaced_test_impl(c);
+
+            // Test one
+            c += 1;
+            replaced_test_impl(c);
+
+            // Test many
+            c += 1,1,1,2,2,2,3,3,3,3,3,4,5,6,6,6,7,8,9;
+            replaced_test_impl(c);
+        }
+
+        void replaced_test()
+        {
+            replaced_test_impl< std::vector< int > >();
+            replaced_test_impl< std::list< int > >();
+            replaced_test_impl< std::set< int > >();
+            replaced_test_impl< std::multiset< int > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced" );
+
+    test->add( BOOST_TEST_CASE( &boost::replaced_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/replaced_example.cpp b/test/adaptor_test/replaced_example.cpp
new file mode 100644
index 0000000..8e1f114
--- /dev/null
+++ b/test/adaptor_test/replaced_example.cpp
@@ -0,0 +1,64 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[replaced_example
+#include <boost/range/adaptor/replaced.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void replaced_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,2,5,2,7,2,9;
+    
+    boost::copy(
+        input | replaced(2, 10),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 1,10,3,10,5,10,7,10,9;
+
+    std::vector<int> test;
+    boost::push_back(test, input | replaced(2, 10));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_example" );
+
+    test->add( BOOST_TEST_CASE( &replaced_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/replaced_if.cpp b/test/adaptor_test/replaced_if.cpp
new file mode 100644
index 0000000..0bf227f
--- /dev/null
+++ b/test/adaptor_test/replaced_if.cpp
@@ -0,0 +1,96 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/replaced_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        struct if_value_is_one
+        {
+            bool operator()(int x) const { return x == 1; }
+        };
+
+        template< class Container >
+        void replaced_if_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            if_value_is_one pred;
+
+            const int replacement_value = 0;
+
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | replaced_if(pred, replacement_value));
+
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, boost::adaptors::replace_if(c, pred, replacement_value));
+
+            std::vector< int > reference( c.begin(), c.end() );
+            std::replace_if(reference.begin(), reference.end(), pred, replacement_value);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result1.begin(), test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result2.begin(), test_result2.end() );
+        }
+
+        template< class Container >
+        void replaced_if_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            replaced_if_test_impl(c);
+
+            // Test one
+            c += 1;
+            replaced_if_test_impl(c);
+
+            // Test many
+            c += 1,1,1,2,2,2,3,3,3,3,3,4,5,6,6,6,7,8,9;
+            replaced_if_test_impl(c);
+        }
+
+        void replaced_if_test()
+        {
+            replaced_if_test_impl< std::vector< int > >();
+            replaced_if_test_impl< std::list< int > >();
+            replaced_if_test_impl< std::set< int > >();
+            replaced_if_test_impl< std::multiset< int > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_if" );
+
+    test->add( BOOST_TEST_CASE( &boost::replaced_if_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/replaced_if_example.cpp b/test/adaptor_test/replaced_if_example.cpp
new file mode 100644
index 0000000..05b5e78
--- /dev/null
+++ b/test/adaptor_test/replaced_if_example.cpp
@@ -0,0 +1,71 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[replaced_if_example
+#include <boost/range/adaptor/replaced_if.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+//->
+struct is_even
+{
+    bool operator()(int x) const { return x % 2 == 0; }
+};
+
+//<-
+void replaced_if_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9;
+    
+    boost::copy(
+        input | replaced_if(is_even(), 10),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 1,10,3,10,5,10,7,10,9;
+
+    std::vector<int> test;
+    boost::push_back(test, input | replaced_if(is_even(), 10));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_if_example" );
+
+    test->add( BOOST_TEST_CASE( &replaced_if_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/reversed.cpp b/test/adaptor_test/reversed.cpp
new file mode 100644
index 0000000..6663b36
--- /dev/null
+++ b/test/adaptor_test/reversed.cpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/reversed.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    template< class Container >
+    void reversed_test_impl( Container& c )
+    {
+        using namespace boost::adaptors;
+
+        std::vector< int > test_result1;
+        boost::push_back(test_result1, c | reversed);
+
+        std::vector< int > test_result2;
+        boost::push_back(test_result2, adaptors::reverse(c));
+
+        std::vector< int > reference( c.rbegin(), c.rend() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test_result1.begin(), test_result1.end() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test_result2.begin(), test_result2.end() );
+    }
+
+    template< class Container >
+    void reversed_test_impl()
+    {
+        using namespace boost::assign;
+
+        Container c;
+
+        // Test empty
+        reversed_test_impl(c);
+
+        // Test one
+        c += 1;
+        reversed_test_impl(c);
+
+        // Test many
+        c += 1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,5,6,7,8,9;
+        reversed_test_impl(c);
+    }
+
+    void reversed_test()
+    {
+        reversed_test_impl< std::vector< int > >();
+        reversed_test_impl< std::list< int > >();
+        reversed_test_impl< std::set< int > >();
+        reversed_test_impl< std::multiset< int > >();
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.reversed" );
+
+    test->add( BOOST_TEST_CASE( &boost::reversed_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/reversed_example.cpp b/test/adaptor_test/reversed_example.cpp
new file mode 100644
index 0000000..585108f
--- /dev/null
+++ b/test/adaptor_test/reversed_example.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[reversed_example
+#include <boost/range/adaptor/reversed.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void reversed_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9;
+    
+    boost::copy(
+        input | reversed,
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> test;
+    boost::push_back(test, input | reversed);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( input.rbegin(), input.rend(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.reversed_example" );
+
+    test->add( BOOST_TEST_CASE( &reversed_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/sliced.cpp b/test/adaptor_test/sliced.cpp
new file mode 100644
index 0000000..f2221f6
--- /dev/null
+++ b/test/adaptor_test/sliced.cpp
@@ -0,0 +1,99 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/sliced.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void sliced_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector< value_t > test_result1;
+            boost::push_back(test_result1, c | sliced(0u,c.size()));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test_result1.begin(), test_result1.end(),
+                                           c.begin(), c.end() );
+
+            std::vector< value_t > test_alt_result1;
+            boost::push_back(test_alt_result1, adaptors::slice(c, 0u, c.size()));
+            BOOST_CHECK_EQUAL_COLLECTIONS( test_alt_result1.begin(), test_alt_result1.end(),
+                                           c.begin(), c.end() );
+
+            BOOST_CHECK( boost::empty(c | sliced(0u, 0u)) );
+            
+            const std::size_t half_count = c.size() / 2u;
+            if (half_count > 0u)
+            {
+                std::vector< value_t > test_result2;
+                boost::push_back(test_result2, c | sliced(0u, half_count));
+
+                BOOST_CHECK_EQUAL_COLLECTIONS( test_result2.begin(), test_result2.end(),
+                                               c.begin(), c.begin() + half_count );
+
+                std::vector< value_t > test_alt_result2;
+                boost::push_back(test_alt_result2, adaptors::slice(c, 0u, half_count));
+                BOOST_CHECK_EQUAL_COLLECTIONS( test_alt_result2.begin(), test_alt_result2.end(),
+                                               c.begin(), c.begin() + half_count );
+            }
+        }
+
+        template< class Container >
+        void sliced_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            sliced_test_impl(c);
+
+            // Test one element
+            c += 1;
+            sliced_test_impl(c);
+
+            // Test many elements
+            c += 1,1,1,2,2,3,4,5,6,6,6,7,8,9;
+            sliced_test_impl(c);
+        }
+
+        void sliced_test()
+        {
+            sliced_test_impl< std::vector< int > >();
+            sliced_test_impl< std::deque< int > >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.sliced" );
+
+    test->add( BOOST_TEST_CASE( &boost::sliced_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/sliced_example.cpp b/test/adaptor_test/sliced_example.cpp
new file mode 100644
index 0000000..2b15691
--- /dev/null
+++ b/test/adaptor_test/sliced_example.cpp
@@ -0,0 +1,64 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[sliced_example
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void sliced_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9;
+    
+    boost::copy(
+        input | sliced(2, 5),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 3,4,5;
+
+    std::vector<int> test;
+    boost::push_back(test, input | sliced(2, 5));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.sliced_example" );
+
+    test->add( BOOST_TEST_CASE( &sliced_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/strided.cpp b/test/adaptor_test/strided.cpp
new file mode 100644
index 0000000..46c16fa
--- /dev/null
+++ b/test/adaptor_test/strided.cpp
@@ -0,0 +1,313 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// The strided_defect_Trac5014 test case is a modified version of a test case
+// contributed by Maxim Yanchenko as part of the trac ticket.
+//
+// The deque test case has been removed due to erroneous standard library
+// implementations causing test failures.
+//
+#include <boost/range/adaptor/strided.hpp>
+
+#include <boost/config.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void strided_test_impl( Container& c, int stride_size )
+        {
+            using namespace boost::adaptors;
+
+            // Rationale:
+            // This requirement was too restrictive. It makes the use of the
+            // strided adaptor too dangerous, and a simple solution existed
+            // to make it safe, hence the strided adaptor has been modified
+            // and this restriction no longer applies.
+            //BOOST_ASSERT( c.size() % STRIDE_SIZE == 0 );
+
+            Container reference;
+
+            {
+                typedef BOOST_DEDUCED_TYPENAME Container::const_iterator
+                            iterator_t BOOST_RANGE_UNUSED;
+                typedef BOOST_DEDUCED_TYPENAME Container::difference_type
+                            diff_t BOOST_RANGE_UNUSED;
+                typedef BOOST_DEDUCED_TYPENAME Container::size_type
+                            size_type BOOST_RANGE_UNUSED;
+                iterator_t it = c.begin();
+
+                iterator_t last = c.end();
+                for (; it != last; )
+                {
+                    reference.push_back(*it);
+
+                    for (int i = 0; (it != last) && (i < stride_size); ++i)
+                        ++it;
+                }
+            }
+
+            Container test;
+            boost::push_back( test, c | strided(stride_size) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
+                reference.begin(), reference.end() );
+
+            Container test2;
+            boost::push_back( test2, adaptors::stride(c, stride_size) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test2.begin(), test2.end(),
+                reference.begin(), reference.end() );
+
+            // Test the const versions:
+            const Container& cc = c;
+            Container test3;
+            boost::push_back( test3, cc | strided(stride_size) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test3.begin(), test3.end(),
+                reference.begin(), reference.end() );
+
+            Container test4;
+            boost::push_back( test4, adaptors::stride(cc, stride_size) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( test4.begin(), test4.end(),
+                reference.begin(), reference.end() );
+        }
+
+        template< class Container >
+        void strided_test_impl(int stride_size)
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            strided_test_impl(c, stride_size);
+
+            // Test two elements
+            c += 1,2;
+            strided_test_impl(c, stride_size);
+
+            // Test many elements
+            c += 1,1,1,2,2,3,4,5,6,6,6,7,8,9;
+            strided_test_impl(c, stride_size);
+
+            // Test an odd number of elements to determine that the relaxation
+            // of the requirements has been successful
+            // Test a sequence of length 1 with a stride of 2
+            c.clear();
+            c += 1;
+            strided_test_impl(c, stride_size);
+
+            // Test a sequence of length 2 with a stride of 2
+            c.clear();
+            c += 1,2;
+            strided_test_impl(c, stride_size);
+
+            // Test a sequence of length 3 with a stride of 2
+            c.clear();
+            c += 1,2,3;
+            strided_test_impl(c, stride_size);
+        }
+
+        template<typename Container>
+        void strided_test_zero_stride()
+        {
+            Container c;
+            c.push_back(1);
+
+            typedef boost::strided_range<Container> strided_range_t;
+            strided_range_t rng( boost::adaptors::stride(c, 0) );
+            boost::ignore_unused_variable_warning(rng);
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<strided_range_t>::type iter_t;
+
+            typedef BOOST_DEDUCED_TYPENAME boost::iterator_traversal<
+                        BOOST_DEDUCED_TYPENAME Container::const_iterator
+            >::type container_traversal_tag;
+
+            iter_t first = boost::range_detail::make_begin_strided_iterator(
+                c, 0, container_traversal_tag());
+
+            iter_t last = boost::range_detail::make_end_strided_iterator(
+                c, 0, container_traversal_tag());
+
+            iter_t it = first;
+            for (int i = 0; i < 10; ++i, ++it)
+            {
+                BOOST_CHECK(it == first);
+            }
+        }
+
+        template<typename Container>
+        void strided_test_impl()
+        {
+            strided_test_zero_stride< Container >();
+
+            const int MAX_STRIDE_SIZE = 10;
+            for (int stride_size = 1; stride_size <= MAX_STRIDE_SIZE; ++stride_size)
+            {
+                strided_test_impl< Container >(stride_size);
+            }
+        }
+
+        void strided_test()
+        {
+            strided_test_impl< std::vector<int> >();
+            strided_test_impl< std::list<int> >();
+        }
+
+        void strided_defect_Trac5014()
+        {
+            using namespace boost::assign;
+
+            std::vector<int> v;
+            for (int i = 0; i < 30; ++i)
+                v.push_back(i);
+
+            std::vector<int> reference;
+            reference += 0,4,8,12,16,20,24,28;
+
+            std::vector<int> output;
+            boost::push_back(output, v | boost::adaptors::strided(4));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           output.begin(), output.end() );
+
+            BOOST_CHECK_EQUAL( output.back(), 28 );
+        }
+
+        template<typename BaseIterator, typename Category>
+        class strided_mock_iterator
+            : public boost::iterator_adaptor<
+                strided_mock_iterator<BaseIterator,Category>
+              , BaseIterator
+              , boost::use_default
+              , Category
+            >
+        {
+            typedef boost::iterator_adaptor<
+                        strided_mock_iterator
+                      , BaseIterator
+                      , boost::use_default
+                      , Category
+                    > super_t;
+        public:
+            explicit strided_mock_iterator(BaseIterator it)
+                : super_t(it)
+            {
+            }
+
+        private:
+            void increment()
+            {
+                ++(this->base_reference());
+            }
+
+            friend class boost::iterator_core_access;
+        };
+
+        template<typename Category, typename Range>
+        boost::iterator_range<strided_mock_iterator<BOOST_DEDUCED_TYPENAME boost::range_iterator<Range>::type, Category> >
+        as_mock_range(Range& rng)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Range>::type range_iter_t;
+            typedef strided_mock_iterator<range_iter_t, Category> mock_iter_t;
+
+            return boost::iterator_range<mock_iter_t>(
+                      mock_iter_t(boost::begin(rng)),
+                      mock_iter_t(boost::end(rng)));
+        }
+
+        void strided_test_traversal()
+        {
+            using namespace boost::assign;
+
+            std::vector<int> v;
+            for (int i = 0; i < 30; ++i)
+                v.push_back(i);
+
+            std::vector<int> reference;
+            reference += 0,4,8,12,16,20,24,28;
+
+            std::vector<int> output;
+            boost::push_back(output, as_mock_range<boost::forward_traversal_tag>(v) | boost::adaptors::strided(4));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           output.begin(), output.end() );
+
+            output.clear();
+            boost::push_back(output, as_mock_range<boost::bidirectional_traversal_tag>(v) | boost::adaptors::strided(4));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           output.begin(), output.end() );
+
+            output.clear();
+            boost::push_back(output, as_mock_range<boost::random_access_traversal_tag>(v) | boost::adaptors::strided(4));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           output.begin(), output.end() );
+        }
+
+        template<typename Range>
+        void strided_test_ticket_5236_check_bidirectional(const Range& rng)
+        {
+            BOOST_CHECK_EQUAL( boost::distance(rng), 1 );
+            BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), boost::prior(boost::end(rng))), 0 );
+        }
+        
+        template<typename Range>
+        void strided_test_ticket_5236_check(const Range& rng)
+        {
+            strided_test_ticket_5236_check_bidirectional(rng);
+                        
+            typename boost::range_iterator<const Range>::type it = boost::end(rng);
+            it = it - 1;
+            BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), it), 0 );
+        }
+        
+        void strided_test_ticket_5236()
+        {
+            std::vector<int> v;
+            v.push_back(1);
+            strided_test_ticket_5236_check( v | boost::adaptors::strided(2) );                
+            
+            // Ensure that there is consistency between the random-access implementation
+            // and the bidirectional.
+            
+            std::list<int> l;
+            l.push_back(1);
+            strided_test_ticket_5236_check_bidirectional( l | boost::adaptors::strided(2) );
+        }
+        
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided" );
+
+    test->add( BOOST_TEST_CASE( &boost::strided_test ) );
+    test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) );
+    test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) );
+    test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/strided2.cpp b/test/adaptor_test/strided2.cpp
new file mode 100644
index 0000000..4ac91f5
--- /dev/null
+++ b/test/adaptor_test/strided2.cpp
@@ -0,0 +1,67 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+// This test was added due to a report that the Range Adaptors:
+// 1. Caused havoc when using namespace boost::adaptors was used
+// 2. Did not work with non-member functions
+// 3. The strided adaptor could not be composed with sliced
+//
+// None of these issues could be reproduced on GCC 4.4, but this
+// work makes for useful additional test coverage since this
+// uses chaining of adaptors and non-member functions whereas
+// most of the tests avoid this use case.
+
+#include <boost/range/adaptor/strided.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/irange.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        int times_two(int x) { return x * 2; }
+
+        void strided_test2()
+        {
+            using namespace boost::adaptors;
+            using namespace boost::assign;
+            std::vector<int> v;
+            boost::push_back(v, boost::irange(0,10));
+            std::vector<int> z;
+            boost::push_back(z, v | sliced(2,6) | strided(2) | transformed(&times_two));
+            std::vector<int> reference;
+            reference += 4,8;
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                z.begin(), z.end() );
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided2" );
+
+    test->add( BOOST_TEST_CASE( &boost::strided_test2 ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/strided_example.cpp b/test/adaptor_test/strided_example.cpp
new file mode 100644
index 0000000..b1f8b42
--- /dev/null
+++ b/test/adaptor_test/strided_example.cpp
@@ -0,0 +1,64 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[strided_example
+#include <boost/range/adaptor/strided.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void strided_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9,10;
+    
+    boost::copy(
+        input | strided(2),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 1,3,5,7,9;
+
+    std::vector<int> test;
+    boost::push_back(test, input | strided(2));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided_example" );
+
+    test->add( BOOST_TEST_CASE( &strided_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp b/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp
new file mode 100644
index 0000000..fdd7118
--- /dev/null
+++ b/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp
@@ -0,0 +1,69 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/phoenix/core.hpp>
+#include <boost/phoenix/operator.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+namespace
+{
+    struct test_struct
+    {
+        double x;
+        double y;
+    };
+
+    struct get_x
+    {
+        typedef double result_type;
+        double operator()(const test_struct& s) const
+        {
+            return s.x;
+        }
+    };
+
+    void range_transformed_warning()
+    {
+        using namespace boost::phoenix::arg_names;
+        using namespace boost::adaptors;
+
+        test_struct t;
+        t.x = 2.0;
+        t.y = -4.0;
+        std::vector<test_struct> v(10u, t);
+
+        std::vector<double> output1;
+        boost::push_back(output1, v | transformed((&arg1)->*& test_struct::x));
+
+        std::vector<double> output2;
+        boost::push_back(output2, v | transformed(get_x()));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(
+                    output1.begin(), output1.end(),
+                    output2.begin(), output2.end());
+    }
+} // anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "Range adaptors - transformed warning" );
+
+    test->add(BOOST_TEST_CASE(&range_transformed_warning));
+
+    return test;
+}
diff --git a/test/adaptor_test/ticket_8676_sliced_transformed.cpp b/test/adaptor_test/ticket_8676_sliced_transformed.cpp
new file mode 100644
index 0000000..da0125e
--- /dev/null
+++ b/test/adaptor_test/ticket_8676_sliced_transformed.cpp
@@ -0,0 +1,56 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+namespace
+{
+    struct identity
+    {
+        typedef int result_type;
+        result_type operator()(int i) const { return i; }
+    };
+
+    void sliced_and_transformed()
+    {
+        using namespace boost::adaptors;
+
+        std::vector<int> input;
+        for (int i = 0; i < 10; ++i)
+            input.push_back(i);
+
+        std::vector<int> out1;
+        boost::push_back(out1, input | sliced(2, 8)
+                                     | transformed(identity()));
+
+        std::vector<int> out2;
+        boost::push_back(out2, input | transformed(identity())
+                                     | sliced(2, 8));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(out1.begin(), out1.end(),
+                                      out2.begin(), out2.end());
+    }
+} // anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "Range adaptors - sliced and transformed" );
+
+    test->add(BOOST_TEST_CASE(&sliced_and_transformed));
+
+    return test;
+}
diff --git a/test/adaptor_test/ticket_9519_strided_reversed.cpp b/test/adaptor_test/ticket_9519_strided_reversed.cpp
new file mode 100644
index 0000000..0c91598
--- /dev/null
+++ b/test/adaptor_test/ticket_9519_strided_reversed.cpp
@@ -0,0 +1,67 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Credit goes to Eric Niebler for providing an example to demonstrate this
+// issue. This has been trivially modified to create this test case.
+//
+#include <boost/range/adaptor/strided.hpp>
+#include <boost/range/adaptor/reversed.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <list>
+#include <vector>
+#include <numeric>
+
+namespace boost
+{
+    namespace
+    {
+
+void ticket_9519_strided_reversed_test()
+{
+    using namespace boost::adaptors;
+
+    std::vector<int> vi;
+    for (int i = 0; i < 50; ++i)
+    {
+        vi.push_back(i);
+    }
+
+    std::vector<int> output;
+    boost::push_back(output, vi | strided(3) | reversed);
+
+    std::list<int> reference;
+    for (int i = 0; i < 50; i += 3)
+    {
+        reference.push_front(i);
+    }
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(output.begin(), output.end(),
+                                  reference.begin(), reference.end());
+}
+
+    } // anonymous namespace
+} // namespace boost
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE(
+            "RangeTestSuite.adaptor.ticket_9519_strided_reversed");
+
+    test->add(BOOST_TEST_CASE(&boost::ticket_9519_strided_reversed_test));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/tokenized.cpp b/test/adaptor_test/tokenized.cpp
new file mode 100644
index 0000000..8180747
--- /dev/null
+++ b/test/adaptor_test/tokenized.cpp
@@ -0,0 +1,79 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/tokenized.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Iterator, class Container >
+        void tokenized_test_impl( Container& c, std::size_t expected_result )
+        {
+            using namespace boost::adaptors;
+
+            std::vector< boost::sub_match< Iterator > > test_result1;
+            boost::push_back(test_result1, c | tokenized(boost::regex("\\b")));
+
+            BOOST_CHECK_EQUAL( test_result1.size(), expected_result );
+
+//            std::vector< boost::sub_match< Iterator > > test_result2;
+//            boost::push_back(test_result2, adaptors::tokenize(c, boost::regex("\\b")));
+
+//            BOOST_CHECK_EQUAL( test_result2.size(), expected_result );
+        }
+
+        template< class Container1, class Container2 >
+        void tokenized_test_impl()
+        {
+            Container1 c;
+            Container2& r = c;
+
+            typedef typename boost::range_iterator<Container2>::type It;
+
+            // Test empty
+            tokenized_test_impl<It, Container2>(r, 0u);
+
+            // Test one element
+            c = "a";
+            tokenized_test_impl<It, Container2>(r, 2u);
+
+            // Test many elements
+            c = "a b c d e f g hijlmnopqrstuvwxyz";
+            tokenized_test_impl<It, Container2>(r, 16u);
+        }
+
+        void tokenized_test()
+        {
+//            tokenized_test_impl<std::string, const std::string>();
+            tokenized_test_impl<std::string, std::string>();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.tokenized" );
+
+    test->add( BOOST_TEST_CASE( &boost::tokenized_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/tokenized_example.cpp b/test/adaptor_test/tokenized_example.cpp
new file mode 100644
index 0000000..5f59bb1
--- /dev/null
+++ b/test/adaptor_test/tokenized_example.cpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[tokenized_example
+#include <boost/range/adaptor/tokenized.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+void tokenized_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    
+    typedef boost::sub_match< std::string::iterator > match_type;
+    
+    std::string input = " a b c d e f g hijklmnopqrstuvwxyz";
+    boost::copy(
+        input | tokenized(boost::regex("\\w+")),
+        std::ostream_iterator<match_type>(std::cout, "\n"));
+
+//=    return 0;
+//=}
+//]
+    using namespace boost::assign;
+
+    std::vector<std::string> reference;
+    reference += "a","b","c","d","e","f","g","hijklmnopqrstuvwxyz";
+    
+    std::vector<match_type> test;
+    boost::push_back(test, input | tokenized(boost::regex("\\w+")));
+    
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.tokenized_example" );
+
+    test->add( BOOST_TEST_CASE( &tokenized_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/transformed.cpp b/test/adaptor_test/transformed.cpp
new file mode 100644
index 0000000..10f6a0c
--- /dev/null
+++ b/test/adaptor_test/transformed.cpp
@@ -0,0 +1,170 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/transformed.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        struct double_x
+        {
+            typedef int result_type;
+            int operator()(int x) const { return x * 2; }
+        };
+
+        struct halve_x
+        {
+            typedef int result_type;
+            int operator()(int x) const { return x / 2; }
+        };
+
+        struct lambda_init
+        {
+        };
+
+        struct lambda
+        {
+            typedef int result_type;
+
+            lambda(const lambda_init& init) {}
+            lambda(const lambda& rhs) {}
+
+            int operator()(int x) const { return x + 1; }
+
+        private:
+            lambda() {}
+            lambda& operator=(const lambda& rhs) { return *this; }
+        };
+
+        template< class Container, class TransformFn >
+        void transformed_test_impl_core( Container& c, TransformFn fn )
+        {
+            using namespace boost::adaptors;
+
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | transformed(fn));
+
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, adaptors::transform(c, fn));
+
+            std::vector< int > reference;
+            std::transform(c.begin(), c.end(), std::back_inserter(reference), fn);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result1.begin(), test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result2.begin(), test_result2.end() );
+        }
+
+        template< class Rng >
+        void check_copy_assign(Rng r)
+        {
+            Rng r2 = r;
+            r2 = r;
+        }
+
+        template< class Container, class TransformFn >
+        void transformed_range_copy_assign(Container& c, TransformFn fn)
+        {
+            using namespace boost::adaptors;
+            check_copy_assign(c | transformed(fn));
+            check_copy_assign(adaptors::transform(c, fn));
+        }
+
+        template< class Container, class TransformFn, class TransformFnInit >
+        void transformed_test_fn_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+            TransformFnInit init;
+            TransformFn fn( init );
+
+            // Test empty
+            transformed_test_impl_core(c, fn);
+
+            // Test one element
+            c += 1;
+            transformed_test_impl_core(c, fn);
+
+            // Test many elements
+            c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9;
+            transformed_test_impl_core(c, fn);
+
+            // test the range and iterator are copy assignable
+            transformed_range_copy_assign(c, fn);
+        }
+
+        template< class Container >
+        void transformed_test_impl()
+        {
+            transformed_test_fn_impl< Container, double_x, double_x >();
+            transformed_test_fn_impl< Container, halve_x, halve_x >();
+            transformed_test_fn_impl< Container, lambda, lambda_init >();
+        }
+
+        void transformed_test()
+        {
+            transformed_test_impl< std::vector< int > >();
+            transformed_test_impl< std::list< int > >();
+            transformed_test_impl< std::set< int > >();
+            transformed_test_impl< std::multiset< int > >();
+        }
+
+        struct foo_bind
+        {
+            int foo() const { return 7; }
+        };
+
+        void transformed_bind()
+        {
+            using namespace boost::adaptors;
+
+            std::vector<foo_bind> input(5);
+            std::vector<int> output;
+            boost::range::push_back(
+                    output,
+                    input | transformed(boost::bind(&foo_bind::foo, _1)));
+
+            BOOST_CHECK_EQUAL(output.size(), input.size());
+
+            std::vector<int> reference_output(5, 7);
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                        output.begin(), output.end(),
+                        reference_output.begin(), reference_output.end());
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
+
+    test->add(BOOST_TEST_CASE(&boost::transformed_test));
+    test->add(BOOST_TEST_CASE(&boost::transformed_bind));
+
+    return test;
+}
diff --git a/test/adaptor_test/transformed_example.cpp b/test/adaptor_test/transformed_example.cpp
new file mode 100644
index 0000000..ff4a689
--- /dev/null
+++ b/test/adaptor_test/transformed_example.cpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[transformed_example
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+namespace 
+{
+//->
+struct double_int
+{
+    typedef int result_type;
+    int operator()(int x) const { return x * 2; }
+};
+
+//<-
+void transformed_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::adaptors;
+    using namespace boost::assign;
+
+    std::vector<int> input;
+    input += 1,2,3,4,5,6,7,8,9,10;
+    
+    boost::copy(
+        input | transformed(double_int()),
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 2,4,6,8,10,12,14,16,18,20;
+
+    std::vector<int> test;
+    boost::push_back(test, input | transformed(double_int()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed_example" );
+
+    test->add( BOOST_TEST_CASE( &transformed_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptor_test/type_erased.cpp b/test/adaptor_test/type_erased.cpp
new file mode 100644
index 0000000..edea1c4
--- /dev/null
+++ b/test/adaptor_test/type_erased.cpp
@@ -0,0 +1,44 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <list>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_type_erased()
+{
+    test_driver< std::list<int> >();
+    test_driver< std::vector<int> >();
+
+    test_driver< std::list<MockType> >();
+    test_driver< std::vector<MockType> >();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased");
+
+    test->add(BOOST_TEST_CASE(
+                &boost_range_adaptor_type_erased_test::test_type_erased));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_abstract.cpp b/test/adaptor_test/type_erased_abstract.cpp
new file mode 100644
index 0000000..dd54890
--- /dev/null
+++ b/test/adaptor_test/type_erased_abstract.cpp
@@ -0,0 +1,88 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+class dummy_interface
+{
+public:
+    virtual ~dummy_interface() { }
+    virtual void test() = 0;
+protected:
+    dummy_interface() { }
+private:
+    dummy_interface(const dummy_interface&);
+    void operator=(const dummy_interface&);
+};
+
+class dummy_impl
+    : public dummy_interface
+{
+public:
+    dummy_impl() { }
+    dummy_impl(const dummy_impl&) { }
+    dummy_impl& operator=(const dummy_impl&) { return *this; }
+    virtual void test() { }
+};
+
+typedef boost::any_range<
+    dummy_interface,
+    boost::random_access_traversal_tag,
+    dummy_interface&,
+    std::ptrdiff_t
+> any_interface_range;
+
+struct foo_dummy_interface_fn
+{
+    void operator()(dummy_interface& iface)
+    {
+        iface.test();
+    }
+};
+
+void foo_test_dummy_interface_range(any_interface_range rng)
+{
+    std::for_each(boost::begin(rng), boost::end(rng),
+                  foo_dummy_interface_fn());
+}
+
+void test_type_erased_abstract()
+{
+    std::vector<dummy_impl> v(10);
+
+    any_interface_range r(v);
+
+    foo_test_dummy_interface_range(r);
+
+    foo_test_dummy_interface_range(any_interface_range(v));
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_abstract");
+
+    test->add(
+        BOOST_TEST_CASE(
+            &boost_range_adaptor_type_erased_test::test_type_erased_abstract));
+
+    return test;
+}
diff --git a/test/adaptor_test/type_erased_bidirectional.cpp b/test/adaptor_test/type_erased_bidirectional.cpp
new file mode 100644
index 0000000..3dc86fe
--- /dev/null
+++ b/test/adaptor_test/type_erased_bidirectional.cpp
@@ -0,0 +1,57 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <list>
+#include <deque>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_bidirectional()
+{
+    test_type_erased_exercise_buffer_types<
+            std::list<int>, boost::bidirectional_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<int>, boost::bidirectional_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<int>, boost::bidirectional_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::list<MockType>, boost::bidirectional_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<MockType>, boost::bidirectional_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<MockType>, boost::bidirectional_traversal_tag >();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_bidirectional");
+
+    test->add(BOOST_TEST_CASE(
+                  &boost_range_adaptor_type_erased_test::test_bidirectional));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_brackets.cpp b/test/adaptor_test/type_erased_brackets.cpp
new file mode 100644
index 0000000..9d5c7dd
--- /dev/null
+++ b/test/adaptor_test/type_erased_brackets.cpp
@@ -0,0 +1,70 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_operator_brackets()
+{
+    typedef boost::adaptors::type_erased<> type_erased_t;
+
+    std::vector<int> c;
+    for (int i = 0; i < 10; ++i)
+        c.push_back(i);
+
+    typedef boost::any_range_type_generator<
+                        std::vector<int> >::type any_range_type;
+
+    BOOST_STATIC_ASSERT((
+            boost::is_same<
+                int,
+                boost::range_value<any_range_type>::type
+            >::value
+    ));
+
+    BOOST_STATIC_ASSERT((
+            boost::is_same<
+                boost::random_access_traversal_tag,
+                boost::iterator_traversal<
+                    boost::range_iterator<any_range_type>::type
+                >::type
+            >::value
+    ));
+
+    any_range_type rng = c | type_erased_t();
+
+    for (int i = 0; i < 10; ++i)
+    {
+        BOOST_CHECK_EQUAL(rng[i], i);
+    }
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_brackets");
+
+    test->add(
+        BOOST_TEST_CASE(
+            &boost_range_adaptor_type_erased_test::test_operator_brackets));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_example.cpp b/test/adaptor_test/type_erased_example.cpp
new file mode 100644
index 0000000..f8416ae
--- /dev/null
+++ b/test/adaptor_test/type_erased_example.cpp
@@ -0,0 +1,124 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[type_erased_example
+#include <boost/range/adaptor/type_erased.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <boost/foreach.hpp>
+#include <iterator>
+#include <iostream>
+#include <list>
+#include <vector>
+//<-
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace
+{
+    namespace boost_range_test
+    {
+        namespace type_erased_example
+        {
+//->            
+
+// The client interface from an OO perspective merely requires a sequence
+// of integers that can be forward traversed
+typedef boost::any_range<
+    int
+  , boost::forward_traversal_tag
+  , int
+  , std::ptrdiff_t
+> integer_range;
+
+namespace server
+{
+    void display_integers(const integer_range& rng)
+    {
+        boost::copy(rng,
+                    std::ostream_iterator<int>(std::cout, ","));
+
+        std::cout << std::endl;
+    }
+}
+
+namespace client
+{
+    void run()
+    {
+        using namespace boost::assign;
+        using namespace boost::adaptors;
+
+        // Under most conditions one would simply use an appropriate
+        // any_range as a function parameter. The type_erased adaptor
+        // is often superfluous. However because the type_erased
+        // adaptor is applied to a range, we can use default template
+        // arguments that are generated in conjunction with the
+        // range type to which we are applying the adaptor.
+
+        std::vector<int> input;
+        input += 1,2,3,4,5;
+
+        // Note that this call is to a non-template function
+        server::display_integers(input);
+
+        std::list<int> input2;
+        input2 += 6,7,8,9,10;
+
+        // Note that this call is to the same non-tempate function
+        server::display_integers(input2);
+
+        input2.clear();
+        input2 += 11,12,13,14,15;
+
+        // Calling using the adaptor looks like this:
+        // Notice that here I have a type_erased that would be a
+        // bidirectional_traversal_tag, but this is convertible
+        // to the forward_traversal_tag equivalent hence this
+        // works.
+        server::display_integers(input2 | type_erased<>());
+
+        // However we may simply wish to define an adaptor that
+        // takes a range and makes it into an appropriate
+        // forward_traversal any_range...
+        typedef boost::adaptors::type_erased<
+            boost::use_default
+          , boost::forward_traversal_tag
+        > type_erased_forward;
+
+        // This adaptor can turn other containers with different
+        // value_types and reference_types into the appropriate
+        // any_range.
+
+        server::display_integers(input2 | type_erased_forward());
+    }
+}
+
+//=int main(int argc, const char* argv[])
+//={
+//=    client::run();
+//=    return 0;
+//=}
+//]
+
+        } // namespace type_erased_example
+    } // namespace boost_range_test
+} // anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_example" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test::type_erased_example::client::run) );
+
+    return test;
+}
diff --git a/test/adaptor_test/type_erased_forward.cpp b/test/adaptor_test/type_erased_forward.cpp
new file mode 100644
index 0000000..7f6540f
--- /dev/null
+++ b/test/adaptor_test/type_erased_forward.cpp
@@ -0,0 +1,57 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <deque>
+#include <list>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_forward()
+{
+    test_type_erased_exercise_buffer_types<
+            std::list<int>, boost::forward_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<int>, boost::forward_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<int>, boost::forward_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::list<MockType>, boost::forward_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<MockType>, boost::forward_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<MockType>, boost::forward_traversal_tag >();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_forward" );
+
+    test->add(BOOST_TEST_CASE(
+                  &boost_range_adaptor_type_erased_test::test_forward));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_mix_values.cpp b/test/adaptor_test/type_erased_mix_values.cpp
new file mode 100644
index 0000000..e91644c
--- /dev/null
+++ b/test/adaptor_test/type_erased_mix_values.cpp
@@ -0,0 +1,94 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+template<
+    class Traversal
+  , class ValueType
+  , class SourceValueType
+  , class SourceReference
+  , class TargetValueType
+  , class TargetReference
+>
+void mix_values_impl()
+{
+    typedef std::vector<ValueType> Container;
+
+    typedef typename boost::any_range_type_generator<
+        Container
+      , SourceValueType
+      , Traversal
+      , SourceReference
+    >::type source_type;
+
+    typedef typename boost::any_range_type_generator<
+        Container
+      , TargetValueType
+      , Traversal
+      , TargetReference
+    >::type target_type;
+
+    Container test_data;
+    for (int i = 0; i < 10; ++i)
+        test_data.push_back(i);
+
+    const source_type source_data(test_data);
+    target_type t1(source_data);
+    BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(),
+                                  t1.begin(), t1.end());
+
+    target_type t2;
+    t2 = source_data;
+    BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(),
+                                  t2.begin(), t2.end());
+}
+
+template<class Traversal>
+void mix_values_driver()
+{
+    mix_values_impl<
+        Traversal,
+        MockType,
+        MockType2, const MockType&,
+        MockType, const MockType&
+    >();
+}
+
+void mix_values()
+{
+    mix_values_driver<boost::single_pass_traversal_tag >();
+    mix_values_driver<boost::forward_traversal_tag >();
+    mix_values_driver<boost::bidirectional_traversal_tag >();
+    mix_values_driver<boost::random_access_traversal_tag >();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_mix_values");
+
+    test->add(BOOST_TEST_CASE(
+            &boost_range_adaptor_type_erased_test::mix_values));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_random_access.cpp b/test/adaptor_test/type_erased_random_access.cpp
new file mode 100644
index 0000000..39cf1c6
--- /dev/null
+++ b/test/adaptor_test/type_erased_random_access.cpp
@@ -0,0 +1,50 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <deque>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_random_access()
+{
+    test_type_erased_exercise_buffer_types<
+            std::deque<int>, boost::random_access_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<int>, boost::random_access_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<MockType>, boost::random_access_traversal_tag >();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<MockType>, boost::random_access_traversal_tag >();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_random_access");
+
+    test->add(BOOST_TEST_CASE(
+            &boost_range_adaptor_type_erased_test::test_random_access));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_single_pass.cpp b/test/adaptor_test/type_erased_single_pass.cpp
new file mode 100644
index 0000000..ad0c4ae
--- /dev/null
+++ b/test/adaptor_test/type_erased_single_pass.cpp
@@ -0,0 +1,57 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <deque>
+#include <list>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void test_single_pass()
+{
+    test_type_erased_exercise_buffer_types<
+            std::list<int>, boost::single_pass_traversal_tag>();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<int>, boost::single_pass_traversal_tag>();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<int>, boost::single_pass_traversal_tag>();
+
+    test_type_erased_exercise_buffer_types<
+            std::list<MockType>, boost::single_pass_traversal_tag>();
+
+    test_type_erased_exercise_buffer_types<
+            std::deque<MockType>, boost::single_pass_traversal_tag>();
+
+    test_type_erased_exercise_buffer_types<
+            std::vector<MockType>, boost::single_pass_traversal_tag>();
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_single_pass");
+
+    test->add(BOOST_TEST_CASE(
+        &boost_range_adaptor_type_erased_test::test_single_pass));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/type_erased_test.hpp b/test/adaptor_test/type_erased_test.hpp
new file mode 100644
index 0000000..9a42e81
--- /dev/null
+++ b/test/adaptor_test/type_erased_test.hpp
@@ -0,0 +1,289 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP
+#define BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP
+
+#include <boost/range/algorithm/fill.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/assign.hpp>
+#include <boost/test/test_tools.hpp>
+
+namespace boost_range_adaptor_type_erased_test
+{
+
+class MockType
+{
+public:
+    MockType()
+        : m_x(0)
+    {
+    }
+
+    MockType(boost::int32_t x)
+        : m_x(x)
+    {
+    }
+
+    boost::int32_t get() const { return m_x; }
+
+    inline bool operator==(const MockType& other) const
+    {
+        return m_x == other.m_x;
+    }
+
+    inline bool operator!=(const MockType& other) const
+    {
+        return m_x != other.m_x;
+    }
+
+private:
+    boost::int32_t m_x;
+};
+
+class MockType2 : public MockType
+{
+public:
+    MockType2() {}
+    MockType2(boost::int32_t x) : MockType(x) { }
+    MockType2(const MockType& other) : MockType(other) { }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const MockType& obj)
+{
+    out << obj.get();
+    return out;
+}
+
+template<class Container>
+void test_type_erased_impl(Container& c)
+{
+    using namespace boost::adaptors;
+    typedef typename boost::range_value<Container>::type value_type;
+    typedef typename boost::adaptors::type_erased<> type_erased_t;
+
+
+    std::vector<value_type> output;
+
+    boost::push_back(output, boost::adaptors::type_erase(c, type_erased_t()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(),
+                                   c.begin(), c.end() );
+
+    output.clear();
+    boost::push_back(output, c | type_erased_t());
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(),
+                                   c.begin(), c.end() );
+}
+
+template<class Container>
+void test_const_and_mutable(Container& c)
+{
+    test_type_erased_impl(c);
+
+    const Container& const_c = c;
+    test_type_erased_impl(const_c);
+}
+
+template<class Container>
+void test_driver()
+{
+    using namespace boost::assign;
+
+    typedef typename boost::range_value<Container>::type value_type;
+
+    Container c;
+    test_const_and_mutable(c);
+
+    c += value_type(1);
+    test_const_and_mutable(c);
+
+    c += value_type(2);
+    test_const_and_mutable(c);
+}
+
+template<
+    class Traversal
+  , class Container
+>
+void test_writeable(Container&, boost::single_pass_traversal_tag)
+{}
+
+template<
+    class Traversal
+  , class Container
+>
+void test_writeable(Container& source, boost::forward_traversal_tag)
+{
+    using namespace boost::adaptors;
+
+    typedef typename boost::range_value<Container>::type value_type;
+    typedef typename boost::range_difference<Container>::type difference_type;
+    typedef typename boost::range_reference<Container>::type mutable_reference_type;
+    typedef boost::any_range<
+                value_type
+              , Traversal
+              , mutable_reference_type
+              , difference_type
+            > mutable_any_range;
+
+    mutable_any_range r = source | boost::adaptors::type_erased<>();
+    std::vector<value_type> output_test;
+    boost::fill(r, value_type(1));
+    BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) );
+    std::vector<value_type> reference_output(source.size(), value_type(1));
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference_output.begin(), reference_output.end(),
+                                   r.begin(), r.end() );
+
+}
+
+template<
+    class Container
+  , class Traversal
+  , class Buffer
+>
+void test_type_erased_impl()
+{
+    using namespace boost::adaptors;
+
+    typedef typename boost::range_value<Container>::type value_type;
+
+    typedef typename boost::any_range_type_generator<
+        Container
+      , boost::use_default
+      , Traversal
+      , boost::use_default
+      , boost::use_default
+      , Buffer
+    >::type mutable_any_range;
+
+    typedef typename boost::any_range_type_generator<
+        const Container
+      , boost::use_default
+      , Traversal
+      , boost::use_default
+      , boost::use_default
+      , Buffer
+    >::type const_any_range;
+
+    typedef boost::adaptors::type_erased<
+                boost::use_default
+              , Traversal
+              , boost::use_default
+              , boost::use_default
+              , Buffer
+            > type_erased_t;
+
+    Container source;
+    for (int i = 0; i < 10; ++i)
+        source.push_back(value_type(i));
+
+    mutable_any_range r(source);
+    BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
+                                   r.begin(), r.end() );
+
+    r = mutable_any_range();
+    BOOST_CHECK_EQUAL( r.empty(), true );
+
+    r = source | type_erased_t();
+    BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
+                                   r.begin(), r.end() );
+    r = mutable_any_range();
+
+    r = boost::adaptors::type_erase(source, type_erased_t());
+    BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
+                                   r.begin(), r.end() );
+    r = mutable_any_range();
+
+    test_writeable<Traversal>(source, Traversal());
+
+    // convert and construct a const any_range from a mutable source
+    // range
+    const_any_range cr(source);
+    BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
+                                   cr.begin(), cr.end() );
+    // assign an empty range and ensure that this correctly results
+    // in an empty range. This is important for the validity of
+    // the rest of the tests.
+    cr = const_any_range();
+    BOOST_CHECK_EQUAL( cr.empty(), true );
+
+    // Test the pipe type_erased adaptor from a constant source
+    // range to a constant any_range
+    const Container& const_source = source;
+    cr = const_any_range();
+    cr = const_source | type_erased_t();
+    BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(),
+                                   cr.begin(), cr.end() );
+
+    // Test the pipe type erased adaptor from a mutable source
+    // range to a constant any_range
+    cr = const_any_range();
+    cr = source | type_erased_t();
+    BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
+                                   cr.begin(), cr.end() );
+
+    // Use the function form of the type_erase adaptor from a constant
+    // source range
+    cr = const_any_range();
+    cr = boost::adaptors::type_erase(const_source, type_erased_t());
+    BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(),
+                                   cr.begin(), cr.end() );
+
+    // Assignment from mutable to const...
+    cr = const_any_range();
+    cr = r;
+    BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(),
+                                   r.begin(), r.end() );
+
+    // Converting copy from mutable to const...
+    cr = const_any_range();
+    cr = const_any_range(r);
+    BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(),
+                                   r.begin(), r.end() );
+}
+
+template<
+    class Container
+  , class Traversal
+  , class Buffer
+>
+class test_type_erased_impl_fn
+{
+public:
+    typedef void result_type;
+    void operator()()
+    {
+        test_type_erased_impl< Container, Traversal, Buffer >();
+    }
+};
+
+template<
+    class Container
+  , class Traversal
+>
+void test_type_erased_exercise_buffer_types()
+{
+    using boost::any_iterator_default_buffer;
+    using boost::any_iterator_buffer;
+    using boost::any_iterator_heap_only_buffer;
+    using boost::any_iterator_stack_only_buffer;
+
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_default_buffer >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_heap_only_buffer >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<1> >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<2> >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<32> >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<64> >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<128> >()();
+    test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()();
+}
+
+} // namespace boost_range_adaptor_type_erased_test
+
+#endif // include guard
diff --git a/test/adaptor_test/type_erased_tparam_conv.cpp b/test/adaptor_test/type_erased_tparam_conv.cpp
new file mode 100644
index 0000000..e235ab3
--- /dev/null
+++ b/test/adaptor_test/type_erased_tparam_conv.cpp
@@ -0,0 +1,74 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/range/adaptor/type_erased.hpp>
+#include "type_erased_test.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include <algorithm>
+#include <vector>
+
+namespace boost_range_adaptor_type_erased_test
+{
+    namespace
+    {
+
+void template_parameter_conversion()
+{
+    typedef boost::any_range<
+                int
+              , boost::random_access_traversal_tag
+              , int&
+              , std::ptrdiff_t
+    > source_range_type;
+
+    typedef boost::any_range<
+                int
+              , boost::single_pass_traversal_tag
+              , const int&
+              , std::ptrdiff_t
+    > target_range_type;
+
+    source_range_type source;
+
+    // Converting via construction
+    target_range_type t1(source);
+
+    // Converting via assignment
+    target_range_type t2;
+    t2 = source;
+
+    // Converting via construction to a type with a reference type
+    // that is a value
+    typedef boost::any_range<
+                int
+              , boost::single_pass_traversal_tag
+              , int
+              , std::ptrdiff_t
+            > target_range2_type;
+
+    target_range2_type t3(source);
+    target_range2_type t4;
+    t4 = source;
+}
+
+    } // anonymous namespace
+} // namespace boost_range_adaptor_type_erased_test
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_tparam_conv");
+
+    test->add(BOOST_TEST_CASE(
+        &boost_range_adaptor_type_erased_test::template_parameter_conversion));
+
+    return test;
+}
+
diff --git a/test/adaptor_test/uniqued.cpp b/test/adaptor_test/uniqued.cpp
new file mode 100644
index 0000000..fdf5454
--- /dev/null
+++ b/test/adaptor_test/uniqued.cpp
@@ -0,0 +1,168 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/uniqued.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/algorithm/unique_copy.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void uniqued_test_impl( Container& c )
+        {
+            using namespace boost::adaptors;
+
+            std::vector< int > test_result1;
+            boost::push_back(test_result1, c | uniqued);
+
+            std::vector< int > test_result2;
+            boost::push_back(test_result2, adaptors::unique(c));
+
+            std::vector< int > reference(c.begin(), c.end());
+            reference.erase(
+                std::unique(reference.begin(), reference.end()),
+                reference.end());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result1.begin(), test_result1.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result2.begin(), test_result2.end() );
+        }
+
+        template< class Container >
+        void uniqued_test_impl()
+        {
+            using namespace boost::assign;
+
+            Container c;
+
+            // Test empty
+            uniqued_test_impl(c);
+
+            // Test one
+            c += 1;
+            uniqued_test_impl(c);
+
+            // Test many
+            c += 1,1,1,2,2,2,2,2,3,3,3,3,4,5,6,6,6,7,7,7,8,8,9,9,9,9,9,10;
+            uniqued_test_impl(c);
+        }
+
+        void uniqued_test()
+        {
+            uniqued_test_impl< std::vector< int > >();
+            uniqued_test_impl< std::list< int > >();
+            uniqued_test_impl< std::set< int > >();
+            uniqued_test_impl< std::multiset< int > >();
+        }
+
+class istring
+{
+public:
+    istring()
+        : m_value("")
+    {
+    }
+
+    explicit istring(const char* value)
+        : m_value(value)
+    {
+    }
+
+    bool operator==(istring r) const
+    {
+        return boost::iequals(m_value, r.m_value);
+    }
+
+    bool operator!=(istring r) const
+    {
+        return !operator==(r);
+    }
+
+    inline friend std::ostream& operator<<(std::ostream& out, istring o)
+    {
+        return out << o.m_value;
+    }
+
+    const char* get() const { return m_value; }
+
+private:
+    const char* m_value;
+};
+
+struct istring_to_string
+{
+    typedef std::string result_type;
+
+    std::string operator()(istring s) const
+    {
+        return s.get();
+    }
+};
+
+// This is based on a test-case provided by Eric Neibler.
+void uniqued_return_first()
+{
+    using namespace boost::adaptors;
+
+    std::vector<istring> strs;
+    strs.push_back(istring("hello"));
+    strs.push_back(istring("hElLo"));
+    strs.push_back(istring("HELLO"));
+    strs.push_back(istring("ZZZZ"));
+
+    std::vector<istring> output1;
+
+    boost::unique_copy(strs, std::back_inserter(output1));
+
+    std::vector<istring> output2;
+    boost::push_back(output2, strs | uniqued);
+
+    std::vector<std::string> test1;
+    boost::push_back(test1, output1 | transformed(istring_to_string()));
+
+    std::vector<std::string> test2;
+    boost::push_back(test2, output2 | transformed(istring_to_string()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(test1.begin(), test1.end(),
+                                  test2.begin(), test2.end());
+}
+
+    } // anonymous namespace
+} // namespace boost
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.uniqued" );
+
+    test->add( BOOST_TEST_CASE( &boost::uniqued_test ) );
+
+    test->add(BOOST_TEST_CASE(&boost::uniqued_return_first));
+
+    return test;
+}
diff --git a/test/adaptor_test/uniqued_example.cpp b/test/adaptor_test/uniqued_example.cpp
new file mode 100644
index 0000000..cf1407a
--- /dev/null
+++ b/test/adaptor_test/uniqued_example.cpp
@@ -0,0 +1,64 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//[uniqued_example
+#include <boost/range/adaptor/uniqued.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/assign.hpp>
+#include <iterator>
+#include <iostream>
+#include <vector>
+
+//<-
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace
+{
+void uniqued_example_test()
+//->
+//=int main(int argc, const char* argv[])
+{
+    using namespace boost::assign;
+    using namespace boost::adaptors;
+
+    std::vector<int> input;
+    input += 1,1,2,2,2,3,4,5,6;
+
+    boost::copy(
+        input | uniqued,
+        std::ostream_iterator<int>(std::cout, ","));
+
+//=    return 0;
+//=}
+//]
+    std::vector<int> reference;
+    reference += 1,2,3,4,5,6;
+
+    std::vector<int> test;
+    boost::push_back( test, input | uniqued );
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+        test.begin(), test.end() );
+}
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.uniqued_example" );
+
+    test->add( BOOST_TEST_CASE( &uniqued_example_test ) );
+
+    return test;
+}
diff --git a/test/adaptors.cpp b/test/adaptors.cpp
new file mode 100644
index 0000000..ea0f503
--- /dev/null
+++ b/test/adaptors.cpp
@@ -0,0 +1,236 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/adaptors.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/foreach.hpp>
+#include <boost/assign/list_of.hpp>
+#include <vector>
+#include <list>
+#include <string>
+#include <map>
+
+template< class T >
+struct less_than
+{
+    T val;
+
+    less_than() : val(0)
+    {}
+    
+    less_than( T t ) : val(t)
+    {}
+
+    bool operator()( const T& r ) const
+    {
+        return r < val;
+    }
+};
+
+
+
+template< class T >
+struct multiply
+{
+    T val;
+    
+    typedef T& result_type;
+
+    multiply( T t ) : val(t)
+    { }
+    
+    T& operator()( T& r ) const
+    {
+        return r *= 2;
+    }
+};
+
+
+
+template< class Rng >
+void check_copy( Rng r )
+{
+    //
+    // Make sure the generated iterators
+    // can actually be copied
+    //
+    Rng r2 = r;
+    r2     = r;
+}
+
+
+template< class Rng >
+void check_direct()
+{
+    using namespace boost::adaptors;
+    
+    Rng rng = boost::assign::list_of(1)(2)(3)(4)(5).to_container( rng );
+    Rng out;
+
+    //
+    // test each alphabetically
+    //
+    BOOST_FOREACH( int i, rng | filtered( less_than<int>(4) ) 
+                              /*| reversed*/ 
+                              | transformed( multiply<int>(2) ) )
+    {
+      out.push_back( i );
+    }
+
+    BOOST_CHECK_EQUAL( out.size(), 3u );
+    BOOST_CHECK_EQUAL( *out.begin(), 2 );
+    BOOST_CHECK_EQUAL( *boost::next(out.begin()), 4 );
+    BOOST_CHECK_EQUAL( *boost::next(out.begin(),2), 6 );
+
+    rng = boost::assign::list_of(1)(1)(2)(2)(3)(3)(4)(5).to_container( rng );
+    out.clear();
+    /*
+    BOOST_FOREACH( int i, rng | adjacent_filtered( std::equal_to<int>() )
+                              | uniqued )
+    {
+        
+        out.push_back( i );
+    }*/
+    
+}
+
+
+template< class IndirectRng >
+void check_indirect()
+{
+    using namespace boost::adaptors;
+
+    IndirectRng rng;
+
+    std::vector< boost::shared_ptr< int > > holder;
+    
+    for( unsigned i = 0u; i != 20u; ++i )
+    {
+        boost::shared_ptr<int> v(new int(i));
+        rng.push_back( v.get() );
+    }
+
+    BOOST_FOREACH( int& i, rng | indirected | reversed 
+                               | transformed( multiply<int>(2) ) )
+    {
+        i += 1;
+    }
+
+    
+    
+}
+
+
+
+template< class RandomAccessRng >
+void check_random_access()
+{
+    using namespace boost::adaptors;
+    
+    RandomAccessRng rng(1, 20u);
+    RandomAccessRng out;
+
+    BOOST_FOREACH( int i, rng | reversed 
+                              | transformed( multiply<int>(2) )  
+                              /* | sliced(0,15) */ )
+    {
+      out.push_back( i );
+    }
+
+    
+    BOOST_FOREACH( int i, rng | copied(3u,13u) )
+    {
+        out.push_back( i );
+    }     
+}
+
+
+
+template< class Map >
+void check_map()
+{
+    using namespace boost::adaptors;
+    
+    Map m;
+    m.insert( std::make_pair(1,2) );
+    m.insert( std::make_pair(2,2) );
+    m.insert( std::make_pair(3,2) );
+    m.insert( std::make_pair(4,2) );
+    m.insert( std::make_pair(5,2) );
+    m.insert( std::make_pair(6,2) );
+    m.insert( std::make_pair(7,2) );
+
+    std::vector<int> keys 
+        = boost::copy_range< std::vector<int> >( m | map_keys );
+    std::vector<int> values 
+       = boost::copy_range< std::vector<int> >( m | map_values );
+}
+
+
+
+void check_regex()
+{
+    using namespace boost::adaptors;
+    std::string s("This is a string of tokens");
+    std::vector<std::string> tokens =
+        boost::copy_range< std::vector<std::string> >( s | tokenized( "\\s+", -1 ) );
+}
+
+
+void check_adaptors()
+{
+    check_direct< std::vector<int> >();
+    check_direct< std::list<int> >();
+    check_indirect< std::vector<int*> >();
+    check_indirect< std::list<int*> >();
+
+    check_map< std::map<int,int> >();
+//    check_random_access< std::vector<int> >();
+    check_regex();
+
+    using namespace boost::adaptors;
+    std::vector<int>  vec(10u,20);
+    std::vector<int*> pvec;
+    std::map<int,int> map;
+    
+    check_copy( vec | adjacent_filtered( std::equal_to<int>() ) );
+  //  check_copy( vec | indexed );
+    check_copy( vec | reversed );
+    check_copy( vec | uniqued );
+    check_copy( pvec | indirected );
+
+//    check_copy( vec | sliced(1,5) );
+    //
+    // This does not return an iterator_range<>, so
+    // won't pass this test of implicit conversion
+    //  check_copy( vec | copied(1,5) );
+    //
+    check_copy( map | map_values );
+    check_copy( map | map_keys );
+    check_copy( std::string( "a string" ) | tokenized( "\\s+", -1 ) );
+    check_copy( vec | filtered( less_than<int>(2) ) );
+    check_copy( vec | transformed( multiply<int>(2) ) ); 
+}
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    using namespace boost;
+
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Adaptors" );
+
+    test->add( BOOST_TEST_CASE( &check_adaptors ) );
+
+    return test;
+}
+
+
diff --git a/test/adl_conformance.cpp b/test/adl_conformance.cpp
new file mode 100644
index 0000000..8bae491
--- /dev/null
+++ b/test/adl_conformance.cpp
@@ -0,0 +1,188 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+enum adl_types
+{
+    unused,
+    boost_namespace,
+    templated_namespace,
+    non_templated_namespace,
+    global_namespace
+};
+
+// Use boost_test rather than boost as the namespace for this test
+// to allow the test framework to use boost::begin() etc. without
+// violating the One Defintion Rule.
+namespace boost_test
+{
+    namespace range_detail
+    {
+        template< class Range >
+        inline typename Range::iterator begin( Range& r )
+        {
+            return boost_namespace;
+        }
+
+        template< class Range >
+        inline typename Range::iterator begin( const Range& r )
+        {
+            return boost_namespace;
+        }
+
+    }
+
+    template< class Range >
+    inline typename Range::iterator begin( Range& r )
+    {
+        using range_detail::begin; // create ADL hook
+        return begin( r );
+    }
+
+    template< class Range >
+    inline typename Range::iterator begin( const Range& r )
+    {
+        using range_detail::begin; // create ADL hook
+        return begin( r );
+    }
+} // 'boost_test'
+
+
+namespace find_templated
+{
+    template< class T >
+    struct range
+    {
+        typedef adl_types iterator;
+
+        range()                { /* allow const objects */ }
+        iterator begin()       { return unused; }
+        iterator begin() const { return unused; }
+        iterator end()         { return unused; }
+        iterator end() const   { return unused; }
+    };
+
+    //
+    // A fully generic version here will create
+    // ambiguity.
+    //
+    template< class T >
+    inline typename range<T>::iterator begin( range<T>& r )
+    {
+        return templated_namespace;
+    }
+
+    template< class T >
+    inline typename range<T>::iterator begin( const range<T>& r )
+    {
+        return templated_namespace;
+    }
+
+}
+
+namespace find_non_templated
+{
+    struct range
+    {
+        typedef adl_types iterator;
+
+        range()                { /* allow const objects */ }
+        iterator begin()       { return unused; }
+        iterator begin() const { return unused; }
+        iterator end()         { return unused; }
+        iterator end() const   { return unused; }
+    };
+
+    inline range::iterator begin( range& r )
+    {
+        return non_templated_namespace;
+    }
+
+
+    inline range::iterator begin( const range& r )
+    {
+        return non_templated_namespace;
+    }
+}
+
+struct range
+{
+    typedef adl_types iterator;
+
+    range()                { /* allow const objects */ }
+    iterator begin()       { return unused; }
+    iterator begin() const { return unused; }
+    iterator end()         { return unused; }
+    iterator end() const   { return unused; }
+};
+
+inline range::iterator begin( range& r )
+{
+    return global_namespace;
+}
+
+inline range::iterator begin( const range& r )
+{
+    return global_namespace;
+}
+
+void check_adl_conformance()
+{
+    find_templated::range<int>       r;
+    const find_templated::range<int> r2;
+    find_non_templated::range        r3;
+    const find_non_templated::range  r4;
+    range                            r5;
+    const range                      r6;
+
+    //
+    // Notice how ADL kicks in even when we have qualified
+    // notation!
+    //
+
+
+    BOOST_CHECK( boost_test::begin( r )  != boost_namespace );
+    BOOST_CHECK( boost_test::begin( r2 ) != boost_namespace );
+    BOOST_CHECK( boost_test::begin( r3 ) != boost_namespace );
+    BOOST_CHECK( boost_test::begin( r4 ) != boost_namespace );
+    BOOST_CHECK( boost_test::begin( r5 ) != boost_namespace );
+    BOOST_CHECK( boost_test::begin( r6 ) != boost_namespace );
+
+    BOOST_CHECK_EQUAL( boost_test::begin( r ), templated_namespace ) ;
+    BOOST_CHECK_EQUAL( boost_test::begin( r2 ), templated_namespace );
+    BOOST_CHECK_EQUAL( boost_test::begin( r3 ), non_templated_namespace );
+    BOOST_CHECK_EQUAL( boost_test::begin( r4 ), non_templated_namespace );
+    BOOST_CHECK_EQUAL( boost_test::begin( r5 ), global_namespace );
+    BOOST_CHECK_EQUAL( boost_test::begin( r6 ), global_namespace );
+}
+
+#include <boost/test/included/unit_test.hpp>
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_adl_conformance ) );
+
+    return test;
+}
+
+
diff --git a/test/adl_conformance_no_using.cpp b/test/adl_conformance_no_using.cpp
new file mode 100644
index 0000000..82c1cd2
--- /dev/null
+++ b/test/adl_conformance_no_using.cpp
@@ -0,0 +1,110 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <iostream>
+
+namespace A
+{
+   namespace detail
+   {
+      template< typename T >
+      int f( const T& x )
+      {
+         // Default:
+         std::cout << 1 << std::endl;
+         return 1;
+      }
+   
+      template< typename T >
+      int adl_f2( const T& x, int* )
+      {
+         return f( x );
+      }
+   
+      template< typename T >
+      int adl_f( const T& x )
+      {
+         return adl_f2( x, 0 );
+      }
+   }
+
+   template< typename T >
+   int f( const T& x )
+   {
+      return detail::adl_f( x );
+   }
+
+   template< typename T >
+   int adl_f2( const T& x, int )
+   {
+      return detail::f( x );
+   }
+   
+   //--------------------------------
+   
+   class C {};
+/*
+   // Optional:
+   int f( const C& x )
+   {
+      std::cout << 2 << std::endl;
+   }
+*/
+   template< typename T >
+   class D {};
+/*
+   // Optional:
+   template< typename T >
+   int f( const D< T >& x )
+   {
+      std::cout << 3 << std::endl;
+   }
+   */
+}
+
+   
+namespace B
+{
+   class C {};
+
+   // Optional:
+/*   int f( const C& )
+   {
+      std::cout << 4 << std::endl;
+   }
+*/
+   template< typename T >
+   class D {};
+/*
+   // Optional:
+   template< typename T >
+   int f( const D< T >& x )
+   {
+      std::cout << 5 << std::endl;
+   }
+   */
+}
+
+int main()
+{
+   A::f( 42 );
+
+   A::C ac;
+   A::f( ac );
+
+   A::D< int > ad;
+   A::f( ad );
+
+   B::C bc;
+   A::f( bc );
+
+   B::D< int > bd;
+   A::f( bd );
+}
diff --git a/test/algorithm.cpp b/test/algorithm.cpp
new file mode 100644
index 0000000..e945d42
--- /dev/null
+++ b/test/algorithm.cpp
@@ -0,0 +1,479 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+//  (C) Copyright Eric Niebler 2004.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+   13 December 2004 : Initial version.
+*/
+
+#ifdef _MSC_VER
+// The 'secure' library warnings produce so much noise that it makes it
+// impossible to see more useful warnings.
+    #define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#ifdef _MSC_VER
+    // counting_iterator generates a warning about truncating an integer
+    #pragma warning(push)
+    #pragma warning(disable : 4244)
+#endif
+#include <boost/iterator/counting_iterator.hpp>
+#ifdef _MSC_VER
+    template ::boost::counting_iterator<int>;
+    #pragma warning(pop)
+#endif
+
+#include <boost/assign.hpp>
+#include <boost/config.hpp>    
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/numeric.hpp>
+#include <boost/range/algorithm.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/size.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/iterator/iterator_traits.hpp>
+
+#include <algorithm>
+#include <cstdlib>
+#include <set>
+#include <list>
+#include <vector>
+#include <iterator>
+#include <functional>
+///////////////////////////////////////////////////////////////////////////////
+// dummy function object, used with algorithms
+//
+struct null_fun
+{
+    template<typename T>
+        void operator()(T const &t) const
+    {
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// dummy predicate, used with algorithms
+//
+struct null_pred
+{
+    template<typename T>
+    bool operator()(T const &t) const
+    {
+        return t == T();
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// dummy unary op, used with algorithms
+//
+struct null_op1
+{
+    template<typename T>
+    T const & operator()(T const & t) const
+    {
+        return t;
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// dummy binary op, used with algorithms
+//
+struct null_op2
+{
+    template<typename T,typename U>
+    T const & operator()(T const & t, U const & u) const
+    {
+        return t;
+    }
+};
+
+template<typename Rng>
+void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
+{
+    typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
+
+    typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
+
+    typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type
+                                        size_type BOOST_RANGE_UNUSED;
+
+    typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type
+                                        iterator_category BOOST_RANGE_UNUSED;
+
+    // just make sure these compile (for now)
+    if(0)
+    {
+        boost::random_shuffle(rng);
+
+        // Must be a value since random_shuffle must take the generator by
+        // reference to match the standard.
+        null_op1 rng_generator; 
+        boost::random_shuffle(rng, rng_generator);
+
+        boost::sort(rng);
+        boost::sort(rng, std::less<value_type>());
+
+        boost::stable_sort(rng);
+        boost::stable_sort(rng, std::less<value_type>());
+
+        boost::partial_sort(rng, boost::begin(rng));
+        boost::partial_sort(rng, boost::begin(rng), std::less<value_type>());
+
+        boost::nth_element(rng, boost::begin(rng));
+        boost::nth_element(rng, boost::begin(rng), std::less<value_type>());
+
+        boost::push_heap(rng);
+        boost::push_heap(rng, std::less<value_type>());
+
+        boost::pop_heap(rng);
+        boost::pop_heap(rng, std::less<value_type>());
+
+        boost::make_heap(rng);
+        boost::make_heap(rng, std::less<value_type>());
+
+        boost::sort_heap(rng);
+        boost::sort_heap(rng, std::less<value_type>());
+    }
+}
+
+template<typename Rng>
+void test_random_algorithms(Rng & rng, std::input_iterator_tag)
+{
+    // no-op
+}
+
+template<typename Rng>
+void test_algorithms(Rng & rng)
+{
+    typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
+    typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
+    typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
+    typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
+
+    // just make sure these compile (for now)
+    if(0)
+    {
+        value_type val = value_type();
+
+        value_type rng2[] = {value_type(),value_type(),value_type()};
+        typedef value_type* iterator2;
+
+        value_type out[100] = {};
+        typedef value_type* out_iterator;
+
+        null_fun f = null_fun();
+        iterator i = iterator();
+        bool b = bool();
+        out_iterator o = out_iterator();
+        size_type s = size_type();
+
+        f = boost::for_each(rng, null_fun());
+
+        i = boost::find(rng, val);
+        i = boost::find_if(rng, null_pred());
+
+        i = boost::find_end(rng, rng2);
+        i = boost::find_end(rng, rng2, std::equal_to<value_type>());
+
+        i = boost::find_first_of(rng, rng2);
+        i = boost::find_first_of(rng, rng2, std::equal_to<value_type>());
+
+        i = boost::adjacent_find(rng);
+        i = boost::adjacent_find(rng, std::equal_to<value_type>());
+
+        s = boost::count(rng, val);
+        s = boost::count_if(rng, null_pred());
+
+        std::pair<iterator,iterator2> p1;
+        p1 = boost::mismatch(rng, rng2);
+        p1 = boost::mismatch(rng, rng2, std::equal_to<value_type>());
+
+        b = boost::equal(rng, rng2);
+        b = boost::equal(rng, rng2, std::equal_to<value_type>());
+
+        i = boost::search(rng, rng2);
+        i = boost::search(rng, rng2, std::equal_to<value_type>());
+
+        o = boost::copy(rng, boost::begin(out));
+        o = boost::copy_backward(rng, boost::end(out));
+
+        o = boost::transform(rng, boost::begin(out), null_op1());
+        o = boost::transform(rng, rng2, boost::begin(out), null_op2());
+
+        boost::replace(rng, val, val);
+        boost::replace_if(rng, null_pred(), val);
+
+/*
+        o = boost::replace_copy(rng, boost::begin(out), val, val);
+        o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
+*/
+
+        boost::fill(rng, val);
+        //
+        // size requires RandomAccess
+        //
+        //boost::fill_n(rng, boost::size(rng), val);
+        //boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
+
+        boost::generate(rng, &std::rand);
+        //
+        // size requires RandomAccess   
+        //
+        //boost::generate_n(rng, boost::size(rng), &std::rand);
+        //boost::generate_n(rng,std::distance(boost::begin(rng),boost::end(rng)), &std::rand);
+
+        i = boost::remove(rng, val);
+        i = boost::remove_if(rng, null_pred());
+
+/*
+        o = boost::remove_copy(rng, boost::begin(out), val);
+        o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
+*/
+
+        typename boost::range_return<Rng, boost::return_begin_found>::type rrng = boost::unique(rng);
+        rrng = boost::unique(rng, std::equal_to<value_type>());
+
+/*
+        o = boost::unique_copy(rng, boost::begin(out));
+        o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
+*/
+
+        boost::reverse(rng);
+
+/*
+        o = boost::reverse_copy(rng, boost::begin(out));
+*/
+
+        boost::rotate(rng, boost::begin(rng));
+
+/*
+        o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
+*/
+
+        i = boost::partition(rng, null_pred());
+        i = boost::stable_partition(rng, null_pred());
+
+/*
+        o = boost::partial_sort_copy(rng, out);
+        o = boost::partial_sort_copy(rng, out, std::less<value_type>());
+*/
+
+        i = boost::lower_bound(rng, val);
+        i = boost::lower_bound(rng, val, std::less<value_type>());
+
+        i = boost::upper_bound(rng, val);
+        i = boost::upper_bound(rng, val, std::less<value_type>());
+
+        std::pair<iterator,iterator> p2;
+        p2 = boost::equal_range(rng, val);
+        p2 = boost::equal_range(rng, val, std::less<value_type>());
+
+        b = boost::binary_search(rng, val);
+        b = boost::binary_search(rng, val, std::less<value_type>());
+
+        boost::inplace_merge(rng, boost::begin(rng));
+        boost::inplace_merge(rng, boost::begin(rng), std::less<value_type>());
+
+        b = boost::includes(rng, rng2);
+        b = boost::includes(rng, rng2, std::equal_to<value_type>());
+
+        o = boost::set_union(rng, rng2, boost::begin(out));
+        o = boost::set_union(rng, rng2, boost::begin(out), std::equal_to<value_type>());
+
+        o = boost::set_intersection(rng, rng2, boost::begin(out));
+        o = boost::set_intersection(rng, rng2, boost::begin(out), std::equal_to<value_type>());
+
+        o = boost::set_difference(rng, rng2, boost::begin(out));
+        o = boost::set_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
+
+        o = boost::set_symmetric_difference(rng, rng2, boost::begin(out));
+        o = boost::set_symmetric_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
+
+        i = boost::min_element(rng);
+        i = boost::min_element(rng, std::less<value_type>());
+
+        i = boost::max_element(rng);
+        i = boost::max_element(rng, std::less<value_type>());
+
+        b = boost::lexicographical_compare(rng, rng);
+        b = boost::lexicographical_compare(rng, rng, std::equal_to<value_type>());
+
+        b = boost::next_permutation(rng);
+        b = boost::next_permutation(rng, std::less<value_type>());
+
+        b = boost::prev_permutation(rng);
+        b = boost::prev_permutation(rng, std::less<value_type>());
+
+        /////////////////////////////////////////////////////////////////////
+        // numeric algorithms
+        /////////////////////////////////////////////////////////////////////
+
+        val = boost::accumulate( rng, val );
+        val = boost::accumulate( rng, val, null_op2() );
+        val = boost::inner_product( rng, rng, val );
+        val = boost::inner_product( rng, rng, val, 
+                                    null_op2(), null_op2() );
+        o   = boost::partial_sum( rng, boost::begin(out) );
+        o   = boost::partial_sum( rng, boost::begin(out), null_op2() );
+        o   = boost::adjacent_difference( rng, boost::begin(out) );
+        o   = boost::adjacent_difference( rng, boost::begin(out), 
+                                          null_op2() );
+        
+        boost::ignore_unused_variable_warning(b);
+         
+    }
+
+    // test the algorithms that require a random-access range
+    test_random_algorithms(rng, iterator_category());
+}
+
+int* addr(int &i) { return &i; }
+bool true_(int) { return true; }
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//   
+void simple_compile_test()
+{
+    // int_iterator
+    typedef ::boost::counting_iterator<int> int_iterator;
+
+    // define come containers
+    std::list<int> my_list(int_iterator(1),int_iterator(6));
+
+
+    std::vector<int> my_vector(int_iterator(1),int_iterator(6));
+
+    std::pair<std::vector<int>::iterator,std::vector<int>::iterator> my_pair(my_vector.begin(),my_vector.end());
+
+    // test the algorithms with list and const list
+    test_algorithms(my_list);
+    test_algorithms(my_vector);
+    test_algorithms(my_pair);
+
+    
+    std::vector<int> v;
+    std::vector<int>& cv = v;
+
+    using namespace boost;
+
+#define BOOST_RANGE_RETURNS_TEST( function_name, cont ) \
+    function_name (cont); \
+    function_name <return_found> (cont); \
+    function_name <return_next> (cont); \
+    function_name <return_prior> (cont); \
+    function_name <return_begin_found> (cont); \
+    function_name <return_begin_next> (cont); \
+    function_name <return_begin_prior> (cont); \
+    function_name <return_found_end> (cont); \
+    function_name <return_next_end>(cont); \
+    function_name <return_prior_end>(cont);
+
+    BOOST_RANGE_RETURNS_TEST( adjacent_find, cv );
+    BOOST_RANGE_RETURNS_TEST( adjacent_find, v );
+    BOOST_RANGE_RETURNS_TEST( max_element, cv );
+    BOOST_RANGE_RETURNS_TEST( max_element, v );
+    BOOST_RANGE_RETURNS_TEST( min_element, cv );
+    BOOST_RANGE_RETURNS_TEST( min_element, v );
+    BOOST_RANGE_RETURNS_TEST( unique, v );
+#undef BOOST_RANGE_RETURNS_TEST
+
+#define BOOST_RANGE_RETURNS_TEST1( function_name, cont, arg1 ) \
+    function_name (cont, arg1); \
+    function_name <return_found> (cont, arg1); \
+    function_name <return_next> (cont, arg1); \
+    function_name <return_prior> (cont, arg1); \
+    function_name <return_begin_found> (cont, arg1); \
+    function_name <return_begin_next> (cont, arg1); \
+    function_name <return_begin_prior> (cont, arg1); \
+    function_name <return_found_end> (cont, arg1); \
+    function_name <return_next_end>(cont, arg1); \
+    function_name <return_prior_end>(cont, arg1);
+
+    BOOST_RANGE_RETURNS_TEST1( adjacent_find, cv, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( adjacent_find, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( find, cv, 0 );
+    BOOST_RANGE_RETURNS_TEST1( find, v, 0 );
+    BOOST_RANGE_RETURNS_TEST1( find_end, cv, cv );
+    BOOST_RANGE_RETURNS_TEST1( find_end, cv, v );
+    BOOST_RANGE_RETURNS_TEST1( find_end, v, cv );
+    BOOST_RANGE_RETURNS_TEST1( find_end, v, v );
+    BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, cv );
+    BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, v );
+    BOOST_RANGE_RETURNS_TEST1( find_first_of, v, cv );
+    BOOST_RANGE_RETURNS_TEST1( find_first_of, v, v );
+    BOOST_RANGE_RETURNS_TEST1( find_if, cv, std::negate<int>() );
+    BOOST_RANGE_RETURNS_TEST1( find_if, v, std::negate<int>() );
+    BOOST_RANGE_RETURNS_TEST1( search, cv, cv );
+    BOOST_RANGE_RETURNS_TEST1( search, cv, v );
+    BOOST_RANGE_RETURNS_TEST1( search, v, cv );
+    BOOST_RANGE_RETURNS_TEST1( search, v, v );
+
+    BOOST_RANGE_RETURNS_TEST1( remove, v, 0 );
+    BOOST_RANGE_RETURNS_TEST1( remove_if, v, std::negate<int>() );
+
+    BOOST_RANGE_RETURNS_TEST1( lower_bound, cv, 0 );
+    BOOST_RANGE_RETURNS_TEST1( lower_bound, v, 0 );
+    BOOST_RANGE_RETURNS_TEST1( max_element, cv, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( max_element, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( min_element, cv, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( min_element, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST1( upper_bound, cv, 0 );
+    BOOST_RANGE_RETURNS_TEST1( upper_bound, v, 0 );
+    BOOST_RANGE_RETURNS_TEST1( partition, cv, std::negate<int>() );
+    BOOST_RANGE_RETURNS_TEST1( partition, v, std::negate<int>() );
+    BOOST_RANGE_RETURNS_TEST1( stable_partition, cv, std::negate<int>() );
+    BOOST_RANGE_RETURNS_TEST1( stable_partition, v, std::negate<int>() );
+
+#undef BOOST_RANGE_RETURNS_TEST1
+
+#define BOOST_RANGE_RETURNS_TEST2( function_name, arg1, arg2 ) \
+    function_name (v, arg1, arg2); \
+    function_name <return_found> (v, arg1, arg2); \
+    function_name <return_next> (v, arg1, arg2); \
+    function_name <return_prior> (v, arg1, arg2); \
+    function_name <return_begin_found> (v, arg1, arg2); \
+    function_name <return_begin_next> (v, arg1, arg2); \
+    function_name <return_begin_prior> (v, arg1, arg2); \
+    function_name <return_found_end> (v, arg1, arg2); \
+    function_name <return_next_end>(v, arg1, arg2); \
+    function_name <return_prior_end>(v, arg1, arg2);
+
+    BOOST_RANGE_RETURNS_TEST2( find_end, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST2( find_first_of, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST2( boost::search, v, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST2( lower_bound, 0, std::less<int>() );
+    BOOST_RANGE_RETURNS_TEST2( upper_bound, 0, std::less<int>() );
+
+#undef BOOST_RANGE_RETURNS_TEST2
+}
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    using namespace boost;
+
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
+
+    test->add( BOOST_TEST_CASE( &simple_compile_test ) );
+
+    return test;
+}
+
diff --git a/test/algorithm_example.cpp b/test/algorithm_example.cpp
new file mode 100644
index 0000000..80c7875
--- /dev/null
+++ b/test/algorithm_example.cpp
@@ -0,0 +1,92 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/test/test_tools.hpp>
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <utility>
+
+namespace
+{
+    //
+    // example: extracting bounds in a generic algorithm
+    //
+    template< typename Range, typename T >
+    inline typename boost::range_iterator<Range>::type
+    find( Range& c, const T& value )
+    {
+       return std::find( boost::begin( c ), boost::end( c ), value );
+    }
+    
+    template< typename Range, typename T >
+    inline typename boost::range_iterator<Range>::type 
+    find( const Range& c, const T& value )
+    {
+       return std::find( boost::begin( c ), boost::end( c ), value );
+    }
+                   
+    // 
+    // replace first value and return its index
+    //                                
+    template< class Range, class T >
+    inline typename boost::range_difference<Range>::type
+    my_generic_replace( Range& c, const T& value, const T& replacement )
+    {
+       typename boost::range_iterator<Range>::type found = find( c, value );
+       
+       if( found != boost::end( c ) )
+           *found = replacement;
+       return std::distance( boost::begin( c ), found );
+    }                  
+}
+
+
+void check_algorithm()
+{
+    //
+    // usage
+    //
+    const int N = 5;                     
+    std::vector<int> my_vector;
+    int values[] = { 1,2,3,4,5,6,7,8,9 };
+    my_vector.assign( values, values + 9 );
+    typedef std::vector<int>::iterator iterator;
+    std::pair<iterator,iterator>       my_view( boost::begin( my_vector ), 
+                                                boost::begin( my_vector ) + N );
+    BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3 );
+    BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
+
+}
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_algorithm ) );
+
+    return test;
+}
+
+
+
diff --git a/test/algorithm_ext_test/copy_n.cpp b/test/algorithm_ext_test/copy_n.cpp
new file mode 100644
index 0000000..854962f
--- /dev/null
+++ b/test/algorithm_ext_test/copy_n.cpp
@@ -0,0 +1,60 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/copy_n.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_copy_n_impl()
+    {
+        std::vector<std::size_t> source;
+        for (std::size_t i = 0; i < 10; ++i)
+            source.push_back(i);
+
+        for (std::size_t k = 0; k < 10; ++k)
+        {
+            std::vector<std::size_t> reference;
+            for (std::size_t j = 0; j < k; ++j)
+                reference.push_back(j);
+
+            Container test;
+            boost::copy_n(source, k, std::back_inserter(test));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                test.begin(), test.end() );
+        }
+    }
+
+    void test_copy_n()
+    {
+        test_copy_n_impl< std::vector<std::size_t> >();
+        test_copy_n_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.copy_n" );
+
+    test->add( BOOST_TEST_CASE( &test_copy_n ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/erase.cpp b/test/algorithm_ext_test/erase.cpp
new file mode 100644
index 0000000..3bdf2da
--- /dev/null
+++ b/test/algorithm_ext_test/erase.cpp
@@ -0,0 +1,128 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/erase.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_erase_impl()
+    {
+        Container source;
+        for (int i = 0; i < 10; ++i)
+            source.push_back(i);
+
+        Container reference(source);
+        Container test(source);
+
+        typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
+
+        iterator_t first_ref = reference.begin();
+        iterator_t last_ref = reference.end();
+
+        boost::iterator_range< iterator_t > test_range(test.begin(), test.end());
+
+        reference.erase(first_ref, last_ref);
+        boost::erase(test, test_range);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    void test_erase()
+    {
+        test_erase_impl<std::vector<int> >();
+        test_erase_impl<std::list<int> >();
+    }
+
+    template< class Container >
+    void test_remove_erase_impl()
+    {
+        Container source;
+        for (int i = 0; i < 10; ++i)
+            source.push_back(i);
+
+        Container reference(source);
+        Container test(source);
+
+        boost::remove_erase(test, 5);
+
+        reference.erase( std::find(reference.begin(), reference.end(), 5) );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    void test_remove_erase()
+    {
+        test_remove_erase_impl<std::vector<int> >();
+        test_remove_erase_impl<std::list<int> >();
+    }
+
+    struct is_even
+    {
+        typedef bool result_type;
+        typedef int argument_type;
+        bool operator()(int x) const { return x % 2 == 0; }
+    };
+
+    template< class Container >
+    void test_remove_erase_if_impl()
+    {
+        Container source;
+        for (int i = 0; i < 10; ++i)
+            source.push_back(i);
+
+        Container reference;
+        typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iterator_t;
+        iterator_t last_source = source.end();
+        is_even pred;
+        for (iterator_t it_source = source.begin(); it_source != last_source; ++it_source)
+        {
+            if (!pred(*it_source))
+                reference.push_back(*it_source);
+        }
+
+        Container test(source);
+        boost::remove_erase_if(test, is_even());
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+    }
+
+    void test_remove_erase_if()
+    {
+        test_remove_erase_if_impl<std::vector<int> >();
+        test_remove_erase_if_impl<std::list<int> >();
+    }
+
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.erase" );
+
+    test->add( BOOST_TEST_CASE( &test_erase ) );
+    test->add( BOOST_TEST_CASE( &test_remove_erase ) );
+    test->add( BOOST_TEST_CASE( &test_remove_erase_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/for_each_ext.cpp b/test/algorithm_ext_test/for_each_ext.cpp
new file mode 100644
index 0000000..9df16c5
--- /dev/null
+++ b/test/algorithm_ext_test/for_each_ext.cpp
@@ -0,0 +1,98 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/for_each.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    struct MockBinaryFn
+    {
+        typedef void result_type;
+        typedef int first_argument_type;
+        typedef int second_argument_type;
+
+        void operator()(int x, int y)
+        {
+            xs.push_back(x);
+            ys.push_back(y);
+        }
+
+        std::vector<int> xs;
+        std::vector<int> ys;
+    };
+
+    template< class Range1, class Range2 >
+    void test_for_each_impl( Range1& rng1, Range2& rng2 )
+    {
+        MockBinaryFn fn = boost::range::for_each(rng1, rng2, MockBinaryFn());
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( ::boost::begin(rng1), ::boost::end(rng1),
+            fn.xs.begin(), fn.xs.end() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( ::boost::begin(rng2), ::boost::end(rng2),
+            fn.ys.begin(), fn.ys.end() );
+    }
+
+    template< class Collection1, class Collection2 >
+    void test_for_each_impl(const int max_count)
+    {
+        Collection1 c1;
+        for (int i = 0; i < max_count; ++i)
+            c1.push_back(i);
+
+        Collection2 c2;
+        for (int i = 0; i < max_count; ++i)
+            c2.push_back(i);
+
+        test_for_each_impl(c1, c2);
+
+        const Collection1& const_c1 = c1;
+        const Collection2& const_c2 = c2;
+
+        test_for_each_impl(c1, const_c2);
+        test_for_each_impl(const_c1, c2);
+        test_for_each_impl(const_c1, const_c2);
+    }
+
+    template< class Collection1, class Collection2 >
+    void test_for_each_impl()
+    {
+        test_for_each_impl< Collection1, Collection2 >(0);
+        test_for_each_impl< Collection1, Collection2 >(1);
+        test_for_each_impl< Collection1, Collection2 >(10);
+    }
+
+    void test_for_each()
+    {
+        test_for_each_impl< std::vector<int>, std::vector<int> >();
+        test_for_each_impl< std::list<int>, std::list<int> >();
+        test_for_each_impl< std::vector<int>, std::list<int> >();
+        test_for_each_impl< std::list<int>, std::vector<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.for_each" );
+
+    test->add( BOOST_TEST_CASE( &test_for_each ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/insert.cpp b/test/algorithm_ext_test/insert.cpp
new file mode 100644
index 0000000..ff1f706
--- /dev/null
+++ b/test/algorithm_ext_test/insert.cpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/insert.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/irange.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_insert_impl( int n )
+    {
+        Container test;
+        boost::insert( test, test.end(), boost::irange(0, n) );
+
+        Container reference;
+        for (int i = 0; i < n; ++i)
+            reference.push_back(i);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+        // Do it again so that we are inserting into a non-empty target
+        boost::insert( test, test.end(), boost::irange(0, n) );
+
+        for (int j = 0; j < n; ++j)
+            reference.push_back(j);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    template< class Container >
+    void test_insert_impl()
+    {
+        test_insert_impl< Container >(0);
+        test_insert_impl< Container >(1);
+        test_insert_impl< Container >(2);
+        test_insert_impl< Container >(100);
+    }
+
+    void test_insert()
+    {
+        test_insert_impl< std::vector<std::size_t> >();
+        test_insert_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.insert" );
+
+    test->add( BOOST_TEST_CASE( &test_insert ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/iota.cpp b/test/algorithm_ext_test/iota.cpp
new file mode 100644
index 0000000..64d9b0e
--- /dev/null
+++ b/test/algorithm_ext_test/iota.cpp
@@ -0,0 +1,70 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/iota.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_iota_impl(std::size_t n)
+    {
+        Container test;
+        test.resize( n );
+        boost::iota( test, n );
+
+        Container reference;
+        reference.resize( n );
+        std::size_t i = n;
+        typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
+        iterator_t last = reference.end();
+        for (iterator_t it = reference.begin(); it != last; ++it, ++i)
+        {
+            *it = i;
+        }
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+    }
+
+    template< class Container >
+    void test_iota_impl()
+    {
+        test_iota_impl< Container >(0);
+        test_iota_impl< Container >(1);
+        test_iota_impl< Container >(2);
+        test_iota_impl< Container >(100);
+    }
+
+    void test_iota()
+    {
+        test_iota_impl< std::vector<std::size_t> >();
+        test_iota_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.iota" );
+
+    test->add( BOOST_TEST_CASE( &test_iota ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/is_sorted.cpp b/test/algorithm_ext_test/is_sorted.cpp
new file mode 100644
index 0000000..bddc5f8
--- /dev/null
+++ b/test/algorithm_ext_test/is_sorted.cpp
@@ -0,0 +1,62 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/is_sorted.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_is_sorted_impl()
+    {
+        Container ascending;
+        Container descending;
+
+        // Empty ranges are regarded as sorted against any predicate.
+        BOOST_CHECK( boost::is_sorted(ascending) );
+        BOOST_CHECK( boost::is_sorted(ascending, std::less<std::size_t>()) );
+        BOOST_CHECK( boost::is_sorted(ascending, std::greater<std::size_t>()) );
+
+        for (std::size_t i = 0; i < 10; ++i)
+        {
+            ascending.push_back(i);
+            descending.push_back(9 - i);
+        }
+
+        BOOST_CHECK( boost::is_sorted(ascending) );
+        BOOST_CHECK( !boost::is_sorted(descending) );
+        BOOST_CHECK( !boost::is_sorted(ascending, std::greater<std::size_t>()) );
+        BOOST_CHECK( boost::is_sorted(descending, std::greater<std::size_t>()) );
+    }
+
+    void test_is_sorted()
+    {
+        test_is_sorted_impl< std::vector<std::size_t> >();
+        test_is_sorted_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.is_sorted" );
+
+    test->add( BOOST_TEST_CASE( &test_is_sorted ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/overwrite.cpp b/test/algorithm_ext_test/overwrite.cpp
new file mode 100644
index 0000000..0d8604a
--- /dev/null
+++ b/test/algorithm_ext_test/overwrite.cpp
@@ -0,0 +1,74 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/overwrite.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_overwrite_impl(std::size_t n)
+    {
+        Container overwrite_source;
+        for (std::size_t i = 0; i < n; ++i)
+            overwrite_source.push_back(i);
+
+        Container reference;
+        reference.resize(n);
+        std::copy(overwrite_source.begin(), overwrite_source.end(), reference.begin());
+
+        Container test;
+        test.resize(n);
+        boost::overwrite(overwrite_source, test);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+        test.clear();
+        test.resize(n);
+        const Container& const_overwrite_source = overwrite_source;
+        boost::overwrite(const_overwrite_source, test);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    template< class Container >
+    void test_overwrite_impl()
+    {
+        test_overwrite_impl<Container>(0);
+        test_overwrite_impl<Container>(1);
+        test_overwrite_impl<Container>(10);
+    }
+
+    void test_overwrite()
+    {
+        test_overwrite_impl< std::vector<std::size_t> >();
+        test_overwrite_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.overwrite" );
+
+    test->add( BOOST_TEST_CASE( &test_overwrite ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/push_back.cpp b/test/algorithm_ext_test/push_back.cpp
new file mode 100644
index 0000000..7e9d539
--- /dev/null
+++ b/test/algorithm_ext_test/push_back.cpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/irange.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_push_back_impl(std::size_t n)
+    {
+        Container reference;
+        for (std::size_t i = 0; i < n; ++i)
+            reference.push_back(i);
+
+        Container test;
+        boost::push_back(test, boost::irange<std::size_t>(0, n));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+        // Do it again to push onto non-empty container
+        for (std::size_t j = 0; j < n; ++j)
+            reference.push_back(j);
+
+        boost::push_back(test, boost::irange<std::size_t>(0, n));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    template< class Container >
+    void test_push_back_impl()
+    {
+        test_push_back_impl< Container >(0);
+        test_push_back_impl< Container >(1);
+        test_push_back_impl< Container >(2);
+        test_push_back_impl< Container >(100);
+    }
+
+    void test_push_back()
+    {
+        test_push_back_impl< std::vector<std::size_t> >();
+        test_push_back_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.push_back" );
+
+    test->add( BOOST_TEST_CASE( &test_push_back ) );
+
+    return test;
+}
diff --git a/test/algorithm_ext_test/push_front.cpp b/test/algorithm_ext_test/push_front.cpp
new file mode 100644
index 0000000..071a7ce
--- /dev/null
+++ b/test/algorithm_ext_test/push_front.cpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm_ext/push_front.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/irange.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace
+{
+    struct DoubleValue
+    {
+        template< class Value >
+        Value operator()(Value x)
+        {
+            return x * 2;
+        }
+    };
+
+    template< class Container >
+    void test_push_front_impl(std::size_t n)
+    {
+        Container reference;
+        for (std::size_t i = 0; i < n; ++i)
+            reference.push_back(i);
+
+        Container test;
+        boost::push_front(test, boost::irange<std::size_t>(0, n));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+
+        // copy the original reference sequence
+        Container reference_copy(reference);
+        std::transform(reference.begin(), reference.end(), reference.begin(), DoubleValue());
+
+        // Do it again to push onto non-empty container
+        reference.insert(reference.end(), reference_copy.begin(), reference_copy.end());
+
+        boost::push_front(test, boost::irange<std::size_t>(0, n * 2, 2));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+    }
+
+    template< class Container >
+    void test_push_front_impl()
+    {
+        test_push_front_impl< Container >(0);
+        test_push_front_impl< Container >(1);
+        test_push_front_impl< Container >(2);
+        test_push_front_impl< Container >(100);
+    }
+
+    void test_push_front()
+    {
+        test_push_front_impl< std::vector<std::size_t> >();
+        test_push_front_impl< std::list<std::size_t> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.push_front" );
+
+    test->add( BOOST_TEST_CASE( &test_push_front ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/adjacent_find.cpp b/test/algorithm_test/adjacent_find.cpp
new file mode 100644
index 0000000..63b65e8
--- /dev/null
+++ b/test/algorithm_test/adjacent_find.cpp
@@ -0,0 +1,95 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/adjacent_find.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_adjacent_find_impl()
+        {
+            using namespace boost::assign;
+
+            typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
+            typedef BOOST_DEDUCED_TYPENAME Container::const_iterator const_iterator_t;
+
+            Container cont;
+            const Container& cref_cont = cont;
+
+            std::equal_to<int> pred;
+
+            BOOST_CHECK( boost::adjacent_find(cont) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cref_cont) == cref_cont.end() );
+            BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont)) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cont, pred) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cref_cont, pred) == cref_cont.end() );
+            BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont), pred) == cont.end() );
+
+            cont += 1;
+            BOOST_CHECK( boost::adjacent_find(cont) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cref_cont) == cref_cont.end() );
+            BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont)) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cont, pred) == cont.end() );
+            BOOST_CHECK( boost::adjacent_find(cref_cont, pred) == cref_cont.end() );
+            BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont), pred) == cont.end() );
+
+            cont += 2,3,4,5,5,5,6,7,8,9;
+            iterator_t it = boost::adjacent_find(cont);
+            iterator_t it_pred = boost::adjacent_find(cont, pred);
+            BOOST_CHECK( it == it_pred );
+            BOOST_CHECK( it != cont.end() );
+            BOOST_CHECK( it == std::adjacent_find(cont.begin(), cont.end()) );
+            if (it != cont.end())
+            {
+                BOOST_CHECK( *it == 5 );
+            }
+            BOOST_CHECK( it == boost::adjacent_find(boost::make_iterator_range(cont)) );
+            BOOST_CHECK( it_pred == boost::adjacent_find(boost::make_iterator_range(cont), pred) );
+            const_iterator_t cit = boost::adjacent_find(cref_cont);
+            const_iterator_t cit_pred = boost::adjacent_find(cref_cont, pred);
+            BOOST_CHECK( cit == cit_pred );
+            BOOST_CHECK( cit != cref_cont.end() );
+            BOOST_CHECK( cit == std::adjacent_find(cref_cont.begin(), cref_cont.end()) );
+            if (cit != cref_cont.end())
+            {
+                BOOST_CHECK( *cit == 5 );
+            }
+        }
+
+        void test_adjacent_find()
+        {
+            test_adjacent_find_impl< std::vector<int> >();
+            test_adjacent_find_impl< std::list<int> >();
+            test_adjacent_find_impl< std::multiset<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.adjacent_find" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_adjacent_find ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/binary_search.cpp b/test/algorithm_test/binary_search.cpp
new file mode 100644
index 0000000..2646c2e
--- /dev/null
+++ b/test/algorithm_test/binary_search.cpp
@@ -0,0 +1,126 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/binary_search.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test(Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            bool reference_result
+                = std::binary_search(reference.begin(), reference.end(), 5);
+
+            bool test_result = boost::binary_search(test, 5);
+
+            BOOST_CHECK( reference_result == test_result );
+
+            BOOST_CHECK( test_result == boost::binary_search(boost::make_iterator_range(test), 5) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_pred(Container& cont, BinaryPredicate pred)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            sort_container(reference, pred);
+            sort_container(test, pred);
+
+            bool reference_result
+                = std::binary_search(reference.begin(), reference.end(), 5,
+                                        pred);
+
+            bool test_result = boost::binary_search(test, 5, pred);
+
+            BOOST_CHECK( test_result == boost::binary_search(boost::make_iterator_range(test), 5, pred) );
+
+            BOOST_CHECK( reference_result == test_result );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+        }
+
+        template<class Container>
+        void test_binary_search_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+
+            test(cont);
+            test_pred(cont, std::less<int>());
+            test_pred(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1;
+            test(cont);
+            test_pred(cont, std::less<int>());
+            test_pred(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test(cont);
+            test_pred(cont, std::less<int>());
+            test_pred(cont, std::greater<int>());
+        }
+
+        void test_binary_search()
+        {
+            test_binary_search_impl< std::vector<int> >();
+            test_binary_search_impl< std::list<int> >();
+            test_binary_search_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.binary_search" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_binary_search ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/copy.cpp b/test/algorithm_test/copy.cpp
new file mode 100644
index 0000000..4b9fcc2
--- /dev/null
+++ b/test/algorithm_test/copy.cpp
@@ -0,0 +1,74 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_copy_impl()
+        {
+            Container source;
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> target;
+            target.resize(source.size());
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator< std::vector<value_t> >::type iterator_t;
+            iterator_t it = boost::copy(source, target.begin());
+
+            BOOST_CHECK( it == target.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                target.begin(), target.end(),
+                source.begin(), source.end()
+                );
+
+            it = boost::copy(boost::make_iterator_range(source), target.begin());
+            
+            BOOST_CHECK( it == target.end() );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
+                                          source.begin(), source.end());
+        }
+
+        void test_copy()
+        {
+            test_copy_impl< std::vector<int> >();
+            test_copy_impl< std::list<int> >();
+            test_copy_impl< std::set<int> >();
+            test_copy_impl< std::multiset<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.copy" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_copy ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/copy_backward.cpp b/test/algorithm_test/copy_backward.cpp
new file mode 100644
index 0000000..4879c28
--- /dev/null
+++ b/test/algorithm_test/copy_backward.cpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Credits:
+//  awulkiew highlighted that this test was not successfully testing the
+//  algorithm.
+//
+#include <boost/range/algorithm/copy_backward.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+template<typename Container>
+void test_copy_backward_impl(std::size_t n)
+{
+    Container source;
+    typedef typename Container::value_type value_t;
+    for (std::size_t i = 0; i < n; ++i)
+        source.push_back(static_cast<value_t>(i));
+
+    std::vector<value_t> target(n);
+
+    typedef typename boost::range_iterator<
+        std::vector<value_t>
+    >::type iterator_t;
+
+    iterator_t it = boost::copy_backward(source, target.end());
+
+    BOOST_CHECK(it == target.begin());
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
+                                  source.begin(), source.end());
+
+    BOOST_CHECK(it == boost::copy_backward(
+                        boost::make_iterator_range(source), target.end()));
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
+                                  source.begin(), source.end());
+}
+
+template<typename Container>
+void test_copy_backward_impl()
+{
+    test_copy_backward_impl<Container>(0u);
+    test_copy_backward_impl<Container>(1u);
+    test_copy_backward_impl<Container>(100u);
+}
+
+void test_copy_backward()
+{
+    test_copy_backward_impl<std::vector<int> >();
+    test_copy_backward_impl<std::list<int> >();
+}
+    } // anonymous namespace
+} // namespace boost_range_test
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE("RangeTestSuite.algorithm.copy_backward");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_copy_backward));
+
+    return test;
+}
diff --git a/test/algorithm_test/copy_n.cpp b/test/algorithm_test/copy_n.cpp
new file mode 100644
index 0000000..230eb03
--- /dev/null
+++ b/test/algorithm_test/copy_n.cpp
@@ -0,0 +1,70 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/copy_n.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace
+{
+    template< class Container >
+    void test_copy_n_impl()
+    {
+        Container source;
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+        std::vector<value_t> target;
+        target.resize(source.size());
+
+        typedef BOOST_DEDUCED_TYPENAME range_iterator< std::vector<value_t> >::type iterator_t;
+        iterator_t it = boost::copy(source, target.begin());
+
+        BOOST_CHECK( it == target.end() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(
+            target.begin(), target.end(),
+            source.begin(), source.end()
+            );
+
+        it = boost::copy(boost::make_iterator_range(source), target.begin());
+
+        BOOST_CHECK( it == target.end() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
+                                      source.begin(), source.end());
+    }
+
+    void test_copy_n()
+    {
+        test_copy_n_impl< std::vector<int> >();
+        test_copy_n_impl< std::list<int> >();
+        test_copy_n_impl< std::set<int> >();
+        test_copy_n_impl< std::multiset<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.copy_n" );
+
+    test->add( BOOST_TEST_CASE( &::test_copy_n ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/count.cpp b/test/algorithm_test/count.cpp
new file mode 100644
index 0000000..90b2090
--- /dev/null
+++ b/test/algorithm_test/count.cpp
@@ -0,0 +1,85 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/count.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_count_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            const Container& cref_cont = cont;
+
+            BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
+
+            cont += 1;
+            BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
+
+            cont += 2,3,4,5,6,7,8,9;
+            BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
+
+            cont += 2;
+            BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
+            BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
+            BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
+            BOOST_CHECK_EQUAL( 2u, boost::count(cont, 2u) );
+            BOOST_CHECK_EQUAL( 2u, boost::count(cref_cont, 2u) );
+            BOOST_CHECK_EQUAL( 2u, boost::count(boost::make_iterator_range(cont), 2u) );
+        }
+
+        void test_count()
+        {
+            test_count_impl< std::vector<int> >();
+            test_count_impl< std::list<int> >();
+            test_count_impl< std::multiset<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.count" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_count ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/count_if.cpp b/test/algorithm_test/count_if.cpp
new file mode 100644
index 0000000..e028741
--- /dev/null
+++ b/test/algorithm_test/count_if.cpp
@@ -0,0 +1,100 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/count_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_function/false_predicate.hpp"
+#include "../test_function/true_predicate.hpp"
+#include "../test_function/equal_to_x.hpp"
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_count_if_impl()
+        {
+            using namespace boost::range_test_function;
+            using namespace boost::assign;
+
+            typedef equal_to_x<int> pred_t;
+            typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BOOST_DEDUCED_TYPENAME Container::iterator>::difference_type diff_t;
+
+            Container cont;
+            const Container& cref_cont = cont;
+
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
+
+            cont += 1;
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
+
+            cont += 2,3,4,5,6,7,8,9;
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
+
+            cont += 2;
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
+            BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
+            BOOST_CHECK_EQUAL( 2u, boost::count_if(cont, pred_t(2)) );
+            BOOST_CHECK_EQUAL( 2u, boost::count_if(cref_cont, pred_t(2)) );
+            BOOST_CHECK_EQUAL( 2u, boost::count_if(boost::make_iterator_range(cont), pred_t(2)) );
+
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, false_predicate()) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, false_predicate()) );
+            BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), false_predicate()) );
+
+            BOOST_CHECK_EQUAL( static_cast<diff_t>(cont.size()), boost::count_if(cont, true_predicate()) );
+            BOOST_CHECK_EQUAL( static_cast<diff_t>(cont.size()), boost::count_if(cref_cont, true_predicate()) );
+            BOOST_CHECK_EQUAL( static_cast<diff_t>(cont.size()), boost::count_if(boost::make_iterator_range(cont), true_predicate()) );
+        }
+
+        void test_count_if()
+        {
+            test_count_if_impl< std::vector<int> >();
+            test_count_if_impl< std::list<int> >();
+            test_count_if_impl< std::multiset<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.count_if" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_count_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/equal.cpp b/test/algorithm_test/equal.cpp
new file mode 100644
index 0000000..243f064
--- /dev/null
+++ b/test/algorithm_test/equal.cpp
@@ -0,0 +1,143 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/equal.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container1, class Container2 >
+        void test_equal_impl()
+        {
+            using namespace boost::assign;
+
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
+
+            container1_t mcont1;
+            container2_t mcont2;
+
+            Container1& cont1 = mcont1;
+            Container2& cont2 = mcont2;
+
+            BOOST_CHECK( boost::equal(cont1, cont2) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(cont1, cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+
+            mcont1 += 1;
+            BOOST_CHECK( !boost::equal(cont1, cont2) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+
+            mcont1.clear();
+            mcont2 += 1;
+            BOOST_CHECK( !boost::equal(cont1, cont2) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+
+            mcont1 += 1;
+            BOOST_CHECK( boost::equal(cont1, cont2) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+
+            mcont1 += 2,3,4,5,6,7,8,9;
+            mcont2 += 2,3,4,5,6,7,8,9;
+            BOOST_CHECK( boost::equal(cont1, cont2) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+            BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
+        }
+
+        template< class Container1, class Container2 >
+        void test_driver()
+        {
+            typedef Container1 container1_t;
+            typedef Container2 container2_t;
+            typedef BOOST_DEDUCED_TYPENAME boost::add_const<Container1>::type const_container1_t;
+            typedef BOOST_DEDUCED_TYPENAME boost::add_const<Container2>::type const_container2_t;
+
+            test_equal_impl< const_container1_t, const_container2_t >();
+            test_equal_impl< const_container1_t, container2_t >();
+            test_equal_impl< container1_t, const_container2_t >();
+            test_equal_impl< container1_t, container2_t >();
+        }
+
+        void test_equal()
+        {
+            test_driver< std::list<int>, std::list<int> >();
+            test_driver< std::vector<int>, std::vector<int> >();
+            test_driver< std::set<int>, std::set<int> >();
+            test_driver< std::multiset<int>, std::multiset<int> >();
+            test_driver< std::list<int>, std::vector<int> >();
+            test_driver< std::vector<int>, std::list<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.equal" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_equal ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/equal_range.cpp b/test/algorithm_test/equal_range.cpp
new file mode 100644
index 0000000..612f1a4
--- /dev/null
+++ b/test/algorithm_test/equal_range.cpp
@@ -0,0 +1,181 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/equal_range.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container, class Pair>
+        void check_result(
+            const Container& reference,
+            Pair             reference_pair,
+            const Container& test,
+            Pair             test_pair
+            )
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<const Container>::type
+                const_iterator_t;
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+
+            BOOST_CHECK_EQUAL(
+                std::distance<const_iterator_t>(reference.begin(), reference_pair.first),
+                std::distance<const_iterator_t>(test.begin(), test_pair.first)
+                );
+
+            BOOST_CHECK_EQUAL(
+                std::distance<const_iterator_t>(reference.begin(), reference_pair.second),
+                std::distance<const_iterator_t>(test.begin(), test_pair.second)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_pair.first, reference_pair.second,
+                test_pair.first, test_pair.second
+                );
+        }
+
+        template<class Container>
+        void test(Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+            typedef std::pair<iterator_t, iterator_t> pair_t;
+
+            pair_t reference_result
+                = std::equal_range(reference.begin(), reference.end(), 5);
+
+            pair_t test_result = boost::equal_range(test, 5);
+
+            check_result(reference, reference_result, test, test_result);
+
+            pair_t test_result2 = boost::equal_range(boost::make_iterator_range(test), 5);
+
+            check_result(reference, reference_result, test, test_result2);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_pred(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
+
+            container_t reference_temp(cont);
+            container_t test_temp(cont);
+
+            sort_container(reference_temp, pred);
+            sort_container(test_temp, pred);
+
+            Container reference(reference_temp);
+            Container test(test_temp);
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+            typedef std::pair<iterator_t, iterator_t> pair_t;
+
+            pair_t reference_result
+                = std::equal_range(reference.begin(), reference.end(), 5,
+                                    BinaryPredicate());
+
+            pair_t test_result = boost::equal_range(test, 5, BinaryPredicate());
+
+            check_result(reference, reference_result, test, test_result);
+
+            pair_t test_result2 = boost::equal_range(boost::make_iterator_range(test), 5, BinaryPredicate());
+
+            check_result(reference, reference_result, test, test_result2);
+        }
+
+        template<class Container>
+        void test_driver(const Container& cont)
+        {
+            Container mutable_cont(cont);
+            test(mutable_cont);
+
+            test(cont);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_pred_driver(const Container& cont, BinaryPredicate pred)
+        {
+            Container mutable_cont(cont);
+            test_pred(mutable_cont, pred);
+
+            test_pred(cont, pred);
+        }
+
+        template<class Container>
+        void test_equal_range_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+
+            test_driver(cont);
+            test_pred_driver(cont, std::less<int>());
+            test_pred_driver(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1;
+            test_driver(cont);
+            test_pred_driver(cont, std::less<int>());
+            test_pred_driver(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_driver(cont);
+            test_pred_driver(cont, std::less<int>());
+            test_pred_driver(cont, std::greater<int>());
+        }
+
+        void test_equal_range()
+        {
+            test_equal_range_impl< std::vector<int> >();
+            test_equal_range_impl< std::list<int> >();
+            test_equal_range_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.equal_range" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_equal_range ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/fill.cpp b/test/algorithm_test/fill.cpp
new file mode 100644
index 0000000..2f975c4
--- /dev/null
+++ b/test/algorithm_test/fill.cpp
@@ -0,0 +1,86 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/fill.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_fill_impl(Container& cont)
+        {
+            Container reference(cont);
+            std::fill(reference.begin(), reference.end(), 1);
+
+            Container target(cont);
+            boost::fill(target, 1);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                target.begin(), target.end() );
+
+            Container target2(cont);
+            boost::fill(boost::make_iterator_range(target2), 1);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target2.begin(), target2.end() );
+        }
+
+        template< class Container >
+        void test_fill_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_fill_impl(cont);
+
+            cont.clear();
+            cont += 2;
+            test_fill_impl(cont);
+
+            cont.clear();
+            cont += 1,2;
+            test_fill_impl(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_fill_impl(cont);
+        }
+
+        void test_fill()
+        {
+            test_fill_impl< std::vector<int> >();
+            test_fill_impl< std::list<int> >();
+            test_fill_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.fill" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_fill ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/find.cpp b/test/algorithm_test/find.cpp
new file mode 100644
index 0000000..02c9f71
--- /dev/null
+++ b/test/algorithm_test/find.cpp
@@ -0,0 +1,131 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/find.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_find
+{
+    class find_test_policy
+    {
+    public:
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::find(cont, 3);
+            iter_t result2 = boost::find(boost::make_iterator_range(cont), 3);
+            BOOST_CHECK( result == result2 );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find<return_type>(cont, 3);
+                result_t result2 = boost::find<return_type>(boost::make_iterator_range(cont), 3);
+                BOOST_CHECK( result == result2 );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find(cont.begin(), cont.end(), 3);
+        }
+    };
+
+    template<class Container>
+    void test_find_container()
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t mcont;
+        Container& cont = mcont;
+        test_driver(cont, find_test_policy());
+
+        mcont.clear();
+        mcont += 1;
+        test_driver(cont, find_test_policy());
+
+        mcont.clear();
+        mcont += 1,2,3,4,5,6,7,8,9;
+        test_driver(cont, find_test_policy());
+    }
+
+    void test_find()
+    {
+        test_find_container< std::vector<int> >();
+        test_find_container< std::list<int> >();
+        test_find_container< std::deque<int> >();
+
+        test_find_container< const std::vector<int> >();
+        test_find_container< const std::list<int> >();
+        test_find_container< const std::deque<int> >();
+
+        std::vector<int> vi;
+        const std::vector<int>& cvi = vi;
+        std::vector<int>::const_iterator it = boost::find(vi, 0);
+        std::vector<int>::const_iterator it2 = boost::find(cvi, 0);
+        BOOST_CHECK( it == it2 );
+    }
+    
+    // The find algorithm can be used like a "contains" algorithm
+    // since the returned iterator_range is convertible to bool.
+    // Therefore if the return value is an empty range it will
+    // convert to the equivalent to "false" whereas a range that
+    // is not empty will convert to "true". Therefore one can
+    // use the syntax boost::find<boost::return_found_end>(rng, x)
+    // as a contains function.
+    void test_find_as_contains()
+    {
+        std::list<int> l;
+        for (int i = 0; i < 10; ++i)
+            l.push_back(i);
+        
+        BOOST_CHECK(boost::find<boost::return_found_end>(l, 3));
+        BOOST_CHECK(!boost::find<boost::return_found_end>(l, 10));
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find::test_find ) );
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find::test_find_as_contains ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/find_end.cpp b/test/algorithm_test/find_end.cpp
new file mode 100644
index 0000000..b4d77a0
--- /dev/null
+++ b/test/algorithm_test/find_end.cpp
@@ -0,0 +1,200 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/find_end.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <set>
+#include <list>
+
+namespace boost_range_test_algorithm_find_end
+{
+    template<class Container2>
+    class find_end_test_policy
+    {
+        typedef Container2 container2_t;
+    public:
+        explicit find_end_test_policy(const Container2& cont)
+            :   m_cont(cont)
+        {
+        }
+
+        container2_t cont() { return m_cont; }
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::find_end(cont, m_cont);
+            BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), m_cont) );
+            BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(m_cont)) );
+            BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find_end<return_type>(cont, policy.cont());
+                BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont), policy.cont()) );
+                BOOST_CHECK( result == boost::find_end<return_type>(cont, boost::make_iterator_range(policy.cont())) );
+                BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont),
+                                                                    boost::make_iterator_range(policy.cont())) );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find_end(cont.begin(), cont.end(),
+                                 m_cont.begin(), m_cont.end());
+        }
+
+    private:
+        Container2 m_cont;
+    };
+
+    template<class Container2, class BinaryPredicate>
+    class find_end_pred_test_policy
+    {
+        typedef Container2 container2_t;
+    public:
+        explicit find_end_pred_test_policy(const Container2& cont)
+            :   m_cont(cont)
+        {
+        }
+
+        container2_t& cont() { return m_cont; }
+        BinaryPredicate& pred() { return m_pred; }
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t it = boost::find_end(cont, m_cont, m_pred);
+            BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), m_cont, m_pred) );
+            BOOST_CHECK( it == boost::find_end(cont, boost::make_iterator_range(m_cont), m_pred) );
+            BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) );
+            return it;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find_end<return_type>(cont, policy.cont(), policy.pred());
+                BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont), policy.cont(), policy.pred()) );
+                BOOST_CHECK( result == boost::find_end<return_type>(cont, boost::make_iterator_range(policy.cont()), policy.pred()) );
+                BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont),
+                                                                    boost::make_iterator_range(policy.cont()), policy.pred()) );
+                return boost::find_end<return_type>(cont, policy.cont(), policy.pred());
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find_end(cont.begin(), cont.end(),
+                                 m_cont.begin(), m_cont.end(),
+                                 m_pred);
+        }
+
+    private:
+        Container2      m_cont;
+        BinaryPredicate m_pred;
+    };
+
+    template<class Container1, class Container2>
+    void run_tests(Container1& cont1, Container2& cont2)
+    {
+        boost::range_test::range_return_test_driver test_driver;
+        test_driver(cont1, find_end_test_policy<Container2>(cont2));
+        test_driver(cont1, find_end_pred_test_policy<Container2, std::less<int> >(cont2));
+        test_driver(cont2, find_end_pred_test_policy<Container2, std::greater<int> >(cont2));
+    }
+
+    template<class Container1, class Container2>
+    void test_find_end_impl()
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
+
+        container1_t mcont1;
+        Container1& cont1 = mcont1;
+        container2_t mcont2;
+        Container2& cont2 = mcont2;
+
+        run_tests(cont1, cont2);
+
+        mcont1 += 1;
+        run_tests(cont1, cont2);
+
+        mcont2 += 1;
+        run_tests(cont1, cont2);
+
+        mcont1 += 2,3,4,5,6,7,8,9;
+        mcont2 += 2,3,4;
+        run_tests(cont1, cont2);
+
+        mcont2.clear();
+        mcont2 += 7,8,9;
+        run_tests(cont1, cont2);
+    }
+
+    void test_find_end()
+    {
+        test_find_end_impl< std::vector<int>, std::vector<int> >();
+        test_find_end_impl< std::list<int>, std::list<int> >();
+        test_find_end_impl< std::deque<int>, std::deque<int> >();
+        test_find_end_impl< const std::vector<int>, const std::vector<int> >();
+        test_find_end_impl< const std::list<int>, const std::list<int> >();
+        test_find_end_impl< const std::deque<int>, const std::deque<int> >();
+        test_find_end_impl< const std::vector<int>, const std::list<int> >();
+        test_find_end_impl< const std::list<int>, const std::vector<int> >();
+        test_find_end_impl< const std::vector<int>, std::list<int> >();
+        test_find_end_impl< const std::list<int>, std::vector<int> >();
+        test_find_end_impl< std::vector<int>, std::list<int> >();
+        test_find_end_impl< std::list<int>, std::vector<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_end" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_end::test_find_end ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/find_first_of.cpp b/test/algorithm_test/find_first_of.cpp
new file mode 100644
index 0000000..296b8fc
--- /dev/null
+++ b/test/algorithm_test/find_first_of.cpp
@@ -0,0 +1,198 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/find_first_of.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <set>
+#include <list>
+
+namespace boost_range_test_algorithm_find_first_of
+{
+    template<class Container2>
+    class find_first_of_test_policy
+    {
+        typedef Container2 container2_t;
+    public:
+        explicit find_first_of_test_policy(const Container2& cont)
+            :   m_cont(cont)
+        {
+        }
+
+        container2_t& cont() { return m_cont; }
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::find_first_of(cont, m_cont);
+            BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont) );
+            BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont)) );
+            BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find_first_of<return_type>(cont, policy.cont());
+                BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont()) );
+                BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont())) );
+                BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont())) );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find_first_of(cont.begin(), cont.end(),
+                                 m_cont.begin(), m_cont.end());
+        }
+
+    private:
+        Container2 m_cont;
+    };
+
+    template<class Container2, class BinaryPredicate>
+    class find_first_of_pred_test_policy
+    {
+        typedef Container2 container2_t;
+    public:
+        explicit find_first_of_pred_test_policy(const Container2& cont)
+            :   m_cont(cont)
+        {
+        }
+
+        container2_t& cont() { return m_cont; }
+        BinaryPredicate& pred() { return m_pred; }
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::find_first_of(cont, m_cont, m_pred);
+            BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont, m_pred) );
+            BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont), m_pred) );
+            BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find_first_of<return_type>(cont, policy.cont(), policy.pred());
+                BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont(), policy.pred()) );
+                BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont()), policy.pred()) );
+                BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont()), policy.pred()) );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find_first_of(cont.begin(), cont.end(),
+                                      m_cont.begin(), m_cont.end(),
+                                      m_pred);
+        }
+
+    private:
+        Container2      m_cont;
+        BinaryPredicate m_pred;
+    };
+
+    template<class Container1, class Container2>
+    void run_tests(Container1& cont1, Container2& cont2)
+    {
+        boost::range_test::range_return_test_driver test_driver;
+        test_driver(cont1, find_first_of_test_policy<Container2>(cont2));
+        test_driver(cont1, find_first_of_pred_test_policy<Container2, std::less<int> >(cont2));
+        test_driver(cont2, find_first_of_pred_test_policy<Container2, std::greater<int> >(cont2));
+    }
+
+    template<class Container1, class Container2>
+    void test_find_first_of_impl()
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
+
+        container1_t mcont1;
+        Container1& cont1 = mcont1;
+        container2_t mcont2;
+        Container2& cont2 = mcont2;
+
+        run_tests(cont1, cont2);
+
+        mcont1 += 1;
+        run_tests(cont1, cont2);
+
+        mcont2 += 1;
+        run_tests(cont1, cont2);
+
+        mcont1 += 2,3,4,5,6,7,8,9;
+        mcont2 += 2,3,4;
+        run_tests(cont1, cont2);
+
+        mcont2.clear();
+        mcont2 += 7,8,9;
+        run_tests(cont1, cont2);
+    }
+
+    void test_find_first_of()
+    {
+        test_find_first_of_impl< std::vector<int>, std::vector<int> >();
+        test_find_first_of_impl< std::list<int>, std::list<int> >();
+        test_find_first_of_impl< std::deque<int>, std::deque<int> >();
+        test_find_first_of_impl< const std::vector<int>, const std::vector<int> >();
+        test_find_first_of_impl< const std::list<int>, const std::list<int> >();
+        test_find_first_of_impl< const std::deque<int>, const std::deque<int> >();
+        test_find_first_of_impl< const std::vector<int>, const std::list<int> >();
+        test_find_first_of_impl< const std::list<int>, const std::vector<int> >();
+        test_find_first_of_impl< const std::vector<int>, std::list<int> >();
+        test_find_first_of_impl< const std::list<int>, std::vector<int> >();
+        test_find_first_of_impl< std::vector<int>, std::list<int> >();
+        test_find_first_of_impl< std::list<int>, std::vector<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_first_of" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_first_of::test_find_first_of ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/find_if.cpp b/test/algorithm_test/find_if.cpp
new file mode 100644
index 0000000..3ab22c9
--- /dev/null
+++ b/test/algorithm_test/find_if.cpp
@@ -0,0 +1,126 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/find_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include "../test_function/greater_than_x.hpp"
+#include "../test_function/false_predicate.hpp"
+#include <algorithm>
+#include <functional>
+#include <deque>
+#include <list>
+#include <vector>
+
+namespace boost_range_test_algorithm_find_if
+{
+    template<class UnaryPredicate>
+    class find_if_test_policy
+    {
+    public:
+        explicit find_if_test_policy(UnaryPredicate pred)
+            : m_pred(pred) {}
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::find_if(cont, m_pred);
+            BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), m_pred) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(find_if_test_policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::find_if<return_type>(cont, policy.pred());
+                BOOST_CHECK( result == boost::find_if<return_type>(boost::make_iterator_range(cont), policy.pred()) );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::find_if(cont.begin(), cont.end(), m_pred);
+        }
+
+        UnaryPredicate& pred() { return m_pred; }
+
+    private:
+        UnaryPredicate m_pred;
+    };
+
+    template<class UnaryPredicate>
+    find_if_test_policy<UnaryPredicate>
+    make_policy(UnaryPredicate pred)
+    {
+        return find_if_test_policy<UnaryPredicate>(pred);
+    }
+
+    template<class Container>
+    void test_find_if_container()
+    {
+        using namespace boost::assign;
+        using namespace boost::range_test_function;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t mcont;
+        Container& cont = mcont;
+        test_driver(cont, make_policy(greater_than_x<int>(5)));
+        test_driver(cont, make_policy(false_predicate()));
+
+        mcont.clear();
+        mcont += 1;
+        test_driver(cont, make_policy(greater_than_x<int>(5)));
+        test_driver(cont, make_policy(false_predicate()));
+
+        mcont.clear();
+        mcont += 1,2,3,4,5,6,7,8,9;
+        test_driver(cont, make_policy(greater_than_x<int>(5)));
+        test_driver(cont, make_policy(false_predicate()));
+    }
+
+    void test_find_if()
+    {
+        test_find_if_container< std::vector<int> >();
+        test_find_if_container< std::list<int> >();
+        test_find_if_container< std::deque<int> >();
+
+        test_find_if_container< const std::vector<int> >();
+        test_find_if_container< const std::list<int> >();
+        test_find_if_container< const std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_if" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_if::test_find_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/for_each.cpp b/test/algorithm_test/for_each.cpp
new file mode 100644
index 0000000..701d676
--- /dev/null
+++ b/test/algorithm_test/for_each.cpp
@@ -0,0 +1,95 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/for_each.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/array.hpp>
+#include <boost/assign.hpp>
+#include <boost/range/algorithm.hpp>
+
+#include <list>
+#include <set>
+#include <vector>
+#include "../test_function/check_equal_fn.hpp"
+
+namespace boost
+{
+    namespace
+    {
+        template< class Range >
+        unsigned int udistance(Range& rng)
+        {
+            return static_cast<unsigned int>(boost::distance(rng));
+        }
+
+        template< class SinglePassRange >
+        void test_for_each_impl( SinglePassRange rng )
+        {
+            using namespace boost::range_test_function;
+
+            typedef check_equal_fn< SinglePassRange > fn_t;
+
+            // Test the mutable version
+            fn_t result_fn = boost::for_each(rng, fn_t(rng));
+            BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn.invocation_count() );
+            
+            fn_t result_fn2 = boost::for_each(boost::make_iterator_range(rng), fn_t(rng));
+            BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn2.invocation_count() );
+
+            // Test the constant version
+            const SinglePassRange& cref_rng = rng;
+            result_fn = boost::for_each(cref_rng, fn_t(cref_rng));
+            BOOST_CHECK_EQUAL( boost::udistance(cref_rng), result_fn.invocation_count() );
+        }
+
+        template< class Container >
+        void test_for_each_t()
+        {
+            using namespace boost::assign;
+
+            // Test empty
+            Container cont;
+            test_for_each_impl(cont);
+
+            // Test one element
+            cont += 0;
+            test_for_each_impl(cont);
+
+            // Test many elements
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_for_each_impl(cont);
+        }
+
+        void test_for_each()
+        {
+            boost::array<int, 10> a = {{ 0,1,2,3,4,5,6,7,8,9 }};
+            test_for_each_impl(a);
+
+            test_for_each_t< std::vector<int> >();
+            test_for_each_t< std::list<int> >();
+            test_for_each_t< std::set<int> >();
+            test_for_each_t< std::multiset<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.for_each" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_for_each ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/generate.cpp b/test/algorithm_test/generate.cpp
new file mode 100644
index 0000000..d8fc0e6
--- /dev/null
+++ b/test/algorithm_test/generate.cpp
@@ -0,0 +1,96 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/generate.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        class generator_fn
+        {
+        public:
+            typedef int result_type;
+
+            generator_fn() : m_count(0) {}
+            int operator()() { return ++m_count; }
+
+        private:
+            int m_count;
+        };
+
+        template< class Container >
+        void test_generate_impl(Container& cont)
+        {
+            Container reference(cont);
+            std::generate(reference.begin(), reference.end(), generator_fn());
+
+            Container test(cont);
+            boost::generate(test, generator_fn());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                test.begin(), test.end() );
+                
+            Container test2(cont);
+            boost::generate(boost::make_iterator_range(test2), generator_fn());
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template< class Container >
+        void test_generate_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_generate_impl(cont);
+
+            cont.clear();
+            cont += 9;
+            test_generate_impl(cont);
+
+            cont.clear();
+            cont += 9,8,7,6,5,4,3,2,1;
+            test_generate_impl(cont);
+        }
+
+        void test_generate()
+        {
+            test_generate_impl< std::vector<int> >();
+            test_generate_impl< std::list<int> >();
+            test_generate_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.generate" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_generate ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/heap.cpp b/test/algorithm_test/heap.cpp
new file mode 100644
index 0000000..74b7fa3
--- /dev/null
+++ b/test/algorithm_test/heap.cpp
@@ -0,0 +1,145 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/heap_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Container2>
+        void check_equal(const Container1& cont1, const Container2& cont2)
+        {
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                cont1.begin(), cont1.end(),
+                cont2.begin(), cont2.end()
+                );
+        }
+
+        void test()
+        {
+            using namespace boost::assign;
+
+            std::vector<int> reference;
+            reference += 1,2,3,4,5,6,7,8,9;
+
+            std::vector<int> test_cont(reference);
+            std::vector<int> test_cont2(reference);
+
+            std::make_heap(reference.begin(), reference.end());
+            boost::make_heap(test_cont);
+            check_equal(reference, test_cont);
+            boost::make_heap(boost::make_iterator_range(test_cont2));
+            check_equal(reference, test_cont2);
+
+            std::push_heap(reference.begin(), reference.end());
+            boost::push_heap(test_cont);
+            check_equal(reference, test_cont);
+            boost::push_heap(boost::make_iterator_range(test_cont2));
+            check_equal(reference, test_cont2);
+
+            std::make_heap(reference.begin(), reference.end());
+            boost::make_heap(test_cont);
+            boost::make_heap(boost::make_iterator_range(test_cont2));
+
+            std::sort_heap(reference.begin(), reference.end());
+            boost::sort_heap(test_cont);
+            check_equal(reference, test_cont);
+            boost::sort_heap(boost::make_iterator_range(test_cont2));
+            check_equal(reference, test_cont2);
+
+            std::make_heap(reference.begin(), reference.end());
+            boost::make_heap(test_cont);
+            boost::make_heap(boost::make_iterator_range(test_cont2));
+
+            std::pop_heap(reference.begin(), reference.end());
+            boost::pop_heap(test_cont);
+            check_equal(reference, test_cont);
+            boost::pop_heap(boost::make_iterator_range(test_cont2));
+            check_equal(reference, test_cont2);
+        }
+
+        template<class BinaryPredicate>
+        void test_pred(BinaryPredicate pred)
+        {
+            using namespace boost::assign;
+
+            std::vector<int> reference;
+            reference += 1,2,3,4,5,6,7,8,9;
+            std::sort(reference.begin(), reference.end(), pred);
+
+            std::vector<int> test_cont(reference);
+            std::vector<int> test_cont2(reference);
+
+            std::make_heap(reference.begin(), reference.end(), pred);
+            boost::make_heap(test_cont, pred);
+            check_equal(reference, test_cont);
+            boost::make_heap(boost::make_iterator_range(test_cont2), pred);
+            check_equal(reference, test_cont2);
+
+            reference.push_back(5);
+            test_cont.push_back(5);
+            test_cont2.push_back(5);
+            std::push_heap(reference.begin(), reference.end(), pred);
+            boost::push_heap(test_cont, pred);
+            check_equal(reference, test_cont);
+            boost::push_heap(boost::make_iterator_range(test_cont2), pred);
+            check_equal(reference, test_cont2);
+
+            std::make_heap(reference.begin(), reference.end(), pred);
+            boost::make_heap(test_cont, pred);
+            boost::make_heap(boost::make_iterator_range(test_cont2), pred);
+
+            std::sort_heap(reference.begin(), reference.end(), pred);
+            boost::sort_heap(test_cont, pred);
+            check_equal(reference, test_cont);
+            boost::sort_heap(boost::make_iterator_range(test_cont2), pred);
+            check_equal(reference, test_cont2);
+
+            std::make_heap(reference.begin(), reference.end(), pred);
+            boost::make_heap(test_cont, pred);
+            boost::make_heap(boost::make_iterator_range(test_cont2), pred);
+
+            std::pop_heap(reference.begin(), reference.end(), pred);
+            boost::pop_heap(test_cont, pred);
+            check_equal(reference, test_cont);
+            boost::pop_heap(boost::make_iterator_range(test_cont2), pred);
+            check_equal(reference, test_cont2);
+        }
+
+        void test_heap()
+        {
+            test();
+            test_pred(std::less<int>());
+            test_pred(std::greater<int>());
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.heap" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_heap ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/includes.cpp b/test/algorithm_test/includes.cpp
new file mode 100644
index 0000000..8977532
--- /dev/null
+++ b/test/algorithm_test/includes.cpp
@@ -0,0 +1,165 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            Container1 old_cont1(cont1);
+            Container2 old_cont2(cont2);
+
+            bool reference_result
+                = std::includes(cont1.begin(), cont1.end(),
+                                cont2.begin(), cont2.end());
+
+            bool test_result = boost::includes(cont1, cont2);
+
+            BOOST_CHECK( reference_result == test_result );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                old_cont1.begin(), old_cont1.end(),
+                cont1.begin(), cont1.end()
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                old_cont2.begin(), old_cont2.end(),
+                cont2.begin(), cont2.end()
+                );
+                
+            BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( test_result == boost::includes(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2,
+                       BinaryPredicate pred)
+        {
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            Container1 old_cont1(cont1);
+            Container2 old_cont2(cont2);
+
+            bool reference_result
+                = std::includes(cont1.begin(), cont1.end(),
+                                cont2.begin(), cont2.end(),
+                                pred);
+
+            bool test_result = boost::includes(cont1, cont2, pred);
+
+            BOOST_CHECK( reference_result == test_result );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                old_cont1.begin(), old_cont1.end(),
+                cont1.begin(), cont1.end()
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                old_cont2.begin(), old_cont2.end(),
+                cont2.begin(), cont2.end()
+                );
+                
+            BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), cont2, pred) );
+            BOOST_CHECK( test_result == boost::includes(cont1, boost::make_iterator_range(cont2), pred) );
+            BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), pred) );
+        }
+
+        template<class Container1, class Container2>
+        void test_includes_impl(
+            Container1& cont1,
+            Container2& cont2
+            )
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_includes_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_includes_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_includes_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_includes_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 2,3,4;
+            test_includes_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2,3,4;
+            cont2 += 1,2,3,4,5,6,7,8,9;
+            test_includes_impl(cont1, cont2);
+        }
+
+        void test_includes()
+        {
+            test_includes_impl< std::vector<int>, std::vector<int> >();
+            test_includes_impl< std::list<int>, std::list<int> >();
+            test_includes_impl< std::deque<int>, std::deque<int> >();
+            test_includes_impl< std::vector<int>, std::list<int> >();
+            test_includes_impl< std::list<int>, std::vector<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.includes" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_includes ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/inplace_merge.cpp b/test/algorithm_test/inplace_merge.cpp
new file mode 100644
index 0000000..948e95e
--- /dev/null
+++ b/test/algorithm_test/inplace_merge.cpp
@@ -0,0 +1,167 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/inplace_merge.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator
+                                                iterator_t BOOST_RANGE_UNUSED;
+
+            std::vector<value_t> reference_target(cont1.begin(), cont1.end());
+            reference_target.insert(reference_target.end(),
+                                    cont2.begin(), cont2.end());
+
+            std::vector<value_t> test_target(reference_target);
+            std::vector<value_t> test_target2(reference_target);
+
+            std::inplace_merge(reference_target.begin(),
+                               reference_target.begin() + cont1.size(),
+                               reference_target.end());
+
+            boost::inplace_merge(test_target,
+                                 test_target.begin() + cont1.size());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            boost::inplace_merge(boost::make_iterator_range(test_target2),
+                                 test_target2.begin() + cont1.size());
+                                 
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target2.begin(), test_target2.end()
+                );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator
+                                                iterator_t BOOST_RANGE_UNUSED;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference_target(cont1.begin(), cont1.end());
+            reference_target.insert(reference_target.end(),
+                                    cont2.begin(), cont2.end());
+
+            std::vector<value_t> test_target(reference_target);
+            std::vector<value_t> test_target2(reference_target);
+
+            std::inplace_merge(reference_target.begin(),
+                               reference_target.begin() + cont1.size(),
+                               reference_target.end(), pred);
+
+            boost::inplace_merge(test_target,
+                                 test_target.begin() + cont1.size(),
+                                 pred);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+
+            boost::inplace_merge(boost::make_iterator_range(test_target2),
+                                 test_target2.begin() + cont1.size(),
+                                 pred);
+                                 
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target2.begin(), test_target2.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test_inplace_merge_impl(Container1& cont1, Container2& cont2)
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_inplace_merge_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_inplace_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_inplace_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_inplace_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,3,5,7,9,11,13,15,17,19;
+            cont2 += 2,4,6,8,10,12,14,16,18,20;
+            test_inplace_merge_impl(cont1, cont2);
+        }
+
+        void test_inplace_merge()
+        {
+            test_inplace_merge_impl< std::vector<int>, std::vector<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.inplace_merge" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_inplace_merge ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/lexicographical_compare.cpp b/test/algorithm_test/lexicographical_compare.cpp
new file mode 100644
index 0000000..f724bd1
--- /dev/null
+++ b/test/algorithm_test/lexicographical_compare.cpp
@@ -0,0 +1,157 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/lexicographical_compare.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/value_type.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class ForwardRange1, class ForwardRange2>
+        void test_lexicographical_compare_impl_nopred(ForwardRange1& rng1,
+                                                      ForwardRange2& rng2)
+        {
+            const bool reference = std::lexicographical_compare(
+                boost::begin(rng1), boost::end(rng1),
+                boost::begin(rng2), boost::end(rng2));
+
+            const bool test = boost::lexicographical_compare(rng1, rng2);
+
+            BOOST_CHECK( reference == test );
+            BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), rng2) );
+            BOOST_CHECK( test == boost::lexicographical_compare(rng1, boost::make_iterator_range(rng2)) );
+            BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), boost::make_iterator_range(rng2)) );
+        }
+
+        template<class ForwardRange1, class ForwardRange2,
+                 class BinaryPredicate>
+        void test_lexicographical_compare_impl_pred(ForwardRange1& rng1,
+                                                    ForwardRange2& rng2,
+                                                    BinaryPredicate pred)
+        {
+            const bool reference = std::lexicographical_compare(
+                boost::begin(rng1), boost::end(rng1),
+                boost::begin(rng2), boost::end(rng2),
+                pred);
+
+            const bool test = boost::lexicographical_compare(rng1, rng2, pred);
+
+            BOOST_CHECK( reference == test );
+            BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), rng2, pred) );
+            BOOST_CHECK( test == boost::lexicographical_compare(rng1, boost::make_iterator_range(rng2), pred) );
+            BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), boost::make_iterator_range(rng2), pred) );
+        }
+
+        template<class Container1, class Container2>
+        void test_lexicographical_compare_impl(Container1& cont1,
+                                               Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container1>::type value_t;
+
+            test_lexicographical_compare_impl_nopred(cont1, cont2);
+            test_lexicographical_compare_impl_pred(cont1, cont2, std::less<value_t>());
+            test_lexicographical_compare_impl_pred(cont1, cont2, std::greater<value_t>());
+        }
+
+        template<class Container1, class Container2>
+        void test_lexicographical_compare_impl()
+        {
+            using namespace boost::assign;
+
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
+
+            container1_t cont1;
+            container2_t cont2;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1.push_back(1);
+            cont2.push_back(1);
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2;
+            cont2 += 1;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            cont2 += 2;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7;
+            cont2 += 1,2,3,4,5,6,7;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7;
+            cont2 += 1,2,3,4,5,6;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6;
+            cont2 += 1,2,3,4,5,6,7;
+            test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
+        }
+
+        template<class Container1>
+        void test_lexicographical_compare_rhs()
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_value<Container1>::type value_t;
+
+            test_lexicographical_compare_impl<Container1, const std::vector<value_t> >();
+            test_lexicographical_compare_impl<Container1, const std::deque<value_t> >();
+            test_lexicographical_compare_impl<Container1, const std::list<value_t> >();
+            test_lexicographical_compare_impl<Container1, std::vector<value_t> >();
+            test_lexicographical_compare_impl<Container1, std::deque<value_t> >();
+            test_lexicographical_compare_impl<Container1, std::list<value_t> >();
+        }
+
+        void test_lexicographical_compare()
+        {
+            test_lexicographical_compare_rhs< const std::vector<int> >();
+            test_lexicographical_compare_rhs< const std::deque<int> >();
+            test_lexicographical_compare_rhs< const std::list<int> >();
+            test_lexicographical_compare_rhs< std::vector<int> >();
+            test_lexicographical_compare_rhs< std::deque<int> >();
+            test_lexicographical_compare_rhs< std::list<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lexicographical_compare" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_lexicographical_compare ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/lower_bound.cpp b/test/algorithm_test/lower_bound.cpp
new file mode 100644
index 0000000..2a120a4
--- /dev/null
+++ b/test/algorithm_test/lower_bound.cpp
@@ -0,0 +1,181 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/lower_bound.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/algorithm/lower_bound.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_lower_bound
+{
+    class lower_bound_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::lower_bound(cont, 5);
+            BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::lower_bound<return_type>(cont, 5);
+                BOOST_CHECK( result == boost::lower_bound<return_type>(boost::make_iterator_range(cont), 5) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::lower_bound(cont.begin(), cont.end(), 5);
+        }
+    };
+
+    template< class BinaryPredicate >
+    struct lower_bound_pred_policy
+    {
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::lower_bound(cont, 5, m_pred);
+            BOOST_CHECK( result == boost::lower_bound(
+                                    boost::make_iterator_range(cont), 5, m_pred) );
+            return result;
+        }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::lower_bound<return_type>(cont, 5, policy.pred());
+                BOOST_CHECK( result == boost::lower_bound<return_type>(
+                                        boost::make_iterator_range(cont), 5, policy.pred()) );
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::lower_bound(
+                    cont.begin(), cont.end(), 5, m_pred);
+        }
+
+        BinaryPredicate& pred() { return m_pred; }
+
+    private:
+        BinaryPredicate m_pred;
+    };
+
+    template<class Container,
+             class TestPolicy,
+             class BinaryPredicate>
+    void test_lower_bound_impl(TestPolicy policy, BinaryPredicate pred)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t mcont;
+        Container& cont = mcont;
+
+        test_driver(cont, policy);
+
+        mcont.clear();
+        mcont += 1;
+
+        std::vector<value_t> temp(mcont.begin(), mcont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        mcont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+
+        mcont.clear();
+        mcont += 1,2,3,4,5,6,7,8,9;
+
+        temp.assign(mcont.begin(), mcont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        mcont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+    }
+
+    template<class Container>
+    void test_lower_bound_impl()
+    {
+        test_lower_bound_impl<Container>(
+            lower_bound_policy(),
+            std::less<int>()
+            );
+
+        test_lower_bound_impl<Container>(
+            lower_bound_pred_policy<std::less<int> >(),
+            std::less<int>()
+            );
+
+        test_lower_bound_impl<Container>(
+            lower_bound_pred_policy<std::greater<int> >(),
+            std::greater<int>()
+            );
+    }
+
+    void test_lower_bound()
+    {
+        test_lower_bound_impl< std::vector<int> >();
+        test_lower_bound_impl< std::list<int> >();
+        test_lower_bound_impl< std::deque<int> >();
+
+        test_lower_bound_impl< const std::vector<int> >();
+        test_lower_bound_impl< const std::list<int> >();
+        test_lower_bound_impl< const std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lower_bound" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_lower_bound::test_lower_bound ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/max_element.cpp b/test/algorithm_test/max_element.cpp
new file mode 100644
index 0000000..d4e87d5
--- /dev/null
+++ b/test/algorithm_test/max_element.cpp
@@ -0,0 +1,165 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/max_element.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/iterator.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_max_element
+{
+    class max_element_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::max_element(cont);
+            BOOST_CHECK( result == boost::max_element(
+                                        boost::make_iterator_range(cont)) );
+            return result;
+        }
+
+        template<boost::range_return_value return_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::max_element<return_type>(cont);
+                BOOST_CHECK( result == boost::max_element<return_type>(
+                                            boost::make_iterator_range(cont)) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::max_element(cont.begin(), cont.end());
+        }
+    };
+
+    template<class Pred>
+    class max_element_pred_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::max_element(cont, Pred());
+            BOOST_CHECK( result == boost::max_element(
+                                        boost::make_iterator_range(cont), Pred()) );
+            return result;
+        }
+
+        Pred pred() const { return Pred(); }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::max_element<return_type>(cont, policy.pred());
+                BOOST_CHECK( result == boost::max_element<return_type>(
+                                            boost::make_iterator_range(cont), policy.pred()) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::max_element(cont.begin(), cont.end(), Pred());
+        }
+    };
+
+    template<class Container, class TestPolicy>
+    void test_max_element_impl(TestPolicy policy)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type
+                                                value_t BOOST_RANGE_UNUSED;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type
+                                                container_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t cont;
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1;
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,3,4,5,6,7,8,9;
+
+        test_driver(cont, policy);
+    }
+
+    template<class Container>
+    void test_max_element_impl()
+    {
+        test_max_element_impl<Container>(max_element_test_policy());
+
+        test_max_element_impl<Container>(
+            max_element_pred_test_policy<std::less<int> >());
+
+        test_max_element_impl<Container>(
+            max_element_pred_test_policy<std::greater<int> >());
+    }
+
+    void test_max_element()
+    {
+        test_max_element_impl< const std::vector<int> >();
+        test_max_element_impl< const std::deque<int> >();
+        test_max_element_impl< const std::list<int> >();
+
+        test_max_element_impl< std::vector<int> >();
+        test_max_element_impl< std::deque<int> >();
+        test_max_element_impl< std::list<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.max_element" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_max_element::test_max_element ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/merge.cpp b/test/algorithm_test/merge.cpp
new file mode 100644
index 0000000..5038782
--- /dev/null
+++ b/test/algorithm_test/merge.cpp
@@ -0,0 +1,237 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/merge.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::vector<value_t> reference_target( cont1.size() + cont2.size() );
+
+            iterator_t reference_it
+                = std::merge(cont1.begin(), cont1.end(),
+                             cont2.begin(), cont2.end(),
+                             reference_target.begin());
+
+            std::vector<value_t> test_target( cont1.size() + cont2.size() );
+
+            iterator_t test_it
+                = boost::merge(cont1, cont2, test_target.begin());
+
+            BOOST_CHECK_EQUAL(
+                std::distance<iterator_t>(reference_target.begin(), reference_it),
+                std::distance<iterator_t>(test_target.begin(), test_it)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(boost::make_iterator_range(cont1),
+                                   cont2, test_target.begin());
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance<iterator_t>(reference_target.begin(), reference_it),
+                std::distance<iterator_t>(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(cont1, boost::make_iterator_range(cont2),
+                                   test_target.begin());
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance<iterator_t>(reference_target.begin(), reference_it),
+                std::distance<iterator_t>(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(boost::make_iterator_range(cont1),
+                                   boost::make_iterator_range(cont2),
+                                   test_target.begin());
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance<iterator_t>(reference_target.begin(), reference_it),
+                std::distance<iterator_t>(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference_target( cont1.size() + cont2.size() );
+
+            iterator_t reference_it
+                = std::merge(cont1.begin(), cont1.end(),
+                             cont2.begin(), cont2.end(),
+                             reference_target.begin(), pred);
+
+            std::vector<value_t> test_target( cont1.size() + cont2.size() );
+
+            iterator_t test_it
+                = boost::merge(cont1, cont2, test_target.begin(), pred);
+
+            BOOST_CHECK_EQUAL(
+                std::distance(reference_target.begin(), reference_it),
+                std::distance(test_target.begin(), test_it)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(boost::make_iterator_range(cont1), cont2,
+                                   test_target.begin(), pred);
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance(reference_target.begin(), reference_it),
+                std::distance(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(cont1, boost::make_iterator_range(cont2),
+                                   test_target.begin(), pred);
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance(reference_target.begin(), reference_it),
+                std::distance(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+                
+            test_it = boost::merge(boost::make_iterator_range(cont1),
+                                   boost::make_iterator_range(cont2),
+                                   test_target.begin(), pred);
+                                   
+            BOOST_CHECK_EQUAL(
+                std::distance(reference_target.begin(), reference_it),
+                std::distance(test_target.begin(), test_it)
+                );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference_target.begin(), reference_target.end(),
+                test_target.begin(), test_target.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test_merge_impl(Container1& cont1, Container2& cont2)
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_merge_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_merge_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,3,5,7,9,11,13,15,17,19;
+            cont2 += 2,4,6,8,10,12,14,16,18,20;
+            test_merge_impl(cont1, cont2);
+        }
+
+        void test_merge()
+        {
+            test_merge_impl< std::vector<int>, std::vector<int> >();
+            test_merge_impl< std::list<int>, std::list<int> >();
+            test_merge_impl< std::deque<int>, std::deque<int> >();
+
+            test_merge_impl< std::list<int>, std::vector<int> >();
+            test_merge_impl< std::vector<int>, std::list<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.merge" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_merge ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/min_element.cpp b/test/algorithm_test/min_element.cpp
new file mode 100644
index 0000000..bb92d2c
--- /dev/null
+++ b/test/algorithm_test/min_element.cpp
@@ -0,0 +1,163 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/min_element.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/iterator.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_min_element
+{
+    class min_element_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::min_element(cont);
+            BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) );
+            return result;
+        }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::min_element<return_type>(cont);
+                BOOST_CHECK( result == boost::min_element<return_type>(boost::make_iterator_range(cont)) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::min_element(cont.begin(), cont.end());
+        }
+    };
+
+    template<class Pred>
+    class min_element_pred_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::min_element(cont, Pred());
+            BOOST_CHECK( result == boost::min_element(
+                                    boost::make_iterator_range(cont), Pred()) );
+            return result;
+        }
+
+        Pred pred() const { return Pred(); }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                result_t result = boost::min_element<return_type>(cont, policy.pred());
+                BOOST_CHECK( result == boost::min_element<return_type>(
+                                boost::make_iterator_range(cont), policy.pred()) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::min_element(cont.begin(), cont.end(), Pred());
+        }
+    };
+
+    template<class Container, class TestPolicy>
+    void test_min_element_impl(TestPolicy policy)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type
+                                                value_t BOOST_RANGE_UNUSED;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type
+                                                container_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t cont;
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1;
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,3,4,5,6,7,8,9;
+
+        test_driver(cont, policy);
+    }
+
+    template<class Container>
+    void test_min_element_impl()
+    {
+        test_min_element_impl<Container>(min_element_test_policy());
+
+        test_min_element_impl<Container>(
+            min_element_pred_test_policy<std::less<int> >());
+
+        test_min_element_impl<Container>(
+            min_element_pred_test_policy<std::greater<int> >());
+    }
+
+    void test_min_element()
+    {
+        test_min_element_impl< const std::vector<int> >();
+        test_min_element_impl< const std::deque<int> >();
+        test_min_element_impl< const std::list<int> >();
+
+        test_min_element_impl< std::vector<int> >();
+        test_min_element_impl< std::deque<int> >();
+        test_min_element_impl< std::list<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.min_element" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_min_element::test_min_element ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/mismatch.cpp b/test/algorithm_test/mismatch.cpp
new file mode 100644
index 0000000..407b5fc
--- /dev/null
+++ b/test/algorithm_test/mismatch.cpp
@@ -0,0 +1,242 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/mismatch.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container1, class Container2 >
+        void eval_mismatch(Container1& cont1,
+                           Container2& cont2,
+                           BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type ref_it1,
+                           BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type ref_it2
+                           )
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
+            typedef std::pair<iter1_t, iter2_t> result_pair_t;
+            
+            result_pair_t result = boost::mismatch(cont1, cont2);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     cont2);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(cont1,
+                                     boost::make_iterator_range(cont2));
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     boost::make_iterator_range(cont2));
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+        }
+        
+        template< class Container1, class Container2, class Pred >
+        void eval_mismatch(Container1& cont1,
+                           Container2& cont2,
+                           Pred pred,
+                           BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type ref_it1,
+                           BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type ref_it2
+                           )
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
+            typedef std::pair<iter1_t, iter2_t> result_pair_t;
+            
+            result_pair_t result = boost::mismatch(cont1, cont2, pred);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     cont2, pred);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(cont1,
+                                     boost::make_iterator_range(cont2), pred);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     boost::make_iterator_range(cont2),
+                                     pred);
+            BOOST_CHECK( result.first == ref_it1 );
+            BOOST_CHECK( result.second == ref_it2 );
+        }
+        
+        template< class Container1, class Container2 >
+        void eval_mismatch(Container1& cont1,
+                           Container2& cont2,
+                           const int ref1,
+                           const int ref2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
+            typedef std::pair<iter1_t, iter2_t> result_pair_t;
+            
+            result_pair_t result = boost::mismatch(cont1, cont2);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1), cont2);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(cont1, boost::make_iterator_range(cont2));
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     boost::make_iterator_range(cont2));
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+        }
+        
+        template< class Container1, class Container2, class Pred >
+        void eval_mismatch(Container1& cont1,
+                           Container2& cont2,
+                           Pred pred,
+                           const int ref1,
+                           const int ref2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
+            typedef std::pair<iter1_t, iter2_t> result_pair_t;
+            
+            result_pair_t result = boost::mismatch(cont1, cont2, pred);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     cont2, pred);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(cont1, boost::make_iterator_range(cont2),
+                                     pred);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+            
+            result = boost::mismatch(boost::make_iterator_range(cont1),
+                                     boost::make_iterator_range(cont2),
+                                     pred);
+            BOOST_CHECK_EQUAL( ref1, *result.first );
+            BOOST_CHECK_EQUAL( ref2, *result.second );
+        }
+        
+        template< class Container1, class Container2 >
+        void test_mismatch_impl()
+        {
+            using namespace boost::assign;
+
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type MutableContainer1;
+            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type MutableContainer2;
+
+            MutableContainer1 cont1;
+            const Container1& cref_cont1 = cont1;
+            MutableContainer2 cont2;
+            const Container2& cref_cont2 = cont2;
+
+            typedef BOOST_DEDUCED_TYPENAME Container1::iterator
+                                        iterator1_t BOOST_RANGE_UNUSED;
+
+            typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator
+                                        const_iterator1_t BOOST_RANGE_UNUSED;
+
+            typedef BOOST_DEDUCED_TYPENAME Container2::iterator
+                                        iterator2_t BOOST_RANGE_UNUSED;
+
+            typedef BOOST_DEDUCED_TYPENAME Container2::const_iterator
+                                        const_iterator2_t BOOST_RANGE_UNUSED;
+
+            eval_mismatch(cont1, cont2, cont1.end(), cont2.end());
+            eval_mismatch(cont1, cont2, std::equal_to<int>(), cont1.end(), cont2.end());
+            eval_mismatch(cref_cont1, cont2, cref_cont1.end(), cont2.end());
+            eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), cref_cont1.end(), cont2.end());
+            eval_mismatch(cont1, cref_cont2, cont1.end(), cref_cont2.end());
+            eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), cont1.end(), cref_cont2.end());
+            eval_mismatch(cref_cont1, cref_cont2, cref_cont1.end(), cref_cont2.end());
+            eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), cref_cont1.end(), cref_cont2.end());
+
+            cont1 += 1,2,3,4;
+            cont2 += 1,2,3,4;
+            eval_mismatch(cont1, cont2, cont1.end(), cont2.end());
+            eval_mismatch(cont1, cont2, std::equal_to<int>(), cont1.end(), cont2.end());
+            eval_mismatch(cref_cont1, cont2, cref_cont1.end(), cont2.end());
+            eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), cref_cont1.end(), cont2.end());
+            eval_mismatch(cont1, cref_cont2, cont1.end(), cref_cont2.end());
+            eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), cont1.end(), cref_cont2.end());
+            eval_mismatch(cref_cont1, cref_cont2, cref_cont1.end(), cref_cont2.end());
+            eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), cref_cont1.end(), cref_cont2.end());
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4;
+            cont2 += 1,2,5,4;
+            eval_mismatch(cont1, cont2, 3, 5);
+            eval_mismatch(cont1, cont2, std::equal_to<int>(), 3, 5);
+            eval_mismatch(cont1, cont2, std::not_equal_to<int>(), cont1.begin(), cont2.begin());
+            eval_mismatch(cref_cont1, cont2, 3, 5);
+            eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), 3, 5);
+            eval_mismatch(cref_cont1, cont2, std::not_equal_to<int>(), cref_cont1.begin(), cont2.begin());
+            eval_mismatch(cont1, cref_cont2, 3, 5);
+            eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), 3, 5);
+            eval_mismatch(cont1, cref_cont2, std::not_equal_to<int>(), cont1.begin(), cref_cont2.begin());
+            eval_mismatch(cref_cont1, cref_cont2, 3, 5);
+            eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), 3, 5);
+            eval_mismatch(cref_cont1, cref_cont2, std::not_equal_to<int>(), cref_cont1.begin(), cref_cont2.begin());
+        }
+
+        void test_mismatch()
+        {
+            test_mismatch_impl< std::list<int>, std::list<int> >();
+            test_mismatch_impl< const std::list<int>, std::list<int> >();
+            test_mismatch_impl< std::list<int>, const std::list<int> >();
+            test_mismatch_impl< const std::list<int>, const std::list<int> >();
+
+            test_mismatch_impl< std::vector<int>, std::list<int> >();
+            test_mismatch_impl< const std::vector<int>, std::list<int> >();
+            test_mismatch_impl< std::vector<int>, const std::list<int> >();
+            test_mismatch_impl< const std::vector<int>, const std::list<int> >();
+
+            test_mismatch_impl< std::list<int>, std::vector<int> >();
+            test_mismatch_impl< const std::list<int>, std::vector<int> >();
+            test_mismatch_impl< std::list<int>, const std::vector<int> >();
+            test_mismatch_impl< const std::list<int>, const std::vector<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.mismatch" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_mismatch ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/next_permutation.cpp b/test/algorithm_test/next_permutation.cpp
new file mode 100644
index 0000000..ee1c371
--- /dev/null
+++ b/test/algorithm_test/next_permutation.cpp
@@ -0,0 +1,125 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/assign.hpp>
+#include <boost/range/algorithm/permutation.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <algorithm>
+#include <deque>
+#include <functional>
+#include <list>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test_next_permutation_impl(const Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            const bool reference_ret
+                = std::next_permutation(reference.begin(), reference.end());
+
+            const bool test_ret = boost::next_permutation(test);
+
+            BOOST_CHECK( reference_ret == test_ret );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+                
+            test = cont;
+            
+            BOOST_CHECK( test_ret == boost::next_permutation(boost::make_iterator_range(test)) );
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_next_permutation_pred_impl(const Container& cont,
+                                             BinaryPredicate  pred)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            const bool reference_ret
+                = std::next_permutation(reference.begin(), reference.end(),
+                                        pred);
+
+            const bool test_ret
+                = boost::next_permutation(test, pred);
+
+            BOOST_CHECK( reference_ret == test_ret );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+                
+            test = cont;
+            
+            BOOST_CHECK( test_ret == boost::next_permutation(boost::make_iterator_range(test), pred) );
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+        }
+
+        template<class Container>
+        void test_next_permutation_(const Container& cont)
+        {
+            test_next_permutation_impl(cont);
+            test_next_permutation_pred_impl(cont, std::less<int>());
+            test_next_permutation_pred_impl(cont, std::greater<int>());
+        }
+
+        template<class Container>
+        void run_tests()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_next_permutation_(cont);
+
+            cont.clear();
+            cont += 1;
+            test_next_permutation_(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_next_permutation_(cont);
+        }
+
+        void test_next_permutation()
+        {
+            run_tests< std::vector<int> >();
+            run_tests< std::list<int> >();
+            run_tests< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.next_permutation" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_next_permutation ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/nth_element.cpp b/test/algorithm_test/nth_element.cpp
new file mode 100644
index 0000000..df241e9
--- /dev/null
+++ b/test/algorithm_test/nth_element.cpp
@@ -0,0 +1,175 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/nth_element.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        struct nth_element_policy
+        {
+            template<class Container, class Iterator>
+            void test_nth_element(Container& cont, Iterator mid)
+            {
+                const Container old_cont(cont);
+                
+                boost::nth_element(cont, mid);
+                
+                // Test the same operation on the container, for the
+                // case where a temporary is passed as the first
+                // argument.
+                Container cont2(old_cont);
+                const std::size_t index = std::distance(cont.begin(), mid);
+                Iterator mid2(cont2.begin());
+                std::advance(mid2, index);
+                boost::nth_element(boost::make_iterator_range(cont2), mid2);
+                
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+            }
+
+            template<class Container, class Iterator>
+            void reference_nth_element(Container& cont, Iterator mid)
+            {
+                std::nth_element(cont.begin(), mid, cont.end());
+            }
+        };
+
+        template<class BinaryPredicate>
+        struct nth_element_pred_policy
+        {
+            template<class Container, class Iterator>
+            void test_nth_element(Container& cont, Iterator mid)
+            {
+                const Container old_cont(cont);
+                
+                boost::nth_element(cont, mid, BinaryPredicate());
+                
+                Container cont2(old_cont);
+                const std::size_t index = std::distance(cont.begin(), mid);
+                Iterator mid2(cont2.begin());
+                std::advance(mid2, index);
+                boost::nth_element(boost::make_iterator_range(cont2), mid2,
+                                   BinaryPredicate());
+                                   
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+            }
+
+            template<class Container, class Iterator>
+            void reference_nth_element(Container& cont, Iterator mid)
+            {
+                std::nth_element(cont.begin(), mid, cont.end(), BinaryPredicate());
+            }
+        };
+
+        template<class Container, class TestPolicy>
+        void test_nth_element_tp_impl(Container& cont, TestPolicy policy)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+
+            BOOST_CHECK_EQUAL( reference.size(), test.size() );
+            if (reference.size() != test.size())
+                return;
+
+            iterator_t reference_mid = reference.begin();
+            iterator_t test_mid = test.begin();
+
+            bool complete = false;
+            while (!complete)
+            {
+                if (reference_mid == reference.end())
+                    complete = true;
+
+                policy.test_nth_element(test, test_mid);
+                policy.reference_nth_element(reference, reference_mid);
+
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                if (reference_mid != reference.end())
+                {
+                    ++reference_mid;
+                    ++test_mid;
+                }
+            }
+        }
+
+        template<class Container>
+        void test_nth_element_impl(Container& cont)
+        {
+            test_nth_element_tp_impl(cont, nth_element_policy());
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_nth_element_impl(Container& cont, BinaryPredicate pred)
+        {
+            test_nth_element_tp_impl(cont, nth_element_pred_policy<BinaryPredicate>());
+        }
+
+        template<class Container>
+        void run_tests(Container& cont)
+        {
+            test_nth_element_impl(cont);
+            test_nth_element_impl(cont, std::less<int>());
+            test_nth_element_impl(cont, std::greater<int>());
+        }
+
+        template<class Container>
+        void test_nth_element_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            run_tests(cont);
+
+            cont.clear();
+            cont += 1;
+            run_tests(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            run_tests(cont);
+        }
+
+        void test_nth_element()
+        {
+            test_nth_element_impl< std::vector<int> >();
+            test_nth_element_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.nth_element" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_nth_element ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/partial_sort.cpp b/test/algorithm_test/partial_sort.cpp
new file mode 100644
index 0000000..c13f7f1
--- /dev/null
+++ b/test/algorithm_test/partial_sort.cpp
@@ -0,0 +1,171 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/partial_sort.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        struct partial_sort_policy
+        {
+            template<class Container, class Iterator>
+            void test_partial_sort(Container& cont, Iterator mid)
+            {
+                const Container old_cont(cont);
+                
+                boost::partial_sort(cont, mid);
+                
+                const std::size_t index = std::distance(cont.begin(), mid);
+                Container cont2(old_cont);
+                Iterator mid2(cont2.begin());
+                std::advance(mid2, index);
+                boost::partial_sort(cont2, mid2);
+                
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+            }
+
+            template<class Container, class Iterator>
+            void reference_partial_sort(Container& cont, Iterator mid)
+            {
+                std::partial_sort(cont.begin(), mid, cont.end());
+            }
+        };
+
+        template<class BinaryPredicate>
+        struct partial_sort_pred_policy
+        {
+            template<class Container, class Iterator>
+            void test_partial_sort(Container& cont, Iterator mid)
+            {
+                const Container old_cont(cont);
+                
+                boost::partial_sort(cont, mid, BinaryPredicate());
+                
+                const std::size_t index = std::distance(cont.begin(), mid);
+                Container cont2(old_cont);
+                Iterator mid2(cont2.begin());
+                std::advance(mid2, index);
+                boost::partial_sort(cont2, mid2, BinaryPredicate());
+                
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+            }
+
+            template<class Container, class Iterator>
+            void reference_partial_sort(Container& cont, Iterator mid)
+            {
+                std::partial_sort(cont.begin(), mid, cont.end(), BinaryPredicate());
+            }
+        };
+
+        template<class Container, class TestPolicy>
+        void test_partial_sort_tp_impl(Container& cont, TestPolicy policy)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+
+            BOOST_CHECK_EQUAL( reference.size(), test.size() );
+            if (reference.size() != test.size())
+                return;
+
+            iterator_t reference_mid = reference.begin();
+            iterator_t test_mid = test.begin();
+
+            bool complete = false;
+            while (!complete)
+            {
+                if (reference_mid == reference.end())
+                    complete = true;
+
+                policy.test_partial_sort(test, test_mid);
+                policy.reference_partial_sort(reference, reference_mid);
+
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                if (reference_mid != reference.end())
+                {
+                    ++reference_mid;
+                    ++test_mid;
+                }
+            }
+        }
+
+        template<class Container>
+        void test_partial_sort_impl(Container& cont)
+        {
+            test_partial_sort_tp_impl(cont, partial_sort_policy());
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_partial_sort_impl(Container& cont, BinaryPredicate pred)
+        {
+            test_partial_sort_tp_impl(cont, partial_sort_pred_policy<BinaryPredicate>());
+        }
+
+        template<class Container>
+        void test_partial_sort_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_partial_sort_impl(cont);
+            test_partial_sort_impl(cont, std::less<int>());
+            test_partial_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1;
+            test_partial_sort_impl(cont);
+            test_partial_sort_impl(cont, std::less<int>());
+            test_partial_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_partial_sort_impl(cont);
+            test_partial_sort_impl(cont, std::less<int>());
+            test_partial_sort_impl(cont, std::greater<int>());
+        }
+
+        void test_partial_sort()
+        {
+            test_partial_sort_impl< std::vector<int> >();
+            test_partial_sort_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partial_sort" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_partial_sort ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/partition.cpp b/test/algorithm_test/partition.cpp
new file mode 100644
index 0000000..22aefd6
--- /dev/null
+++ b/test/algorithm_test/partition.cpp
@@ -0,0 +1,136 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/partition.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_partition
+{
+    struct equal_to_5
+    {
+        typedef bool result_type;
+        typedef int argument_type;
+        bool operator()(int x) const { return x == 5; }
+    };
+
+    // test the 'partition' algorithm
+    template<class UnaryPredicate>
+    class partition_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+
+            const Container old_cont(cont);
+            Container cont2(old_cont);
+            iter_t result = boost::partition(cont, UnaryPredicate());
+
+            boost::partition(cont2, UnaryPredicate());
+            cont2 = old_cont;
+            boost::partition(
+                boost::make_iterator_range(cont2), UnaryPredicate());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                           cont2.begin(), cont2.end() );
+
+            return result;
+        }
+
+        UnaryPredicate pred() const { return UnaryPredicate(); }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+
+                const Container old_cont(cont);
+                Container cont2(old_cont);
+                result_t result = boost::partition<return_type>(cont, policy.pred());
+
+                // Test that operation a temporary created by using
+                // make_iterator_range.
+                boost::partition<return_type>(
+                    boost::make_iterator_range(cont2), policy.pred());
+
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::partition(cont.begin(), cont.end(), UnaryPredicate());
+        }
+    };
+
+    template<class Container>
+    void test_partition_impl()
+    {
+        using namespace boost::assign;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        partition_test_policy< equal_to_5 > policy;
+
+        Container cont;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,2,2,3,4,5,6,7,8,9;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9;
+        test_driver(cont, policy);
+    }
+
+    void test_partition()
+    {
+        test_partition_impl< std::vector<int> >();
+        test_partition_impl< std::list<int> >();
+        test_partition_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partition" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_partition::test_partition ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/prev_permutation.cpp b/test/algorithm_test/prev_permutation.cpp
new file mode 100644
index 0000000..a4adc7b
--- /dev/null
+++ b/test/algorithm_test/prev_permutation.cpp
@@ -0,0 +1,124 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/assign.hpp>
+#include <boost/range/algorithm/permutation.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <algorithm>
+#include <deque>
+#include <functional>
+#include <list>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test_prev_permutation_impl(const Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+            Container test2(cont);
+
+            const bool reference_ret
+                = std::prev_permutation(reference.begin(), reference.end());
+
+            const bool test_ret = boost::prev_permutation(test);
+
+            BOOST_CHECK( reference_ret == test_ret );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+
+            BOOST_CHECK( test_ret == boost::prev_permutation(
+                                boost::make_iterator_range(test2)) );
+                                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test2.begin(), test2.end()
+                );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_prev_permutation_pred_impl(const Container& cont,
+                                             BinaryPredicate  pred)
+        {
+            Container reference(cont);
+            Container test(cont);
+            Container test2(cont);
+
+            const bool reference_ret
+                = std::prev_permutation(reference.begin(), reference.end(),
+                                        pred);
+
+            const bool test_ret = boost::prev_permutation(test, pred);
+
+            BOOST_CHECK( reference_ret == test_ret );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+                
+            BOOST_CHECK( test_ret == boost::prev_permutation(
+                boost::make_iterator_range(test2), pred) );
+                
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test2.begin(), test2.end()
+                );
+        }
+
+        template<class Container>
+        void test_prev_permutation_(const Container& cont)
+        {
+            test_prev_permutation_impl(cont);
+            test_prev_permutation_pred_impl(cont, std::less<int>());
+            test_prev_permutation_pred_impl(cont, std::greater<int>());
+        }
+
+        template<class Container>
+        void run_tests()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_prev_permutation_(cont);
+
+            cont.clear();
+            cont += 1;
+            test_prev_permutation_(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_prev_permutation_(cont);
+        }
+
+        void test_prev_permutation()
+        {
+            run_tests< std::vector<int> >();
+            run_tests< std::list<int> >();
+            run_tests< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.prev_permutation" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_prev_permutation ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/random_shuffle.cpp b/test/algorithm_test/random_shuffle.cpp
new file mode 100644
index 0000000..71915ee
--- /dev/null
+++ b/test/algorithm_test/random_shuffle.cpp
@@ -0,0 +1,198 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/random_shuffle.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include "../test_function/counted_function.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Int>
+        class counted_generator
+            : private range_test_function::counted_function
+        {
+        public:
+            typedef Int result_type;
+            typedef Int argument_type;
+
+            using range_test_function::counted_function::invocation_count;
+
+            result_type operator()(argument_type modulo_value)
+            {
+                invoked();
+                return static_cast<result_type>(std::rand() % modulo_value);
+            }
+        };
+
+        template<class Container>
+        bool test_shuffle_result(
+            const Container& old_cont,
+            const Container& new_cont
+            )
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<const Container>::type iterator_t;
+
+            // The size must remain equal
+            BOOST_CHECK_EQUAL( old_cont.size(), new_cont.size() );
+            if (old_cont.size() != new_cont.size())
+                return false;
+
+            if (new_cont.size() < 2)
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    old_cont.begin(), old_cont.end(),
+                    new_cont.begin(), new_cont.end()
+                    );
+
+                return std::equal(old_cont.begin(), old_cont.end(),
+                                  new_cont.begin());
+            }
+
+            // Elements must only be moved around. This is tested by
+            // ensuring the count of each element remains the
+            // same.
+            bool failed = false;
+            iterator_t last = old_cont.end();
+            for (iterator_t it = old_cont.begin(); !failed && (it != last); ++it)
+            {
+                const std::size_t old_count
+                    = std::count(old_cont.begin(), old_cont.end(), *it);
+
+                const std::size_t new_count
+                    = std::count(new_cont.begin(), new_cont.end(), *it);
+
+                BOOST_CHECK_EQUAL( old_count, new_count );
+
+                failed = (old_count != new_count);
+            }
+
+            return !failed;
+        }
+
+        template<class Container>
+        void test_random_shuffle_nogen_impl(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
+                                                iterator_t BOOST_RANGE_UNUSED;
+
+            const int MAX_RETRIES = 10000;
+
+            bool shuffled = false;
+            for (int attempt = 0; !shuffled && (attempt < MAX_RETRIES); ++attempt)
+            {
+                Container test(cont);
+                boost::random_shuffle(test);
+                bool ok = test_shuffle_result(cont, test);
+                if (!ok)
+                    break;
+
+                // Since the counts are equal, then if they are 
+                // not equal the contents must have been shuffled
+                if (cont.size() == test.size()
+                &&  !std::equal(cont.begin(), cont.end(), test.begin()))
+                {
+                    shuffled = true;
+                }
+                
+                // Verify that the shuffle can be performed on a
+                // temporary range
+                Container test2(cont);
+                boost::random_shuffle(boost::make_iterator_range(test2));
+                ok = test_shuffle_result(cont, test2);
+                if (!ok)
+                    break;
+            }
+        }
+
+        template<class RandomGenerator, class Container>
+        void test_random_shuffle_gen_impl(Container& cont)
+        {
+            RandomGenerator gen;
+            Container old_cont(cont);
+            boost::random_shuffle(cont, gen);
+            test_shuffle_result(cont, old_cont);
+            if (cont.size() > 2)
+            {
+                BOOST_CHECK( gen.invocation_count() > 0 );
+            }
+            
+            // Test that random shuffle works when 
+            // passed a temporary range
+            RandomGenerator gen2;
+            Container cont2(old_cont);
+            boost::random_shuffle(boost::make_iterator_range(cont2), gen2);
+            test_shuffle_result(cont2, old_cont);
+            if (cont2.size() > 2)
+            {
+                BOOST_CHECK( gen2.invocation_count() > 0 );
+            }
+        }
+
+        template<class Container>
+        void test_random_shuffle_impl(Container& cont)
+        {
+            Container old_cont(cont);
+            boost::random_shuffle(cont);
+            test_shuffle_result(cont, old_cont);
+        }
+
+        template<class Container>
+        void test_random_shuffle_impl()
+        {
+            using namespace boost::assign;
+
+            typedef counted_generator<
+                BOOST_DEDUCED_TYPENAME range_difference<Container>::type > generator_t;
+
+            Container cont;
+            test_random_shuffle_nogen_impl(cont);
+            test_random_shuffle_gen_impl<generator_t>(cont);
+
+            cont.clear();
+            cont += 1;
+            test_random_shuffle_nogen_impl(cont);
+            test_random_shuffle_gen_impl<generator_t>(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_random_shuffle_nogen_impl(cont);
+            test_random_shuffle_gen_impl<generator_t>(cont);
+        }
+
+        void test_random_shuffle()
+        {
+            test_random_shuffle_impl< std::vector<int> >();
+            test_random_shuffle_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.random_shuffle" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_random_shuffle ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/remove.cpp b/test/algorithm_test/remove.cpp
new file mode 100644
index 0000000..3e4ab16
--- /dev/null
+++ b/test/algorithm_test/remove.cpp
@@ -0,0 +1,101 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/remove.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container, class Value >
+        void test_remove_impl( const Container& c, Value to_remove )
+        {
+            Container reference(c);
+
+            typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
+
+            iterator_t reference_it
+                = std::remove(reference.begin(), reference.end(), to_remove);
+
+            Container test(c);
+            iterator_t test_it = boost::remove(test, to_remove);
+
+            BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
+                               std::distance(reference.begin(), reference_it) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                                           
+            Container test2(c);
+            iterator_t test_it2 = boost::remove(test2, to_remove);
+            
+            BOOST_CHECK_EQUAL( std::distance(test2.begin(), test_it2),
+                               std::distance(reference.begin(), reference_it) );
+                               
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template< class Container >
+        void test_remove_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_remove_impl(cont, 0);
+
+            cont.clear();
+            cont += 1;
+            test_remove_impl(cont, 0);
+            test_remove_impl(cont, 1);
+
+            cont.clear();
+            cont += 1,1,1,1,1;
+            test_remove_impl(cont, 0);
+            test_remove_impl(cont, 1);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_remove_impl(cont, 1);
+            test_remove_impl(cont, 9);
+            test_remove_impl(cont, 4);
+        }
+
+        void test_remove()
+        {
+            test_remove_impl< std::vector<int> >();
+            test_remove_impl< std::list<int> >();
+            test_remove_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_remove ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/remove_copy.cpp b/test/algorithm_test/remove_copy.cpp
new file mode 100644
index 0000000..b3eb8e2
--- /dev/null
+++ b/test/algorithm_test/remove_copy.cpp
@@ -0,0 +1,108 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/remove_copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<typename Iterator, typename Value>
+    void test_append(Iterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template< class Container, class Value >
+    void test_remove_copy_impl( const Container& c, Value to_remove )
+    {
+        typedef typename boost::range_value<Container>::type value_type;
+        std::vector<value_type> reference;
+
+        typedef BOOST_DEDUCED_TYPENAME std::vector<value_type>::iterator
+                                            iterator_t BOOST_RANGE_UNUSED;
+
+        test_append(
+            std::remove_copy(c.begin(), c.end(),
+                                std::back_inserter(reference), to_remove),
+            to_remove);
+
+        std::vector<value_type> test;
+        test_append(
+            boost::remove_copy(c, std::back_inserter(test), to_remove),
+            to_remove);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            test.begin(), test.end() );
+            
+        std::vector<value_type> test2;
+        test_append(
+            boost::remove_copy(boost::make_iterator_range(c),
+                               std::back_inserter(test2), to_remove),
+            to_remove);
+                               
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test2.begin(), test2.end() );
+    }
+
+    template< class Container >
+    void test_remove_copy_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_remove_copy_impl(cont, 0);
+
+        cont.clear();
+        cont += 1;
+        test_remove_copy_impl(cont, 0);
+        test_remove_copy_impl(cont, 1);
+
+        cont.clear();
+        cont += 1,1,1,1,1;
+        test_remove_copy_impl(cont, 0);
+        test_remove_copy_impl(cont, 1);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_remove_copy_impl(cont, 1);
+        test_remove_copy_impl(cont, 9);
+        test_remove_copy_impl(cont, 4);
+    }
+
+    void test_remove_copy()
+    {
+        test_remove_copy_impl< std::vector<int> >();
+        test_remove_copy_impl< std::list<int> >();
+        test_remove_copy_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_copy" );
+
+    test->add( BOOST_TEST_CASE( &test_remove_copy ) );
+
+    return test;
+}
+
diff --git a/test/algorithm_test/remove_copy_if.cpp b/test/algorithm_test/remove_copy_if.cpp
new file mode 100644
index 0000000..c269c2a
--- /dev/null
+++ b/test/algorithm_test/remove_copy_if.cpp
@@ -0,0 +1,113 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/remove_copy_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template< class Iterator, class Value >
+    void test_append(Iterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template< class Container, class UnaryPredicate >
+    void test_remove_copy_if_impl( const Container& c, UnaryPredicate pred )
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<const Container>::type value_type;
+        std::vector<value_type> reference;
+
+        test_append(
+            std::remove_copy_if(c.begin(), c.end(), std::back_inserter(reference), pred),
+            value_type()
+            );
+
+        std::vector<value_type> test;
+        test_append(
+            boost::remove_copy_if(c, std::back_inserter(test), pred),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+                                       
+        std::vector<value_type> test2;
+        test_append(
+            boost::remove_copy_if(boost::make_iterator_range(c),
+                                  std::back_inserter(test2), pred),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test2.begin(), test2.end() );
+    }
+
+    template< class Container >
+    void test_remove_copy_if_( const Container& c, int to_remove )
+    {
+        test_remove_copy_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_remove));
+        test_remove_copy_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_remove));
+    }
+
+    template< class Container >
+    void test_remove_copy_if_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_remove_copy_if_(cont, 0);
+
+        cont.clear();
+        cont += 1;
+        test_remove_copy_if_(cont, 0);
+        test_remove_copy_if_(cont, 1);
+
+        cont.clear();
+        cont += 1,1,1,1,1;
+        test_remove_copy_if_(cont, 0);
+        test_remove_copy_if_(cont, 1);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_remove_copy_if_(cont, 1);
+        test_remove_copy_if_(cont, 9);
+        test_remove_copy_if_(cont, 4);
+    }
+
+    inline void test_remove_copy_if()
+    {
+        test_remove_copy_if_impl< std::vector<int> >();
+        test_remove_copy_if_impl< std::list<int> >();
+        test_remove_copy_if_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_copy_if" );
+
+    test->add( BOOST_TEST_CASE( &test_remove_copy_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/remove_if.cpp b/test/algorithm_test/remove_if.cpp
new file mode 100644
index 0000000..58fc07f
--- /dev/null
+++ b/test/algorithm_test/remove_if.cpp
@@ -0,0 +1,109 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/remove_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container, class UnaryPredicate >
+        void test_remove_if_impl( const Container& c, UnaryPredicate pred )
+        {
+            Container reference(c);
+
+            typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
+
+            iterator_t reference_it
+                = std::remove_if(reference.begin(), reference.end(), pred);
+
+            Container test(c);
+            iterator_t test_it = boost::remove_if(test, pred);
+
+            BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
+                               std::distance(reference.begin(), reference_it) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                
+            Container test2(c);
+            iterator_t test_it2 = boost::remove_if(
+                boost::make_iterator_range(test2), pred);
+                
+            BOOST_CHECK_EQUAL( std::distance(test2.begin(), test_it2),
+                               std::distance(reference.begin(), reference_it) );
+                               
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template< class Container >
+        void test_remove_if_( const Container& c, int to_remove )
+        {
+            test_remove_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_remove));
+            test_remove_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_remove));
+        }
+
+        template< class Container >
+        void test_remove_if_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_remove_if_(cont, 0);
+
+            cont.clear();
+            cont += 1;
+            test_remove_if_(cont, 0);
+            test_remove_if_(cont, 1);
+
+            cont.clear();
+            cont += 1,1,1,1,1;
+            test_remove_if_(cont, 0);
+            test_remove_if_(cont, 1);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_remove_if_(cont, 1);
+            test_remove_if_(cont, 9);
+            test_remove_if_(cont, 4);
+        }
+
+        inline void test_remove_if()
+        {
+            test_remove_if_impl< std::vector<int> >();
+            test_remove_if_impl< std::list<int> >();
+            test_remove_if_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_if" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_remove_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/replace.cpp b/test/algorithm_test/replace.cpp
new file mode 100644
index 0000000..356024f
--- /dev/null
+++ b/test/algorithm_test/replace.cpp
@@ -0,0 +1,86 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/replace.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_replace_impl(Container& cont)
+        {
+            const int what = 2;
+            const int with_what = 5;
+
+            std::vector<int> reference(cont.begin(), cont.end());
+            std::replace(reference.begin(), reference.end(), what, with_what);
+
+            std::vector<int> target(cont.begin(), cont.end());
+            boost::replace(target, what, with_what);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                
+            std::vector<int> target2(cont.begin(), cont.end());
+            boost::replace(boost::make_iterator_range(target2), what,
+                           with_what);
+                           
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target2.begin(), target2.end() );
+
+        }
+
+        template< class Container >
+        void test_replace_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_replace_impl(cont);
+
+            cont.clear();
+            cont += 1;
+            test_replace_impl(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_replace_impl(cont);
+        }
+
+        void test_replace()
+        {
+            test_replace_impl< std::vector<int> >();
+            test_replace_impl< std::list<int> >();
+            test_replace_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.replace" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_replace ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/replace_copy.cpp b/test/algorithm_test/replace_copy.cpp
new file mode 100644
index 0000000..5629856
--- /dev/null
+++ b/test/algorithm_test/replace_copy.cpp
@@ -0,0 +1,111 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/replace_copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<typename Iterator, typename Value>
+    void test_append(Iterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template< class Container, class Value >
+    void test_replace_copy_impl( const Container& c, Value to_replace )
+    {
+        const Value replace_with = to_replace * 2;
+
+        typedef typename boost::range_value<Container>::type value_type;
+        std::vector<value_type> reference;
+
+        typedef BOOST_DEDUCED_TYPENAME std::vector<value_type>::iterator
+                                            iterator_t BOOST_RANGE_UNUSED;
+
+        test_append(
+            std::replace_copy(c.begin(), c.end(),
+                                std::back_inserter(reference), to_replace, replace_with),
+            to_replace);
+
+        std::vector<value_type> test;
+        test_append(
+            boost::replace_copy(c, std::back_inserter(test), to_replace, replace_with),
+            to_replace);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+            
+        std::vector<value_type> test2;
+        test_append(
+            boost::replace_copy(boost::make_iterator_range(c),
+                                std::back_inserter(test2), to_replace,
+                                replace_with),
+            to_replace);
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test2.begin(), test2.end() );
+    }
+
+    template< class Container >
+    void test_replace_copy_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_replace_copy_impl(cont, 0);
+
+        cont.clear();
+        cont += 1;
+        test_replace_copy_impl(cont, 0);
+        test_replace_copy_impl(cont, 1);
+
+        cont.clear();
+        cont += 1,1,1,1,1;
+        test_replace_copy_impl(cont, 0);
+        test_replace_copy_impl(cont, 1);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_replace_copy_impl(cont, 1);
+        test_replace_copy_impl(cont, 9);
+        test_replace_copy_impl(cont, 4);
+    }
+
+    void test_replace_copy()
+    {
+        test_replace_copy_impl< std::vector<int> >();
+        test_replace_copy_impl< std::list<int> >();
+        test_replace_copy_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.replace_copy" );
+
+    test->add( BOOST_TEST_CASE( &test_replace_copy ) );
+
+    return test;
+}
+
diff --git a/test/algorithm_test/replace_copy_if.cpp b/test/algorithm_test/replace_copy_if.cpp
new file mode 100644
index 0000000..6873547
--- /dev/null
+++ b/test/algorithm_test/replace_copy_if.cpp
@@ -0,0 +1,115 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/replace_copy_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template< class Iterator, class Value >
+    void test_append(Iterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template< class Container, class UnaryPredicate >
+    void test_replace_copy_if_impl( const Container& c, UnaryPredicate pred )
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<const Container>::type value_type;
+        const value_type replace_with = value_type();
+        std::vector<value_type> reference;
+
+        test_append(
+            std::replace_copy_if(c.begin(), c.end(), std::back_inserter(reference), pred, replace_with),
+            value_type()
+            );
+
+        std::vector<value_type> test;
+        test_append(
+            boost::replace_copy_if(c, std::back_inserter(test), pred, replace_with),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+            
+        std::vector<value_type> test2;
+        test_append(
+            boost::replace_copy_if(boost::make_iterator_range(c),
+                                   std::back_inserter(test2), pred,
+                                   replace_with),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test2.begin(), test2.end() );
+    }
+
+    template< class Container >
+    void test_replace_copy_if_( const Container& c, int to_replace )
+    {
+        test_replace_copy_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_replace));
+        test_replace_copy_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_replace));
+    }
+
+    template< class Container >
+    void test_replace_copy_if_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_replace_copy_if_(cont, 0);
+
+        cont.clear();
+        cont += 1;
+        test_replace_copy_if_(cont, 0);
+        test_replace_copy_if_(cont, 1);
+
+        cont.clear();
+        cont += 1,1,1,1,1;
+        test_replace_copy_if_(cont, 0);
+        test_replace_copy_if_(cont, 1);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_replace_copy_if_(cont, 1);
+        test_replace_copy_if_(cont, 9);
+        test_replace_copy_if_(cont, 4);
+    }
+
+    inline void test_replace_copy_if()
+    {
+        test_replace_copy_if_impl< std::vector<int> >();
+        test_replace_copy_if_impl< std::list<int> >();
+        test_replace_copy_if_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.replace_copy_if" );
+
+    test->add( BOOST_TEST_CASE( &test_replace_copy_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/replace_if.cpp b/test/algorithm_test/replace_if.cpp
new file mode 100644
index 0000000..12d7293
--- /dev/null
+++ b/test/algorithm_test/replace_if.cpp
@@ -0,0 +1,96 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/replace_if.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container, class UnaryPredicate >
+        void test_replace_if_impl(Container& cont, UnaryPredicate pred)
+        {
+            const int what = 2;
+            const int with_what = 5;
+
+            std::vector<int> reference(cont.begin(), cont.end());
+            std::replace_if(reference.begin(), reference.end(),
+                boost::bind(pred, _1, what), with_what);
+
+            std::vector<int> target(cont.begin(), cont.end());
+            boost::replace_if(target, boost::bind(pred, _1, what), with_what);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                
+            std::vector<int> target2(cont.begin(), cont.end());
+            boost::replace_if(boost::make_iterator_range(target2),
+                              boost::bind(pred, _1, what), with_what);
+                              
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target2.begin(), target2.end() );
+        }
+
+        template< class Container >
+        void test_replace_if_impl(Container& cont)
+        {
+            test_replace_if_impl(cont, std::equal_to<int>());
+            test_replace_if_impl(cont, std::not_equal_to<int>());
+        }
+
+        template< class Container >
+        void test_replace_if_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_replace_if_impl(cont);
+
+            cont.clear();
+            cont += 1;
+            test_replace_if_impl(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_replace_if_impl(cont);
+        }
+
+        void test_replace_if()
+        {
+            test_replace_if_impl< std::vector<int> >();
+            test_replace_if_impl< std::list<int> >();
+            test_replace_if_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.replace_if" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_replace_if ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/reverse.cpp b/test/algorithm_test/reverse.cpp
new file mode 100644
index 0000000..3ad63cb
--- /dev/null
+++ b/test/algorithm_test/reverse.cpp
@@ -0,0 +1,80 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/reverse.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test_reverse_impl(Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+            Container test2(cont);
+
+            boost::reverse(test);
+            std::reverse(reference.begin(), reference.end());
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                                           
+            boost::reverse(boost::make_iterator_range(test2));
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template<class Container>
+        void test_reverse_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_reverse_impl(cont);
+
+            cont.clear();
+            cont += 1;
+            test_reverse_impl(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_reverse_impl(cont);
+        }
+
+        void test_reverse()
+        {
+            test_reverse_impl< std::vector<int> >();
+            test_reverse_impl< std::list<int> >();
+            test_reverse_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.reverse" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_reverse ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/reverse_copy.cpp b/test/algorithm_test/reverse_copy.cpp
new file mode 100644
index 0000000..92ef485
--- /dev/null
+++ b/test/algorithm_test/reverse_copy.cpp
@@ -0,0 +1,97 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/reverse_copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<class OutputIterator, class Value>
+    void test_append(OutputIterator out, Value value)
+    {
+        *out++ = value;
+    }
+
+    template<class Container>
+    void test_reverse_copy_impl(Container& cont)
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type;
+        std::vector<value_type> reference;
+        std::vector<value_type> test;
+
+        test_append(
+            std::reverse_copy(cont.begin(), cont.end(), std::back_inserter(reference)),
+            value_type()
+            );
+
+        test_append(
+            boost::reverse_copy(cont, std::back_inserter(test)),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+            
+        test.clear();
+        
+        test_append(
+            boost::reverse_copy(boost::make_iterator_range(cont),
+                                std::back_inserter(test)),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+    }
+
+    template<class Container>
+    void test_reverse_copy_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_reverse_copy_impl(cont);
+
+        cont.clear();
+        cont += 1;
+        test_reverse_copy_impl(cont);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_reverse_copy_impl(cont);
+    }
+
+    void test_reverse_copy()
+    {
+        test_reverse_copy_impl< std::vector<int> >();
+        test_reverse_copy_impl< std::list<int> >();
+        test_reverse_copy_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.reverse_copy" );
+
+    test->add( BOOST_TEST_CASE( &::test_reverse_copy ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/rotate.cpp b/test/algorithm_test/rotate.cpp
new file mode 100644
index 0000000..b6b7af2
--- /dev/null
+++ b/test/algorithm_test/rotate.cpp
@@ -0,0 +1,107 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/rotate.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container, class Iterator>
+        void test_rotate_impl(Container& cont, Iterator where_it)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            Iterator reference_where_it = reference.begin();
+            std::advance(reference_where_it,
+                std::distance(cont.begin(), where_it));
+
+            std::rotate(reference.begin(), reference_where_it, reference.end());
+
+            Iterator test_where_it = test.begin();
+            std::advance(test_where_it,
+                std::distance(cont.begin(), where_it));
+
+            boost::rotate(test, test_where_it);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                
+            test = cont;
+            test_where_it = test.begin();
+            std::advance(test_where_it,
+                         std::distance(cont.begin(), where_it));
+                         
+            boost::rotate(boost::make_iterator_range(test), test_where_it);
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+        }
+
+        template<class Container>
+        void test_rotate_impl(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+
+            iterator_t last = cont.end();
+            for (iterator_t it = cont.begin(); it != last; ++it)
+            {
+                test_rotate_impl(cont, it);
+            }
+        }
+
+        template<class Container>
+        void test_rotate_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_rotate_impl(cont);
+
+            cont.clear();
+            cont += 1;
+            test_rotate_impl(cont);
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_rotate_impl(cont);
+        }
+
+        void test_rotate()
+        {
+            test_rotate_impl< std::vector<int> >();
+            test_rotate_impl< std::list<int> >();
+            test_rotate_impl< std::deque<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.rotate" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_rotate ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/rotate_copy.cpp b/test/algorithm_test/rotate_copy.cpp
new file mode 100644
index 0000000..05aa4d2
--- /dev/null
+++ b/test/algorithm_test/rotate_copy.cpp
@@ -0,0 +1,115 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/rotate_copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<class OutputIterator, class Value>
+    void test_append(OutputIterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template<class Container, class Iterator>
+    void test_rotate_copy_impl(Container& cont, Iterator where_it)
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type
+                                            value_type;
+
+        std::vector<value_type> reference;
+        std::vector<value_type> test;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+                                            iterator_t BOOST_RANGE_UNUSED;
+
+        test_append(
+            std::rotate_copy(cont.begin(), where_it, cont.end(),
+                std::back_inserter(reference)),
+            value_type()
+            );
+
+        test_append(
+            boost::rotate_copy(cont, where_it, std::back_inserter(test)),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+            
+        test.clear();
+        
+        test_append(
+            boost::rotate_copy(boost::make_iterator_range(cont), where_it,
+                               std::back_inserter(test)),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                       test.begin(), test.end() );
+    }
+
+    template<class Container>
+    void test_rotate_copy_impl(Container& cont)
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iterator_t;
+
+        iterator_t last = cont.end();
+        for (iterator_t it = cont.begin(); it != last; ++it)
+        {
+            test_rotate_copy_impl(cont, it);
+        }
+    }
+
+    template<class Container>
+    void test_rotate_copy_impl()
+    {
+        using namespace boost::assign;
+
+        Container cont;
+        test_rotate_copy_impl(cont);
+
+        cont.clear();
+        cont += 1;
+        test_rotate_copy_impl(cont);
+
+        cont.clear();
+        cont += 1,2,3,4,5,6,7,8,9;
+        test_rotate_copy_impl(cont);
+    }
+
+    void test_rotate_copy()
+    {
+        test_rotate_copy_impl< std::vector<int> >();
+        test_rotate_copy_impl< std::list<int> >();
+        test_rotate_copy_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.rotate_copy" );
+
+    test->add( BOOST_TEST_CASE( &test_rotate_copy ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/search.cpp b/test/algorithm_test/search.cpp
new file mode 100644
index 0000000..91f19bd
--- /dev/null
+++ b/test/algorithm_test/search.cpp
@@ -0,0 +1,113 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/search.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container1, class Container2 >
+        void test_search_impl(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t;
+            typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t;
+
+            const Container1& ccont1 = cont1;
+            const Container2& ccont2 = cont2;
+
+            iterator1_t it = boost::search(cont1, cont2);
+            BOOST_CHECK( it == boost::search(boost::make_iterator_range(cont1), cont2) );
+            BOOST_CHECK( it == boost::search(cont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( it == boost::search(boost::make_iterator_range(cont1),
+                                             boost::make_iterator_range(cont2)) );
+            iterator1_t it2 = boost::search(cont1, ccont2);
+            BOOST_CHECK( it2 == boost::search(boost::make_iterator_range(cont1), ccont2) );
+            BOOST_CHECK( it2 == boost::search(cont1, boost::make_iterator_range(ccont2)) );
+            BOOST_CHECK( it2 == boost::search(boost::make_iterator_range(cont1),
+                                              boost::make_iterator_range(ccont2)) );
+            const_iterator1_t cit = boost::search(ccont1, cont2);
+            BOOST_CHECK( cit == boost::search(boost::make_iterator_range(ccont1), cont2) );
+            BOOST_CHECK( cit == boost::search(ccont1, boost::make_iterator_range(cont2)) );
+            BOOST_CHECK( cit == boost::search(boost::make_iterator_range(ccont1),
+                                              boost::make_iterator_range(cont2)) );
+            const_iterator1_t cit2 = boost::search(ccont1, ccont2);
+            BOOST_CHECK( cit2 == boost::search(boost::make_iterator_range(ccont1), ccont2) );
+            BOOST_CHECK( cit2 == boost::search(ccont1, boost::make_iterator_range(ccont2)) );
+            BOOST_CHECK( cit2 == boost::search(boost::make_iterator_range(ccont1),
+                                               boost::make_iterator_range(ccont2)) );
+
+            BOOST_CHECK( it == std::search(cont1.begin(), cont1.end(), cont2.begin(), cont2.end()) );
+            BOOST_CHECK( it2 == std::search(cont1.begin(), cont1.end(), ccont2.begin(), ccont2.end()) );
+            BOOST_CHECK( cit == std::search(ccont1.begin(), ccont1.end(), cont2.begin(), cont2.end()) );
+            BOOST_CHECK( cit2 == std::search(ccont1.begin(), ccont1.end(), ccont2.begin(), ccont2.end()) );
+        }
+
+        template< class Container1, class Container2 >
+        void test_search_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_search_impl(cont1, cont2);
+
+            cont1 += 1;
+            test_search_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2 += 1;
+            test_search_impl(cont1, cont2);
+
+            cont1 += 1;
+            test_search_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 10,11,12;
+            test_search_impl(cont1, cont2);
+
+            cont2.clear();
+            cont2 += 4,5,6;
+            test_search_impl(cont1, cont2);
+        }
+
+        void test_search()
+        {
+            test_search_impl< std::list<int>, std::list<int> >();
+            test_search_impl< std::vector<int>, std::vector<int> >();
+            test_search_impl< std::set<int>, std::set<int> >();
+            test_search_impl< std::list<int>, std::vector<int> >();
+            test_search_impl< std::vector<int>, std::list<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.search" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_search ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/search_n.cpp b/test/algorithm_test/search_n.cpp
new file mode 100644
index 0000000..76f5b78
--- /dev/null
+++ b/test/algorithm_test/search_n.cpp
@@ -0,0 +1,198 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/search_n.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace
+{
+    template<typename ForwardIterator, typename Integer, typename Value>
+    inline ForwardIterator
+    reference_search_n(ForwardIterator first, ForwardIterator last,
+                       Integer count, const Value& value)
+    {
+        if (count <= 0)
+            return first;
+        else if (count == 1)
+            return std::find(first, last, value);
+        else
+        {
+            first = std::find(first, last, value);
+            while (first != last)
+            {
+                typename std::iterator_traits<ForwardIterator>::difference_type n = count;
+                ForwardIterator i = first;
+                ++i;
+                while (i != last && n != 1 && *i==value)
+                {
+                    ++i;
+                    --n;
+                }
+                if (n == 1)
+                    return first;
+                if (i == last)
+                    return last;
+                first = std::find(++i, last, value);
+            }
+        }
+        return last;
+    }
+
+    template<typename ForwardIterator, typename Integer, typename Value,
+             typename BinaryPredicate>
+    inline ForwardIterator
+    reference_search_n(ForwardIterator first, ForwardIterator last,
+                       Integer count, const Value& value,
+                       BinaryPredicate pred)
+    {
+        typedef typename std::iterator_traits<
+            ForwardIterator
+        >::iterator_category cat_t BOOST_RANGE_UNUSED;
+
+        if (count <= 0)
+            return first;
+        if (count == 1)
+        {
+            while (first != last && !static_cast<bool>(pred(*first, value)))
+                ++first;
+            return first;
+        }
+        else
+        {
+            typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
+
+            while (first != last && !static_cast<bool>(pred(*first, value)))
+                ++first;
+
+            while (first != last)
+            {
+                difference_t n = count;
+                ForwardIterator i = first;
+                ++i;
+                while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
+                {
+                    ++i;
+                    --n;
+                }
+                if (n == 1)
+                    return first;
+                if (i == last)
+                    return last;
+                first = ++i;
+                while (first != last && !static_cast<bool>(pred(*first, value)))
+                    ++first;
+            }
+        }
+        return last;
+    }
+
+    template< class Container1, class Value, class Pred >
+    void test_search_n_pred_impl(Container1& cont1, Value value, Pred pred)
+    {
+        typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t;
+        typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t;
+
+        const Container1& ccont1 = cont1;
+
+        for (std::size_t n = 0; n < cont1.size(); ++n)
+        {
+            iterator1_t it = boost::search_n(cont1, n, value, pred);
+            BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value, pred) );
+            BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value, pred) );
+
+            const_iterator1_t cit = boost::search_n(ccont1, n, value, pred);
+            BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value, pred) );
+            BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value, pred) );
+        }
+    }
+
+    template< class Container1, class Value >
+    void test_search_n_impl(Container1& cont1, Value value)
+    {
+        typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t;
+        typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t;
+
+        const Container1& ccont1 = cont1;
+
+        for (std::size_t n = 0; n < cont1.size(); ++n)
+        {
+            iterator1_t it = boost::search_n(cont1, n, value);
+            BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value) );
+            BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value) );
+
+            const_iterator1_t cit = boost::search_n(ccont1, n, value);
+            BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value) );
+            BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value) );
+        }
+
+        test_search_n_pred_impl(cont1, value, std::less<int>());
+        test_search_n_pred_impl(cont1, value, std::greater<int>());
+        test_search_n_pred_impl(cont1, value, std::equal_to<int>());
+        test_search_n_pred_impl(cont1, value, std::not_equal_to<int>());
+    }
+
+    template< class Container1, class Container2 >
+    void test_search_n_impl()
+    {
+        using namespace boost::assign;
+
+        Container1 cont1;
+
+        test_search_n_impl(cont1, 1);
+
+        cont1 += 1;
+        test_search_n_impl(cont1, 1);
+        test_search_n_impl(cont1, 0);
+
+        cont1.clear();
+        cont1 += 1,1;
+        test_search_n_impl(cont1, 1);
+        test_search_n_impl(cont1, 0);
+
+        cont1 += 1,1,1;
+        test_search_n_impl(cont1, 1);
+        test_search_n_impl(cont1, 0);
+
+        cont1.clear();
+        cont1 += 1,2,3,4,5,6,7,8,9;
+        test_search_n_impl(cont1, 1);
+        test_search_n_impl(cont1, 2);
+        test_search_n_impl(cont1, 5);
+        test_search_n_impl(cont1, 9);
+    }
+
+    void test_search_n()
+    {
+        test_search_n_impl< std::list<int>, std::list<int> >();
+        test_search_n_impl< std::vector<int>, std::vector<int> >();
+        test_search_n_impl< std::set<int>, std::set<int> >();
+        test_search_n_impl< std::list<int>, std::vector<int> >();
+        test_search_n_impl< std::vector<int>, std::list<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.search_n" );
+
+    test->add( BOOST_TEST_CASE( &test_search_n ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/set_difference.cpp b/test/algorithm_test/set_difference.cpp
new file mode 100644
index 0000000..84dc62c
--- /dev/null
+++ b/test/algorithm_test/set_difference.cpp
@@ -0,0 +1,214 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Iterator, class Container2>
+        void check_result(
+            Container1& reference,
+            Iterator    reference_result,
+            Container2& test_cont,
+            Iterator    test_result
+            )
+        {
+            BOOST_CHECK_EQUAL(
+                std::distance<Iterator>(reference.begin(), reference_result),
+                std::distance<Iterator>(test_cont.begin(), test_result)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test_cont.begin(), test_cont.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_difference(cont1.begin(), cont1.end(),
+                                        cont2.begin(), cont2.end(),
+                                        reference.begin());
+
+            iterator_t test_result
+                = boost::set_difference(cont1, cont2, test_cont.begin());
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin());
+            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2,
+                       BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_difference(cont1.begin(), cont1.end(),
+                                        cont2.begin(), cont2.end(),
+                                        reference.begin(),
+                                        pred);
+
+            iterator_t test_result
+                = boost::set_difference(cont1, cont2, test_cont.begin(), pred);
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_difference(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container1, class Container2>
+        void test_set_difference_impl(
+            Container1& cont1,
+            Container2& cont2
+            )
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_set_difference_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_set_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_set_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_set_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 2,3,4;
+            test_set_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2,3,4;
+            cont2 += 1,2,3,4,5,6,7,8,9;
+            test_set_difference_impl(cont1, cont2);
+        }
+
+        void test_set_difference()
+        {
+            test_set_difference_impl< std::vector<int>, std::vector<int> >();
+            test_set_difference_impl< std::list<int>, std::list<int> >();
+            test_set_difference_impl< std::deque<int>, std::deque<int> >();
+            test_set_difference_impl< std::vector<int>, std::list<int> >();
+            test_set_difference_impl< std::list<int>, std::vector<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_difference" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_set_difference ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/set_intersection.cpp b/test/algorithm_test/set_intersection.cpp
new file mode 100644
index 0000000..213bbdf
--- /dev/null
+++ b/test/algorithm_test/set_intersection.cpp
@@ -0,0 +1,214 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Iterator, class Container2>
+        void check_result(
+            Container1& reference,
+            Iterator    reference_result,
+            Container2& test_cont,
+            Iterator    test_result
+            )
+        {
+            BOOST_CHECK_EQUAL(
+                std::distance<Iterator>(reference.begin(), reference_result),
+                std::distance<Iterator>(test_cont.begin(), test_result)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test_cont.begin(), test_cont.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_intersection(cont1.begin(), cont1.end(),
+                                        cont2.begin(), cont2.end(),
+                                        reference.begin());
+
+            iterator_t test_result
+                = boost::set_intersection(cont1, cont2, test_cont.begin());
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2,
+                       BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_intersection(cont1.begin(), cont1.end(),
+                                        cont2.begin(), cont2.end(),
+                                        reference.begin(),
+                                        pred);
+
+            iterator_t test_result
+                = boost::set_intersection(cont1, cont2, test_cont.begin(), pred);
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_intersection(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container1, class Container2>
+        void test_set_intersection_impl(
+            Container1& cont1,
+            Container2& cont2
+            )
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_set_intersection_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_set_intersection_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_set_intersection_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_set_intersection_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 2,3,4;
+            test_set_intersection_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2,3,4;
+            cont2 += 1,2,3,4,5,6,7,8,9;
+            test_set_intersection_impl(cont1, cont2);
+        }
+
+        void test_set_intersection()
+        {
+            test_set_intersection_impl< std::vector<int>, std::vector<int> >();
+            test_set_intersection_impl< std::list<int>, std::list<int> >();
+            test_set_intersection_impl< std::deque<int>, std::deque<int> >();
+            test_set_intersection_impl< std::vector<int>, std::list<int> >();
+            test_set_intersection_impl< std::list<int>, std::vector<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_intersection" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_set_intersection ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/set_symmetric_difference.cpp b/test/algorithm_test/set_symmetric_difference.cpp
new file mode 100644
index 0000000..b792fd8
--- /dev/null
+++ b/test/algorithm_test/set_symmetric_difference.cpp
@@ -0,0 +1,216 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Iterator, class Container2>
+        void check_result(
+            Container1& reference,
+            Iterator    reference_result,
+            Container2& test_cont,
+            Iterator    test_result
+            )
+        {
+            BOOST_CHECK_EQUAL(
+                std::distance<Iterator>(reference.begin(), reference_result),
+                std::distance<Iterator>(test_cont.begin(), test_result)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test_cont.begin(), test_cont.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_symmetric_difference(cont1.begin(), cont1.end(),
+                                                cont2.begin(), cont2.end(),
+                                                reference.begin());
+
+            iterator_t test_result
+                = boost::set_symmetric_difference(cont1, cont2,
+                                                  test_cont.begin());
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin());
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2,
+                       BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_symmetric_difference(cont1.begin(), cont1.end(),
+                                                cont2.begin(), cont2.end(),
+                                                reference.begin(),
+                                                pred);
+
+            iterator_t test_result
+                = boost::set_symmetric_difference(cont1, cont2,
+                                                  test_cont.begin(), pred);
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            boost::make_iterator_range(cont1), cont2,
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            cont1, boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_symmetric_difference(
+                            boost::make_iterator_range(cont1),
+                            boost::make_iterator_range(cont2),
+                            test_cont.begin(), pred);
+                            
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container1, class Container2>
+        void test_set_symmetric_difference_impl(
+            Container1& cont1,
+            Container2& cont2
+            )
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_set_symmetric_difference_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_set_symmetric_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_set_symmetric_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_set_symmetric_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 2,3,4;
+            test_set_symmetric_difference_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2,3,4;
+            cont2 += 1,2,3,4,5,6,7,8,9;
+            test_set_symmetric_difference_impl(cont1, cont2);
+        }
+
+        void test_set_symmetric_difference()
+        {
+            test_set_symmetric_difference_impl< std::vector<int>, std::vector<int> >();
+            test_set_symmetric_difference_impl< std::list<int>, std::list<int> >();
+            test_set_symmetric_difference_impl< std::deque<int>, std::deque<int> >();
+            test_set_symmetric_difference_impl< std::vector<int>, std::list<int> >();
+            test_set_symmetric_difference_impl< std::list<int>, std::vector<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_symmetric_difference" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_set_symmetric_difference ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/set_union.cpp b/test/algorithm_test/set_union.cpp
new file mode 100644
index 0000000..7f9f10a
--- /dev/null
+++ b/test/algorithm_test/set_union.cpp
@@ -0,0 +1,210 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container1, class Iterator, class Container2>
+        void check_result(
+            Container1& reference,
+            Iterator    reference_result,
+            Container2& test_cont,
+            Iterator    test_result
+            )
+        {
+            BOOST_CHECK_EQUAL(
+                std::distance<Iterator>(reference.begin(), reference_result),
+                std::distance<Iterator>(test_cont.begin(), test_result)
+                );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test_cont.begin(), test_cont.end()
+                );
+        }
+
+        template<class Container1, class Container2>
+        void test(Container1& cont1, Container2& cont2)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_union(cont1.begin(), cont1.end(),
+                                 cont2.begin(), cont2.end(),
+                                 reference.begin());
+
+            iterator_t test_result
+                = boost::set_union(cont1, cont2, test_cont.begin());
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(boost::make_iterator_range(cont1),
+                                           cont2, test_cont.begin());
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(cont1,
+                                           boost::make_iterator_range(cont2),
+                                           test_cont.begin());
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(boost::make_iterator_range(cont1),
+                                           boost::make_iterator_range(cont2),
+                                           test_cont.begin());
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container, class BinaryPredicate>
+        void sort_container(Container& cont, BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> temp(cont.begin(), cont.end());
+            std::sort(temp.begin(), temp.end(), pred);
+            cont.assign(temp.begin(), temp.end());
+        }
+
+        template<class Container1,
+                 class Container2,
+                 class BinaryPredicate>
+        void test_pred(Container1 cont1, Container2 cont2,
+                       BinaryPredicate pred)
+        {
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            sort_container(cont1, pred);
+            sort_container(cont2, pred);
+
+            std::vector<value_t> reference(cont1.size() + cont2.size());
+            std::vector<value_t> test_cont(reference);
+
+            iterator_t reference_result
+                = std::set_union(cont1.begin(), cont1.end(),
+                                 cont2.begin(), cont2.end(),
+                                 reference.begin(),
+                                 pred);
+
+            iterator_t test_result
+                = boost::set_union(cont1, cont2, test_cont.begin(), pred);
+
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(boost::make_iterator_range(cont1),
+                                           cont2, test_cont.begin(), pred);
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(cont1,
+                                           boost::make_iterator_range(cont2),
+                                           test_cont.begin(), pred);
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+                         
+            test_result = boost::set_union(boost::make_iterator_range(cont1),
+                                           boost::make_iterator_range(cont2),
+                                           test_cont.begin(), pred);
+                                           
+            check_result(reference, reference_result,
+                         test_cont, test_result);
+        }
+
+        template<class Container1, class Container2>
+        void test_set_union_impl(
+            Container1& cont1,
+            Container2& cont2
+            )
+        {
+            test(cont1, cont2);
+            test_pred(cont1, cont2, std::less<int>());
+            test_pred(cont1, cont2, std::greater<int>());
+        }
+
+        template<class Container1, class Container2>
+        void test_set_union_impl()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_set_union_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1;
+            test_set_union_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont2 += 1;
+            test_set_union_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 1,2,3,4,5,6,7,8,9;
+            cont2 += 2,3,4;
+            test_set_union_impl(cont1, cont2);
+
+            cont1.clear();
+            cont2.clear();
+            cont1 += 2,3,4;
+            cont2 += 1,2,3,4,5,6,7,8,9;
+            test_set_union_impl(cont1, cont2);
+        }
+
+        void test_set_union()
+        {
+            test_set_union_impl< std::vector<int>, std::vector<int> >();
+            test_set_union_impl< std::list<int>, std::list<int> >();
+            test_set_union_impl< std::deque<int>, std::deque<int> >();
+            test_set_union_impl< std::vector<int>, std::list<int> >();
+            test_set_union_impl< std::list<int>, std::vector<int> >();
+        }
+    }
+}
+
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_union" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_set_union ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/sort.cpp b/test/algorithm_test/sort.cpp
new file mode 100644
index 0000000..c6611f7
--- /dev/null
+++ b/test/algorithm_test/sort.cpp
@@ -0,0 +1,105 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/sort.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test_sort_impl(Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            boost::sort(test);
+            std::sort(reference.begin(), reference.end());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                                           
+            Container test2(cont);
+            boost::sort(boost::make_iterator_range(test2));
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_sort_impl(Container& cont, BinaryPredicate pred)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            boost::sort(test, pred);
+            std::sort(reference.begin(), reference.end(), pred);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end()
+                );
+                
+            Container test2(cont);
+            boost::sort(boost::make_iterator_range(test2), pred);
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test2.begin(), test2.end() );
+        }
+
+        template<class Container>
+        void test_sort_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_sort_impl(cont);
+            test_sort_impl(cont, std::less<int>());
+            test_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1;
+            test_sort_impl(cont);
+            test_sort_impl(cont, std::less<int>());
+            test_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_sort_impl(cont);
+            test_sort_impl(cont, std::less<int>());
+            test_sort_impl(cont, std::greater<int>());
+        }
+
+        void test_sort()
+        {
+            test_sort_impl< std::vector<int> >();
+            test_sort_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.sort" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_sort ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/stable_partition.cpp b/test/algorithm_test/stable_partition.cpp
new file mode 100644
index 0000000..b39161f
--- /dev/null
+++ b/test/algorithm_test/stable_partition.cpp
@@ -0,0 +1,134 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/stable_partition.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_stable_partition
+{
+    struct equal_to_5
+    {
+        typedef bool result_type;
+        typedef int argument_type;
+        bool operator()(int x) const { return x == 5; }
+    };
+
+    // test the 'partition' algorithm
+    template<class UnaryPredicate>
+    class stable_partition_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            Container cont2(cont);
+
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::stable_partition(cont, UnaryPredicate());
+
+            iter_t temp_result = boost::stable_partition(
+                boost::make_iterator_range(cont2), UnaryPredicate());
+
+            BOOST_CHECK_EQUAL( std::distance(cont.begin(), result),
+                               std::distance(cont2.begin(), temp_result) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                           cont2.begin(), cont2.end() );
+
+            return result;
+        }
+
+        UnaryPredicate pred() const { return UnaryPredicate(); }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+                Container cont2(cont);
+                result_t result = boost::stable_partition<return_type>(cont, policy.pred());
+
+                result_t result2 = boost::stable_partition<return_type>(
+                                    boost::make_iterator_range(cont2), policy.pred());
+                                    
+                boost::ignore_unused_variable_warning(result2);
+
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont2.begin(), cont2.end(),
+                                               cont.begin(), cont.end() );
+
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::stable_partition(cont.begin(), cont.end(), UnaryPredicate());
+        }
+    };
+
+    template<class Container>
+    void test_stable_partition_impl()
+    {
+        using namespace boost::assign;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        stable_partition_test_policy< equal_to_5 > policy;
+
+        Container cont;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,2,2,3,4,5,6,7,8,9;
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9;
+        test_driver(cont, policy);
+    }
+
+    void test_stable_partition()
+    {
+        test_stable_partition_impl< std::vector<int> >();
+        test_stable_partition_impl< std::list<int> >();
+        test_stable_partition_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.stable_partition" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_stable_partition::test_stable_partition ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/stable_sort.cpp b/test/algorithm_test/stable_sort.cpp
new file mode 100644
index 0000000..8372bd6
--- /dev/null
+++ b/test/algorithm_test/stable_sort.cpp
@@ -0,0 +1,103 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/stable_sort.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void test_stable_sort_impl(Container& cont)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            boost::stable_sort(test);
+            std::stable_sort(reference.begin(), reference.end());
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                
+            test = cont;
+            boost::stable_sort(boost::make_iterator_range(test));
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+        }
+
+        template<class Container, class BinaryPredicate>
+        void test_stable_sort_impl(Container& cont, BinaryPredicate pred)
+        {
+            Container reference(cont);
+            Container test(cont);
+
+            boost::stable_sort(test, pred);
+            std::stable_sort(reference.begin(), reference.end(), pred);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+                                           
+            test = cont;
+            boost::stable_sort(boost::make_iterator_range(test), pred);
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test.begin(), test.end() );
+        }
+
+        template<class Container>
+        void test_stable_sort_impl()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+            test_stable_sort_impl(cont);
+            test_stable_sort_impl(cont, std::less<int>());
+            test_stable_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1;
+            test_stable_sort_impl(cont);
+            test_stable_sort_impl(cont, std::less<int>());
+            test_stable_sort_impl(cont, std::greater<int>());
+
+            cont.clear();
+            cont += 1,2,3,4,5,6,7,8,9;
+            test_stable_sort_impl(cont);
+            test_stable_sort_impl(cont, std::less<int>());
+            test_stable_sort_impl(cont, std::greater<int>());
+        }
+
+        void test_stable_sort()
+        {
+            test_stable_sort_impl< std::vector<int> >();
+            test_stable_sort_impl< std::deque<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.stable_sort" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_stable_sort ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/swap_ranges.cpp b/test/algorithm_test/swap_ranges.cpp
new file mode 100644
index 0000000..a96bfac
--- /dev/null
+++ b/test/algorithm_test/swap_ranges.cpp
@@ -0,0 +1,116 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/swap_ranges.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<class Container1, class Container2>
+    void test_swap_ranges_impl(const Container1& source1, const Container2& source2)
+    {
+        Container1 reference1(source1);
+        Container2 reference2(source2);
+        std::swap_ranges(reference1.begin(), reference1.end(), reference2.begin());
+
+        Container1 test1(source1);
+        Container2 test2(source2);
+        boost::swap_ranges(test1, test2);
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(),
+                                       test1.begin(), test1.end() );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(),
+                                       test2.begin(), test2.end() );
+                                       
+        test1 = source1;
+        test2 = source2;
+        boost::swap_ranges(boost::make_iterator_range(test1), test2);
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(),
+                                       test1.begin(), test1.end() );
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(),
+                                       test2.begin(), test2.end() );
+                                       
+        test1 = source1;
+        test2 = source2;
+        boost::swap_ranges(test1, boost::make_iterator_range(test2));
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(),
+                                       test1.begin(), test1.end() );
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(),
+                                       test2.begin(), test2.end() );
+                                       
+        test1 = source1;
+        test2 = source2;
+        boost::swap_ranges(boost::make_iterator_range(test1),
+                           boost::make_iterator_range(test2));
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(),
+                                       test1.begin(), test1.end() );
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(),
+                                       test2.begin(), test2.end() );
+    }
+
+    template<class Container1, class Container2>
+    void test_swap_ranges_impl()
+    {
+        using namespace boost::assign;
+
+        Container1 c1;
+        Container2 c2;
+
+        test_swap_ranges_impl(c1, c2);
+
+        c1.clear();
+        c1 += 1;
+        c2.clear();
+        c2 += 2;
+        test_swap_ranges_impl(c1, c2);
+
+        c1.clear();
+        c1 += 1,2,3,4,5,6,7,8,9,10;
+        c2.clear();
+        c2 += 10,9,8,7,6,5,4,3,2,1;
+        test_swap_ranges_impl(c1, c2);
+    }
+
+    inline void test_swap_ranges()
+    {
+        test_swap_ranges_impl< std::vector<int>, std::vector<int> >();
+        test_swap_ranges_impl< std::vector<int>, std::list<int> >();
+        test_swap_ranges_impl< std::vector<int>, std::deque<int> >();
+        test_swap_ranges_impl< std::list<int>, std::vector<int> >();
+        test_swap_ranges_impl< std::list<int>, std::list<int> >();
+        test_swap_ranges_impl< std::list<int>, std::deque<int> >();
+        test_swap_ranges_impl< std::deque<int>, std::vector<int> >();
+        test_swap_ranges_impl< std::deque<int>, std::list<int> >();
+        test_swap_ranges_impl< std::deque<int>, std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.swap_ranges" );
+
+    test->add( BOOST_TEST_CASE( &test_swap_ranges ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/transform.cpp b/test/algorithm_test/transform.cpp
new file mode 100644
index 0000000..11ac5f0
--- /dev/null
+++ b/test/algorithm_test/transform.cpp
@@ -0,0 +1,184 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/transform.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include "../test_function/multiply_by_x.hpp"
+#include <algorithm>
+#include <list>
+#include <set>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        template< class Container >
+        void test_transform_impl1(Container& cont)
+        {
+            using namespace boost::range_test_function;
+
+            const Container& ccont = cont;
+
+            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+            std::vector<value_t> target(cont.size());
+            std::vector<value_t> reference(cont.size());
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            multiply_by_x<int> fn(2);
+
+            iterator_t reference_it
+                = std::transform(cont.begin(), cont.end(), reference.begin(), fn);
+                
+            boost::ignore_unused_variable_warning(reference_it);
+
+            iterator_t test_it
+                = boost::transform(cont, target.begin(), fn);
+
+            BOOST_CHECK( test_it == target.end() );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                
+            BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont), target.begin(), fn) );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                                           
+            target.clear();
+            target.resize(ccont.size());
+
+            test_it = boost::transform(ccont, target.begin(), fn);
+            
+            BOOST_CHECK( test_it == target.end() );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+            BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(ccont), target.begin(), fn) );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+        }
+
+        template< class Container >
+        void test_transform_impl1()
+        {
+            using namespace boost::assign;
+
+            Container cont;
+
+            test_transform_impl1(cont);
+
+            cont += 1;
+            test_transform_impl1(cont);
+
+            cont += 2,3,4,5,6,7;
+            test_transform_impl1(cont);
+        }
+
+        template< class Container1, class Container2 >
+        void test_transform_impl2(Container1& cont1, Container2& cont2)
+        {
+            const Container1& ccont1 = cont1;
+            const Container2& ccont2 = cont2;
+
+            BOOST_CHECK_EQUAL( cont1.size(), cont2.size() );
+
+            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
+
+            std::vector<value_t> target(cont1.size());
+            std::vector<value_t> reference(cont1.size());
+            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
+
+            std::multiplies<int> fn;
+
+            iterator_t reference_it
+                = std::transform(cont1.begin(), cont1.end(),
+                                 cont2.begin(), reference.begin(), fn);
+                                 
+            boost::ignore_unused_variable_warning(reference_it);
+
+            iterator_t test_it
+                = boost::transform(cont1, cont2, target.begin(), fn);
+                
+            BOOST_CHECK( test_it == target.end() );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                                           
+            BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont1), cont2, target.begin(), fn) );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                                           
+            BOOST_CHECK( test_it == boost::transform(cont1, boost::make_iterator_range(cont2), target.begin(), fn) );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                                           
+            BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont1),
+                                                     boost::make_iterator_range(cont2),
+                                                     target.begin(), fn) );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           target.begin(), target.end() );
+                         
+
+            target.clear();
+            target.resize(ccont1.size());
+
+            test_it = boost::transform(ccont1, ccont2, target.begin(), fn);
+
+            BOOST_CHECK( test_it == target.end() );
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                target.begin(), target.end() );
+        }
+
+        template< class Container1, class Container2 >
+        void test_transform_impl2()
+        {
+            using namespace boost::assign;
+
+            Container1 cont1;
+            Container2 cont2;
+
+            test_transform_impl2(cont1, cont2);
+
+            cont1 += 1;
+            cont2 += 2;
+            test_transform_impl2(cont1, cont2);
+
+            cont1 += 2,3,4,5,6,7;
+            cont2 += 4,6,8,10,12,14;
+            test_transform_impl2(cont1, cont2);
+        }
+
+        void test_transform()
+        {
+            test_transform_impl1< std::vector<int> >();
+            test_transform_impl1< std::list<int> >();
+            test_transform_impl1< std::set<int> >();
+            test_transform_impl1< std::multiset<int> >();
+
+            test_transform_impl2< std::vector<int>, std::list<int> >();
+            test_transform_impl2< std::list<int>, std::vector<int> >();
+            test_transform_impl2< std::set<int>, std::set<int> >();
+            test_transform_impl2< std::multiset<int>, std::list<int> >();
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.transform" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_transform ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/unique.cpp b/test/algorithm_test/unique.cpp
new file mode 100644
index 0000000..d8eb784
--- /dev/null
+++ b/test/algorithm_test/unique.cpp
@@ -0,0 +1,263 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/unique.hpp>
+#include <boost/range/detail/range_return.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <boost/config.hpp>
+#include "../test_driver/range_overload_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_unique
+{
+    // test the 'unique' algorithm without a predicate
+    class unique_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            // There isn't an iterator return version of boost::unique, so just
+            // perform the standard algorithm
+            return std::unique(cont.begin(), cont.end());
+        }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+
+                Container cont2(cont);
+
+                result_t result = boost::unique<return_type>(cont);
+
+                boost::unique<return_type>(boost::make_iterator_range(cont2));
+
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+
+                return result;
+            }
+        };
+
+        template<typename Container>
+        struct test_range_overload
+        {
+            BOOST_STATIC_CONSTANT(
+                ::boost::range_return_value,
+                result_type = ::boost::return_begin_found);
+                
+            template<typename Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<
+                Container, result_type
+            >::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<
+                                Container,result_type>::type result_t;
+                
+                Container cont2(cont);
+                
+                result_t result = boost::unique(cont);
+                
+                boost::unique(boost::make_iterator_range(cont2));
+                
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    cont.begin(), cont.end(),
+                    cont2.begin(), cont2.end());
+                
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::unique(cont.begin(), cont.end());
+        }
+    };
+   
+    // test the 'unique' algorithm with a predicate
+    template<class Pred>
+    class unique_pred_test_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            // There isn't an iterator return version of boost::unique, so just
+            // perform the standard algorithm
+            return std::unique(cont.begin(), cont.end(), Pred());
+        }
+
+        Pred pred() const { return Pred(); }
+
+        template< boost::range_return_value return_type >
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
+
+                Container cont2(cont);
+
+                result_t result = boost::unique<return_type>(cont, policy.pred());
+
+                boost::unique<return_type>(boost::make_iterator_range(cont2), policy.pred());
+
+                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
+                                               cont2.begin(), cont2.end() );
+
+                return result;
+            }
+        };
+        
+        template<typename Container>
+        struct test_range_overload
+        {
+            BOOST_STATIC_CONSTANT(
+                ::boost::range_return_value,
+                result_type = ::boost::return_begin_found);
+                
+            template<typename Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<
+                            Container,result_type>::type result_t;
+                
+                Container cont2(cont);
+                
+                result_t result = boost::unique(cont, policy.pred());
+                
+                boost::unique(boost::make_iterator_range(cont2), policy.pred());
+                
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    cont.begin(), cont.end(),
+                    cont2.begin(), cont2.end());
+                    
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::unique(cont.begin(), cont.end(), Pred());
+        }
+    };
+
+    template<class Container, class TestPolicy, class Pred>
+    void test_unique_impl(TestPolicy policy, Pred pred)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+        boost::range_test::range_overload_test_driver test_driver;
+
+        Container cont;
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1;
+
+        std::vector<value_t> temp(cont.begin(), cont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        cont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+
+        cont.clear();
+        cont += 1,2,2,2,2,3,4,5,6,7,8,9;
+
+        temp.assign(cont.begin(), cont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        cont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+    }
+    
+    template<typename T>
+    struct equal_div_2
+    {
+        typedef bool result_type;
+        typedef const T& first_argument_type;
+        typedef const T& second_argument_type;
+        
+        bool operator()(const T& left, const T& right) const
+        {
+            return left / 2 == right / 2;
+        }
+    };
+
+    template<class Container>
+    void test_unique_impl()
+    {
+        test_unique_impl<Container>(
+            unique_test_policy(),
+            std::less<int>()
+        );
+
+        test_unique_impl<Container>(
+            unique_pred_test_policy<std::equal_to<int> >(),
+            std::less<int>()
+        );
+
+        test_unique_impl<Container>(
+            unique_pred_test_policy<std::equal_to<int> >(),
+            std::greater<int>()
+        );
+        
+        test_unique_impl<Container>(
+            unique_pred_test_policy<equal_div_2<int> >(),
+            std::less<int>()
+        );
+    }
+
+    void test_unique()
+    {
+        test_unique_impl< std::vector<int> >();
+        test_unique_impl< std::list<int> >();
+        test_unique_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.unique" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_unique::test_unique ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/unique_copy.cpp b/test/algorithm_test/unique_copy.cpp
new file mode 100644
index 0000000..21f107a
--- /dev/null
+++ b/test/algorithm_test/unique_copy.cpp
@@ -0,0 +1,158 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/unique_copy.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace
+{
+    template<class OutputIterator, class Value>
+    void test_append(OutputIterator target, Value value)
+    {
+        *target++ = value;
+    }
+
+    template<class Container>
+    void test_unique_copy_impl(Container& c)
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type;
+        std::vector<value_type> reference;
+        std::vector<value_type> test;
+
+        test_append(
+            std::unique_copy(c.begin(), c.end(), std::back_inserter(reference)),
+            value_type()
+            );
+
+        test_append(
+            boost::unique_copy(c, std::back_inserter(test)),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(),
+                                      test.begin(), test.end());
+                                      
+        test.clear();
+        
+        test_append(
+            boost::unique_copy(boost::make_iterator_range(c),
+                               std::back_inserter(test)),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(),
+                                      test.begin(), test.end());
+    }
+
+    template<class Container, class Pred>
+    void test_unique_copy_impl(Container& c, Pred pred)
+    {
+        typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type;
+        std::vector<value_type> reference;
+        std::vector<value_type> test;
+
+        test_append(
+            std::unique_copy(c.begin(), c.end(), std::back_inserter(reference), pred),
+            value_type()
+            );
+
+        test_append(
+            boost::unique_copy(c, std::back_inserter(test), pred),
+            value_type()
+            );
+
+        BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(),
+                                      test.begin(), test.end());
+                                      
+        test.clear();
+        
+        test_append(
+            boost::unique_copy(boost::make_iterator_range(c),
+                               std::back_inserter(test), pred),
+            value_type()
+            );
+            
+        BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(),
+                                      test.begin(), test.end());
+    }
+
+    template<class Container, class Pred>
+    void test_unique_copy_driver(Pred pred)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+        Container cont;
+
+        test_unique_copy_impl(cont);
+        test_unique_copy_impl(cont, pred);
+
+        cont.clear();
+        cont += 1;
+
+        std::vector<value_t> temp(cont.begin(), cont.end());
+        std::sort(temp.begin(), temp.end());
+        cont.assign(temp.begin(), temp.end());
+        test_unique_copy_impl(cont);
+
+        std::sort(temp.begin(), temp.end(), pred);
+        cont.assign(temp.begin(), temp.end());
+        test_unique_copy_impl(cont, pred);
+
+        cont.clear();
+        cont += 1,2,2,2,2,3,4,5,6,7,8,9;
+
+        temp.assign(cont.begin(), cont.end());
+        std::sort(temp.begin(), temp.end());
+        cont.assign(temp.begin(), temp.end());
+        test_unique_copy_impl(cont);
+
+        std::sort(temp.begin(), temp.end(), pred);
+        cont.assign(temp.begin(), temp.end());
+        test_unique_copy_impl(cont, pred);
+    }
+
+    template<class Container>
+    void test_unique_copy_impl()
+    {
+        test_unique_copy_driver<Container>(std::less<int>());
+        test_unique_copy_driver<Container>(std::greater<int>());
+    }
+
+    void test_unique_copy()
+    {
+        test_unique_copy_impl< std::vector<int> >();
+        test_unique_copy_impl< std::list<int> >();
+        test_unique_copy_impl< std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.unique_copy" );
+
+    test->add( BOOST_TEST_CASE( &test_unique_copy ) );
+
+    return test;
+}
diff --git a/test/algorithm_test/upper_bound.cpp b/test/algorithm_test/upper_bound.cpp
new file mode 100644
index 0000000..daae764
--- /dev/null
+++ b/test/algorithm_test/upper_bound.cpp
@@ -0,0 +1,182 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/algorithm/upper_bound.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+#include "../test_driver/range_return_test_driver.hpp"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <numeric>
+#include <deque>
+#include <vector>
+
+namespace boost_range_test_algorithm_upper_bound
+{
+    class upper_bound_policy
+    {
+    public:
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::upper_bound(cont, 5);
+            BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) );
+            return result;
+        }
+
+        template<boost::range_return_value result_type>
+        struct test_range
+        {
+            template<class Container, class Policy>
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type
+            operator()(Policy&, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t;
+                result_t result = boost::upper_bound<result_type>(cont, 5);
+                BOOST_CHECK( result == boost::upper_bound<result_type>(boost::make_iterator_range(cont), 5) );
+                return result;
+            }
+        };
+
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::upper_bound(cont.begin(), cont.end(), 5);
+        }
+    };
+
+    template< class BinaryPredicate >
+    struct upper_bound_pred_policy
+    {
+        template< class Container >
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        test_iter(Container& cont)
+        {
+            typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
+            iter_t result = boost::upper_bound(cont, 5, BinaryPredicate());
+            BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5, BinaryPredicate()) );
+            return result;
+        }
+
+        template< boost::range_return_value result_type>
+        struct test_range
+        {
+            template< class Container, class Policy >
+            BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type
+            operator()(Policy& policy, Container& cont)
+            {
+                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t;
+
+                result_t result = boost::upper_bound<result_type>(cont, 5, policy.pred());
+
+                BOOST_CHECK( result == boost::upper_bound<result_type>(
+                    boost::make_iterator_range(cont), 5, policy.pred()) );
+
+                return result;
+            }
+        };
+
+        template<class Container>
+        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+        reference(Container& cont)
+        {
+            return std::upper_bound(
+                    cont.begin(), cont.end(), 5, BinaryPredicate());
+        }
+
+        BinaryPredicate& pred() { return m_pred; }
+
+    private:
+        BinaryPredicate m_pred;
+    };
+
+    template<class Container,
+             class TestPolicy,
+             class BinaryPredicate>
+    void test_upper_bound_impl(TestPolicy policy, BinaryPredicate pred)
+    {
+        using namespace boost::assign;
+
+        typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
+        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
+
+        boost::range_test::range_return_test_driver test_driver;
+
+        container_t mcont;
+        Container& cont = mcont;
+
+        test_driver(cont, policy);
+
+        mcont.clear();
+        mcont += 1;
+
+        std::vector<value_t> temp(mcont.begin(), mcont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        mcont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+
+        mcont.clear();
+        mcont += 1,2,3,4,5,6,7,8,9;
+
+        temp.assign(mcont.begin(), mcont.end());
+        std::sort(temp.begin(), temp.end(), pred);
+        mcont.assign(temp.begin(), temp.end());
+
+        test_driver(cont, policy);
+    }
+
+    template<class Container>
+    void test_upper_bound_impl()
+    {
+        test_upper_bound_impl<Container>(
+            upper_bound_policy(),
+            std::less<int>()
+            );
+
+        test_upper_bound_impl<Container>(
+            upper_bound_pred_policy<std::less<int> >(),
+            std::less<int>()
+            );
+
+        test_upper_bound_impl<Container>(
+            upper_bound_pred_policy<std::greater<int> >(),
+            std::greater<int>()
+            );
+    }
+
+    void test_upper_bound()
+    {
+        test_upper_bound_impl< std::vector<int> >();
+        test_upper_bound_impl< std::list<int> >();
+        test_upper_bound_impl< std::deque<int> >();
+
+        test_upper_bound_impl< const std::vector<int> >();
+        test_upper_bound_impl< const std::list<int> >();
+        test_upper_bound_impl< const std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.upper_bound" );
+
+    test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_upper_bound::test_upper_bound ) );
+
+    return test;
+}
diff --git a/test/array.cpp b/test/array.cpp
new file mode 100644
index 0000000..b913fde
--- /dev/null
+++ b/test/array.cpp
@@ -0,0 +1,83 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+
+using namespace boost;
+using namespace std;
+
+void check_array()
+{
+    const int sz = 9;
+    typedef int   array_t[sz];
+    int           my_array[sz]  = { 1,2,3,4,5,6,7,8,9 };
+    const array_t ca           = { 1,2,3,4,5,6,7,8,10 };
+
+ 
+// BOOST_RANGE_NO_STATIC_ASSERT 
+#if !defined( __BORLANDC__ )
+#else
+    BOOST_STATIC_ASSERT(( is_same< range_value<array_t>::type, int >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<array_t>::type, int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_const_iterator<array_t>::type, const int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_difference<array_t>::type, std::ptrdiff_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_size<array_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<array_t>::type, int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
+    
+    BOOST_STATIC_ASSERT(( is_same< range_value<const array_t>::type, const int >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const array_t>::type, const int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_difference<const array_t>::type, std::ptrdiff_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_size<const array_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
+#endif
+    
+    BOOST_CHECK_EQUAL( begin( my_array ), my_array );
+    BOOST_CHECK_EQUAL( end( my_array ), my_array + size( my_array ) );
+    BOOST_CHECK_EQUAL( empty( my_array ), false );
+
+    BOOST_CHECK_EQUAL( begin( ca ), ca );
+    BOOST_CHECK_EQUAL( end( ca ), ca + size( ca ) );
+    BOOST_CHECK_EQUAL( empty( ca ),false );
+
+    const char A[] = "\0A";
+    BOOST_CHECK_EQUAL( boost::size(A), 3 );
+}
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_array ) );
+
+    return test;
+}
+
+
+
+
+
diff --git a/test/atl.cpp b/test/atl.cpp
new file mode 100644
index 0000000..50905b1
--- /dev/null
+++ b/test/atl.cpp
@@ -0,0 +1,623 @@
+
+
+// Boost.Range ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+// #include <pstade/vodka/drink.hpp>
+
+#include <boost/test/test_tools.hpp>
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define BOOST_LIB_NAME boost_test_exec_monitor
+#include <boost/config/auto_link.hpp>
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
+#include <boost/range/atl.hpp> // can be placed first
+
+
+#include <map>
+#include <string>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+#include <boost/foreach.hpp>
+
+
+#include <atlbase.h> // for ATL3 CSimpleArray/CSimpleValArray
+#if !(_ATL_VER < 0x0700)
+    #include <atlcoll.h>
+    #include <cstringt.h>
+    #include <atlsimpstr.h>
+    #include <atlstr.h>
+#endif
+
+
+namespace brdm = boost::range_detail_microsoft;
+
+
+#if !(_ATL_VER < 0x0700)
+
+
+template< class ArrayT, class SampleRange >
+bool test_init_auto_ptr_array(ArrayT& arr, SampleRange& sample)
+{
+    typedef typename boost::range_iterator<SampleRange>::type iter_t;
+
+    for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+        arr.Add(*it); // moves ownership
+    }
+
+    return boost::distance(arr) == boost::distance(sample);
+}
+
+
+template< class ListT, class SampleRange >
+bool test_init_auto_ptr_list(ListT& lst, SampleRange& sample)
+{
+    typedef typename boost::range_iterator<SampleRange>::type iter_t;
+    typedef typename boost::range_value<SampleRange>::type val_t;
+
+    for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+        lst.AddTail(*it); // moves ownership
+    }
+
+    return boost::distance(lst) == boost::distance(sample);
+}
+
+
+// Workaround:
+// CRBTree provides no easy access function, but yes, it is the range!
+//
+template< class AtlMapT, class KeyT, class MappedT >
+bool test_atl_map_has(AtlMapT& map, const KeyT& k, const MappedT m)
+{
+    typedef typename boost::range_iterator<AtlMapT>::type iter_t;
+
+    for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+        if (it->m_key == k && it->m_value == m)
+            return true;
+    }
+
+    return false;
+}
+
+
+template< class AtlMapT, class MapT >
+bool test_atl_map(AtlMapT& map, const MapT& sample)
+{
+    typedef typename boost::range_iterator<AtlMapT>::type iter_t;
+    typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+    bool result = true;
+
+    result = result && (boost::distance(map) == boost::distance(sample));
+    if (!result)
+        return false;
+
+    {
+        for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+            result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->m_key, it->m_value));
+        }
+    }
+
+    {
+        for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+            result = result && (test_atl_map_has)(map, it->first, it->second);
+        }
+    }
+
+    return result;
+}
+
+
+template< class MapT, class SampleMap >
+bool test_init_atl_multimap(MapT& map, const SampleMap& sample)
+{
+    typedef typename boost::range_const_iterator<SampleMap>::type iter_t;
+
+    for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+        map.Insert(it->first, it->second);
+    }
+
+    return boost::distance(map) == boost::distance(sample);
+}
+
+
+// arrays
+//
+
+template< class Range >
+void test_CAtlArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CAtlArray<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, val_t const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CAutoPtrArray(Range& sample)
+{
+    typedef ValT val_t;
+
+    typedef ATL::CAutoPtrArray<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> *> >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> const*> >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( ::test_init_auto_ptr_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class I, class Range >
+void test_CInterfaceArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CInterfaceArray<I> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ATL::CComQIPtr<I> * >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, ATL::CComQIPtr<I> const* >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// lists
+//
+
+template< class Range >
+void test_CAtlList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CAtlList<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       val_t> >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CAutoPtrList(Range& sample)
+{
+    typedef ValT val_t;
+
+    typedef ATL::CAutoPtrList<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t,       ATL::CAutoPtr<val_t> > > >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CAutoPtr<val_t> const> > >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CHeapPtrList(const Range& sample)
+{
+    typedef ValT val_t;
+
+    typedef ATL::CHeapPtrList<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t,       ATL::CHeapPtr<val_t> > > >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CHeapPtr<val_t> const> > >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class I, class Range >
+void test_CInterfaceList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CInterfaceList<I> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       ATL::CComQIPtr<I> > >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, ATL::CComQIPtr<I> const> >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// strings
+//
+
+template< class Range >
+void test_CSimpleStringT(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+        ATL::CAtlStringA,
+        ATL::CAtlStringW
+    >::type derived_t;
+
+    typedef ATL::CSimpleStringT<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, typename rng_t::PCXSTR>::value ));
+
+    derived_t drng;
+    rng_t& rng = drng;
+    BOOST_CHECK( brdm::test_init_string(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    // BOOST_CHECK( brdm::test_emptiness(rng) ); no default constructible
+}
+
+
+template< int n, class Range >
+void test_CFixedStringT(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+        ATL::CAtlStringA,
+        ATL::CAtlStringW
+    >::type base_t;
+
+    typedef ATL::CFixedStringT<base_t, n> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, typename rng_t::PCXSTR>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_string(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStringT(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+        ATL::CAtlStringA, // == CStringT<char, X>
+        ATL::CAtlStringW  // == CStringT<wchar_t, X>
+    >::type rng_t;
+
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, typename rng_t::PCXSTR>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_string(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStaticString(const Range& sample)
+{
+#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
+    {
+        typedef ATL::CStaticString<char, 20> rng_t;
+        BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, char const *>::value ));
+        BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, char const *>::value ));
+
+        rng_t rng("hello static string");
+        BOOST_CHECK( *(boost::begin(rng)+4) == 'o' );
+        BOOST_CHECK( *(boost::end(rng)-3) == 'i' );
+    }
+
+    {
+        typedef ATL::CStaticString<wchar_t, 40> rng_t;
+        BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, wchar_t const *>::value ));
+        BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, wchar_t const *>::value ));
+
+        rng_t rng(L"hello static string");
+        BOOST_CHECK( *(boost::begin(rng)+4) == L'o' );
+        BOOST_CHECK( *(boost::end(rng)-3) == L'i' );
+    }
+#endif
+
+    (void)sample; // unused
+}
+
+
+#endif // !(_ATL_VER < 0x0700) 
+
+
+template< class Range >
+void test_CComBSTR(const Range& sample)
+{
+    typedef ATL::CComBSTR rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, OLECHAR *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, OLECHAR const*>::value ));
+
+    rng_t rng(OLESTR("hello CComBSTR range!"));
+    BOOST_CHECK( brdm::test_equals(rng, std::string("hello CComBSTR range!")) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+
+    (void)sample; // unused
+}
+
+
+// simples
+//
+
+template< class Range >
+void test_CSimpleArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CSimpleArray<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, val_t const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CSimpleMap(const Range& sample)
+{
+#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
+
+    typedef ATL::CSimpleMap<int, double> rng_t;
+
+    rng_t rng;
+    rng.Add(3, 3.0);
+    rng.Add(4, 2.0);
+
+    BOOST_CHECK( boost::begin(rng)->get<0>() == 3.0 );
+    BOOST_CHECK( (boost::end(rng)-1)->get<1>() == 2.0 );
+
+#endif
+
+    (void)sample; // unused
+}
+
+
+template< class Range >
+void test_CSimpleValArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ATL::CSimpleArray<val_t> rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, val_t const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// maps
+//
+
+template< class MapT >
+void test_CAtlMap(const MapT& sample)
+{
+    typedef typename MapT::key_type k_t;
+    typedef typename MapT::mapped_type m_t;
+
+    typedef ATL::CAtlMap<k_t, m_t> rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBTree(const MapT& sample)
+{
+    typedef typename MapT::key_type k_t;
+    typedef typename MapT::mapped_type m_t;
+
+    typedef ATL::CRBMap<k_t, m_t> derived_t;
+    typedef ATL::CRBTree<k_t, m_t> rng_t;
+
+    derived_t drng;
+    rng_t& rng = drng;
+
+    boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(drng, sample) );
+    BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBMap(const MapT& sample)
+{
+    typedef typename MapT::key_type k_t;
+    typedef typename MapT::mapped_type m_t;
+
+    typedef ATL::CRBMap<k_t, m_t> rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBMultiMap(const MapT& sample)
+{
+    typedef typename MapT::key_type k_t;
+    typedef typename MapT::mapped_type m_t;
+
+    typedef ATL::CRBMultiMap<k_t, m_t> rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+    BOOST_CHECK( ::test_init_atl_multimap(rng, sample) );
+    BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+// main test
+//
+
+void test_atl()
+{
+
+    // ordinary ranges
+    //
+    {
+        std::string sample("rebecca judy and mary whiteberry chat monchy");
+#if !(_ATL_VER < 0x0700)
+        ::test_CAtlArray(sample);
+        ::test_CAtlList(sample);
+        ::test_CSimpleStringT(sample);
+        ::test_CFixedStringT<44>(sample);
+        ::test_CStringT(sample);
+        ::test_CStaticString(sample);
+#endif
+        ::test_CComBSTR(sample);
+        ::test_CSimpleArray(sample);
+        ::test_CSimpleMap(sample);
+        ::test_CSimpleValArray(sample);
+    }
+
+
+    {
+        std::wstring sample(L"rebecca judy and mary whiteberry chat monchy");
+#if !(_ATL_VER < 0x0700)
+        ::test_CAtlArray(sample);
+        ::test_CAtlList(sample);
+        ::test_CSimpleStringT(sample);
+        ::test_CFixedStringT<44>(sample);
+        ::test_CStringT(sample);
+        ::test_CStaticString(sample);
+#endif
+        ::test_CComBSTR(sample);
+        ::test_CSimpleArray(sample);
+        ::test_CSimpleMap(sample);
+        ::test_CSimpleValArray(sample);
+    }
+
+    // pointer ranges
+    //
+#if !(_ATL_VER < 0x0700)
+    {
+        typedef ATL::CAutoPtr<int> ptr_t;
+        ptr_t
+            ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
+            ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
+
+        ptr_t ptrs[8] = {
+            ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
+        };
+
+        boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+        ::test_CAutoPtrArray<int>(workaround);
+    }
+
+    {
+        typedef ATL::CAutoPtr<int> ptr_t;
+        ptr_t
+            ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
+            ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
+
+        ptr_t ptrs[8] = {
+            ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
+        };
+
+        boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+        ::test_CAutoPtrList<int>(workaround);
+    }
+
+    {
+        typedef ATL::CHeapPtr<int> ptr_t;
+        ptr_t ptrs[5]; {
+            ptrs[0].AllocateBytes(sizeof(int));
+            ptrs[1].AllocateBytes(sizeof(int));
+            ptrs[2].AllocateBytes(sizeof(int));
+            ptrs[3].AllocateBytes(sizeof(int));
+            ptrs[4].AllocateBytes(sizeof(int));
+        }
+
+        boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+5);
+        ::test_CHeapPtrList<int>(workaround);
+    }
+
+
+    {
+        typedef ATL::CComQIPtr<IDispatch> ptr_t;
+        ptr_t ptrs[8];
+
+        boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+        ::test_CInterfaceArray<IDispatch>(workaround);
+        ::test_CInterfaceList<IDispatch>(workaround);
+    }
+#endif
+
+    // maps
+    //
+    {
+#if !(_ATL_VER < 0x0700)
+        std::map<int, std::string> sample; {
+            sample[0] = "hello";
+            sample[1] = "range";
+            sample[2] = "atl";
+            sample[3] = "mfc";
+            sample[4] = "collections";
+        }
+
+        ::test_CAtlMap(sample);
+        ::test_CRBTree(sample);
+        ::test_CRBMap(sample);
+        ::test_CRBMultiMap(sample);
+#endif
+    }
+
+
+} // test_atl
+
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+
+test_suite *
+init_unit_test_suite(int argc, char* argv[])
+{
+    test_suite *test = BOOST_TEST_SUITE("ATL Range Test Suite");
+    test->add(BOOST_TEST_CASE(&test_atl));
+
+    (void)argc, (void)argv; // unused
+    return test;
+}
diff --git a/test/begin.cpp b/test/begin.cpp
new file mode 100644
index 0000000..f014535
--- /dev/null
+++ b/test/begin.cpp
@@ -0,0 +1,119 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/included/unit_test.hpp>
+
+namespace mock_std
+{
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME boost::range_iterator<SinglePassRange>::type
+    begin(SinglePassRange& rng)
+    {
+        return rng.begin();
+    }
+
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const SinglePassRange>::type
+    begin(const SinglePassRange& rng)
+    {
+        return rng.begin();
+    }
+
+    template<class SinglePassRange>
+    void mock_algorithm_using_begin(const SinglePassRange& rng)
+    {
+        BOOST_CHECK( begin(rng) == rng.begin() );
+    }
+
+    template<class SinglePassRange>
+    void mock_algorithm_using_begin(SinglePassRange& rng)
+    {
+        BOOST_CHECK( begin(rng) == rng.begin() );
+    }
+}
+
+namespace boost
+{
+#ifdef BOOST_RANGE_SIMULATE_BEGIN_WITHOUT_ADL_NAMESPACE_BARRIER
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+    begin(SinglePassRange& rng)
+    {
+        return rng.begin();
+    }
+
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+    begin(const SinglePassRange& rng)
+    {
+        return rng.begin();
+    }
+#endif
+
+    class MockTestBeginCollection
+    {
+    public:
+        typedef char value_type;
+        typedef const char* const_pointer;
+        typedef char* pointer;
+        typedef const_pointer const_iterator;
+        typedef pointer iterator;
+
+        MockTestBeginCollection()
+            : m_first()
+            , m_last()
+        {
+        }
+
+        const_iterator begin() const { return m_first; }
+        iterator begin() { return m_first; }
+        const_iterator end() const { return m_last; }
+        iterator end() { return m_last; }
+
+    private:
+        iterator m_first;
+        iterator m_last;
+    };
+}
+
+namespace
+{
+    void test_range_begin()
+    {
+        boost::MockTestBeginCollection c;
+        const boost::MockTestBeginCollection& const_c = c;
+        mock_std::mock_algorithm_using_begin(const_c);
+        mock_std::mock_algorithm_using_begin(c);
+    }
+}
+
+using boost::unit_test::test_suite;
+
+boost::unit_test::test_suite*
+init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - begin() ADL namespace barrier" );
+
+    test->add( BOOST_TEST_CASE( &test_range_begin ) );
+
+    return test;
+}
+
+
diff --git a/test/category.cpp b/test/category.cpp
new file mode 100644
index 0000000..154c411
--- /dev/null
+++ b/test/category.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/category.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_category()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::iterator_category<cont::const_iterator>::type,
+            boost::range_category<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::iterator_category<cont::const_iterator>::type,
+            boost::range_category<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::iterator_category<cont::const_iterator>::type,
+            boost::range_category<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_category meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_category));
+
+    return test;
+}
diff --git a/test/combine.cpp b/test/combine.cpp
new file mode 100644
index 0000000..11f674b
--- /dev/null
+++ b/test/combine.cpp
@@ -0,0 +1,160 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014
+//
+//  Copyright Thorsten Ottosen 2006. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/combine.hpp>
+
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+template<typename ContRef1, typename ContRef2>
+void test_combine2()
+{
+    std::vector<int> v;
+    std::list<int> l;
+
+    for (int i = 0; i < 10; ++i)
+    {
+        v.push_back(i);
+        l.push_back(i * 2);
+    }
+
+    ContRef1& in1 = v;
+    ContRef2& in2 = l;
+
+    std::vector<boost::tuple<int,int> > output;
+    boost::push_back(output, boost::combine(in1, in2));
+
+    int index = 0;
+    int i1, i2;
+    BOOST_FOREACH(boost::tie(i1,i2), output)
+    {
+        BOOST_CHECK_EQUAL(i1, index);
+        BOOST_CHECK_EQUAL(i2, index * 2);
+        ++index;
+    }
+}
+
+template<typename ContRef1, typename ContRef2, typename ContRef3>
+void test_combine3()
+{
+    std::vector<int> v1;
+    std::vector<int> v2;
+    std::vector<int> v3;
+
+    for (int i = 0; i < 10; ++i)
+    {
+        v1.push_back(i);
+        v2.push_back(i * 2);
+        v3.push_back(i * 3);
+    }
+
+    ContRef1& in1 = v1;
+    ContRef2& in2 = v2;
+    ContRef3& in3 = v3;
+
+    std::vector<boost::tuple<int,int,int> > output;
+    boost::push_back(output, boost::combine(in1, in2, in3));
+
+    int index = 0;
+    int i1, i2, i3;
+
+    BOOST_FOREACH(boost::tie(i1,i2,i3), output)
+    {
+        BOOST_CHECK_EQUAL(i1, index);
+        BOOST_CHECK_EQUAL(i2, index * 2);
+        BOOST_CHECK_EQUAL(i3, index * 3);
+        ++index;
+    }
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char*[] )
+{
+    boost::unit_test::test_suite* test =
+            BOOST_TEST_SUITE( "Boost.Range combine() test suite" );
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine2<
+                        const std::vector<int>, const std::list<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine2<
+                        const std::vector<int>, std::list<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine2<
+                        std::vector<int>, const std::list<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine2<
+                        std::vector<int>, std::list<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        std::vector<int>,
+                        std::vector<int>,
+                        std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        std::vector<int>,
+                        std::vector<int>,
+                        const std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        std::vector<int>,
+                        const std::vector<int>,
+                        std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        std::vector<int>,
+                        const std::vector<int>,
+                        const std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        const std::vector<int>,
+                        std::vector<int>,
+                        std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        const std::vector<int>,
+                        std::vector<int>,
+                        const std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        const std::vector<int>,
+                        const std::vector<int>,
+                        std::vector<int> >)));
+
+    test->add(BOOST_TEST_CASE((
+            &boost_range_test::test_combine3<
+                        const std::vector<int>,
+                        const std::vector<int>,
+                        const std::vector<int> >)));
+
+    return test;
+}
diff --git a/test/compat2.cpp b/test/compat2.cpp
new file mode 100644
index 0000000..feaa047
--- /dev/null
+++ b/test/compat2.cpp
@@ -0,0 +1,75 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/config.hpp>
+
+enum Container {};
+enum String {};
+
+template< typename T >
+struct range_iterator;
+
+template<>
+struct range_iterator<Container>
+{
+    template< typename C >
+    struct pts
+    {
+        typedef BOOST_DEDUCED_TYPENAME C::iterator type;
+    };
+};
+
+template<>
+struct range_iterator<String>
+{
+    template< typename C >
+    struct pts
+    {
+        typedef C type;
+    };
+};
+
+template< typename C >
+class iterator_of
+{
+public:
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
+};
+
+#include <vector>
+
+void compat1()
+{
+    std::vector<int> v;
+    iterator_of< std::vector<int> >::type i = v.begin();
+    boost::ignore_unused_variable_warning(i);
+}
+
+#include <boost/test/included/unit_test.hpp> 
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &compat1 ) );
+
+    return test;
+}
+
+
+
+
+
+
diff --git a/test/compat3.cpp b/test/compat3.cpp
new file mode 100644
index 0000000..e4e4c83
--- /dev/null
+++ b/test/compat3.cpp
@@ -0,0 +1,75 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/config.hpp>
+
+enum Container {};
+enum String {};
+
+template< typename T >
+struct range_iterator;
+
+template<>
+struct range_iterator<Container>
+{
+    template< typename C >
+    struct pts
+    {
+        typedef BOOST_DEDUCED_TYPENAME C::iterator type;
+    };
+};
+
+template<>
+struct range_iterator<String>
+{
+    template< typename C >
+    struct pts
+    {
+        typedef C type;
+    };
+};
+
+template< typename C >
+class iterator_of
+{
+public:
+    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>:: template pts<C>::type type; 
+};
+
+#include <vector>
+
+void compat1()
+{
+    std::vector<int> v;
+    iterator_of< std::vector<int> >::type i = v.begin();
+    boost::ignore_unused_variable_warning(i);
+}
+
+#include <boost/test/included/unit_test.hpp> 
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &compat1 ) );
+
+    return test;
+}
+
+
+
+
+
+
diff --git a/test/compile_fail/adaptor/adjacent_filtered_concept.cpp b/test/compile_fail/adaptor/adjacent_filtered_concept.cpp
new file mode 100644
index 0000000..e67215d
--- /dev/null
+++ b/test/compile_fail/adaptor/adjacent_filtered_concept.cpp
@@ -0,0 +1,39 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+namespace
+{
+
+struct always_true
+{
+    typedef bool result_type;
+
+    bool operator()(int, int) const
+    {
+        return true;
+    }
+};
+
+} // anonymous namespace
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::adjacent_filtered;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adjacent_filtered adaptor takes at least a
+    // ForwardRange.
+    return (mock_range<boost::single_pass_traversal_tag>() |
+                adjacent_filtered(always_true())).front();
+}
diff --git a/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp b/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp
new file mode 100644
index 0000000..160f7c9
--- /dev/null
+++ b/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp
@@ -0,0 +1,39 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+namespace
+{
+
+struct always_true
+{
+    typedef bool result_type;
+
+    bool operator()(int, int) const
+    {
+        return true;
+    }
+};
+
+} // anonymous namespace
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::adjacent_filtered;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adjacent_filtered adaptor takes at least a
+    // ForwardRange.
+    return (mock_const_range<boost::single_pass_traversal_tag>() |
+                adjacent_filtered(always_true())).front();
+}
diff --git a/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp b/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp
new file mode 100644
index 0000000..310ac21
--- /dev/null
+++ b/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+namespace
+{
+
+struct always_true
+{
+    typedef bool result_type;
+
+    bool operator()(int, int) const
+    {
+        return true;
+    }
+};
+
+} // anonymous namespace
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::adjacent_filter;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adjacent_filtered adaptor takes at least a
+    // ForwardRange.
+    return adjacent_filter(
+            mock_range<boost::single_pass_traversal_tag>(),
+            always_true()).front();
+}
diff --git a/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp b/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp
new file mode 100644
index 0000000..f84b31e
--- /dev/null
+++ b/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+namespace
+{
+
+struct always_true
+{
+    typedef bool result_type;
+
+    bool operator()(int, int) const
+    {
+        return true;
+    }
+};
+
+} // anonymous namespace
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::adjacent_filter;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adjacent_filtered adaptor takes at least a
+    // ForwardRange.
+    return adjacent_filter(
+            mock_const_range<boost::single_pass_traversal_tag>(),
+            always_true()).front();
+}
diff --git a/test/compile_fail/adaptor/copied_concept.cpp b/test/compile_fail/adaptor/copied_concept.cpp
new file mode 100644
index 0000000..27e7f72
--- /dev/null
+++ b/test/compile_fail/adaptor/copied_concept.cpp
@@ -0,0 +1,24 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/adaptor/copied.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::copied;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return (mock_range<boost::bidirectional_traversal_tag>() |
+                copied(0,1)).front();
+}
diff --git a/test/compile_fail/adaptor/copied_concept2.cpp b/test/compile_fail/adaptor/copied_concept2.cpp
new file mode 100644
index 0000000..5df8ab6
--- /dev/null
+++ b/test/compile_fail/adaptor/copied_concept2.cpp
@@ -0,0 +1,24 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/adaptor/copied.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::copied;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return (mock_const_range<boost::bidirectional_traversal_tag>() |
+                copied(0,1)).front();
+}
diff --git a/test/compile_fail/adaptor/copied_concept3.cpp b/test/compile_fail/adaptor/copied_concept3.cpp
new file mode 100644
index 0000000..da1659f
--- /dev/null
+++ b/test/compile_fail/adaptor/copied_concept3.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/adaptor/copied.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return boost::adaptors::copy(
+        mock_range<boost::bidirectional_traversal_tag>(), 0, 1).front();
+}
diff --git a/test/compile_fail/adaptor/copied_concept4.cpp b/test/compile_fail/adaptor/copied_concept4.cpp
new file mode 100644
index 0000000..3df0a6c
--- /dev/null
+++ b/test/compile_fail/adaptor/copied_concept4.cpp
@@ -0,0 +1,24 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/adaptor/copied.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return boost::adaptors::copy(
+        mock_const_range<boost::bidirectional_traversal_tag>(),
+                                 0, 1).front();
+}
diff --git a/test/compile_fail/adaptor/mock_iterator.hpp b/test/compile_fail/adaptor/mock_iterator.hpp
new file mode 100644
index 0000000..97f67a9
--- /dev/null
+++ b/test/compile_fail/adaptor/mock_iterator.hpp
@@ -0,0 +1,82 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+#ifndef BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_ITERATOR_HPP_INCLUDED
+
+#include <boost/iterator/iterator_facade.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+        namespace unit_test
+        {
+
+template<typename TraversalTag>
+class mock_iterator
+        : public boost::iterator_facade<
+                    mock_iterator<TraversalTag>,
+                    int,
+                    TraversalTag,
+                    const int&
+        >
+{
+public:
+    mock_iterator()
+        : m_value(0)
+    {
+    }
+
+    explicit mock_iterator(int value)
+        : m_value(value)
+    {
+    }
+
+private:
+
+    void increment()
+    {
+        ++m_value;
+    }
+
+    void decrement()
+    {
+        --m_value;
+    }
+
+    bool equal(const mock_iterator& other) const
+    {
+        return m_value == other.m_value;
+    }
+
+    void advance(std::ptrdiff_t offset)
+    {
+        m_value += offset;
+    }
+
+    std::ptrdiff_t distance_to(const mock_iterator& other) const
+    {
+        return other.m_value - m_value;
+    }
+
+    const int& dereference() const
+    {
+        return m_value;
+    }
+
+    int m_value;
+    friend class boost::iterator_core_access;
+};
+
+        } // namespace unit_test
+    } // namespace range
+} // namespace boost
+
+#endif // include guard
diff --git a/test/compile_fail/adaptor/mock_range.hpp b/test/compile_fail/adaptor/mock_range.hpp
new file mode 100644
index 0000000..18fe2fa
--- /dev/null
+++ b/test/compile_fail/adaptor/mock_range.hpp
@@ -0,0 +1,50 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+#ifndef BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_RANGE_HPP_INCLUDED
+
+#include "mock_iterator.hpp"
+#include <boost/range/iterator_range_core.hpp>
+
+namespace boost
+{
+    namespace range
+    {
+        namespace unit_test
+        {
+
+// Make a non-empty range that models the corresponding range concept.
+// This is only useful in unit tests. It is main use is to help test concepts
+// assertions are present.
+template<typename TraversalTag>
+iterator_range<mock_iterator<TraversalTag> >&
+    mock_range()
+{
+    static iterator_range<mock_iterator<TraversalTag> > instance(
+                mock_iterator<TraversalTag>(0),
+                mock_iterator<TraversalTag>(1));
+    return instance;
+}
+
+template<typename TraversalTag>
+const iterator_range<mock_iterator<TraversalTag> >&
+    mock_const_range()
+{
+    static iterator_range<mock_iterator<TraversalTag> > instance(
+                mock_iterator<TraversalTag>(0),
+                mock_iterator<TraversalTag>(1));
+    return instance;
+}
+
+        } // namespace unit_test
+    } // namespace range
+} // namespace boost
+
+#endif // include guard
diff --git a/test/compile_fail/adaptor/reversed_concept.cpp b/test/compile_fail/adaptor/reversed_concept.cpp
new file mode 100644
index 0000000..5ad0041
--- /dev/null
+++ b/test/compile_fail/adaptor/reversed_concept.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/reversed.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::reversed;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a BidirectionalRange.
+    return (mock_range<boost::forward_traversal_tag>() | reversed).front();
+}
+ 
diff --git a/test/compile_fail/adaptor/reversed_concept2.cpp b/test/compile_fail/adaptor/reversed_concept2.cpp
new file mode 100644
index 0000000..e2b8cb6
--- /dev/null
+++ b/test/compile_fail/adaptor/reversed_concept2.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/reversed.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::reversed;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a BidirectionalRange.
+    return (mock_const_range<boost::forward_traversal_tag>() | reversed).front();
+}
+ 
diff --git a/test/compile_fail/adaptor/reversed_concept3.cpp b/test/compile_fail/adaptor/reversed_concept3.cpp
new file mode 100644
index 0000000..619dfa8
--- /dev/null
+++ b/test/compile_fail/adaptor/reversed_concept3.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/reversed.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a BidirectionalRange.
+    return boost::adaptors::reverse(
+        mock_range<boost::forward_traversal_tag>()).front();
+}
+ 
diff --git a/test/compile_fail/adaptor/reversed_concept4.cpp b/test/compile_fail/adaptor/reversed_concept4.cpp
new file mode 100644
index 0000000..0e183ee
--- /dev/null
+++ b/test/compile_fail/adaptor/reversed_concept4.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/reversed.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a BidirectionalRange.
+    return boost::adaptors::reverse(
+        mock_const_range<boost::forward_traversal_tag>()).front();
+}
+ 
diff --git a/test/compile_fail/adaptor/sliced_concept.cpp b/test/compile_fail/adaptor/sliced_concept.cpp
new file mode 100644
index 0000000..08a653f
--- /dev/null
+++ b/test/compile_fail/adaptor/sliced_concept.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/sliced.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::sliced;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return (mock_range<boost::bidirectional_traversal_tag>() |
+                sliced(0,1)).front();
+}
diff --git a/test/compile_fail/adaptor/sliced_concept2.cpp b/test/compile_fail/adaptor/sliced_concept2.cpp
new file mode 100644
index 0000000..9965020
--- /dev/null
+++ b/test/compile_fail/adaptor/sliced_concept2.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/sliced.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::sliced;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return (mock_const_range<boost::bidirectional_traversal_tag>() |
+                sliced(0,1)).front();
+}
diff --git a/test/compile_fail/adaptor/sliced_concept3.cpp b/test/compile_fail/adaptor/sliced_concept3.cpp
new file mode 100644
index 0000000..1274911
--- /dev/null
+++ b/test/compile_fail/adaptor/sliced_concept3.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/sliced.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return boost::adaptors::slice(
+        mock_range<boost::bidirectional_traversal_tag>(), 0, 1).front();
+}
diff --git a/test/compile_fail/adaptor/sliced_concept4.cpp b/test/compile_fail/adaptor/sliced_concept4.cpp
new file mode 100644
index 0000000..c7f8206
--- /dev/null
+++ b/test/compile_fail/adaptor/sliced_concept4.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/sliced.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a RandomAccessRange.
+    return boost::adaptors::slice(
+        mock_const_range<boost::bidirectional_traversal_tag>(), 0, 1).front();
+}
diff --git a/test/compile_fail/adaptor/uniqued_concept.cpp b/test/compile_fail/adaptor/uniqued_concept.cpp
new file mode 100644
index 0000000..bbaaf11
--- /dev/null
+++ b/test/compile_fail/adaptor/uniqued_concept.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/uniqued.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+    using boost::adaptors::uniqued;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a ForwardRange.
+    return (mock_range<boost::single_pass_traversal_tag>() | uniqued).front();
+}
diff --git a/test/compile_fail/adaptor/uniqued_concept2.cpp b/test/compile_fail/adaptor/uniqued_concept2.cpp
new file mode 100644
index 0000000..a390d13
--- /dev/null
+++ b/test/compile_fail/adaptor/uniqued_concept2.cpp
@@ -0,0 +1,23 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/uniqued.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+    using boost::adaptors::uniqued;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a ForwardRange.
+    return (mock_const_range<boost::single_pass_traversal_tag>() |
+                uniqued).front();
+}
diff --git a/test/compile_fail/adaptor/uniqued_concept3.cpp b/test/compile_fail/adaptor/uniqued_concept3.cpp
new file mode 100644
index 0000000..fea058c
--- /dev/null
+++ b/test/compile_fail/adaptor/uniqued_concept3.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/uniqued.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a ForwardRange.
+    return boost::adaptors::unique(
+        mock_range<boost::single_pass_traversal_tag>()).front();
+}
diff --git a/test/compile_fail/adaptor/uniqued_concept4.cpp b/test/compile_fail/adaptor/uniqued_concept4.cpp
new file mode 100644
index 0000000..1e02390
--- /dev/null
+++ b/test/compile_fail/adaptor/uniqued_concept4.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2014. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include "mock_range.hpp"
+#include <boost/range/adaptor/uniqued.hpp>
+
+int main(int, const char**)
+{
+    using boost::range::unit_test::mock_const_range;
+
+    // This next line should fail when Boost.Range concept checking is
+    // enabled since the adaptor takes at least a ForwardRange.
+    return boost::adaptors::unique(
+        mock_const_range<boost::single_pass_traversal_tag>()).front();
+}
diff --git a/test/compile_fail/iterator_range1.cpp b/test/compile_fail/iterator_range1.cpp
new file mode 100644
index 0000000..2e5eec3
--- /dev/null
+++ b/test/compile_fail/iterator_range1.cpp
@@ -0,0 +1,22 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2011. Use, modification and distribution is subject
+// to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range
+//
+
+#include <boost/range/iterator_range_core.hpp>
+
+namespace iterator_range_test_detail
+{
+    void check_iterator_range_doesnt_convert_pointers()
+    {
+        double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };        
+        boost::iterator_range<float*> rng = boost::make_iterator_range(source);
+        boost::ignore_unused_variable_warning(rng);
+    }
+}
+
diff --git a/test/const_iterator.cpp b/test/const_iterator.cpp
new file mode 100644
index 0000000..63238c8
--- /dev/null
+++ b/test/const_iterator.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/const_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_const_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_iterator,
+            boost::range_const_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_iterator,
+            boost::range_const_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_iterator,
+            boost::range_const_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_const_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_const_iterator));
+
+    return test;
+}
diff --git a/test/const_ranges.cpp b/test/const_ranges.cpp
new file mode 100644
index 0000000..22bf83c
--- /dev/null
+++ b/test/const_ranges.cpp
@@ -0,0 +1,59 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <string>
+
+template< class T >
+const T& as_const( const T& r )
+{
+    return r;
+}
+
+void check_const_ranges()
+{
+    std::string       foo( "foo" );
+    const std::string bar( "bar" );
+
+    BOOST_CHECK( boost::const_begin( foo )  == boost::begin( as_const( foo ) ) );
+    BOOST_CHECK( boost::const_end( foo )    == boost::end( as_const( foo ) ) );
+    BOOST_CHECK( boost::const_rbegin( foo ) == boost::rbegin( as_const( foo ) ) );
+    BOOST_CHECK( boost::const_rend( foo )   == boost::rend( as_const( foo ) ) );
+
+    BOOST_CHECK( boost::const_begin( bar )  == boost::begin( as_const( bar ) ) );
+    BOOST_CHECK( boost::const_end( bar )    == boost::end( as_const( bar ) ) );
+    BOOST_CHECK( boost::const_rbegin( bar ) == boost::rbegin( as_const( bar ) ) );
+    BOOST_CHECK( boost::const_rend( bar )   == boost::rend( as_const( bar ) ) );
+
+}
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_const_ranges ) );
+
+    return test;
+}
+
+
+
+
+
diff --git a/test/const_reverse_iterator.cpp b/test/const_reverse_iterator.cpp
new file mode 100644
index 0000000..44726fd
--- /dev/null
+++ b/test/const_reverse_iterator.cpp
@@ -0,0 +1,62 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/const_reverse_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_const_reverse_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::const_iterator>,
+            boost::range_const_reverse_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::const_iterator>,
+            boost::range_const_reverse_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::const_iterator>,
+            boost::range_const_reverse_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE(
+                "Boost.Range range_const_reverse_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_const_reverse_iterator));
+
+    return test;
+}
diff --git a/test/counting_range.cpp b/test/counting_range.cpp
new file mode 100644
index 0000000..d1f1d3f
--- /dev/null
+++ b/test/counting_range.cpp
@@ -0,0 +1,90 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Disable a warning from <xutility> since this noise might
+// stop us detecting a problem in our code.
+#include <boost/range/counting_range.hpp>
+#include <boost/range/adaptor/indirected.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+
+#include <algorithm>
+#include <deque>
+#include <string>
+#include <vector>
+#include <boost/range/algorithm_ext.hpp>
+namespace boost
+{
+    namespace
+    {
+        template<class Container>
+        void counting_range_test_impl(int first, int last)
+        {
+            Container reference;
+            for (int i = first; i < last; ++i)
+                reference.push_back(i);
+
+            Container test;
+            push_back( test, counting_range(first, last) );
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(
+                reference.begin(), reference.end(),
+                test.begin(), test.end());
+        }
+
+        template<class Container>
+        void counting_range_test_impl()
+        {
+            counting_range_test_impl<Container>(0, 0);
+            counting_range_test_impl<Container>(-1, -1);
+            counting_range_test_impl<Container>(-1, 0);
+            counting_range_test_impl<Container>(0, 1);
+            counting_range_test_impl<Container>(-100, 100);
+            counting_range_test_impl<Container>(50, 55);
+        }
+
+        void counting_range_test_range()
+        {
+            std::vector<int> v;
+            for (int i = 0; i < 10; ++i)
+                v.push_back(i);
+
+            std::vector<std::vector<int>::iterator> x;
+            push_back(x, counting_range(v));
+
+            std::vector<int> t;
+            push_back(t, x | boost::adaptors::indirected);
+
+            BOOST_CHECK_EQUAL_COLLECTIONS(t.begin(), t.end(),
+                                          v.begin(), v.end());
+        }
+    }
+
+    void counting_range_test()
+    {
+        counting_range_test_impl<std::vector<int> >();
+        counting_range_test_impl<std::list<int> >();
+        counting_range_test_impl<std::deque<int> >();
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.counting_range" );
+
+    test->add( BOOST_TEST_CASE( &boost::counting_range_test ) );
+
+    return test;
+}
diff --git a/test/difference_type.cpp b/test/difference_type.cpp
new file mode 100644
index 0000000..556250a
--- /dev/null
+++ b/test/difference_type.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/difference_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_difference()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::difference_type,
+            boost::range_difference<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::difference_type,
+            boost::range_difference<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::difference_type,
+            boost::range_difference<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_difference meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_difference));
+
+    return test;
+}
diff --git a/test/end.cpp b/test/end.cpp
new file mode 100644
index 0000000..c885555
--- /dev/null
+++ b/test/end.cpp
@@ -0,0 +1,119 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/end.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/included/unit_test.hpp>
+
+namespace mock_std
+{
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME boost::range_iterator<SinglePassRange>::type
+    end(SinglePassRange& rng)
+    {
+        return rng.end();
+    }
+
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const SinglePassRange>::type
+    end(const SinglePassRange& rng)
+    {
+        return rng.end();
+    }
+
+    template<class SinglePassRange>
+    void mock_algorithm_using_end(const SinglePassRange& rng)
+    {
+        BOOST_CHECK( end(rng) == rng.end() );
+    }
+
+    template<class SinglePassRange>
+    void mock_algorithm_using_end(SinglePassRange& rng)
+    {
+        BOOST_CHECK( end(rng) == rng.end() );
+    }
+}
+
+namespace boost
+{
+#ifdef BOOST_RANGE_SIMULATE_END_WITHOUT_ADL_NAMESPACE_BARRIER
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+    end(SinglePassRange& rng)
+    {
+        return rng.end();
+    }
+
+    template<class SinglePassRange>
+    inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+    end(const SinglePassRange& rng)
+    {
+        return rng.end();
+    }
+#endif
+
+    class MockTestEndCollection
+    {
+    public:
+        typedef char value_type;
+        typedef const char* const_pointer;
+        typedef char* pointer;
+        typedef const_pointer const_iterator;
+        typedef pointer iterator;
+
+        MockTestEndCollection()
+            : m_first()
+            , m_last()
+        {
+        }
+
+        const_iterator begin() const { return m_first; }
+        iterator begin() { return m_first; }
+        const_iterator end() const { return m_last; }
+        iterator end() { return m_last; }
+
+    private:
+        iterator m_first;
+        iterator m_last;
+    };
+}
+
+namespace
+{
+    void test_range_end_adl_avoidance()
+    {
+        boost::MockTestEndCollection c;
+        const boost::MockTestEndCollection& const_c = c;
+        mock_std::mock_algorithm_using_end(const_c);
+        mock_std::mock_algorithm_using_end(c);
+    }
+}
+
+using boost::unit_test::test_suite;
+
+boost::unit_test::test_suite*
+init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - end() ADL namespace barrier" );
+
+    test->add( BOOST_TEST_CASE( &test_range_end_adl_avoidance ) );
+
+    return test;
+}
+
+
diff --git a/test/extension_mechanism.cpp b/test/extension_mechanism.cpp
new file mode 100644
index 0000000..b8b7112
--- /dev/null
+++ b/test/extension_mechanism.cpp
@@ -0,0 +1,109 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+//
+// Generic range algorithm
+//
+template< class Rng >
+typename boost::range_iterator<Rng>::type foo_algo( Rng& r )
+{
+        //
+        // This will only compile for Rng = UDT if the qualified calls
+        // find boost_range_XXX via ADL.
+        //
+        return boost::size(r) == 0u ? boost::begin(r) : boost::end(r);
+}
+
+namespace Foo
+{
+        //
+        // Our sample UDT
+        //
+        struct X
+        {
+          X() : vec() { }
+
+                typedef std::vector<int>       data_t;
+                typedef data_t::iterator       iterator;
+                typedef data_t::const_iterator const_iterator;
+
+                data_t vec;
+
+                void push_back( int i )
+                { vec.push_back(i); }
+        };
+
+        //
+        // The required functions. No type-traits need
+        // to be defined because X defines the proper set of
+        // nested types.
+        //
+        inline X::iterator range_begin( X& x )
+        {
+                return x.vec.begin();
+        }
+
+
+        inline X::const_iterator range_begin( const X& x )
+        {
+                return x.vec.begin();
+        }
+
+
+        inline X::iterator range_end( X& x )
+        {
+                return x.vec.end();
+        }
+
+        inline X::const_iterator range_end( const X& x )
+        {
+                return x.vec.end();
+        }
+
+}
+
+void check_extension()
+{
+        Foo::X x;
+        x.push_back(3);
+        const Foo::X x2;
+
+        foo_algo( x );
+        foo_algo( x2 );
+}
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_extension ) );
+
+    return test;
+}
+
+
+
+
+
diff --git a/test/extension_size.cpp b/test/extension_size.cpp
new file mode 100644
index 0000000..b9cc1b2
--- /dev/null
+++ b/test/extension_size.cpp
@@ -0,0 +1,224 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/cstdint.hpp>
+#include <list>
+#include <vector>
+
+namespace boost_range_extension_size_test
+{
+    class FooWithoutSize
+    {
+        typedef std::list<int> impl_t;
+        
+        BOOST_STATIC_ASSERT((
+            boost::is_same<
+                boost::range_size<std::list<int> >::type,
+                std::list<int>::size_type
+            >::value));
+        
+        typedef impl_t::const_iterator const_iterator;
+        typedef impl_t::iterator iterator;
+
+    public:
+        friend inline const_iterator range_begin(const FooWithoutSize& obj) { return obj.m_impl.begin(); }
+        friend inline iterator range_begin(FooWithoutSize& obj) { return obj.m_impl.begin(); }
+        friend inline const_iterator range_end(const FooWithoutSize& obj) { return obj.m_impl.end(); }
+        friend inline iterator range_end(FooWithoutSize& obj){ return obj.m_impl.end(); }
+
+    private:
+        impl_t m_impl;
+    };
+    
+    template<typename SizeType>
+    class FooWithSize
+    {
+    public:
+        typedef SizeType size_type;
+        typedef boost::uint8_t* iterator;
+        typedef const boost::uint8_t* const_iterator;
+        
+        const_iterator begin() const;
+        iterator begin();
+        const_iterator end() const;
+        iterator end();
+    };
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::uint8_t,
+            boost::range_size<FooWithSize<boost::uint8_t> >::type
+        >::value
+    ));
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::uint16_t,
+            boost::range_size<FooWithSize<boost::uint16_t> >::type
+        >::value
+    ));
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::uint32_t,
+            boost::range_size<FooWithSize<boost::uint32_t> >::type
+        >::value
+    ));
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::uint64_t,
+            boost::range_size<FooWithSize<boost::uint64_t> >::type
+        >::value
+    ));
+    
+    class UdtSizeType
+    {
+    public:
+        typedef boost::uint16_t value_type;
+        
+        UdtSizeType() : value_(0) { }
+        UdtSizeType(value_type value) : value_(value) { }
+        
+        operator value_type() const { return value_; }
+        
+    private:
+        value_type value_;
+    };
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            UdtSizeType,
+            boost::range_size<FooWithSize<UdtSizeType> >::type
+        >::value
+    ));
+    
+    class Foo2WithoutSize
+    {
+    public:
+        struct const_iterator
+        {
+            typedef std::forward_iterator_tag iterator_category;
+            typedef boost::int8_t difference_type;
+            typedef boost::int16_t value_type;
+            typedef value_type* pointer;
+            typedef value_type& reference;
+            
+            reference operator*() const;
+            pointer operator->() const;
+            const_iterator& operator++();
+            const_iterator operator++(int);
+            bool operator==(const const_iterator&) const;
+            bool operator!=(const const_iterator&) const;
+        };
+        
+        struct iterator : const_iterator
+        {
+            typedef const value_type* pointer;
+            typedef const value_type& reference;
+            
+            reference operator*() const;
+            pointer operator->() const;
+            
+            iterator& operator++();
+            iterator operator++(int);
+            
+            bool operator==(const iterator&) const;
+            bool operator!=(const iterator&) const;
+        };
+        
+        const_iterator begin() const;
+        iterator begin();
+        const_iterator end() const;
+        iterator end();
+    };
+    
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::uint8_t,
+            boost::range_size<
+                ::boost_range_extension_size_test::Foo2WithoutSize>::type
+        >::value
+    ));
+}
+
+namespace boost
+{
+    template<> struct range_iterator<const ::boost_range_extension_size_test::FooWithoutSize>
+    {
+        typedef std::list<int>::const_iterator type;
+    };
+
+    template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutSize>
+    {
+        typedef std::list<int>::iterator type;
+    };
+}
+
+namespace boost_range_extension_size_test
+{
+    inline boost::range_size<FooWithoutSize>::type
+    range_calculate_size(const FooWithoutSize& rng)
+    {
+        return 2u;
+    }
+}
+
+BOOST_STATIC_ASSERT((
+    boost::is_same<
+        boost::make_unsigned<std::ptrdiff_t>::type,
+        boost::range_size<
+                    boost_range_extension_size_test::FooWithoutSize>::type
+    >::value
+));
+
+typedef boost::make_unsigned<std::ptrdiff_t>::type t1;
+typedef boost::range_size<boost_range_extension_size_test::FooWithoutSize>::type t1;
+
+namespace
+{
+
+void check_size_works_with_random_access()
+{
+    std::vector<int> container;
+    container.push_back(1);
+    BOOST_CHECK_EQUAL( boost::size(container), 1u );
+}
+
+void check_extension_size()
+{
+    BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutSize()), 2u );
+}
+
+} // anonymous namespace
+
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_size_works_with_random_access ));
+    test->add( BOOST_TEST_CASE( &check_extension_size ) );
+
+    return test;
+}
diff --git a/test/has_range_iterator.cpp b/test/has_range_iterator.cpp
new file mode 100644
index 0000000..2efc88b
--- /dev/null
+++ b/test/has_range_iterator.cpp
@@ -0,0 +1,68 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/has_range_iterator.hpp>
+#include <boost/config.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace
+{
+    class MockClassWithoutIterators {};
+
+    template<typename Container>
+    void test_has_range_iterator_impl(const bool expected_value)
+    {
+        BOOST_CHECK_EQUAL( boost::has_range_iterator<Container>::value, expected_value );
+    }
+
+    template<typename Container>
+    void test_has_range_const_iterator_impl(const bool expected_value)
+    {
+        BOOST_CHECK_EQUAL( boost::has_range_const_iterator<Container>::value, expected_value );
+    }
+
+    void test_has_range_iterator()
+    {
+        test_has_range_iterator_impl< std::vector<int> >(true);
+        test_has_range_iterator_impl< MockClassWithoutIterators >(false);
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+        test_has_range_iterator_impl<std::vector<int>&&>(true);
+        test_has_range_iterator_impl<MockClassWithoutIterators&&>(false);
+#endif
+    }
+
+    void test_has_range_const_iterator()
+    {
+        test_has_range_const_iterator_impl< std::vector<int> >(true);
+        test_has_range_const_iterator_impl< MockClassWithoutIterators >(false);
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+        test_has_range_const_iterator_impl<std::vector<int>&&>(true);
+        test_has_range_const_iterator_impl<MockClassWithoutIterators&&>(false);
+#endif
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.has_range_iterator" );
+
+    test->add(BOOST_TEST_CASE(&test_has_range_iterator));
+    test->add(BOOST_TEST_CASE(&test_has_range_const_iterator));
+
+    return test;
+}
diff --git a/test/irange.cpp b/test/irange.cpp
new file mode 100644
index 0000000..7e1a564
--- /dev/null
+++ b/test/irange.cpp
@@ -0,0 +1,191 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/irange.hpp>
+#include <boost/range/algorithm_ext.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+namespace boost
+{
+    // Test an integer range with a step size of 1.
+    template<typename Integer>
+    void test_irange_impl(Integer last)
+    {
+        std::vector<Integer> reference;
+        for (Integer i = static_cast<Integer>(0); i < last; ++i)
+        {
+            reference.push_back(i);
+        }
+
+        std::vector<Integer> test;
+        boost::push_back(test, boost::irange(last));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
+                                       reference.begin(), reference.end() );
+    }
+
+    // Test an integer range with a step size of 1.
+    template<typename Integer>
+    void test_irange_impl(Integer first, Integer last)
+    {
+        std::vector<Integer> reference;
+        for (Integer i = first; i < last; ++i)
+        {
+            reference.push_back(i);
+        }
+
+        std::vector<Integer> test;
+        boost::push_back(test, boost::irange(first, last));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
+                                       reference.begin(), reference.end() );
+    }
+
+    // Test an integer range with a runtime specified step size.
+    template<typename Integer, typename IntegerInput>
+    void test_irange_impl(IntegerInput first, IntegerInput last, int step)
+    {
+        BOOST_ASSERT( step != 0 );
+
+        // Skip tests that have negative values if the type is
+        // unsigned
+        if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first)
+        ||  (static_cast<IntegerInput>(static_cast<Integer>(last)) != last))
+            return;
+
+        std::vector<Integer> reference;
+
+        const std::ptrdiff_t first_p = static_cast<std::ptrdiff_t>(first);
+        const std::ptrdiff_t last_p = static_cast<std::ptrdiff_t>(last);
+        const std::ptrdiff_t step_p = static_cast<std::ptrdiff_t>(step);
+        for (std::ptrdiff_t current_value = first_p;
+             step_p >= 0 ? current_value < last_p : current_value > last_p;
+             current_value += step_p)
+            reference.push_back(current_value);
+
+        std::vector<Integer> test;
+        boost::push_back(test, boost::irange(first, last, step));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
+                                       reference.begin(), reference.end() );
+    }
+
+    // Test driver function that for an integer range [first, last)
+    // drives the test implementation through various integer
+    // types.
+    void test_irange(int last)
+    {
+        test_irange_impl<signed char>(last);
+        test_irange_impl<unsigned char>(last);
+        test_irange_impl<signed short>(last);
+        test_irange_impl<unsigned short>(last);
+        test_irange_impl<signed int>(last);
+        test_irange_impl<unsigned int>(last);
+        test_irange_impl<signed long>(last);
+        test_irange_impl<unsigned long>(last);
+    }
+
+
+    // Test driver function that for an integer range [first, last)
+    // drives the test implementation through various integer
+    // types.
+    void test_irange(int first, int last)
+    {
+        test_irange_impl<signed char>(first,last);
+        test_irange_impl<unsigned char>(first, last);
+        test_irange_impl<signed short>(first, last);
+        test_irange_impl<unsigned short>(first, last);
+        test_irange_impl<signed int>(first, last);
+        test_irange_impl<unsigned int>(first, last);
+        test_irange_impl<signed long>(first, last);
+        test_irange_impl<unsigned long>(first, last);
+    }
+
+    // Test driver function that for an integer range [first, last)
+    // drives the test implementation through various integer
+    // types step_size items at a time.
+    void test_irange(int first, int last, int step_size)
+    {
+        BOOST_ASSERT( step_size != 0 );
+        test_irange_impl<signed char>(first, last, step_size);
+        test_irange_impl<unsigned char>(first, last, step_size);
+        test_irange_impl<signed short>(first, last, step_size);
+        test_irange_impl<unsigned short>(first, last, step_size);
+        test_irange_impl<signed int>(first, last, step_size);
+        test_irange_impl<unsigned int>(first, last, step_size);
+        test_irange_impl<signed long>(first, last, step_size);
+        test_irange_impl<unsigned long>(first, last, step_size);
+    }
+
+    // Implementation of the unit test for the integer range
+    // function.
+    // This starts the test drivers to drive a set of integer types
+    // for a combination of range values chosen to exercise a large
+    // number of implementation branches.
+    void irange_unit_test()
+    {
+        // Test the single-step version of irange(last)
+        test_irange(0);
+        test_irange(1);
+        test_irange(10);
+
+        // Test the single-step version of irange(first, last)
+        test_irange(0, 0);
+        test_irange(0, 1);
+        test_irange(0, 10);
+        test_irange(1, 1);
+        test_irange(1, 2);
+        test_irange(1, 11);
+
+        // Test the n-step version of irange(first, last, step-size)
+        test_irange(0, 0, 1);
+        test_irange(0, 0, -1);
+        test_irange(0, 10, 1);
+        test_irange(10, 0, -1);
+        test_irange(0, 2, 2);
+        test_irange(2, 0, -2);
+        test_irange(0, 9, 2);
+        test_irange(9, 0, -2);
+        test_irange(-9, 0, 2);
+        test_irange(-9, 9, 2);
+        test_irange(9, -9, -2);
+        test_irange(10, 20, 5);
+        test_irange(20, 10, -5);
+
+        test_irange(0, 0, 3);
+        test_irange(0, 1, 3);
+        test_irange(0, 2, 3);
+        test_irange(0, 3, 3);
+        test_irange(0, 4, 3);
+        test_irange(0, 10, 3);
+
+        test_irange(0, 0, -3);
+        test_irange(0, -1, -3);
+        test_irange(0, -2, -3);
+        test_irange(0, -3, -3);
+        test_irange(0, -4, -3);
+        test_irange(0, -10, -3);
+    }
+} // namespace boost
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.irange" );
+
+    test->add(BOOST_TEST_CASE( &boost::irange_unit_test ));
+
+    return test;
+}
diff --git a/test/istream_range.cpp b/test/istream_range.cpp
new file mode 100644
index 0000000..7d10313
--- /dev/null
+++ b/test/istream_range.cpp
@@ -0,0 +1,58 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/istream_range.hpp>
+#include <boost/range/algorithm_ext.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <sstream>
+#include <vector>
+
+namespace
+{
+    template <typename CharT>
+    void test_istream_range_impl()
+    {
+        std::basic_stringstream<CharT> s;
+        std::vector<int> reference;
+        for (int i = 0; i < 10; ++i)
+        {
+            reference.push_back(i);
+            s << i << CharT(' ');
+        }
+
+        std::vector<int> target;
+        boost::push_back(target, boost::range::istream_range<int>(s));
+
+        BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+            target.begin(), target.end() );
+    }
+    
+    // Test an istream range.
+    void test_istream_range()
+    {
+        test_istream_range_impl<char>();
+        test_istream_range_impl<wchar_t>();
+    }
+
+} // namespace anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.istream_range" );
+
+    test->add(BOOST_TEST_CASE( &test_istream_range ));
+
+    return test;
+}
diff --git a/test/iterator.cpp b/test/iterator.cpp
new file mode 100644
index 0000000..76c915a
--- /dev/null
+++ b/test/iterator.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_iterator,
+            boost::range_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator));
+
+    return test;
+}
diff --git a/test/iterator_ext.cpp b/test/iterator_ext.cpp
new file mode 100644
index 0000000..820bf2a
--- /dev/null
+++ b/test/iterator_ext.cpp
@@ -0,0 +1,153 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/decay.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+
+struct point
+{
+    int x;
+    int y;
+};
+
+class shape
+{
+public:
+    virtual ~shape()
+    {
+    }
+
+    const std::vector<point>& points() const
+    {
+        return m_points;
+    }
+
+private:
+    std::vector<point> m_points;
+};
+
+class rectangle : public shape
+{
+};
+
+class circle : public shape
+{
+};
+
+class container
+{
+    typedef std::vector<point> impl_t;
+};
+
+} // namespace boost_range_test
+
+namespace boost
+{
+    template<typename T>
+    struct range_mutable_iterator<
+            T,
+            typename boost::enable_if<
+                boost::is_base_of<
+                    boost_range_test::shape,
+                    typename boost::remove_reference<
+                        typename boost::remove_cv<T>::type
+                    >::type
+                >
+            >::type
+        >
+    {
+        typedef std::vector<boost_range_test::point>::iterator type;
+    };
+
+    template<typename T>
+    struct range_const_iterator<
+            T,
+            typename boost::enable_if<
+                boost::is_base_of<
+                    boost_range_test::shape,
+                    typename boost::remove_reference<
+                        typename boost::remove_cv<T>::type
+                    >::type
+                >
+            >::type
+        >
+    {
+        typedef std::vector<boost_range_test::point>::const_iterator type;
+    };
+
+    template<>
+    struct range_mutable_iterator<boost_range_test::container>
+    {
+        typedef std::vector<boost_range_test::point>::iterator type;
+    };
+
+    template<>
+    struct range_const_iterator<boost_range_test::container>
+    {
+        typedef std::vector<boost_range_test::point>::const_iterator type;
+    };
+}
+
+namespace boost_range_test
+{
+    template<typename Shape>
+    void test_iterator_impl()
+    {
+        BOOST_STATIC_ASSERT((
+            boost::is_same<
+                std::vector<point>::iterator,
+                typename boost::range_iterator<Shape>::type
+            >::value));
+
+        BOOST_STATIC_ASSERT((
+            boost::is_same<
+                std::vector<point>::const_iterator,
+                typename boost::range_iterator<const Shape>::type
+            >::value));
+
+    #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+        BOOST_STATIC_ASSERT((
+            boost::is_same<
+                std::vector<point>::iterator,
+                typename boost::range_iterator<Shape&&>::type
+            >::value));
+    #endif
+    }
+
+    void test_iterator()
+    {
+        test_iterator_impl<shape>();
+        test_iterator_impl<rectangle>();
+        test_iterator_impl<circle>();
+
+        test_iterator_impl<container>();
+    }
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator));
+
+    return test;
+}
diff --git a/test/iterator_pair.cpp b/test/iterator_pair.cpp
new file mode 100644
index 0000000..7b615a9
--- /dev/null
+++ b/test/iterator_pair.cpp
@@ -0,0 +1,104 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/concepts.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/test/test_tools.hpp>
+#include <vector>
+#include <iterator>
+#include <utility>
+
+void check_iterator_pair()
+{
+    typedef std::vector<int> vec_t;
+    vec_t                    vec;
+    vec.push_back( 4 );
+    typedef std::pair<vec_t::iterator,vec_t::iterator>
+                             pair_t;
+    typedef std::pair<vec_t::const_iterator,vec_t::const_iterator>
+                             const_pair_t;
+    typedef const pair_t     const_pair_tt;
+    pair_t                   pair       = std::make_pair( boost::begin( vec ), boost::end( vec ) );
+    const_pair_t             const_pair = std::make_pair( boost::begin( vec ), boost::end( vec ) );
+    const_pair_tt            constness_pair( pair );
+
+
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<pair_t>::type,
+                          std::iterator_traits<pair_t::first_type>::value_type>::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<pair_t>::type, pair_t::first_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_const_iterator<pair_t>::type, pair_t::first_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<pair_t>::type,
+                          std::iterator_traits<pair_t::first_type>::difference_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<pair_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<pair_t>::type, pair_t::first_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_t>::type, const_pair_t::first_type >::value ));
+
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<const_pair_tt>::type,
+                          std::iterator_traits<const_pair_t::first_type>::value_type>::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
+    //
+    // This behavior is not supported with v2.
+    //BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<const_pair_tt>::type,
+                          std::iterator_traits<const_pair_tt::first_type>::difference_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<const_pair_tt>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
+
+    BOOST_CHECK( boost::begin( pair ) == pair.first );
+    BOOST_CHECK( boost::end( pair )   == pair.second );
+    BOOST_CHECK( boost::empty( pair ) == (pair.first == pair.second) );
+    BOOST_CHECK( boost::size( pair )  ==
+                    static_cast<std::size_t>(
+                        std::distance(pair.first, pair.second)) );
+
+    BOOST_CHECK( boost::begin( const_pair ) == const_pair.first );
+    BOOST_CHECK( boost::end( const_pair )   == const_pair.second );
+    BOOST_CHECK( boost::empty( const_pair ) == (const_pair.first == const_pair.second) );
+    BOOST_CHECK( boost::size( const_pair )  ==
+                    static_cast<std::size_t>(
+                        std::distance(const_pair.first, const_pair.second)) );
+
+    BOOST_CHECK( boost::begin( constness_pair ) == constness_pair.first );
+    BOOST_CHECK( boost::end( constness_pair )   == constness_pair.second );
+    BOOST_CHECK( boost::empty( constness_pair ) == (constness_pair.first == const_pair.second) );
+    BOOST_CHECK( boost::size( constness_pair )  ==
+                    static_cast<std::size_t>(
+                        std::distance(constness_pair.first,
+                                      constness_pair.second)) );
+}
+
+
+#include <boost/test/unit_test.hpp>
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_iterator_pair ) );
+
+    return test;
+}
+
+
+
+
+
+
diff --git a/test/iterator_range.cpp b/test/iterator_range.cpp
new file mode 100644
index 0000000..9bbcff2
--- /dev/null
+++ b/test/iterator_range.cpp
@@ -0,0 +1,330 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen & Larry Evans 2003-2005. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+//#include <boost/range/as_array.hpp>
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+#include <string>
+#include <vector>
+
+void check_reference_type();
+
+void check_iterator_range()
+{
+
+    typedef std::string::iterator                 iterator;
+    typedef std::string::const_iterator           const_iterator;
+    typedef boost::iterator_range<iterator>       irange;
+    typedef boost::iterator_range<const_iterator> cirange;
+    std::string       str  = "hello world";
+    const std::string cstr = "const world";
+    irange r    = boost::make_iterator_range( str );
+    r           = boost::make_iterator_range( str.begin(), str.end() );
+    cirange r2  = boost::make_iterator_range( cstr );
+    r2          = boost::make_iterator_range( cstr.begin(), cstr.end() );
+    r2          = boost::make_iterator_range( str );
+
+    BOOST_CHECK( !r.empty() );
+    BOOST_CHECK( !r2.empty() );
+
+//#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+//    if( !(bool)r )
+//        BOOST_CHECK( false );
+//    if( !(bool)r2 )
+//        BOOST_CHECK( false );
+//#else
+    if( !r )
+        BOOST_CHECK( false );
+    if( !r2 )
+        BOOST_CHECK( false );
+//#endif
+
+    BOOST_CHECK_EQUAL( r.size(), boost::size( r ) );
+    BOOST_CHECK_EQUAL( r2.size(), boost::size( r2 ) );
+
+    BOOST_CHECK_EQUAL( std::distance( r.begin(), r.end() ),
+                       std::distance( boost::begin( r2 ), boost::end( r2 ) ) );
+    std::cout << r << r2;
+
+
+#ifndef BOOST_NO_STD_WSTRING
+    std::wcout << boost::make_iterator_range( std::wstring( L"a wide string" ) )
+               << boost::make_iterator_range( L"another wide string" );
+#endif
+
+    std::string res  = boost::copy_range<std::string>( r );
+    BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() );
+
+    irange rr = boost::make_iterator_range( str );
+    BOOST_CHECK( rr.equal( r ) );
+
+    rr  = boost::make_iterator_range( str.begin(), str.begin() + 5 );
+    BOOST_CHECK( rr == boost::as_literal("hello") );
+    BOOST_CHECK( rr != boost::as_literal("hell") );
+    BOOST_CHECK( rr < boost::as_literal("hello dude") );
+    BOOST_CHECK( boost::as_literal("hello") == rr );
+    BOOST_CHECK( boost::as_literal("hell")  != rr );
+    BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) );
+    irange rrr = rr;
+    BOOST_CHECK( rrr == rr );
+    BOOST_CHECK( !( rrr != rr ) );
+    BOOST_CHECK( !( rrr < rr ) );
+
+    const irange cr = boost::make_iterator_range( str );
+    BOOST_CHECK_EQUAL( cr.front(), 'h' );
+    BOOST_CHECK_EQUAL( cr.back(), 'd' );
+    BOOST_CHECK_EQUAL( cr[1], 'e' );
+    BOOST_CHECK_EQUAL( cr(1), 'e' );
+
+    rrr = boost::make_iterator_range( str, 1, -1 );
+    BOOST_CHECK( rrr == boost::as_literal("ello worl") );
+    rrr = boost::make_iterator_range( rrr, -1, 1 );
+    BOOST_CHECK( rrr == str );
+
+    check_reference_type();
+    
+    // Check that an iterator range can be instantiated with
+    // a pointer to an array as an iterator.
+    int arr[2][2];
+    boost::make_iterator_range(arr, arr + 2);
+}
+
+namespace iterator_range_test_detail
+{
+    struct less
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l < r;
+        }
+    };
+    
+    struct greater
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l > r;
+        }
+    };
+    
+    struct less_or_equal
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l <= r;
+        }
+    };
+    
+    struct greater_or_equal
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l >= r;
+        }
+    };
+    
+    struct equal_to
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l == r;
+        }
+    };
+    
+    struct not_equal_to
+    {
+        template< class Left, class Right >
+        bool operator()(const Left& l, const Right& r) const
+        {
+            return l != r;
+        }
+    };
+    
+    template< class Pred >
+    void check_iterator_range_operators_impl(Pred pred)
+    {
+        std::vector<std::string> vals;
+        vals.push_back(std::string());
+        vals.push_back("a");
+        vals.push_back("b");
+        vals.push_back("z");
+        vals.push_back("ab");
+        vals.push_back("ba");
+        vals.push_back("abc");
+        vals.push_back("cba");
+        vals.push_back("aa");
+        vals.push_back("aaa");
+        vals.push_back("aab");
+        vals.push_back("bba");
+
+        typedef std::string::const_iterator citer;
+        typedef boost::iterator_range<citer> iter_range;
+
+        typedef std::vector<std::string>::const_iterator value_const_iterator;
+        value_const_iterator first_val = vals.begin();
+        value_const_iterator last_val = vals.end();
+        
+        for (value_const_iterator left_it = first_val; left_it != last_val; ++left_it)
+        {
+            const std::string& leftValue = *left_it;
+            for (value_const_iterator right_it = first_val; right_it != last_val; ++right_it)
+            {
+                const std::string& rightValue = *right_it;
+                iter_range left = boost::make_iterator_range(leftValue);
+                iter_range right = boost::make_iterator_range(rightValue);
+                
+                const bool reference = pred(leftValue, rightValue);
+                
+                BOOST_CHECK_EQUAL( pred(left, right), reference );
+                BOOST_CHECK_EQUAL( pred(left, rightValue), reference );
+                BOOST_CHECK_EQUAL( pred(leftValue, right), reference );
+            }
+        }
+    }
+    
+    void check_iterator_range_from_array()
+    {
+        double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
+        boost::iterator_range<double*> rng = boost::make_iterator_range(source);
+        BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(),
+                                       source, source + 6 );
+    }
+
+    void check_make_iterator_range_n()
+    {
+        using boost::uint32_t;
+
+        std::vector<uint32_t> input;
+        for (uint32_t i = 0; i < 10u; ++i)
+            input.push_back(i);
+
+        boost::iterator_range<std::vector<uint32_t>::iterator> rng =
+                boost::make_iterator_range_n(boost::begin(input), 8u);
+
+        BOOST_CHECK(rng.begin() == input.begin());
+        BOOST_CHECK(rng.end() == input.begin() + 8);
+        BOOST_CHECK_EQUAL(rng.size(), 8u);
+
+        const std::vector<uint32_t>& cinput = input;
+
+        boost::iterator_range<std::vector<uint32_t>::const_iterator> crng =
+                boost::make_iterator_range_n(boost::begin(cinput), 8u);
+
+        BOOST_CHECK(crng.begin() == cinput.begin());
+        BOOST_CHECK(crng.end() == cinput.begin() + 8);
+        BOOST_CHECK_EQUAL(crng.size(), 8u);
+    }
+
+} // namespace iterator_range_test_detail
+
+template<typename Pred>
+inline void check_iterator_range_operator()
+{
+    iterator_range_test_detail::check_iterator_range_operators_impl(
+        Pred());
+}
+
+inline void test_advance()
+{
+    std::vector<int> l;
+    l.push_back(1);
+    l.push_back(2);
+    typedef boost::iterator_range<std::vector<int>::iterator> rng_t;
+
+    rng_t r1(l.begin(), l.end());
+    BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty());
+    
+    rng_t r2(l.begin(), l.end());
+    BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u);
+
+    rng_t r3(l.begin(), l.end());
+    BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u);
+}
+
+struct ptr_iterator
+  : boost::iterator_adaptor<ptr_iterator, int *>
+{
+    ptr_iterator() {}
+    ptr_iterator(int *p) : boost::iterator_adaptor<ptr_iterator, int *>(p) {}
+private:
+    typedef void iterator; // To throw off the SFINAE mechanism in iterator_range
+};
+
+void test_sfinae()
+{
+    boost::iterator_range<ptr_iterator> r(ptr_iterator(0), ptr_iterator(0));
+}
+
+//
+//
+// Check that constness is propagated correct from
+// the iterator types.
+//
+// Test contributed by Larry Evans.
+//
+
+template< class Container >
+int test_iter_range( Container& a_cont )
+{
+    typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type citer_type;
+    typedef boost::iterator_range<citer_type> riter_type;
+    riter_type a_riter( boost::make_iterator_range( a_cont ) );
+    a_riter.front();
+    a_riter.back();
+    int i = a_riter[0];
+    return i;
+}
+
+
+
+void check_reference_type()
+{
+    typedef std::vector<int> veci_type;
+    veci_type a_vec;
+    a_vec.push_back( 999 );
+    test_iter_range<veci_type>(a_vec);
+    test_iter_range<veci_type const>(a_vec);
+}
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+    
+    test->add(BOOST_TEST_CASE(&check_iterator_range));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less>));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less_or_equal>));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater>));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater_or_equal>));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::equal_to>));
+    test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::not_equal_to>));
+    test->add(BOOST_TEST_CASE(&iterator_range_test_detail::check_make_iterator_range_n));
+    test->add(BOOST_TEST_CASE(&test_advance));
+    
+    return test;
+}
+
diff --git a/test/iterator_range_drop.cpp b/test/iterator_range_drop.cpp
new file mode 100644
index 0000000..58ac43c
--- /dev/null
+++ b/test/iterator_range_drop.cpp
@@ -0,0 +1,200 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+class single_pass_iterator
+        : public boost::iterator_facade<
+            single_pass_iterator,
+            boost::int32_t,
+            boost::single_pass_traversal_tag,
+            const boost::int32_t&
+        >
+{
+    friend class boost::iterator_core_access;
+
+    typedef std::vector<boost::int32_t>::const_iterator iterator_t;
+
+public:
+    single_pass_iterator() { }
+
+    explicit single_pass_iterator(iterator_t it)
+        : m_it(it)
+    {
+    }
+
+private:
+    void increment()
+    {
+        ++m_it;
+    }
+
+    bool equal(single_pass_iterator other) const
+    {
+        return m_it == other.m_it;
+    }
+
+    reference dereference() const
+    {
+        return *m_it;
+    }
+
+    iterator_t m_it;
+};
+
+class bidirectional_iterator
+        : public boost::iterator_facade<
+            bidirectional_iterator,
+            boost::int32_t,
+            boost::bidirectional_traversal_tag,
+            const boost::int32_t&
+        >
+{
+    friend class boost::iterator_core_access;
+
+    typedef std::vector<boost::int32_t>::const_iterator iterator_t;
+
+public:
+    bidirectional_iterator() { }
+
+    explicit bidirectional_iterator(iterator_t it)
+        : m_it(it)
+    {
+    }
+
+private:
+    void increment()
+    {
+        ++m_it;
+    }
+
+    void decrement()
+    {
+        --m_it;
+    }
+
+    bool equal(bidirectional_iterator other) const
+    {
+        return m_it == other.m_it;
+    }
+
+    reference dereference() const
+    {
+        return *m_it;
+    }
+
+    iterator_t m_it;
+};
+
+template<typename SinglePassRange>
+boost::iterator_range<single_pass_iterator>
+single_pass_range(const SinglePassRange& rng)
+{
+    return boost::iterator_range<single_pass_iterator>(
+                single_pass_iterator(boost::begin(rng)),
+                single_pass_iterator(boost::end(rng)));
+}
+
+template<typename BidirectionalRange>
+boost::iterator_range<bidirectional_iterator>
+bidirectional_range(const BidirectionalRange& rng)
+{
+    return boost::iterator_range<bidirectional_iterator>(
+                bidirectional_iterator(boost::begin(rng)),
+                bidirectional_iterator(boost::end(rng)));
+}
+
+void test_drop_front()
+{
+    std::vector<boost::int32_t> v;
+    std::vector<boost::int32_t> ref_output;
+
+    for (boost::int32_t i = 0; i < 10; ++i)
+    {
+        v.push_back(i);
+        ref_output.push_back(i);
+    }
+
+    boost::iterator_range<single_pass_iterator> rng = single_pass_range(v);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+
+    rng.drop_front();
+
+    ref_output.erase(ref_output.begin());
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+
+    rng.drop_front(5);
+
+    ref_output.erase(ref_output.begin(), ref_output.begin() + 5);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+}
+
+void test_drop_back()
+{
+    std::vector<boost::int32_t> v;
+    std::vector<boost::int32_t> ref_output;
+
+    for (boost::int32_t i = 0; i < 10; ++i)
+    {
+        v.push_back(i);
+        ref_output.push_back(i);
+    }
+
+    boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(v);
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+
+    rng.drop_back();
+
+    ref_output.pop_back();
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+
+    rng.drop_back(5);
+
+    ref_output.erase(ref_output.end() - 5, ref_output.end());
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
+                                  ref_output.begin(), ref_output.end());
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range iterator_range drop functions");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_front));
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_back));
+
+    return test;
+}
diff --git a/test/iterator_range_equality_bug.cpp b/test/iterator_range_equality_bug.cpp
new file mode 100644
index 0000000..eea47cb
--- /dev/null
+++ b/test/iterator_range_equality_bug.cpp
@@ -0,0 +1,39 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// As reported in https://groups.google.com/forum/#!msg/boost-developers-archive/6JVNg7ZPb4k/RAlvPUec4MAJ
+
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/algorithm/string.hpp>
+
+namespace boost
+{
+    enum {unnamed};
+    struct S { 
+        bool operator<(int) const {return false;}
+        bool operator==(int) const {return false;}
+    };
+    template<typename T>
+    bool foo(T i)
+    {
+        return i < unnamed || i == unnamed;
+    }
+}
+
+int main()
+{
+    using boost::lambda::_1;
+    (void)(_1 == 42);
+    (void)(42 == _1);
+
+    boost::foo(42);
+    boost::foo(boost::S());
+}
diff --git a/test/iterator_range_hash.cpp b/test/iterator_range_hash.cpp
new file mode 100644
index 0000000..3ef9007
--- /dev/null
+++ b/test/iterator_range_hash.cpp
@@ -0,0 +1,52 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/iterator_range_hash.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_iterator_range_hash()
+{
+    std::vector<boost::int32_t> v;
+
+    for (boost::int32_t i = 0; i < 10; ++i)
+    {
+        v.push_back(i);
+    }
+
+    std::size_t ref_output = boost::hash_range(v.begin(), v.end());
+
+    boost::iterator_range<std::vector<boost::int32_t>::iterator> rng(v);
+
+    std::size_t test_output = boost::hash_value(rng);
+
+    BOOST_CHECK_EQUAL(ref_output, test_output);
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range iterator_range hash function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator_range_hash));
+
+    return test;
+}
diff --git a/test/iterator_range_variant.cpp b/test/iterator_range_variant.cpp
new file mode 100644
index 0000000..d55ae85
--- /dev/null
+++ b/test/iterator_range_variant.cpp
@@ -0,0 +1,60 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/detail/workaround.hpp>
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <string>
+
+namespace
+{
+    enum E
+    {
+        e1, e2, e3
+    };
+
+    void test_variant_report()
+    {
+        typedef boost::mpl::vector<
+            E,
+            std::string,
+            boost::iterator_range<std::string::iterator>
+        >::type args;
+
+        typedef boost::make_variant_over<args>::type variant_t;
+
+        variant_t v;
+        std::string s;
+        v = boost::iterator_range<std::string::iterator>(s.begin(), s.end());
+        v = e2;
+        v = std::string();
+
+        // Rationale:
+        // This is cast to const char* to guard against ambiguity in the case
+        // where std::string::iterator it a char*
+        v = static_cast<const char*>("");
+    }
+}
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("iterator range and variant interoperability");
+
+    test->add(BOOST_TEST_CASE(&test_variant_report));
+
+    return test;
+}
diff --git a/test/join.cpp b/test/join.cpp
new file mode 100644
index 0000000..300028b
--- /dev/null
+++ b/test/join.cpp
@@ -0,0 +1,397 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+// Credits:
+// Trac 7376 - was raised by Leonid Gershanovich and his sample was used to
+// make the test case to cover this condition.
+//
+#include <boost/range/join.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+
+#include <boost/foreach.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/assign.hpp>
+#include <boost/range/algorithm_ext.hpp>
+#include <boost/range/irange.hpp>
+
+#include <boost/iterator/iterator_facade.hpp>
+
+#include <algorithm>
+#include <deque>
+#include <list>
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        // This function is a helper function that writes integers
+        // of increasing value into a range. It is used to test
+        // that joined ranged may be written to.
+        //
+        // Requires:
+        // - Range uses shallow copy semantics.
+        template< typename Range >
+        void fill_with_ints(Range rng)
+        {
+            typedef typename range_iterator<Range>::type iterator;
+            iterator target = boost::begin(rng);
+            const int count = boost::distance(rng);
+            for (int i = 0; i < count; ++i)
+            {
+                *target = i;
+                ++target;
+            }
+        }
+
+        // The test_join_traversal function is used to provide additional
+        // tests based upon the underlying join iterator traversal.
+        // The join iterator takes care of the appropriate demotion, and
+        // this demotion.
+
+        // test_join_traversal - additional tests for input and forward
+        // traversal iterators. This is of course a no-op.
+        template< typename Range1, typename Range2, typename TraversalTag >
+        void test_join_traversal(Range1& rng1, Range2& rng2, TraversalTag)
+        {
+        }
+
+        // test_join_traversal - additional tests for bidirectional
+        // traversal iterators.
+        template< typename Range1, typename Range2 >
+        void test_join_traversal(Range1& rng1, Range2& rng2, boost::bidirectional_traversal_tag)
+        {
+            typedef typename range_value<Range1>::type value_type;
+            std::vector<value_type> reference(boost::begin(rng1), boost::end(rng1));
+            boost::push_back(reference, rng2);
+            std::reverse(reference.begin(), reference.end());
+
+            std::vector<value_type> test_result;
+            BOOST_REVERSE_FOREACH( value_type x, join(rng1, rng2) )
+            {
+                test_result.push_back(x);
+            }
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result.begin(), test_result.end() );
+        }
+
+        // Test helper function to implement the additional tests for random
+        // access traversal iterators. This is used by the test_join_traversal
+        // function for random access iterators. The reason that the test
+        // implementation is put into this function is to utilise
+        // template parameter type deduction for the joined range type.
+        template< typename Range1, typename Range2, typename JoinedRange >
+        void test_random_access_join(Range1& rng1, Range2& rng2, JoinedRange joined)
+        {
+            BOOST_CHECK_EQUAL( boost::end(joined) - boost::begin(joined), boost::distance(joined) );
+            BOOST_CHECK( boost::end(joined) <= boost::begin(joined) );
+            BOOST_CHECK( boost::begin(joined) >= boost::end(joined) );
+            if (boost::empty(joined))
+            {
+                BOOST_CHECK(!(boost::begin(joined) < boost::end(joined)));
+                BOOST_CHECK(!(boost::end(joined) > boost::begin(joined)));
+            }
+            else
+            {
+                BOOST_CHECK(boost::begin(joined) < boost::end(joined));
+                BOOST_CHECK(boost::end(joined) < boost::begin(joined));
+            }
+
+            typedef typename boost::range_difference<JoinedRange>::type difference_t;
+            const difference_t count = boost::distance(joined);
+            BOOST_CHECK( boost::begin(joined) + count == boost::end(joined) );
+            BOOST_CHECK( boost::end(joined) - count == boost::begin(joined) );
+
+            typedef typename boost::range_iterator<JoinedRange>::type iterator_t;
+            iterator_t it = boost::begin(joined);
+            it += count;
+            BOOST_CHECK( it == boost::end(joined) );
+
+            it = boost::end(joined);
+            it -= count;
+            BOOST_CHECK( it == boost::begin(joined) );
+        }
+
+        // test_join_traversal function for random access traversal joined
+        // ranges.
+        template< typename Range1, typename Range2 >
+        void test_join_traversal(Range1& rng1, Range2& rng2, boost::random_access_traversal_tag)
+        {
+            test_join_traversal(rng1, rng2, boost::bidirectional_traversal_tag());
+            test_random_access_join(rng1, rng2, join(rng1, rng2));
+        }
+
+        // Test the ability to write values into a joined range. This is
+        // achieved by copying the constant collections, altering them
+        // and then checking the result. Hence this relies upon both
+        // rng1 and rng2 having value copy semantics.
+        template< typename Collection1, typename Collection2 >
+        void test_write_to_joined_range(const Collection1& rng1, const Collection2& rng2)
+        {
+            Collection1 c1(rng1);
+            Collection2 c2(rng2);
+            
+            typedef BOOST_DEDUCED_TYPENAME boost::range_value<
+                Collection1
+            >::type value_t BOOST_RANGE_UNUSED;
+            
+            fill_with_ints(boost::join(c1,c2));
+
+            // Ensure that the size of the written range has not been
+            // altered.
+            BOOST_CHECK_EQUAL( boost::distance(c1), boost::distance(rng1) );
+            BOOST_CHECK_EQUAL( boost::distance(c2), boost::distance(rng2) );
+
+            // For each element x, in c1 ensure that it has been written to
+            // with incrementing integers
+            int x = 0;
+            typedef typename range_iterator<Collection1>::type iterator1;
+            iterator1 it1 = boost::begin(c1);
+            for (; it1 != boost::end(c1); ++it1)
+            {
+                BOOST_CHECK_EQUAL( x, *it1 );
+                ++x;
+            }
+
+            // For each element y, in c2 ensure that it has been written to
+            // with incrementing integers
+            typedef typename range_iterator<Collection2>::type iterator2;
+            iterator2 it2 = boost::begin(c2);
+            for (; it2 != boost::end(c2); ++it2)
+            {
+                BOOST_CHECK_EQUAL( x, *it2 );
+                ++x;
+            }
+        }
+
+        // Perform a unit test of a Boost.Range join() comparing
+        // it to a reference that is populated by appending
+        // elements from both source ranges into a vector.
+        template< typename Collection1, typename Collection2 >
+        void test_join_impl(Collection1& rng1, Collection2& rng2)
+        {
+            typedef typename range_value<Collection1>::type value_type;
+            std::vector<value_type> reference(boost::begin(rng1), boost::end(rng1));
+            boost::push_back(reference, rng2);
+
+            std::vector<value_type> test_result;
+            boost::push_back(test_result, join(rng1, rng2));
+
+            BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                                           test_result.begin(), test_result.end() );
+
+            typedef boost::range_detail::join_iterator<
+                typename boost::range_iterator<Collection1>::type,
+                typename boost::range_iterator<Collection2>::type
+                > join_iterator_t;
+
+            typedef boost::iterator_traversal< join_iterator_t > tag_t;
+
+           test_join_traversal(rng1, rng2, tag_t());
+
+           test_write_to_joined_range(rng1, rng2);
+        }
+
+        // Make a collection filling it with items from the source
+        // range. This is used to build collections of various
+        // sizes populated with various values designed to optimize
+        // the code coverage exercised by the core test function
+        // test_join_impl.
+        template<typename Collection, typename Range>
+        boost::shared_ptr<Collection> makeCollection(const Range& source)
+        {
+            boost::shared_ptr<Collection> c(new Collection);
+            c->insert(c->end(), boost::begin(source), boost::end(source));
+            return c;
+        }
+
+        // This templatised version of the test_join_impl function
+        // generates and populates collections which are later
+        // used as input to the core test function.
+        // The caller of this function explicitly provides the
+        // template parameters. This supports the generation
+        // of testing a large combination of range types to be
+        // joined. It is of particular importance to remember
+        // to combine a random_access range with a bidirectional
+        // range to determine that the correct demotion of
+        // types occurs in the join_iterator.
+        template< typename Collection1, typename Collection2 >
+        void test_join_impl()
+        {
+            typedef boost::shared_ptr<Collection1> collection1_ptr;
+            typedef boost::shared_ptr<Collection2> collection2_ptr;
+            typedef boost::shared_ptr<const Collection1> collection1_cptr;
+            typedef boost::shared_ptr<const Collection2> collection2_cptr;
+            std::vector< collection1_cptr > left_containers;
+            std::vector< collection2_cptr > right_containers;
+
+            left_containers.push_back(collection1_ptr(new Collection1));
+            left_containers.push_back(makeCollection<Collection1>(irange(0,1)));
+            left_containers.push_back(makeCollection<Collection1>(irange(0,100)));
+
+            right_containers.push_back(collection2_ptr(new Collection2));
+            right_containers.push_back(makeCollection<Collection2>(irange(0,1)));
+            right_containers.push_back(makeCollection<Collection2>(irange(0,100)));
+
+            BOOST_FOREACH( collection1_cptr left_container, left_containers )
+            {
+                BOOST_FOREACH( collection2_cptr right_container, right_containers )
+                {
+                    test_join_impl(*left_container, *right_container);
+                }
+            }
+        }
+
+        // entry-point into the unit test for the join() function
+        // this tests a representative sample of combinations of
+        // source range type.
+        void join_test()
+        {
+            test_join_impl< std::vector<int>, std::vector<int> >();
+            test_join_impl< std::list<int>,   std::list<int>   >();
+            test_join_impl< std::deque<int>,  std::deque<int>  >();
+
+            test_join_impl< std::vector<int>, std::list<int>   >();
+            test_join_impl< std::list<int>,   std::vector<int> >();
+            test_join_impl< std::vector<int>, std::deque<int>  >();
+            test_join_impl< std::deque<int>,  std::vector<int> >();
+        }
+        
+        void test_join_iterator_reference_type_constness_ticket8483()
+        {
+            // Just test that this compiles.
+            // Before the fix for bug 8483, the reference type of the joined
+            // range's iterator was incorrect ('int&' instead of 'const int&'),
+            // causing compiler errors.
+            const std::vector<int> v1;
+            std::vector<int> v2;
+            std::vector<int> joined;
+            boost::push_back(joined, join(v1, v2));
+            boost::push_back(joined, join(v2, v1));
+        }
+
+        namespace trac7376
+        {
+            struct base_type
+            {
+                explicit base_type(boost::int32_t value)
+                    : value(value)
+                {
+                }
+
+                virtual boost::int32_t get() const = 0;
+
+                boost::int32_t value;
+            };
+
+            struct derived_type1
+                : base_type
+            {
+                derived_type1(boost::int32_t value)
+                    : base_type(value)
+                {
+                }
+
+                virtual boost::int32_t get() const
+                {
+                    return value * 2;
+                }
+            };
+
+            struct derived_type2
+                : base_type
+            {
+                derived_type2(boost::int32_t value)
+                    : base_type(value)
+                {
+                }
+
+                virtual boost::int32_t get() const
+                {
+                    return value * 4;
+                }
+            };
+
+            struct apply_get
+            {
+                typedef boost::int32_t result_type;
+                result_type operator()(const base_type& arg) const
+                {
+                    return arg.get();
+                }
+            };
+
+            void test_reference_types()
+            {
+                using namespace boost::adaptors;
+
+                typedef boost::range_detail::join_iterator<
+                        std::vector<derived_type1>::iterator,
+                        std::vector<derived_type2>::iterator,
+                        const base_type&,
+                        const base_type&
+                > join_iterator_t;
+
+                std::vector<boost::int32_t> reference_output;
+
+                std::vector<derived_type1> x;
+                for (boost::int32_t i = 0; i < 10; ++i)
+                {
+                    x.push_back(derived_type1(i));
+                    reference_output.push_back(i * 2);
+                }
+
+                std::vector<derived_type2> y;
+                for (boost::int32_t i = 0; i < 10; ++i)
+                {
+                    y.push_back(derived_type2(i));
+                    reference_output.push_back(i * 4);
+                }
+
+                join_iterator_t it(
+                    x,
+                    y,
+                    boost::range_detail::join_iterator_begin_tag());
+
+                std::vector<boost::int32_t> output;
+                boost::push_back(
+                    output,
+                    boost::make_iterator_range(
+                        join_iterator_t(
+                            x, y,
+                            boost::range_detail::join_iterator_begin_tag()),
+                        join_iterator_t(
+                            x, y,
+                            boost::range_detail::join_iterator_end_tag()))
+                        | transformed(apply_get()));
+
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                            output.begin(), output.end(),
+                            reference_output.begin(), reference_output.end());
+            }
+        } // namespace trac7376
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.joined" );
+
+    test->add( BOOST_TEST_CASE( &boost::join_test ) );
+    test->add( BOOST_TEST_CASE( &boost::test_join_iterator_reference_type_constness_ticket8483 ) );
+    test->add( BOOST_TEST_CASE( &boost::trac7376::test_reference_types ) );
+
+    return test;
+}
diff --git a/test/mfc.cpp b/test/mfc.cpp
new file mode 100644
index 0000000..7a13e8e
--- /dev/null
+++ b/test/mfc.cpp
@@ -0,0 +1,743 @@
+// Boost.Range MFC Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <afx.h> // must be here
+
+// #include <pstade/vodka/drink.hpp>
+
+#include <boost/test/test_tools.hpp>
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define BOOST_LIB_NAME boost_test_exec_monitor
+#include <boost/config/auto_link.hpp>
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
+#include <boost/range/mfc.hpp> // can be placed first
+
+
+#include <map>
+#include <boost/concept_check.hpp>
+// #include <boost/foreach.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/end.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/algorithm/string.hpp>
+
+
+#include <afx.h>
+#include <afxcoll.h>
+#include <afxtempl.h>
+
+#if !(_ATL_VER < 0x0700)
+    #include <cstringt.h>
+    #include <atlsimpstr.h>
+    #include <atlstr.h>
+#endif
+
+
+namespace brdm = boost::range_detail_microsoft;
+
+
+// helpers
+//
+
+template< class MfcMapT, class MapT >
+bool test_mfc_map(MfcMapT& map, const MapT& sample)
+{
+    typedef typename boost::range_iterator<MfcMapT>::type iter_t;
+    typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+    bool result = true;
+
+    result = result && (boost::distance(map) == boost::distance(sample));
+    if (!result)
+        return false;
+
+    {
+        for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+            result = result && brdm::test_find_key_and_mapped(sample, *it);
+        }
+    }
+
+    {
+        for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+            result = result && (map[it->first] == it->second);
+        }
+    }
+
+    return result;
+}
+
+
+template< class MfcMapT, class MapT >
+bool test_mfc_cpair_map(MfcMapT& map, const MapT& sample)
+{
+    typedef typename boost::range_iterator<MfcMapT>::type iter_t;
+    typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+    bool result = true;
+
+    result = result && (boost::distance(map) == boost::distance(sample));
+    if (!result)
+        return false;
+
+    {
+        for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+            result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->key, it->value));
+        }
+    }
+
+    {
+        for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+            result = result && (map[it->first] == it->second);
+        }
+    }
+
+    return result;
+}
+
+
+// arrays
+//
+template< class Range >
+void test_CByteArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CByteArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, BYTE *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, BYTE const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CDWordArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CDWordArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, DWORD *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, DWORD const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CObArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CObArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, ::CObject *> >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const ::CObject *> >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CPtrArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CPtrArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, void *> >::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const void *> >::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStringArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CStringArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ::CString *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, ::CString const *>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CUIntArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CUIntArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, UINT *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, UINT const *>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CWordArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CWordArray rng_t;
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, WORD *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, WORD const *>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// lists
+//
+
+template< class Range >
+void test_CObList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CObList rng_t;
+
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       ::CObject *> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, ::CObject const *> >::value ));
+#else
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, ::CObject const * const, ::CObject const * const> >::value ));
+#endif
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CPtrList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CPtrList rng_t;
+
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       void *> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, void const *> >::value ));
+#else
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, void const * const, void const * const> >::value ));
+#endif
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStringList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CStringList rng_t;
+
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       ::CString> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, ::CString const> >::value ));
+#else
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, ::CString const, ::CString const> >::value ));
+#endif
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// maps
+//
+
+template< class MapT >
+void test_CMapPtrToWord(const MapT& sample)
+{
+    typedef ::CMapPtrToWord rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapPtrToPtr(const MapT& sample)
+{
+    typedef ::CMapPtrToPtr rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapStringToOb(const MapT& sample)
+{
+    typedef ::CMapStringToOb rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapStringToPtr(const MapT& sample)
+{
+    typedef ::CMapStringToPtr rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapStringToString(const MapT& sample)
+{
+    typedef ::CMapStringToString rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+    BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
+#endif
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapWordToOb(const MapT& sample)
+{
+    typedef ::CMapWordToOb rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapWordToPtr(const MapT& sample)
+{
+    typedef ::CMapWordToPtr rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+    BOOST_CHECK( ::test_mfc_map(rng, sample) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// templates
+//
+
+template< class Range >
+void test_CArray(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CArray<val_t, const val_t&> rng_t; // An old MFC needs the second template argument.
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, val_t const*>::value ));
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_array(rng, sample) );
+    BOOST_CHECK( brdm::test_random_access(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CList(const Range& sample)
+{
+    typedef typename boost::range_value<Range>::type val_t;
+
+    typedef ::CList<val_t, const val_t&> rng_t;
+
+    BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t,       val_t> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
+#else
+    BOOST_STATIC_ASSERT(( brdm::test_const_iter  < rng_t, brdm::list_iterator<rng_t const, val_t const, val_t const> >::value ));
+#endif
+
+    rng_t rng;
+    BOOST_CHECK( brdm::test_init_list(rng, sample) );
+    BOOST_CHECK( brdm::test_bidirectional(rng) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMap(const MapT& sample)
+{
+    typedef typename MapT::key_type k_t;
+    typedef typename MapT::mapped_type m_t;
+
+    typedef ::CMap<k_t, const k_t&, m_t, const m_t&> rng_t;
+
+    rng_t rng;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+    BOOST_CHECK( brdm::test_init_map(rng, sample) );
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+    BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
+#endif
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrArray()
+{
+    typedef ::CTypedPtrArray< ::CPtrArray, int * > rng_t;
+    boost::function_requires< boost::RandomAccessRangeConcept<rng_t> >();
+
+    rng_t rng;
+    int o1, o2, o3, o4, o5;
+    int *data[] = { &o1, &o2, &o3, &o4, &o5 };
+    BOOST_CHECK( brdm::test_init_array(rng, boost::make_iterator_range(data, data+5)) );
+
+    BOOST_CHECK( *(boost::begin(rng) + 2) == &o3 );
+    BOOST_CHECK( *(boost::end(rng) - 1) == &o5 );        
+
+    // BOOST_CHECK( brdm::test_random_access(rng) ); this range is not mutable
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrList()
+{
+    typedef ::CTypedPtrList< ::CObList, ::CObList * > rng_t;
+    boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+
+    rng_t rng;
+
+    ::CObList o1, o2, o3, o4, o5;
+    ::CObList *data[] = { &o1, &o2, &o3, &o4, &o5 };
+    BOOST_CHECK( brdm::test_init_list(rng, data) );
+
+    boost::range_iterator<rng_t>::type it = boost::begin(rng);
+    std::advance(it, 1);
+    BOOST_CHECK( *it == &o2 );
+    std::advance(it, 2);
+    BOOST_CHECK( *it == &o4 );
+
+    // BOOST_CHECK( brdm::test_bidirectional(rng) ); this range is not mutable
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrMap()
+{
+    typedef ::CTypedPtrMap< ::CMapStringToPtr, ::CString, int *> rng_t;
+    boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+
+    rng_t rng;
+    ::CString o0(_T('a')), o1(_T('c')), o2(_T('f')), o3(_T('q')), o4(_T('g'));
+    int d0, d1, d2, d3, d4;
+    std::map< ::CString, int * > data;
+    data[o0] = &d0, data[o1] = &d1, data[o2] = &d2, data[o3] = &d3, data[o4] = &d4;
+
+    BOOST_CHECK( brdm::test_init_map(rng, data) );
+    BOOST_CHECK( ::test_mfc_map(rng, data) );
+    BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// strings
+//
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+    template< class Range >
+    void test_CString(const Range& sample)
+    {
+        typedef typename boost::range_value<Range>::type val_t;
+
+        typedef ::CString rng_t; // An old MFC needs the second template argument.
+        BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, TCHAR *>::value ));
+        BOOST_STATIC_ASSERT(( brdm::test_const_iter  <rng_t, TCHAR const*>::value ));
+
+        rng_t rng;
+        BOOST_CHECK( brdm::test_init_string(rng, sample) );
+        BOOST_CHECK( brdm::test_random_access(rng) );
+        BOOST_CHECK( brdm::test_emptiness(rng) );
+    }
+
+#endif
+
+
+struct CPerson
+{
+    void hello_range() { };
+};
+
+
+void test_mfc()
+{
+#if 0
+    // overview
+    //
+    {
+        CTypedPtrArray<CPtrArray, CList<CString> *> myArray;
+        // ...
+        BOOST_FOREACH (CList<CString> *theList, myArray)
+        {
+            BOOST_FOREACH (CString& str, *theList)
+            {
+                boost::to_upper(str);
+                std::sort(boost::begin(str), boost::end(str));
+                // ...
+            }
+        }
+    }
+#endif
+
+    // arrays
+    //
+    {
+        BYTE data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+        ::test_CByteArray(boost::make_iterator_range(data, data+22));
+    }
+
+    {
+        DWORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+        test_CDWordArray(boost::make_iterator_range(data, data+22));
+    }
+
+    {
+        ::CObArray o1, o2, o3, o4, o5;
+        ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+        ::test_CObArray(boost::make_iterator_range(data, data+5));
+    }
+
+    {
+        ::CPtrArray o1, o2, o3, o4, o5;
+        void *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+        ::test_CPtrArray(boost::make_iterator_range(data, data+5));
+    }
+
+    {
+        ::CString data[] = {
+            ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
+            ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
+        };
+
+        ::test_CStringArray(boost::make_iterator_range(data, data+8));
+    }
+
+    {
+        ::CUIntArray rng;
+        UINT data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+        ::test_CUIntArray(boost::make_iterator_range(data, data+22));
+    }
+
+    {
+        ::CWordArray rng;
+        WORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+        ::test_CWordArray(boost::make_iterator_range(data, data+22));
+    }
+
+    
+    // lists
+    //
+    {
+        ::CObList rng;
+        ::CObList o1, o2, o3, o4, o5;
+        ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+        ::test_CObList(boost::make_iterator_range(data, data+5));
+    }
+
+    {
+        ::CPtrList rng;
+        ::CPtrList o1, o2, o3, o4, o5;
+        void *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+        ::test_CPtrList(boost::make_iterator_range(data, data+5));
+    }
+
+    {
+        ::CString data[] = {
+            ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
+            ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
+        };
+
+        ::test_CStringList(boost::make_iterator_range(data, data+8));
+    }
+
+
+    // maps
+    //
+    {
+        std::map<void *, WORD> data;
+        int o0, o1, o2, o3, o4;
+        data[&o0] = 15, data[&o1] = 14, data[&o2] = 3, data[&o3] = 6, data[&o4] = 1;
+
+        ::test_CMapPtrToWord(data);
+    }
+
+    {
+        std::map<void *, void*> data;
+        int o0, o1, o2, o3, o4;
+        data[&o0] = &o3, data[&o1] = &o2, data[&o2] = &o1, data[&o3] = &o0, data[&o4] = &o4;
+
+        ::test_CMapPtrToPtr(data);
+    }
+
+    {
+        std::map< ::CString, CObject * > data;
+        CObArray o0, o1, o2, o3, o4;
+        data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
+        data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
+
+        ::test_CMapStringToOb(data);
+    }
+
+    {
+        std::map< ::CString, void * > data;
+        CObArray o0, o1, o2, o3, o4;
+        data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
+        data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
+
+        ::test_CMapStringToPtr(data);
+    }
+
+    {
+        std::map< ::CString, ::CString > data;
+        CString o0('a'), o1('b'), o2('c'), o3('d'), o4('e');
+        data[ ::CString('0') ] = o0, data[ ::CString('1') ] = o1, data[ ::CString('2') ] = o2,
+        data[ ::CString('3') ] = o3, data[ ::CString('4') ] = o4;
+
+        ::test_CMapStringToString(data);
+    }
+
+    {
+        std::map< WORD, CObject * > data;
+        ::CDWordArray o0, o1, o2, o3, o4;
+        data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
+
+        ::test_CMapWordToOb(data);
+    }
+
+    {
+        std::map< WORD, void * > data;
+        ::CDWordArray o0, o1, o2, o3, o4;
+        data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
+
+        ::test_CMapWordToPtr(data);
+    }
+
+    // templates
+    //
+    {
+        std::string data("0987654321qwertyuiop");
+        ::test_CArray(data);
+        ::test_CList(data);
+    }    
+
+    {
+        std::wstring data(L"asdfghjklzxcvbnm");
+        ::test_CArray(data);
+        ::test_CList(data);
+    }    
+
+    {
+        std::map< int, std::string > data;
+        data[0] = "abcde", data[1] = "ajfie", data[2] = "lij", data[3] = "abc", data[4] = "ioiu";
+
+        ::test_CMap(data);
+    }
+
+
+    // typed
+    //
+    {
+        ::test_CTypedPtrArray();
+        ::test_CTypedPtrList();
+        ::test_CTypedPtrMap();
+    }
+
+
+    // strings
+    //
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+    {
+        std::string data("123456789 abcdefghijklmn");
+        ::test_CString(data);
+    }
+#endif
+
+
+} // test_mfc
+
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+
+test_suite *
+init_unit_test_suite(int argc, char* argv[])
+{
+    test_suite *test = BOOST_TEST_SUITE("MFC Range Test Suite");
+    test->add(BOOST_TEST_CASE(&test_mfc));
+
+    (void)argc, (void)argv; // unused
+    return test;
+}
diff --git a/test/mutable_iterator.cpp b/test/mutable_iterator.cpp
new file mode 100644
index 0000000..40a3879
--- /dev/null
+++ b/test/mutable_iterator.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_mutable_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_mutable_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_mutable_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_mutable_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_mutable_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_mutable_iterator));
+
+    return test;
+}
diff --git a/test/partial_workaround.cpp b/test/partial_workaround.cpp
new file mode 100644
index 0000000..edaae71
--- /dev/null
+++ b/test/partial_workaround.cpp
@@ -0,0 +1,114 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/test/test_tools.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+//#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/difference_type.hpp>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/detail/sfinae.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <iostream>
+#include <vector>
+
+using namespace boost;
+using namespace std;
+
+void check_partial_workaround()
+{
+    using namespace range_detail;
+    using type_traits::yes_type;
+    using type_traits::no_type;
+
+    //////////////////////////////////////////////////////////////////////
+    // string
+    //////////////////////////////////////////////////////////////////////
+    char*          c_ptr;
+    const char*    cc_ptr;
+    wchar_t*       w_ptr;
+    const wchar_t* cw_ptr;
+
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( c_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cc_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( w_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cw_ptr ) ) );
+
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_char_ptr_impl( c_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_char_ptr_impl( cc_ptr ) ) );
+
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_wchar_t_ptr_impl( w_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_wchar_t_ptr_impl( cw_ptr ) ) );
+    
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( c_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( cc_ptr ) ) );
+    
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( w_ptr ) ) );
+    BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( cw_ptr ) ) );
+
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_, 
+                          boost::range_detail::range< vector<int> >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_pair_, 
+                          boost::range_detail::range< pair<int,int> >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::array_, 
+                          boost::range_detail::range< int[42] >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::char_ptr_, 
+                          boost::range_detail::range< char* >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_char_ptr_, 
+                          boost::range_detail::range< const char* >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::wchar_t_ptr_, 
+                          boost::range_detail::range< wchar_t* >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_wchar_t_ptr_,
+                          boost::range_detail::range< const wchar_t* >::type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_, 
+                          boost::range_detail::range< vector<int> >::type >::value ));
+
+}
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+void check_partial_workaround()
+{
+    //
+    // test if warnings are generated
+    //
+    std::size_t s = boost::range_detail::array_size( "foo" );
+    BOOST_CHECK_EQUAL( s,  4u );
+}
+
+#endif
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_partial_workaround ) );
+
+    return test;
+}
diff --git a/test/pointer.cpp b/test/pointer.cpp
new file mode 100644
index 0000000..94e78f3
--- /dev/null
+++ b/test/pointer.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/pointer.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_pointer()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::pointer,
+            boost::range_pointer<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_pointer,
+            boost::range_pointer<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::pointer,
+            boost::range_pointer<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_pointer meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_pointer));
+
+    return test;
+}
diff --git a/test/pointer_as_iterator.cpp b/test/pointer_as_iterator.cpp
new file mode 100644
index 0000000..e0e28d0
--- /dev/null
+++ b/test/pointer_as_iterator.cpp
@@ -0,0 +1,39 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/array.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+#include <vector>
+
+namespace
+{
+    void test_pointer_as_iterator()
+    {
+        boost::array<int,3> arr;
+        boost::iterator_range<const int*> r(arr.begin(), arr.end());
+        r[0];
+    }
+} // anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.pointer_as_iterator" );
+
+    test->add(BOOST_TEST_CASE( &test_pointer_as_iterator ));
+
+    return test;
+}
diff --git a/test/reference.cpp b/test/reference.cpp
new file mode 100644
index 0000000..755be0e
--- /dev/null
+++ b/test/reference.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/reference.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_reference()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::reference,
+            boost::range_reference<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_reference,
+            boost::range_reference<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::reference,
+            boost::range_reference<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_reference meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_reference));
+
+    return test;
+}
diff --git a/test/result_iterator.cpp b/test/result_iterator.cpp
new file mode 100644
index 0000000..88dd7a5
--- /dev/null
+++ b/test/result_iterator.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/result_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_result_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_result_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::const_iterator,
+            boost::range_result_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::iterator,
+            boost::range_result_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_result_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_result_iterator));
+
+    return test;
+}
diff --git a/test/reverse_iterator.cpp b/test/reverse_iterator.cpp
new file mode 100644
index 0000000..827f244
--- /dev/null
+++ b/test/reverse_iterator.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/reverse_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_reverse_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::iterator>,
+            boost::range_reverse_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::const_iterator>,
+            boost::range_reverse_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::iterator>,
+            boost::range_reverse_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_reverse_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_iterator));
+
+    return test;
+}
diff --git a/test/reverse_result_iterator.cpp b/test/reverse_result_iterator.cpp
new file mode 100644
index 0000000..7d160fe
--- /dev/null
+++ b/test/reverse_result_iterator.cpp
@@ -0,0 +1,62 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/reverse_result_iterator.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_reverse_result_iterator()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::iterator>,
+            boost::range_reverse_result_iterator<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::const_iterator>,
+            boost::range_reverse_result_iterator<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            boost::reverse_iterator<cont::iterator>,
+            boost::range_reverse_result_iterator<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE(
+                "Boost.Range range_reverse_result_iterator meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_result_iterator));
+
+    return test;
+}
diff --git a/test/reversible_range.cpp b/test/reversible_range.cpp
new file mode 100644
index 0000000..a3dd20c
--- /dev/null
+++ b/test/reversible_range.cpp
@@ -0,0 +1,74 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/rbegin.hpp>
+#include <boost/range/rend.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <vector>
+#include <algorithm>
+
+void check_iterator()
+{
+    typedef std::vector<int>                            vec_t;
+    typedef vec_t::iterator                             iterator;
+    typedef std::pair<iterator,iterator>                pair_t;
+    typedef boost::range_reverse_iterator<pair_t>::type rev_iterator;
+    typedef std::pair<rev_iterator,rev_iterator>        rev_pair_t;
+
+    vec_t                            vec;
+    pair_t                           p    = std::make_pair( vec.begin(), vec.end() );
+    rev_pair_t                       rp   = std::make_pair( boost::rbegin( p ), boost::rend( p ) );
+    int                             a[]  = {1,2,3,4,5,6,7,8,9,10};
+    const int                       ca[] = {1,2,3,4,5,6,7,8,9,10,11,12};
+    BOOST_CHECK( boost::rbegin( vec ) == boost::range_reverse_iterator<vec_t>::type( vec.end() ) );
+    BOOST_CHECK( boost::rend( vec ) == boost::range_reverse_iterator<vec_t>::type( vec.begin() ) );
+    BOOST_CHECK( std::distance( boost::rbegin( vec ), boost::rend( vec ) ) == std::distance( boost::begin( vec ), boost::end( vec ) ) );
+
+    BOOST_CHECK( boost::rbegin( p ) == boost::begin( rp ) );
+    BOOST_CHECK( boost::rend( p ) == boost::end( rp ) );
+    BOOST_CHECK( std::distance( boost::rbegin( p ), boost::rend( p ) ) == std::distance( boost::begin( rp ), boost::end( rp ) ) );
+    BOOST_CHECK( std::distance( boost::begin( p ), boost::end( p ) ) == std::distance( boost::rbegin( rp ), boost::rend( rp ) ) );
+
+
+    BOOST_CHECK_EQUAL( &*boost::begin( a ), &*( boost::rend( a ) - 1 ) );
+    BOOST_CHECK_EQUAL( &*( boost::end( a ) - 1 ), &*boost::rbegin( a ) );
+    BOOST_CHECK_EQUAL( &*boost::begin( ca ), &*( boost::rend( ca ) - 1 ) );
+    BOOST_CHECK_EQUAL( &*( boost::end( ca ) - 1 ), &*boost::rbegin( ca ) );
+}
+
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_iterator ) );
+
+    return test;
+}
+
+
+
+
+
+
+
diff --git a/test/size_type.cpp b/test/size_type.cpp
new file mode 100644
index 0000000..9c335f1
--- /dev/null
+++ b/test/size_type.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/size_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_size()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::size_type,
+            boost::range_size<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::size_type,
+            boost::range_size<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::size_type,
+            boost::range_size<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_size meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_size));
+
+    return test;
+}
diff --git a/test/std_container.cpp b/test/std_container.cpp
new file mode 100644
index 0000000..75a584f
--- /dev/null
+++ b/test/std_container.cpp
@@ -0,0 +1,74 @@
+    // Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <vector>
+
+void check_std_container()
+{
+    typedef std::vector<int> vec_t;
+    vec_t                    vec;
+    vec.push_back( 3 ); vec.push_back( 4 );
+    const vec_t              cvec( vec );
+
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<vec_t>::type, vec_t::value_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<vec_t>::type, vec_t::iterator >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const vec_t>::type, vec_t::const_iterator >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<vec_t>::type, vec_t::difference_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<vec_t>::type, vec_t::size_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<vec_t>::type, vec_t::iterator >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const vec_t>::type, vec_t::const_iterator >::value ));
+
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<const vec_t>::type, vec_t::value_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<const vec_t>::type, vec_t::difference_type >::value ));
+    BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<const vec_t>::type, vec_t::size_type >::value ));
+
+    BOOST_CHECK( boost::begin( vec ) == vec.begin() );
+    BOOST_CHECK( boost::end( vec )   == vec.end() );
+    BOOST_CHECK( boost::empty( vec ) == vec.empty() );
+    BOOST_CHECK( static_cast<std::size_t>(boost::size( vec )) == vec.size() );
+
+    BOOST_CHECK( boost::begin( cvec ) == cvec.begin() );
+    BOOST_CHECK( boost::end( cvec )   == cvec.end() );
+    BOOST_CHECK( boost::empty( cvec ) == cvec.empty() );
+    BOOST_CHECK( static_cast<std::size_t>(boost::size( cvec )) == cvec.size() );
+
+}
+
+
+#include <boost/test/unit_test.hpp>
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_std_container ) );
+
+    return test;
+}
+
+
+
+
+
+
diff --git a/test/string.cpp b/test/string.cpp
new file mode 100644
index 0000000..9ff13f9
--- /dev/null
+++ b/test/string.cpp
@@ -0,0 +1,280 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+//#define _MSL_USING_NAMESPACE 1
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/array.hpp>
+#include <boost/range/as_array.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/config.hpp>
+#include <vector>
+#include <fstream>
+#include <algorithm>
+
+namespace
+{
+    template< class CharT, std::size_t Length >
+    class test_string
+    {
+    public:
+        typedef CharT value_type;
+        typedef value_type* pointer;
+        typedef const value_type* const_pointer;
+        typedef std::size_t size_type;
+        typedef value_type array_t[Length];
+        typedef const value_type const_array_t[Length];
+
+        explicit test_string(const CharT literal_sz[])
+        {
+            std::copy(literal_sz, literal_sz + Length, m_buffer.data());
+            m_buffer[Length] = value_type();
+        }
+
+        const_pointer const_sz() const { return m_buffer.data(); }
+        pointer mutable_sz() { return m_buffer.data(); }
+
+    private:
+        typedef boost::array<value_type, Length + 1> buffer_t;
+        buffer_t m_buffer;
+    };
+}
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
+str_begin( T& r )
+{
+    return boost::begin( boost::as_literal(r) );
+}
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
+str_end( T& r )
+{
+    return boost::end( boost::as_literal(r) );
+}
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<T>::type
+str_size( const T& r )
+{
+    return boost::size( boost::as_literal(r) );
+}
+
+template< class T >
+inline bool
+str_empty( T& r )
+{
+    return boost::empty( boost::as_literal(r) );
+}
+
+template< typename Container, typename T >
+BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+find( Container& c,  T value )
+{
+    return std::find( str_begin(c), str_end(c),
+                      value );
+}
+
+template< typename Container, typename T >
+BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
+find( const Container& c, T value )
+{
+    return std::find( str_begin(c), str_end(c),
+                      value );
+}
+
+template< typename Container, typename T >
+BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
+find_mutable( Container& c,  T value )
+{
+    str_size( c );
+    return std::find( str_begin(c), str_end(c),
+                      value );
+}
+
+template< typename Container, typename T >
+BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
+find_const( const Container& c, T value )
+{
+    str_size( c );
+    return std::find( str_begin(c), str_end(c),
+                      value );
+}
+
+
+std::vector<char>
+check_rvalue_return()
+{
+    return std::vector<char>( 10, 'm' );
+}
+
+using namespace boost;
+
+
+void check_char()
+{
+    typedef boost::range_difference<std::string>::type diff_t;
+    typedef char*                  char_iterator_t;
+    typedef char                   char_array_t[10];
+
+    test_string<char, 8> a_string("a string");
+    test_string<char, 14> another_string("another string");
+
+    const char*      char_s = a_string.const_sz();
+    char             my_string[] = "another_string";
+    const char       my_const_string[] = "another string";
+    const diff_t     my_string_length = 14;
+    char*            char_s2 = a_string.mutable_sz();
+
+    BOOST_STATIC_ASSERT(( is_same<  range_value<char_iterator_t>::type,
+                                    detail::iterator_traits<char_iterator_t>::value_type>::value ));
+    BOOST_STATIC_ASSERT(( is_same<  range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
+
+    BOOST_STATIC_ASSERT(( is_same<  range_difference<char_iterator_t>::type,
+                                    ::std::ptrdiff_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same<  range_size<char_iterator_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same<  range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same<  range_iterator<const char*>::type, const char* >::value ));
+
+    BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type,
+                                    char>::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type,
+                                    ::std::ptrdiff_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_size<char_array_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
+
+    BOOST_CHECK_EQUAL( str_begin( char_s ), char_s );
+    const diff_t sz = str_size(char_s);
+    const char* str_end1 = str_begin( char_s ) + sz;
+    BOOST_CHECK_EQUAL( str_end( char_s ), str_end1 );
+    BOOST_CHECK_EQUAL( str_empty( char_s ), (char_s == 0 || char_s[0] == char()) );
+    BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<char>::length(char_s)) );
+
+    BOOST_CHECK_EQUAL( str_begin( my_string ), my_string );
+    range_iterator<char_array_t>::type str_end2 = str_begin( my_string ) + str_size(my_string);
+    range_iterator<char_array_t>::type str_end3 = str_end(my_string);
+    BOOST_CHECK_EQUAL( str_end3, str_end2 );
+    BOOST_CHECK_EQUAL( str_empty( my_string ), (my_string == 0 || my_string[0] == char()) );
+    BOOST_CHECK_EQUAL( str_size( my_string ), my_string_length );
+    BOOST_CHECK_EQUAL( str_size( my_string ), static_cast<diff_t>(std::char_traits<char>::length(my_string)) );
+
+    char to_search = 'n';
+    BOOST_CHECK( find_mutable( char_s, to_search ) != str_end( char_s ) );
+    BOOST_CHECK( find_const( char_s, to_search ) != str_end(char_s) );
+
+    BOOST_CHECK( find_mutable( my_string, to_search ) != str_end(my_string) );
+    BOOST_CHECK( find_const( my_string, to_search ) != str_end(my_string) );
+
+    BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) );
+    BOOST_CHECK( find_const( char_s2, to_search ) != str_end(char_s2) );
+
+    BOOST_CHECK( find_const( as_array( my_string ), to_search ) != str_end(my_string) );
+    BOOST_CHECK( find_const( as_array( my_const_string ), to_search ) != str_end(my_string) );
+
+    //
+    // Test that as_literal() always scan for null terminator
+    //
+    char an_array[] = "foo\0bar";
+    BOOST_CHECK_EQUAL( str_begin( an_array ), an_array );
+    BOOST_CHECK_EQUAL( str_end( an_array ), an_array + 3 );
+    BOOST_CHECK_EQUAL( str_size( an_array ), 3 );
+
+    const char a_const_array[] = "foobar\0doh";
+    BOOST_CHECK_EQUAL( str_begin( a_const_array ), a_const_array );
+    BOOST_CHECK_EQUAL( str_end( a_const_array ), a_const_array + 6 );
+    BOOST_CHECK_EQUAL( str_size( a_const_array ), 6 );
+
+}
+
+
+
+void check_string()
+{
+    check_char();
+
+#ifndef BOOST_NO_STD_WSTRING
+    typedef wchar_t*               wchar_iterator_t;
+
+    test_string<wchar_t, 13> a_wide_string(L"a wide string");
+    test_string<wchar_t, 19> another_wide_string(L"another wide string");
+
+    const wchar_t*  char_ws      = a_wide_string.const_sz();
+    wchar_t         my_wstring[] = L"another wide string";
+    wchar_t*        char_ws2     = a_wide_string.mutable_sz();
+
+    BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type,
+                                   detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type,
+                                   detail::iterator_traits<wchar_iterator_t>::difference_type >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_size<wchar_iterator_t>::type, std::size_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
+    BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
+
+    typedef boost::range_difference<std::wstring>::type diff_t;
+    const diff_t sz = str_size( char_ws );
+    BOOST_CHECK_EQUAL( str_begin( char_ws ), char_ws );
+    BOOST_CHECK_EQUAL( str_end(char_ws), (str_begin( char_ws ) + sz) );
+    BOOST_CHECK_EQUAL( str_empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) );
+    BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<wchar_t>::length(char_ws)) );
+
+    wchar_t to_search = L'n';
+    BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) );
+    BOOST_CHECK( find( char_ws2, to_search ) != str_end(char_ws2) );
+
+#if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300))
+
+    BOOST_CHECK( find( my_wstring, to_search ) != str_end(my_wstring) );
+
+#else
+
+    boost::ignore_unused_variable_warning( my_wstring );
+
+#endif
+#endif
+
+    find( check_rvalue_return(), 'n' );
+
+}
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+
+    test->add( BOOST_TEST_CASE( &check_string ) );
+
+    return test;
+}
+
+
+
+
+
+
diff --git a/test/sub_range.cpp b/test/sub_range.cpp
new file mode 100644
index 0000000..a6dbb36
--- /dev/null
+++ b/test/sub_range.cpp
@@ -0,0 +1,289 @@
+// Boost.Range library
+//
+//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#  pragma warn -8091 // suppress warning in Boost.Test
+#  pragma warn -8057 // unused argument argc/argv in Boost.Test
+#endif
+
+#include <boost/range/sub_range.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void check_sub_range()
+{
+
+    typedef std::string::iterator                 iterator;
+    typedef std::string::const_iterator           const_iterator;
+    typedef boost::iterator_range<iterator>       irange;
+    typedef boost::iterator_range<const_iterator> cirange;
+    std::string       str  = "hello world";
+    const std::string cstr = "const world";
+    irange r    = boost::make_iterator_range( str );
+    r           = boost::make_iterator_range( str.begin(), str.end() );
+    cirange r2  = boost::make_iterator_range( cstr );
+    r2          = boost::make_iterator_range( cstr.begin(), cstr.end() );
+    r2          = boost::make_iterator_range( str );
+
+    typedef boost::sub_range<std::string>       srange;
+    typedef boost::sub_range<const std::string> csrange;
+    srange s     = r;
+    BOOST_CHECK( r == r );
+    BOOST_CHECK( s == r );
+    s            = boost::make_iterator_range( str );
+    csrange s2   = r;
+    s2           = r2;
+    s2           = boost::make_iterator_range( cstr );
+    BOOST_CHECK( r2 == r2 );
+    BOOST_CHECK( s2 != r2 );
+    s2           = boost::make_iterator_range( str );
+    BOOST_CHECK( !(s != s) );
+
+    BOOST_CHECK( r.begin() == s.begin() );
+    BOOST_CHECK( r2.begin()== s2.begin() );
+    BOOST_CHECK( r.end()   == s.end() );
+    BOOST_CHECK( r2.end()  == s2.end() );
+    BOOST_CHECK_EQUAL( r.size(), s.size() );
+    BOOST_CHECK_EQUAL( r2.size(), s2.size() );
+
+//#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+//    if( !(bool)r )
+//        BOOST_CHECK( false );
+//    if( !(bool)r2 )
+//        BOOST_CHECK( false );
+//    if( !(bool)s )
+//        BOOST_CHECK( false );
+//    if( !(bool)s2 )
+//        BOOST_CHECK( false );
+//#else
+    if( !r )
+        BOOST_CHECK( false );
+    if( !r2 )
+        BOOST_CHECK( false );
+    if( !s )
+        BOOST_CHECK( false );
+    if( !s2 )
+        BOOST_CHECK( false );
+//#endif
+
+    std::cout << r << r2 << s << s2;
+
+    std::string res  = boost::copy_range<std::string>( r );
+    BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() );
+
+    r.empty();
+    s.empty();
+    r.size();
+    s.size();
+
+    //
+    // As of range v2 not legal anymore.
+    //
+    //irange singular_irange;
+    //BOOST_CHECK( singular_irange.empty() );
+    //BOOST_CHECK( singular_irange.size() == 0 );
+    //
+    //srange singular_srange;
+    //BOOST_CHECK( singular_srange.empty() );
+    //BOOST_CHECK( singular_srange.size() == 0 );
+    //
+    //BOOST_CHECK( empty( singular_irange ) );
+    //BOOST_CHECK( empty( singular_srange ) );
+    //
+
+    srange rr = boost::make_iterator_range( str );
+    BOOST_CHECK( rr.equal( r ) );
+
+    rr  = boost::make_iterator_range( str.begin(), str.begin() + 5 );
+    BOOST_CHECK( rr == boost::as_literal("hello") );
+    BOOST_CHECK( rr != boost::as_literal("hell") );
+    BOOST_CHECK( rr < boost::as_literal("hello dude") );
+    BOOST_CHECK( boost::as_literal("hello") == rr );
+    BOOST_CHECK( boost::as_literal("hell")  != rr );
+    BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) );
+
+    irange rrr = rr;
+    BOOST_CHECK( rrr == rr );
+    BOOST_CHECK( !( rrr != rr ) );
+    BOOST_CHECK( !( rrr < rr ) );
+
+    const irange cr = boost::make_iterator_range( str );
+    BOOST_CHECK_EQUAL( cr.front(), 'h' );
+    BOOST_CHECK_EQUAL( cr.back(), 'd' );
+    BOOST_CHECK_EQUAL( cr[1], 'e' );
+    BOOST_CHECK_EQUAL( cr(1), 'e' );
+
+    rrr = boost::make_iterator_range( str, 1, -1 );
+    BOOST_CHECK( rrr == boost::as_literal("ello worl") );
+    rrr = boost::make_iterator_range( rrr, -1, 1 );
+    BOOST_CHECK( rrr == str );
+    rrr.front() = 'H';
+    rrr.back()  = 'D';
+    rrr[1]      = 'E';
+    BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") );
+}
+
+template<class T>
+void check_mutable_type(T&)
+{
+    BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
+}
+
+template<class T>
+void check_constant_type(T&)
+{
+    BOOST_STATIC_ASSERT(boost::is_const<T>::value);
+}
+
+template<class Range, class Iterator>
+void check_is_const_iterator(Iterator it)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            BOOST_DEDUCED_TYPENAME boost::range_iterator<
+                BOOST_DEDUCED_TYPENAME boost::add_const<Range>::type
+            >::type,
+            Iterator
+        >::value));
+}
+
+template<class Range, class Iterator>
+void check_is_iterator(Iterator it)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            BOOST_DEDUCED_TYPENAME boost::range_iterator<
+                BOOST_DEDUCED_TYPENAME boost::remove_const<Range>::type
+            >::type,
+            Iterator
+        >::value));
+}
+
+void const_propagation_mutable_collection(void)
+{
+    typedef std::vector<int> coll_t;
+    typedef boost::sub_range<coll_t> sub_range_t;
+
+    coll_t c;
+    c.push_back(0);
+
+    sub_range_t rng(c);
+    const sub_range_t crng(c);
+
+    check_is_iterator<sub_range_t>(rng.begin());
+    check_is_iterator<sub_range_t>(rng.end());
+
+    check_is_const_iterator<sub_range_t>(crng.begin());
+    check_is_const_iterator<sub_range_t>(crng.end());
+
+    check_mutable_type(rng[0]);
+    check_mutable_type(rng.front());
+    check_mutable_type(rng.back());
+    check_constant_type(crng[0]);
+    check_constant_type(crng.front());
+    check_constant_type(crng.back());
+}
+
+void const_propagation_const_collection(void)
+{
+    typedef std::vector<int> coll_t;
+    typedef boost::sub_range<const coll_t> sub_range_t;
+
+    coll_t c;
+    c.push_back(0);
+
+    sub_range_t rng(c);
+    const sub_range_t crng(c);
+
+    check_is_const_iterator<sub_range_t>(rng.begin());
+    check_is_const_iterator<sub_range_t>(rng.end());
+
+    check_is_const_iterator<sub_range_t>(crng.begin());
+    check_is_const_iterator<sub_range_t>(crng.end());
+
+    check_constant_type(rng[0]);
+    check_constant_type(rng.front());
+    check_constant_type(rng.back());
+    check_constant_type(crng[0]);
+    check_constant_type(crng.front());
+    check_constant_type(crng.back());
+}
+
+inline void test_advance()
+{
+    std::vector<int> l;
+    l.push_back(1);
+    l.push_back(2);
+    typedef boost::sub_range<std::vector<int> > rng_t;
+    rng_t r1(l.begin(), l.end());
+    BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty());
+    
+    rng_t r2(l.begin(), l.end());
+    BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u);
+    
+    rng_t r3(l.begin(), l.end());
+    BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u);
+}
+
+void ticket_10514()
+{
+    typedef std::vector<int> vec_t;
+    typedef boost::sub_range<vec_t> range_t;
+    vec_t v(10);
+    range_t r(v.begin(), v.end());
+    const range_t& cr = r;
+    range_t copy_r = cr;
+
+    BOOST_CHECK(r.begin() == copy_r.begin());
+    BOOST_CHECK(r.end() == copy_r.end());
+
+    BOOST_CHECK(cr.begin() == copy_r.begin());
+    BOOST_CHECK(cr.end() == copy_r.end());
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test::test_suite* test =
+            BOOST_TEST_SUITE( "Boost.Range sub_range test suite" );
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::check_sub_range));
+
+    test->add(BOOST_TEST_CASE(
+                  &boost_range_test::const_propagation_const_collection));
+
+    test->add(BOOST_TEST_CASE(
+                  &boost_range_test::const_propagation_mutable_collection));
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_advance));
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::ticket_10514));
+
+    return test;
+}
+
+
+
+
+
diff --git a/test/test_driver/range_overload_test_driver.hpp b/test/test_driver/range_overload_test_driver.hpp
new file mode 100644
index 0000000..e4b2ce7
--- /dev/null
+++ b/test/test_driver/range_overload_test_driver.hpp
@@ -0,0 +1,74 @@
+    //  Copyright Neil Groves 2013. Use, modification and 
+    //  distribution is subject to the Boost Software License, Version 
+    //  1.0. (See accompanying file LICENSE_1_0.txt or copy at 
+    //  http://www.boost.org/LICENSE_1_0.txt) 
+    // 
+    // 
+    // For more information, see http://www.boost.org/libs/range/ 
+    // 
+    // Acknowledgments:
+    // Implemented by Andy in response to Ticket 6888 - unique fix
+    //
+    #ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED 
+    #define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED 
+     
+    #include "range_return_test_driver.hpp" 
+    #include <boost/assert.hpp> 
+    #include <boost/test/test_tools.hpp> 
+    #include <boost/test/unit_test.hpp> 
+     
+    namespace boost 
+    { 
+        namespace range_test 
+        { 
+             
+            // A test driver to exercise a test through range_return_test_driver 
+            // plus the overload that determines the return_type by overload 
+            // 
+            // The test driver also contains the code required to check the 
+            // return value correctness. 
+            // 
+            // The TestPolicy needs to implement all those required by  
+            // range_return_test_driver, and additionally 
+            // 
+            // - perform the boost range version of the algorithm that determines 
+            //   the return_type by overload 
+            class range_overload_test_driver : range_return_test_driver 
+            { 
+            public: 
+                template< class Container, 
+                          class TestPolicy > 
+                void operator()(Container& cont, TestPolicy policy) 
+                { 
+                    range_return_test_driver::operator()(cont, policy); 
+                    test_range_overload<Container, TestPolicy>()(cont, policy); 
+                } 
+     
+            private: 
+                template< class Container, class TestPolicy > 
+                struct test_range_overload 
+                { 
+                    void operator()(Container& cont, TestPolicy policy) 
+                    { 
+                        typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t; 
+                        typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range_overload<Container> test_range_overload_t; 
+                        const range_return_value result_type = test_range_overload_t::result_type;  
+                        typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t; 
+     
+                        Container reference(cont); 
+                        Container test_cont(cont); 
+     
+                        test_range_overload_t test_range_overload_fn; 
+                        range_return_t range_result = test_range_overload_fn(policy, test_cont); 
+     
+                        iterator_t reference_it = policy.reference(reference); 
+     
+                        check_results<result_type>::test(test_cont, reference, 
+                                                         range_result, reference_it); 
+                    } 
+                }; 
+            }; 
+        } 
+    } 
+     
+    #endif // include guard 
\ No newline at end of file
diff --git a/test/test_driver/range_return_test_driver.hpp b/test/test_driver/range_return_test_driver.hpp
new file mode 100644
index 0000000..3dfd2a2
--- /dev/null
+++ b/test/test_driver/range_return_test_driver.hpp
@@ -0,0 +1,406 @@
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
+#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+    namespace range_test
+    {
+        // check the results of an algorithm that returns
+        // a range_return.
+        //
+        // This version is the general version. It should never be called.
+        // All calls should invoke specialized implementations.
+        template< range_return_value return_type >
+        struct check_results
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&          test,
+                Container&          reference,
+                Iterator            test_it,
+                Iterator            reference_it
+                )
+            {
+                BOOST_ASSERT( false );
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a 'found' iterator
+        template< >
+        struct check_results<return_found>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&          test,
+                Container&          reference,
+                Iterator            test_it,
+                Iterator            reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                    test.begin(), test.end() );
+
+                BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
+                   std::distance(reference.begin(), reference_it) );
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a 'next(found)' iterator
+        template< >
+        struct check_results<return_next>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&          test,
+                Container&          reference,
+                Iterator            test_it,
+                Iterator            reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                    test.begin(), test.end() );
+
+                if (reference_it == reference.end())
+                {
+                    BOOST_CHECK( test_it == test.end() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL(
+                        std::distance(test.begin(), test_it),
+                        std::distance(reference.begin(), reference_it) + 1);
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a 'prior(found)' iterator
+        template< >
+        struct check_results<return_prior>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&          test,
+                Container&          reference,
+                Iterator            test_it,
+                Iterator            reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                    test.begin(), test.end() );
+
+                if (reference_it == reference.begin())
+                {
+                    BOOST_CHECK( test_it == test.begin() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL(
+                        std::distance(test.begin(), test_it) + 1,
+                        std::distance(reference.begin(), reference_it));
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[begin, found)' range
+        template< >
+        struct check_results<return_begin_found>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                BOOST_CHECK( test_rng.begin() == test.begin() );
+
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference_it,
+                    boost::begin(test_rng), boost::end(test_rng)
+                    );
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[begin, next(found))' range
+        template< >
+        struct check_results<return_begin_next>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                BOOST_CHECK( test_rng.begin() == test.begin() );
+
+                if (reference_it == reference.end())
+                {
+                    BOOST_CHECK( test_rng.end() == test.end() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL_COLLECTIONS(
+                        reference.begin(), boost::next(reference_it),
+                        test_rng.begin(), test_rng.end());
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[begin, prior(found))' range
+        template< >
+        struct check_results<return_begin_prior>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                    test.begin(), test.end() );
+
+                BOOST_CHECK( test_rng.begin() == test.begin() );
+
+                if (reference_it == reference.begin())
+                {
+                    BOOST_CHECK( boost::end(test_rng) == test.begin() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1,
+                                       std::distance(reference.begin(), reference_it) );
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[found, end)' range
+        template< >
+        struct check_results<return_found_end>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
+                    test.begin(), test.end() );
+
+                BOOST_CHECK_EQUAL(
+                    std::distance(test.begin(), boost::begin(test_rng)),
+                    std::distance(reference.begin(), reference_it));
+
+                BOOST_CHECK( boost::end(test_rng) == test.end() );
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[next(found), end)' range
+        template< >
+        struct check_results<return_next_end>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                BOOST_CHECK( test_rng.end() == test.end() );
+
+                if (reference_it == reference.end())
+                {
+                    BOOST_CHECK( test_rng.begin() == test.end() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL_COLLECTIONS(
+                        boost::next(reference_it), reference.end(),
+                        test_rng.begin(), test_rng.end()
+                        );
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a 'prior(found), end)' range
+        template< >
+        struct check_results<return_prior_end>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                BOOST_CHECK( test_rng.end() == test.end() );
+
+                if (reference_it == reference.begin())
+                {
+                    BOOST_CHECK( test_rng.begin() == test.begin() );
+                }
+                else
+                {
+                    BOOST_CHECK_EQUAL_COLLECTIONS(
+                        boost::prior(reference_it), reference.end(),
+                        test_rng.begin(), test_rng.end()
+                        );
+                }
+            }
+        };
+
+        // check the results of an algorithm that returns
+        // a '[begin, end)' range
+        template< >
+        struct check_results<return_begin_end>
+        {
+            template< class Container, class Iterator >
+            static void test(
+                Container&                  test,
+                Container&                  reference,
+                iterator_range<Iterator>    test_rng,
+                Iterator                    reference_it
+                )
+            {
+                BOOST_CHECK_EQUAL_COLLECTIONS(
+                    reference.begin(), reference.end(),
+                    test.begin(), test.end()
+                    );
+
+                BOOST_CHECK( test_rng.begin() == test.begin() );
+                BOOST_CHECK( test_rng.end() == test.end() );
+            }
+        };
+
+        // A test driver to exercise a test through all of the range_return
+        // combinations.
+        //
+        // The test driver also contains the code required to check the
+        // return value correctness.
+        //
+        // The TestPolicy needs to implement two functions:
+        //
+        // - perform the boost range version of the algorithm that returns
+        //   a range_return<Container,return_type>::type
+        // template<range_return_value return_type, class Container>
+        // BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type
+        // test(Container& cont);
+        //
+        // - perform the reference std version of the algorithm that
+        //   returns the standard iterator result
+        // template<class Container>
+        // BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
+        // reference(Container& cont);
+        class range_return_test_driver
+        {
+        public:
+            template< class Container,
+                      class TestPolicy >
+            void operator()(Container& cont, TestPolicy policy)
+            {
+                test_range_iter               (cont, policy);
+                test_range<return_found,Container,TestPolicy>      ()(cont, policy);
+                test_range<return_next,Container,TestPolicy>       ()(cont, policy);
+                test_range<return_prior,Container,TestPolicy>      ()(cont, policy);
+                test_range<return_begin_found,Container,TestPolicy>()(cont, policy);
+                test_range<return_begin_next,Container,TestPolicy> ()(cont, policy);
+                test_range<return_begin_prior,Container,TestPolicy>()(cont, policy);
+                test_range<return_found_end,Container,TestPolicy>  ()(cont, policy);
+                test_range<return_next_end,Container,TestPolicy>   ()(cont, policy);
+                test_range<return_prior_end,Container,TestPolicy>  ()(cont, policy);
+                test_range<return_begin_end,Container,TestPolicy>  ()(cont, policy);
+            }
+
+        private:
+            template< class Container, class TestPolicy >
+            void test_range_iter(
+                Container&          cont,
+                TestPolicy          policy
+                )
+            {
+                typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+
+                Container reference(cont);
+                Container test(cont);
+
+                iterator_t range_result = policy.test_iter(test);
+                iterator_t reference_it = policy.reference(reference);
+
+                check_results<return_found>::test(test, reference,
+                                                  range_result, reference_it);
+            }
+
+            template< range_return_value result_type, class Container, class TestPolicy >
+            struct test_range
+            {
+                void operator()(Container& cont, TestPolicy policy)
+                {
+                    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
+                    typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
+                    typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t;
+
+                    Container reference(cont);
+                    Container test_cont(cont);
+
+                    test_range_t test_range_fn;
+                    range_return_t range_result = test_range_fn(policy, test_cont);
+                    iterator_t reference_it = policy.reference(reference);
+
+                    check_results<result_type>::test(test_cont, reference,
+                                                     range_result, reference_it);
+                }
+            };
+        };
+    }
+}
+
+#endif // include guard
diff --git a/test/test_function/check_equal_fn.hpp b/test/test_function/check_equal_fn.hpp
new file mode 100644
index 0000000..8da2ed8
--- /dev/null
+++ b/test/test_function/check_equal_fn.hpp
@@ -0,0 +1,49 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_FUNCTIONS_CHECK_EQUAL_FN_HPP_INCLUDED
+#define BOOST_RANGE_TEST_FUNCTIONS_CHECK_EQUAL_FN_HPP_INCLUDED
+
+#include "counted_function.hpp"
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        template< class Collection >
+        class check_equal_fn : private counted_function
+        {
+            typedef BOOST_DEDUCED_TYPENAME Collection::const_iterator iter_t;
+        public:
+            explicit check_equal_fn( const Collection& c )
+                : m_it(boost::begin(c)), m_last(boost::end(c)) {}
+
+            using counted_function::invocation_count;
+
+            void operator()(int x) const
+            {
+                invoked();
+                BOOST_CHECK( m_it != m_last );
+                if (m_it != m_last)
+                {
+                    BOOST_CHECK_EQUAL( *m_it, x );
+                    ++m_it;
+                }
+            }
+
+        private:
+            mutable iter_t m_it;
+            iter_t m_last;
+        };
+
+    } // namespace range_test_function
+} // namespace boost
+
+#endif // include guard
diff --git a/test/test_function/counted_function.hpp b/test/test_function/counted_function.hpp
new file mode 100644
index 0000000..4a74515
--- /dev/null
+++ b/test/test_function/counted_function.hpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_FUNCTION_COUNTED_FUNCTION_HPP_INCLUDED
+#define BOOST_RANGE_TEST_FUNCTION_COUNTED_FUNCTION_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+
+        class counted_function
+        {
+        public:
+            counted_function() : m_count(0u) {}
+
+            void invoked() const
+            {
+                ++m_count;
+            }
+
+            // Return the number of times that this function object
+            // has been invoked.
+            unsigned int invocation_count() const { return m_count; }
+
+        private:
+            mutable unsigned int m_count;
+        };
+
+    }
+}
+
+#endif // include guard
diff --git a/test/test_function/equal_to_x.hpp b/test/test_function/equal_to_x.hpp
new file mode 100644
index 0000000..14d0016
--- /dev/null
+++ b/test/test_function/equal_to_x.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_EQUAL_TO_X_HPP_INCLUDED
+#define BOOST_RANGE_TEST_TEST_FUNCTION_EQUAL_TO_X_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        template<class Arg>
+        struct equal_to_x
+        {
+            typedef bool result_type;
+            typedef Arg argument_type;
+
+            explicit equal_to_x(Arg x) : m_x(x) {}
+            bool operator()(Arg x) const { return x == m_x; }
+
+        private:
+            Arg m_x;
+        };
+    }
+}
+
+#endif // include guard
diff --git a/test/test_function/false_predicate.hpp b/test/test_function/false_predicate.hpp
new file mode 100644
index 0000000..533e83d
--- /dev/null
+++ b/test/test_function/false_predicate.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_FALSE_PREDICATE_HPP_INCLUDED
+#define BOOST_RANGE_TEST_TEST_FUNCTION_FALSE_PREDICATE_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        struct false_predicate
+        {
+            typedef bool result_type;
+
+            bool operator()() const { return false; }
+            template<class Arg> bool operator()(Arg) const { return false; }
+            template<class Arg1, class Arg2> bool operator()(Arg1,Arg2) const { return false; }
+        };
+    }
+}
+
+#endif // include guard
diff --git a/test/test_function/greater_than_x.hpp b/test/test_function/greater_than_x.hpp
new file mode 100644
index 0000000..032f594
--- /dev/null
+++ b/test/test_function/greater_than_x.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_FUNCTION_GREATER_THAN_X_HPP_INCLUDED
+#define BOOST_RANGE_TEST_FUNCTION_GREATER_THAN_X_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        template< class Number >
+        struct greater_than_x
+        {
+            typedef bool result_type;
+            typedef Number argument_type;
+
+            explicit greater_than_x(Number x) : m_x(x) {}
+            bool operator()(Number x) const { return x > m_x; }
+        private:
+            Number m_x;
+        };
+    } // namespace range_test_function
+} // namespace boost
+
+#endif // include guard
diff --git a/test/test_function/multiply_by_x.hpp b/test/test_function/multiply_by_x.hpp
new file mode 100644
index 0000000..b343c61
--- /dev/null
+++ b/test/test_function/multiply_by_x.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2009. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_MULTIPLY_BY_X_HPP_INCLUDED
+#define BOOST_RANGE_TEST_TEST_FUNCTION_MULTIPLY_BY_X_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        template< class Arg >
+        struct multiply_by_x
+        {
+            typedef Arg result_type;
+            typedef Arg argument_type;
+
+            explicit multiply_by_x(Arg x) : m_x(x) {}
+            Arg operator()(Arg x) const { return x * m_x; }
+        private:
+            Arg m_x;
+        };
+    }
+}
+
+#endif // include guard
diff --git a/test/test_function/true_predicate.hpp b/test/test_function/true_predicate.hpp
new file mode 100644
index 0000000..87a0dca
--- /dev/null
+++ b/test/test_function/true_predicate.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2010. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED
+#define BOOST_RANGE_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED
+
+namespace boost
+{
+    namespace range_test_function
+    {
+        struct true_predicate
+        {
+            typedef bool result_type;
+
+            bool operator()() const { return true; }
+            template<class Arg> bool operator()(Arg) const { return true; }
+            template<class Arg1, class Arg2> bool operator()(Arg1,Arg2) const { return true; }
+        };
+    }
+}
+
+#endif // include guard
diff --git a/test/test_utils.hpp b/test/test_utils.hpp
new file mode 100644
index 0000000..7af920a
--- /dev/null
+++ b/test/test_utils.hpp
@@ -0,0 +1,24 @@
+// Boost.Range library
+//
+//  Copyright Akira Takahashi 2013. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/concepts.hpp>
+
+template <class RandomAccessRng>
+void check_random_access_range_concept(const RandomAccessRng& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRng> ));
+}
+
+template <class BidirectionalRng>
+void check_bidirectional_range_concept(const BidirectionalRng& rng)
+{
+    BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRng> ));
+}
diff --git a/test/ticket_10336.cpp b/test/ticket_10336.cpp
new file mode 100644
index 0000000..541e037
--- /dev/null
+++ b/test/ticket_10336.cpp
@@ -0,0 +1,43 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/iterator_range.hpp>
+#include <boost/unordered_map.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+    namespace
+    {
+        // Ticket 10336 - compilation error in iterator_range and unordered_map
+        void test_ticket_10336()
+        {
+            typedef boost::unordered_map<int,int> container_t;
+            typedef container_t::const_iterator citer_t;
+            typedef boost::iterator_range<citer_t> rng_t;
+            
+            const container_t c;
+            rng_t rng(c.begin(), c.end());
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_10336" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_ticket_10336 ) );
+
+    return test;
+}
diff --git a/test/ticket_5486.cpp b/test/ticket_5486.cpp
new file mode 100644
index 0000000..94d8dd4
--- /dev/null
+++ b/test/ticket_5486.cpp
@@ -0,0 +1,58 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        class TestTicket5486Pred
+        {
+        public:
+            typedef int first_argument_type;
+            typedef int second_argument_type;
+            typedef bool result_type;
+
+            explicit TestTicket5486Pred(int x) {}
+            bool operator()(int,int) const { return true; }
+        private:
+            TestTicket5486Pred();
+        };
+    
+        // Ticket 5486 - pertained to predicates erroneous
+        // requiring default construction
+        void test_ticket_5486()
+        {
+            std::vector<int> v;
+            boost::push_back(v, v | boost::adaptors::adjacent_filtered(TestTicket5486Pred(1)));
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(),
+                                           v.begin(), v.end() );
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5486" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_ticket_5486 ) );
+
+    return test;
+}
diff --git a/test/ticket_5544_terminate_irange.cpp b/test/ticket_5544_terminate_irange.cpp
new file mode 100644
index 0000000..fa64436
--- /dev/null
+++ b/test/ticket_5544_terminate_irange.cpp
@@ -0,0 +1,47 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/irange.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        void test_irange_termination()
+        {
+            std::vector<int> reference;
+            for (int i = 0; i < 9; i += 2)
+                reference.push_back(i);
+                
+            std::vector<int> actual;
+            boost::push_back(actual, boost::irange(0,9,2));
+            
+            BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.end(),
+                                          reference.begin(), reference.end());
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5544" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_irange_termination ) );
+
+    return test;
+}
diff --git a/test/ticket_5547.cpp b/test/ticket_5547.cpp
new file mode 100644
index 0000000..1b9d3f6
--- /dev/null
+++ b/test/ticket_5547.cpp
@@ -0,0 +1,42 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/algorithm/string/join.hpp>
+#include <boost/range/join.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+   
+        // Ticket 5547 - boost::join ambiguous with algorithm::join
+        void test_ticket_5547()
+        {
+            std::vector<int> x;
+            boost::range::join(x,x);
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5547" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_ticket_5547 ) );
+
+    return test;
+}
diff --git a/test/ticket_5556_is_sorted_namespace.cpp b/test/ticket_5556_is_sorted_namespace.cpp
new file mode 100644
index 0000000..78a75cd
--- /dev/null
+++ b/test/ticket_5556_is_sorted_namespace.cpp
@@ -0,0 +1,37 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+// Embarrasingly, the mere inclusion of these headers in this order was
+// enough to trigger the defect. 
+#include <boost/range/algorithm.hpp>
+#include <boost/range/algorithm_ext.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+    namespace
+    {
+        void test_ticket_5556() {}
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5556" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_ticket_5556 ) );
+
+    return test;
+}
diff --git a/test/ticket_5811_indirected_optional.cpp b/test/ticket_5811_indirected_optional.cpp
new file mode 100644
index 0000000..1279a4a
--- /dev/null
+++ b/test/ticket_5811_indirected_optional.cpp
@@ -0,0 +1,48 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/adaptor/indirected.hpp>
+#include <boost/optional.hpp>
+#include <boost/optional/optional_io.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost
+{
+    namespace
+    {
+        void test_ticket_5811_indirected_optional()
+        {
+            std::vector<boost::optional<int> > v;
+            std::vector<int> r;
+            for (int i = 0; i < 10; ++i)
+            {
+                v.push_back(i);
+                r.push_back(i);
+            }
+            BOOST_CHECK_EQUAL_COLLECTIONS(r.begin(), r.end(),
+                                          v.begin(), v.end());
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE("RangeTestSuite.ticket_5811_indirected_optional");
+
+    test->add(BOOST_TEST_CASE(&boost::test_ticket_5811_indirected_optional));
+
+    return test;
+}
diff --git a/test/ticket_6715_iterator_range_equality.cpp b/test/ticket_6715_iterator_range_equality.cpp
new file mode 100644
index 0000000..6c6972d
--- /dev/null
+++ b/test/ticket_6715_iterator_range_equality.cpp
@@ -0,0 +1,52 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/iterator_range_core.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <string>
+
+namespace boost
+{
+    namespace
+    {
+        class str_ref : public boost::iterator_range<const char*>
+        {
+        public:
+            explicit str_ref(const std::string& str)
+                : boost::iterator_range<const char*>(
+                    str.c_str(), str.c_str() + str.size())
+            {
+            }
+        };
+
+        void test_ticket_6715_iterator_range_equality()
+        {
+            std::string src("test");
+            str_ref a(src);
+            str_ref b(src);
+            BOOST_CHECK(a == b);
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE(
+                   "RangeTestSuite.ticket_6715_iterator_range_equality");
+
+    test->add(BOOST_TEST_CASE(
+                      &boost::test_ticket_6715_iterator_range_equality));
+
+    return test;
+}
diff --git a/test/ticket_6944.cpp b/test/ticket_6944.cpp
new file mode 100644
index 0000000..43796a8
--- /dev/null
+++ b/test/ticket_6944.cpp
@@ -0,0 +1,46 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2011. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost
+{
+    typedef std::vector<int>::iterator iter_base;
+    struct iter : boost::iterator_adaptor<iter, iter_base, int, boost::use_default, int> {}; // will be deduced as random-access traversal but input category
+    typedef boost::iterator_range<iter> iter_range;
+    
+    namespace
+    {
+        // Ticket 6944 - Some Range concepts use the incorrect Iterator concept
+        void test_ticket_6944()
+        {
+            BOOST_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<iter_range> ));
+        }
+    }
+}
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+    boost::unit_test::test_suite* test
+        = BOOST_TEST_SUITE( "RangeTestSuite.ticket_6944" );
+
+    test->add( BOOST_TEST_CASE( &boost::test_ticket_6944 ) );
+
+    return test;
+}
diff --git a/test/value_type.cpp b/test/value_type.cpp
new file mode 100644
index 0000000..9a18b2f
--- /dev/null
+++ b/test/value_type.cpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+//  Copyright Neil Groves 2014. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#include <boost/range/value_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace boost_range_test
+{
+    namespace
+    {
+
+void test_value_type()
+{
+    typedef std::vector<int> cont;
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::value_type,
+            boost::range_value<cont>::type
+        >::value));
+
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::value_type,
+            boost::range_value<const cont>::type
+        >::value));
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_ASSERT((
+        boost::is_same<
+            cont::value_type,
+            boost::range_value<cont&&>::type
+        >::value));
+#endif
+}
+
+    } // anonymous namespace
+} // namespace boost_range_test
+
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    boost::unit_test::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Range range_value meta-function");
+
+    test->add(BOOST_TEST_CASE(&boost_range_test::test_value_type));
+
+    return test;
+}